mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 10:31:38 +08:00
🎁 Sync 2026-03-21 00:42:24
This commit is contained in:
parent
4c741ce45d
commit
a6f709fc36
@ -1,8 +1,8 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=0.1.1
|
||||
PKG_RELEASE:=3
|
||||
PKG_VERSION:=0.1.2
|
||||
PKG_RELEASE:=4
|
||||
|
||||
LUCI_TITLE:=LuCI support for OpenClaw Launcher
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
@ -74,6 +74,18 @@
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.oclm-section-heading {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.oclm-section-heading h2 {
|
||||
margin: 0 0 2px;
|
||||
}
|
||||
|
||||
.oclm-section-heading .oclm-hint {
|
||||
margin: 0 0 14px;
|
||||
}
|
||||
|
||||
.oclm-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@ -281,6 +293,14 @@
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.oclm-form-grid-ai {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.oclm-form-grid-ai > .oclm-field:first-child {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.oclm-field {
|
||||
display: grid;
|
||||
grid-template-columns: 150px minmax(0, 1fr);
|
||||
|
||||
@ -295,7 +295,7 @@
|
||||
function tick(remaining) {
|
||||
request(config.readyUrl).then(function(rv) {
|
||||
state.consoleReady = !!(rv && rv.ok && rv.ready);
|
||||
render();
|
||||
updateStatusDom(state.status);
|
||||
if (!state.consoleReady && remaining > 1) {
|
||||
state.consoleCheckTimer = window.setTimeout(function() { tick(remaining - 1); }, 1000);
|
||||
} else {
|
||||
@ -303,7 +303,7 @@
|
||||
}
|
||||
}).catch(function() {
|
||||
state.consoleReady = false;
|
||||
render();
|
||||
updateStatusDom(state.status);
|
||||
if (remaining > 1) {
|
||||
state.consoleCheckTimer = window.setTimeout(function() { tick(remaining - 1); }, 1500);
|
||||
} else {
|
||||
@ -379,6 +379,7 @@
|
||||
var showServiceActions = status.installed && !status.installing;
|
||||
var activeTab = state.activeTab || "basic";
|
||||
var savingBasic = state.savingSection === "basic";
|
||||
var savingAi = state.savingSection === "ai";
|
||||
var savingAccess = state.savingSection === "access";
|
||||
|
||||
var serviceButtons = showServiceActions ? (
|
||||
@ -400,30 +401,36 @@
|
||||
'<section class="oclm-card">' +
|
||||
'<h2>服务状态</h2>' +
|
||||
'<div class="oclm-status-grid">' +
|
||||
'<div class="oclm-status-row"><span class="oclm-status-label">状态</span><span class="oclm-status-pill" style="--oclm-spin-duration:' + escapeAttr(statusSpinSeconds(status)) + 's"><span class="oclm-dot ' + statusDotClass(status) + '"></span><span class="oclm-status-spinner" aria-hidden="true"></span>' + escapeHtml(statusText(status)) + '</span>' + (status.running && status.uptime_human ? ('<span class="oclm-tag">运行时间 <strong>' + escapeHtml(status.uptime_human) + '</strong></span>') : '') + '</div>' +
|
||||
'<div>' + ((status.running && status.pid) ? ('<div class="oclm-inline-row"><span class="oclm-tag">PID <strong>' + escapeHtml(status.pid) + '</strong></span></div>') : '') + '</div>' +
|
||||
'<div><div class="oclm-meta-label">地址</div><div class="oclm-address-row"><span class="oclm-address-text">' + escapeHtml(maskedTokenUrl(status.token_url || status.base_url || "")) + '</span>' + ((status.token_url || status.base_url) ? ('<button class="oclm-icon-button" type="button" data-copy-token-url="1" aria-label="复制地址">' + copyIcon("oclm-copy-icon") + '</button>') : '') + '</div></div>' +
|
||||
'<div><div class="oclm-meta-label">目录</div><div>' + escapeHtml(status.base_dir || "-") + '</div></div>' +
|
||||
'<div><div class="oclm-meta-label">版本</div><div class="oclm-version-tags"><a class="oclm-tag oclm-tag-link" href="https://github.com/openclaw/openclaw/releases" target="_blank" rel="noreferrer">OpenClaw <strong>' + escapeHtml(status.openclaw_version || "-") + '</strong></a><span class="oclm-tag">Node <strong>' + escapeHtml(status.node_version || "-") + '</strong></span></div></div>' +
|
||||
'<div class="oclm-status-row"><span class="oclm-status-label">状态</span><span id="oclm-status-pill" class="oclm-status-pill" style="--oclm-spin-duration:' + escapeAttr(statusSpinSeconds(status)) + 's"><span id="oclm-status-dot" class="oclm-dot ' + statusDotClass(status) + '"></span><span class="oclm-status-spinner" aria-hidden="true"></span><span id="oclm-status-text">' + escapeHtml(statusText(status)) + '</span></span>' +
|
||||
'<span id="oclm-uptime" class="oclm-tag' + (status.running && status.uptime_human ? '' : ' oclm-hidden') + '">运行时间 <strong id="oclm-uptime-text">' + escapeHtml(status.uptime_human || "") + '</strong></span>' +
|
||||
'</div>' +
|
||||
'<div><div id="oclm-pid-row"' + ((status.running && status.pid) ? '' : ' class="oclm-hidden"') + '><div class="oclm-inline-row"><span class="oclm-tag">PID <strong id="oclm-pid">' + escapeHtml(status.pid || "") + '</strong></span></div></div></div>' +
|
||||
'<div><div class="oclm-meta-label">地址</div><div class="oclm-address-row"><span id="oclm-address-text" class="oclm-address-text">' + escapeHtml(maskedTokenUrl(status.token_url || status.base_url || "")) + '</span><button id="oclm-copy-token-url" class="oclm-icon-button' + ((status.token_url || status.base_url) ? '' : ' oclm-hidden') + '" type="button" data-copy-token-url="1" aria-label="复制地址">' + copyIcon("oclm-copy-icon") + '</button></div></div>' +
|
||||
'<div><div class="oclm-meta-label">目录</div><div id="oclm-status-base-dir">' + escapeHtml(status.base_dir || "-") + '</div></div>' +
|
||||
'<div><div class="oclm-meta-label">版本</div><div class="oclm-version-tags"><a class="oclm-tag oclm-tag-link" href="https://github.com/openclaw/openclaw/releases" target="_blank" rel="noreferrer">OpenClaw <strong id="oclm-openclaw-version">' + escapeHtml(status.openclaw_version || "-") + '</strong></a><span class="oclm-tag">Node <strong id="oclm-node-version">' + escapeHtml(status.node_version || "-") + '</strong></span></div></div>' +
|
||||
'<div></div>' +
|
||||
'</div>' +
|
||||
'<div class="oclm-status-actions">' +
|
||||
(showInstallAction ? '<div class="oclm-install-inline"><button class="oclm-button oclm-button-primary" type="button" data-install-action="1">' + installLabel + '</button><label class="oclm-check"><input type="checkbox" id="oclm-install-accelerated"' + (installAcceleratedChecked ? ' checked' : '') + ' />Kspeeder 加速安装</label></div>' : '') +
|
||||
(status.running ? '<button class="oclm-button oclm-button-primary" type="button" data-open-console="1"' + (state.consoleReady ? '' : ' disabled') + '>' + openclawIcon("oclm-button-icon") + (state.consoleReady ? '打开控制台' : '控制台准备中…') + '</button>' : '') +
|
||||
(status.installing ? '<button class="oclm-button oclm-button-danger" type="button" data-op="cancel_install">停止安装</button>' : '') +
|
||||
'<div id="oclm-status-actions" class="oclm-status-actions">' +
|
||||
'<div id="oclm-install-inline" class="oclm-install-inline' + (showInstallAction ? '' : ' oclm-hidden') + '">' +
|
||||
'<button id="oclm-install-btn" class="oclm-button oclm-button-primary" type="button" data-install-action="1"' + (status.installing ? ' disabled' : '') + '>' + installLabel + '</button>' +
|
||||
'<label class="oclm-check"><input type="checkbox" id="oclm-install-accelerated"' + (installAcceleratedChecked ? ' checked' : '') + ' />Kspeeder 加速安装</label>' +
|
||||
'</div>' +
|
||||
(status.installing ? '<div class="oclm-status-note">安装任务正在后台运行,点击“安装中”可继续查看日志。</div>' : '') +
|
||||
'<button id="oclm-open-console" class="oclm-button oclm-button-primary' + (status.running ? '' : ' oclm-hidden') + '" type="button" data-open-console="1"' + (state.consoleReady ? '' : ' disabled') + '>' + openclawIcon("oclm-button-icon") + (state.consoleReady ? '打开控制台' : '控制台准备中…') + '</button>' +
|
||||
'<button id="oclm-cancel-install" class="oclm-button oclm-button-danger' + (status.installing ? '' : ' oclm-hidden') + '" type="button" data-op="cancel_install">停止安装</button>' +
|
||||
'</div>' +
|
||||
'<div id="oclm-status-note" class="oclm-status-note' + (status.installing ? '' : ' oclm-hidden') + '">安装任务正在后台运行,点击“安装中”可继续查看日志。</div>' +
|
||||
'</section>' +
|
||||
|
||||
'<section class="oclm-card">' +
|
||||
'<div class="oclm-tabs">' +
|
||||
'<button class="oclm-tab' + (activeTab === "basic" ? ' is-active' : '') + '" type="button" data-tab="basic">基础配置</button>' +
|
||||
'<button class="oclm-tab' + (activeTab === "ai" ? ' is-active' : '') + '" type="button" data-tab="ai">AI配置</button>' +
|
||||
'<button class="oclm-tab' + (activeTab === "access" ? ' is-active' : '') + '" type="button" data-tab="access">访问控制</button>' +
|
||||
'<button class="oclm-tab' + (activeTab === "cleanup" ? ' is-active' : '') + '" type="button" data-tab="cleanup">卸载清理</button>' +
|
||||
'</div>' +
|
||||
'<div class="' + (activeTab === "basic" ? '' : 'oclm-hidden') + '">' +
|
||||
'<h2>基础配置</h2>' +
|
||||
'<div class="oclm-form-grid">' +
|
||||
'<div class="oclm-form-grid oclm-form-grid-ai" style="margin-top: 26px;">' +
|
||||
fieldInput("监听端口", '<input class="oclm-control" type="number" min="1" max="65535" id="oclm-port" value="' + escapeHtml(form.port || "18789") + '" />') +
|
||||
fieldInput("监听范围", selectHtml("oclm-bind", form.bind, [
|
||||
["lan", "所有地址"],
|
||||
@ -431,16 +438,22 @@
|
||||
["auto", "自动"]
|
||||
])) +
|
||||
fieldInput("数据目录", '<input class="oclm-control" type="text" id="oclm-base-dir" list="oclm-base-dir-options" value="' + escapeAttr(form.base_dir || "") + '" /><datalist id="oclm-base-dir-options">' + baseDirOptions + '</datalist>') +
|
||||
'<div class="oclm-section-submit"><button class="oclm-button oclm-button-primary" type="button" id="oclm-save-basic"' + (savingBasic ? ' disabled' : '') + '>' + (savingBasic ? '应用中…' : '保存并应用') + '</button>' + serviceButtons + (state.lastAppliedAt ? '<span class="oclm-applied-hint">已于 ' + escapeHtml(state.lastAppliedAt) + ' 更新配置</span>' : '') + '</div>' +
|
||||
'</div></div>' +
|
||||
|
||||
'<div class="' + (activeTab === "ai" ? '' : 'oclm-hidden') + '">' +
|
||||
'<div class="oclm-section-heading"><h2>AI配置</h2><div class="oclm-hint">先配好一个能马上聊起来的默认 AI,再让openclaw协助你设置更多的AGENT、加角色等操作</div></div>' +
|
||||
'<div class="oclm-form-grid oclm-form-grid-ai">' +
|
||||
fieldInput("默认服务提供商", selectHtml("oclm-agent", form.default_agent, [
|
||||
["openai", "OpenAI"],
|
||||
["anthropic", "Anthropic"],
|
||||
["minimax-cn", "MiniMax CN"],
|
||||
["moonshot", "Moonshot CN"]
|
||||
])) +
|
||||
]) + '<div class="oclm-hint">如果你的供应商是兼容 OpenAI 等协议,可在下方填写中转地址</div>') +
|
||||
fieldInput("API 密钥", passwordHtml("oclm-api-key", form.provider_api_key || "", "sk-...")) +
|
||||
fieldInput("中转地址(可选)", '<input class="oclm-control" type="text" id="oclm-base-url" value="' + escapeHtml(form.provider_base_url || "") + '" placeholder="https://api.example.com" />') +
|
||||
fieldInput("默认模型", '<input class="oclm-control" type="text" id="oclm-model" value="' + escapeAttr(resolveModelValue(form)) + '" placeholder="请按照<provider>/<model-id>格式填写" />') +
|
||||
'<div class="oclm-section-submit"><button class="oclm-button oclm-button-primary" type="button" id="oclm-save-basic"' + (savingBasic ? ' disabled' : '') + '>' + (savingBasic ? '应用中…' : '保存并应用') + '</button>' + serviceButtons + (state.lastAppliedAt ? '<span class="oclm-applied-hint">已于 ' + escapeHtml(state.lastAppliedAt) + ' 更新配置</span>' : '') + '</div>' +
|
||||
'<div class="oclm-section-submit"><button class="oclm-button oclm-button-primary" type="button" id="oclm-save-ai"' + (savingAi ? ' disabled' : '') + '>' + (savingAi ? '应用中…' : '保存 AI配置') + '</button>' + (state.lastAppliedAt ? '<span class="oclm-applied-hint">已于 ' + escapeHtml(state.lastAppliedAt) + ' 更新配置</span>' : '') + '</div>' +
|
||||
'</div></div>' +
|
||||
|
||||
'<div class="' + (activeTab === "access" ? '' : 'oclm-hidden') + '">' +
|
||||
@ -470,6 +483,99 @@
|
||||
bindEvents();
|
||||
}
|
||||
|
||||
function updateStatusDom(status) {
|
||||
status = status || {};
|
||||
|
||||
function byId(id) {
|
||||
if (root.getElementById) return root.getElementById(id);
|
||||
return root.querySelector("#" + id);
|
||||
}
|
||||
|
||||
var pill = byId("oclm-status-pill");
|
||||
var dot = byId("oclm-status-dot");
|
||||
var textEl = byId("oclm-status-text");
|
||||
if (!pill || !dot || !textEl) {
|
||||
render();
|
||||
return;
|
||||
}
|
||||
|
||||
pill.style.setProperty("--oclm-spin-duration", statusSpinSeconds(status) + "s");
|
||||
dot.classList.remove("is-success");
|
||||
dot.classList.remove("is-danger");
|
||||
var cls = statusDotClass(status);
|
||||
if (cls) dot.classList.add(cls);
|
||||
textEl.textContent = statusText(status);
|
||||
|
||||
var uptimeWrap = byId("oclm-uptime");
|
||||
var uptimeText = byId("oclm-uptime-text");
|
||||
if (uptimeWrap && uptimeText) {
|
||||
if (status.running && status.uptime_human) {
|
||||
uptimeText.textContent = String(status.uptime_human);
|
||||
uptimeWrap.classList.remove("oclm-hidden");
|
||||
} else {
|
||||
uptimeText.textContent = "";
|
||||
uptimeWrap.classList.add("oclm-hidden");
|
||||
}
|
||||
}
|
||||
|
||||
var pidRow = byId("oclm-pid-row");
|
||||
var pidText = byId("oclm-pid");
|
||||
if (pidRow && pidText) {
|
||||
if (status.running && status.pid) {
|
||||
pidText.textContent = String(status.pid);
|
||||
pidRow.classList.remove("oclm-hidden");
|
||||
} else {
|
||||
pidText.textContent = "";
|
||||
pidRow.classList.add("oclm-hidden");
|
||||
}
|
||||
}
|
||||
|
||||
var addrText = byId("oclm-address-text");
|
||||
if (addrText) addrText.textContent = maskedTokenUrl(status.token_url || status.base_url || "");
|
||||
var copyBtn = byId("oclm-copy-token-url");
|
||||
if (copyBtn) {
|
||||
if (status.token_url || status.base_url) copyBtn.classList.remove("oclm-hidden");
|
||||
else copyBtn.classList.add("oclm-hidden");
|
||||
}
|
||||
|
||||
var baseDirEl = byId("oclm-status-base-dir");
|
||||
if (baseDirEl) baseDirEl.textContent = String(status.base_dir || "-");
|
||||
var openclawVerEl = byId("oclm-openclaw-version");
|
||||
if (openclawVerEl) openclawVerEl.textContent = String(status.openclaw_version || "-");
|
||||
var nodeVerEl = byId("oclm-node-version");
|
||||
if (nodeVerEl) nodeVerEl.textContent = String(status.node_version || "-");
|
||||
|
||||
var installInline = byId("oclm-install-inline");
|
||||
var installBtn = byId("oclm-install-btn");
|
||||
var cancelInstallBtn = byId("oclm-cancel-install");
|
||||
var openConsoleBtn = byId("oclm-open-console");
|
||||
var noteEl = byId("oclm-status-note");
|
||||
|
||||
var showInstallAction = !status.installed || status.installing;
|
||||
if (installInline) {
|
||||
if (showInstallAction) installInline.classList.remove("oclm-hidden");
|
||||
else installInline.classList.add("oclm-hidden");
|
||||
}
|
||||
if (installBtn) {
|
||||
installBtn.textContent = status.installing ? "安装中" : "立即安装";
|
||||
installBtn.disabled = !!status.installing;
|
||||
}
|
||||
if (cancelInstallBtn) {
|
||||
if (status.installing) cancelInstallBtn.classList.remove("oclm-hidden");
|
||||
else cancelInstallBtn.classList.add("oclm-hidden");
|
||||
}
|
||||
if (openConsoleBtn) {
|
||||
if (status.running) openConsoleBtn.classList.remove("oclm-hidden");
|
||||
else openConsoleBtn.classList.add("oclm-hidden");
|
||||
openConsoleBtn.disabled = !(status.running && state.consoleReady);
|
||||
openConsoleBtn.innerHTML = openclawIcon("oclm-button-icon") + (state.consoleReady ? "打开控制台" : "控制台准备中…");
|
||||
}
|
||||
if (noteEl) {
|
||||
if (status.installing) noteEl.classList.remove("oclm-hidden");
|
||||
else noteEl.classList.add("oclm-hidden");
|
||||
}
|
||||
}
|
||||
|
||||
function fieldInput(label, control) {
|
||||
return '<div class="oclm-field"><div class="oclm-label">' + label + '</div><div>' + control + '</div></div>';
|
||||
}
|
||||
@ -514,9 +620,56 @@
|
||||
'</svg>';
|
||||
}
|
||||
|
||||
function syncDraftFromDom() {
|
||||
if (!state.form) {
|
||||
state.form = {};
|
||||
}
|
||||
|
||||
function getEl(id) {
|
||||
return root.getElementById ? root.getElementById(id) : root.querySelector("#" + id);
|
||||
}
|
||||
|
||||
var portEl = getEl("oclm-port");
|
||||
if (portEl) state.form.port = portEl.value;
|
||||
|
||||
var bindEl = getEl("oclm-bind");
|
||||
if (bindEl) state.form.bind = bindEl.value;
|
||||
|
||||
var baseDirEl = getEl("oclm-base-dir");
|
||||
if (baseDirEl) state.form.base_dir = baseDirEl.value;
|
||||
|
||||
var installAccelEl = getEl("oclm-install-accelerated");
|
||||
if (installAccelEl) state.form.install_accelerated = !!installAccelEl.checked;
|
||||
|
||||
var agentEl = getEl("oclm-agent");
|
||||
if (agentEl) state.form.default_agent = agentEl.value;
|
||||
|
||||
var apiKeyEl = getEl("oclm-api-key");
|
||||
if (apiKeyEl) state.form.provider_api_key = apiKeyEl.value;
|
||||
|
||||
var baseUrlEl = getEl("oclm-base-url");
|
||||
if (baseUrlEl) state.form.provider_base_url = baseUrlEl.value;
|
||||
|
||||
var modelEl = getEl("oclm-model");
|
||||
if (modelEl) state.form.default_model = modelEl.value;
|
||||
|
||||
var tokenEl = getEl("oclm-token");
|
||||
if (tokenEl) state.form.token = tokenEl.value;
|
||||
|
||||
var allowInsecureEl = getEl("oclm-allow_insecure_auth");
|
||||
if (allowInsecureEl) state.form.allow_insecure_auth = !!allowInsecureEl.checked;
|
||||
|
||||
var disableDeviceEl = getEl("oclm-disable_device_auth");
|
||||
if (disableDeviceEl) state.form.disable_device_auth = !!disableDeviceEl.checked;
|
||||
|
||||
var newOriginEl = getEl("oclm-new-origin");
|
||||
if (newOriginEl) state.newOrigin = newOriginEl.value;
|
||||
}
|
||||
|
||||
function bindEvents() {
|
||||
Array.prototype.forEach.call(root.querySelectorAll("[data-tab]"), function(el) {
|
||||
el.onclick = function() {
|
||||
syncDraftFromDom();
|
||||
state.activeTab = el.getAttribute("data-tab") || "basic";
|
||||
render();
|
||||
};
|
||||
@ -652,6 +805,27 @@
|
||||
};
|
||||
}
|
||||
|
||||
var apiKey = root.getElementById("oclm-api-key");
|
||||
if (apiKey) {
|
||||
apiKey.oninput = function() {
|
||||
state.form.provider_api_key = apiKey.value;
|
||||
};
|
||||
}
|
||||
|
||||
var baseUrl = root.getElementById("oclm-base-url");
|
||||
if (baseUrl) {
|
||||
baseUrl.oninput = function() {
|
||||
state.form.provider_base_url = baseUrl.value;
|
||||
};
|
||||
}
|
||||
|
||||
var modelInput = root.getElementById("oclm-model");
|
||||
if (modelInput) {
|
||||
modelInput.oninput = function() {
|
||||
state.form.default_model = modelInput.value;
|
||||
};
|
||||
}
|
||||
|
||||
var addOrigin = root.getElementById("oclm-add-origin");
|
||||
if (addOrigin) {
|
||||
addOrigin.onclick = function() {
|
||||
@ -665,6 +839,13 @@
|
||||
};
|
||||
}
|
||||
|
||||
var newOrigin = root.getElementById("oclm-new-origin");
|
||||
if (newOrigin) {
|
||||
newOrigin.oninput = function() {
|
||||
state.newOrigin = newOrigin.value;
|
||||
};
|
||||
}
|
||||
|
||||
Array.prototype.forEach.call(root.querySelectorAll("[data-remove-origin]"), function(el) {
|
||||
el.onclick = function() {
|
||||
var index = parseInt(el.getAttribute("data-remove-origin"), 10);
|
||||
@ -690,11 +871,7 @@
|
||||
port: root.getElementById("oclm-port").value,
|
||||
bind: root.getElementById("oclm-bind").value,
|
||||
base_dir: root.getElementById("oclm-base-dir").value,
|
||||
default_agent: root.getElementById("oclm-agent").value,
|
||||
default_model: root.getElementById("oclm-model").value,
|
||||
install_accelerated: !!(root.getElementById("oclm-install-accelerated") && root.getElementById("oclm-install-accelerated").checked),
|
||||
provider_api_key: root.getElementById("oclm-api-key").value,
|
||||
provider_base_url: root.getElementById("oclm-base-url").value
|
||||
};
|
||||
state.savingSection = "basic";
|
||||
render();
|
||||
@ -706,6 +883,25 @@
|
||||
};
|
||||
}
|
||||
|
||||
var saveAi = root.getElementById("oclm-save-ai");
|
||||
if (saveAi) {
|
||||
saveAi.onclick = function() {
|
||||
var payload = {
|
||||
default_agent: root.getElementById("oclm-agent").value,
|
||||
default_model: root.getElementById("oclm-model").value,
|
||||
provider_api_key: root.getElementById("oclm-api-key").value,
|
||||
provider_base_url: root.getElementById("oclm-base-url").value
|
||||
};
|
||||
state.savingSection = "ai";
|
||||
render();
|
||||
postJson(config.configUrl, payload).then(function(rv) { handleSaveResult(rv, "ai"); }).catch(function() {
|
||||
state.savingSection = "";
|
||||
render();
|
||||
window.alert("保存失败");
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
var saveAccess = root.getElementById("oclm-save-access");
|
||||
if (saveAccess) {
|
||||
saveAccess.onclick = function() {
|
||||
@ -770,14 +966,14 @@
|
||||
showTaskLog("openclawmgr");
|
||||
}
|
||||
state.lastTaskRunning = !!(state.status && state.status.task_running);
|
||||
render();
|
||||
updateStatusDom(state.status);
|
||||
ensureInstallWatch();
|
||||
if (typeof done === "function") {
|
||||
done();
|
||||
}
|
||||
}).catch(function() {
|
||||
state.status = state.status || {};
|
||||
render();
|
||||
updateStatusDom(state.status);
|
||||
ensureInstallWatch();
|
||||
if (typeof done === "function") {
|
||||
done();
|
||||
|
||||
@ -890,6 +890,15 @@ install_openclaw() {
|
||||
# Node version is bundled/managed by installer code; do not allow UCI override.
|
||||
uci -q delete "${UCI_NS}.main.node_version" >/dev/null 2>&1 || true
|
||||
uci -q commit "$UCI_NS" >/dev/null 2>&1 || true
|
||||
|
||||
# Ensure token exists even if runtime is already installed (service start requires it).
|
||||
TOKEN="$(uci_get token)"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
TOKEN="$(gen_token)"
|
||||
uci -q set "${UCI_NS}.main.token=$TOKEN" && uci -q commit "$UCI_NS" || true
|
||||
fi
|
||||
ensure_gateway_config || true
|
||||
|
||||
if have_openclaw_runtime; then
|
||||
write_installer_log "OpenClaw is already installed: $(openclaw_version || echo unknown)"
|
||||
write_installer_log "Skip install. Use restart/apply config if you only need to refresh configuration."
|
||||
@ -902,12 +911,6 @@ install_openclaw() {
|
||||
fi
|
||||
check_space_mb "$BASE_DIR" 2048 || return 1
|
||||
|
||||
TOKEN="$(uci_get token)"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
TOKEN="$(gen_token)"
|
||||
uci -q set "${UCI_NS}.main.token=$TOKEN" && uci -q commit "$UCI_NS" || true
|
||||
fi
|
||||
|
||||
install_node
|
||||
install_openclaw
|
||||
ensure_gateway_config || true
|
||||
@ -1134,6 +1137,7 @@ ACTION="${1:-help}"
|
||||
shift 1 || true
|
||||
|
||||
BASE_DIR="$(uci_get base_dir)"
|
||||
ENABLED="$(uci_get enabled)"
|
||||
PORT="$(uci_get port)"
|
||||
BIND="$(uci_get bind)"
|
||||
TOKEN="$(uci_get token)"
|
||||
@ -1148,6 +1152,7 @@ PROVIDER_BASE_URL="$(uci_get provider_base_url)"
|
||||
|
||||
[ -n "$PORT" ] || PORT="18789"
|
||||
[ -n "$BIND" ] || BIND="lan"
|
||||
[ -n "$ENABLED" ] || ENABLED="0"
|
||||
NODE_VERSION="24.14.0"
|
||||
[ -n "$ALLOW_INSECURE_AUTH" ] || ALLOW_INSECURE_AUTH="1"
|
||||
[ -n "$DISABLE_DEVICE_AUTH" ] || DISABLE_DEVICE_AUTH="1"
|
||||
@ -1164,6 +1169,10 @@ case "$BIND" in
|
||||
loopback|lan|auto|tailnet|custom) ;;
|
||||
*) BIND="lan" ;;
|
||||
esac
|
||||
case "$ENABLED" in
|
||||
1|true|yes|on) ENABLED="1" ;;
|
||||
*) ENABLED="0" ;;
|
||||
esac
|
||||
case "$ALLOW_INSECURE_AUTH" in
|
||||
1|true|yes|on) ALLOW_INSECURE_AUTH="1" ;;
|
||||
*) ALLOW_INSECURE_AUTH="0" ;;
|
||||
|
||||
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=miniupnpd
|
||||
PKG_VERSION:=2.3.9
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_URL:=https://github.com/miniupnp/miniupnp/releases/download/miniupnpd_$(subst .,_,$(PKG_VERSION))
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
|
||||
@ -13,7 +13,7 @@ config upnpd config
|
||||
option upnp_lease_file /var/run/miniupnpd.leases
|
||||
option igdv1 1
|
||||
option ipv6_disable 1
|
||||
option use_stun 1
|
||||
option use_stun 0
|
||||
option stun_host stun.miwifi.com
|
||||
option stun_port 3478
|
||||
option force_forwarding 1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user