create-principles-disciple 1.134.6 → 1.134.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/console/dist/server/routes/update.js +27 -15
- package/console/dist/server/utils/gateway.d.ts +4 -0
- package/console/dist/server/utils/gateway.js +24 -4
- package/console/dist/ui/pages/settings/UpdatePage.js +5 -3
- package/console/dist/ui/utils/validators.d.ts +2 -0
- package/console/dist/ui/utils/validators.js +3 -0
- package/console/dist/web/assets/app.js +11 -5
- package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js +107 -1
- package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +1 -1
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +1 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/candidate-lineage.pri717.test.d.ts +26 -0
- package/core/dist/runtime-v2/internalization/__tests__/candidate-lineage.pri717.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/candidate-lineage.pri717.test.js +420 -0
- package/core/dist/runtime-v2/internalization/__tests__/candidate-lineage.pri717.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/candidate-lineage.property.test.js +6 -1
- package/core/dist/runtime-v2/internalization/__tests__/candidate-lineage.property.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/candidate-lineage.d.ts +50 -1
- package/core/dist/runtime-v2/internalization/candidate-lineage.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/candidate-lineage.js +204 -77
- package/core/dist/runtime-v2/internalization/candidate-lineage.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +41 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js +59 -9
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/core/package.json +1 -1
- package/host-runtime/dist/internalization-consumer-cycle.js +71 -23
- package/host-runtime/package.json +1 -1
- package/package.json +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js +23 -7
- package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js +4 -1
- package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js.map +1 -1
- package/pd-cli/dist/services/resolve-runtime-from-pd-config.d.ts +28 -2
- package/pd-cli/dist/services/resolve-runtime-from-pd-config.d.ts.map +1 -1
- package/pd-cli/dist/services/resolve-runtime-from-pd-config.js +19 -6
- package/pd-cli/dist/services/resolve-runtime-from-pd-config.js.map +1 -1
- package/pd-cli/dist/services/rulehost-readiness.js +1 -1
- package/pd-cli/dist/services/rulehost-readiness.js.map +1 -1
- package/pd-cli/dist/services/runtime-adapter-resolver.d.ts +14 -1
- package/pd-cli/dist/services/runtime-adapter-resolver.d.ts.map +1 -1
- package/pd-cli/dist/services/runtime-adapter-resolver.js +4 -1
- package/pd-cli/dist/services/runtime-adapter-resolver.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +515 -515
- package/plugin/dist/governance-audit.js +1 -1
- package/plugin/dist/rulehost-evidence.js +1 -1
- package/release-manager/package.json +1 -1
|
@@ -541,7 +541,21 @@ async function fetchWithRetry(url, label) {
|
|
|
541
541
|
}
|
|
542
542
|
throw new Error(`${label} failed after ${MAX_RETRIES + 1} attempts: ${lastError?.message ?? 'unknown'}`);
|
|
543
543
|
}
|
|
544
|
-
|
|
544
|
+
function stopGatewayForUpdate(flow) {
|
|
545
|
+
const stopRes = stopOpenClawGateway();
|
|
546
|
+
if (stopRes.ok)
|
|
547
|
+
return true;
|
|
548
|
+
flow.notice = `OpenClaw gateway stop failed — the gateway kept running during the update (${stopRes.error}). Restart the gateway afterwards so it loads the updated plugin.`;
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
function restartGatewayAfterUpdate(flow) {
|
|
552
|
+
const restartRes = restartOpenClawGateway();
|
|
553
|
+
if (restartRes.ok)
|
|
554
|
+
return;
|
|
555
|
+
const message = `OpenClaw gateway was stopped for the update but failed to restart (${restartRes.error}). Run \`openclaw gateway start\` to restore it.`;
|
|
556
|
+
flow.notice = flow.notice ? `${flow.notice} ${message}` : message;
|
|
557
|
+
}
|
|
558
|
+
async function doApplyUpdate(options, workspaceDir, gatewayFlow = {}) {
|
|
545
559
|
const { targetDir, mergeStrategy, createBackup } = options;
|
|
546
560
|
let backupPath = undefined;
|
|
547
561
|
let appliedChanges = false;
|
|
@@ -564,13 +578,11 @@ async function doApplyUpdate(options, workspaceDir) {
|
|
|
564
578
|
// the gateway isn't running, we proceed (dist/*.js files are not locked).
|
|
565
579
|
const gatewayStatus = await checkOpenClawGateway();
|
|
566
580
|
if (gatewayStatus.isRunning) {
|
|
567
|
-
|
|
568
|
-
if (stopRes.ok) {
|
|
569
|
-
gatewayWasStopped = true;
|
|
570
|
-
}
|
|
581
|
+
gatewayWasStopped = stopGatewayForUpdate(gatewayFlow);
|
|
571
582
|
// If stop failed, proceed anyway — the file operations below don't touch
|
|
572
583
|
// node_modules (excluded from backup and diff), so locks on native modules
|
|
573
584
|
// don't matter. dist/*.js files are read-once by Node, never locked.
|
|
585
|
+
// The failure itself reaches the Owner via gatewayFlow.notice (PRI-723).
|
|
574
586
|
}
|
|
575
587
|
try {
|
|
576
588
|
// 0. Save current version BEFORE any changes
|
|
@@ -791,7 +803,7 @@ async function doApplyUpdate(options, workspaceDir) {
|
|
|
791
803
|
// Fix 5: restart the gateway if we stopped it (even on failure), so the
|
|
792
804
|
// user is never left without a running gateway. Mirrors installer.ts behavior.
|
|
793
805
|
if (gatewayWasStopped) {
|
|
794
|
-
|
|
806
|
+
restartGatewayAfterUpdate(gatewayFlow);
|
|
795
807
|
}
|
|
796
808
|
}
|
|
797
809
|
}
|
|
@@ -1136,7 +1148,7 @@ function ensureRuntimeResolutionLinks(layout, tempDir) {
|
|
|
1136
1148
|
}
|
|
1137
1149
|
return { quarantined };
|
|
1138
1150
|
}
|
|
1139
|
-
async function doInlineFullUpdate(workspaceDir) {
|
|
1151
|
+
async function doInlineFullUpdate(workspaceDir, gatewayFlow = {}) {
|
|
1140
1152
|
const layout = resolveUpdateLayout();
|
|
1141
1153
|
if (!layout) {
|
|
1142
1154
|
return {
|
|
@@ -1292,9 +1304,7 @@ async function doInlineFullUpdate(workspaceDir) {
|
|
|
1292
1304
|
? await checkOpenClawGateway()
|
|
1293
1305
|
: { isRunning: false };
|
|
1294
1306
|
if (gatewayStatus.isRunning) {
|
|
1295
|
-
|
|
1296
|
-
if (stopRes.ok)
|
|
1297
|
-
gatewayWasStopped = true;
|
|
1307
|
+
gatewayWasStopped = stopGatewayForUpdate(gatewayFlow);
|
|
1298
1308
|
}
|
|
1299
1309
|
// Heal legacy installs only after candidate verification. This writes
|
|
1300
1310
|
// outside the release tree, so it must not happen for a refused release.
|
|
@@ -1597,7 +1607,7 @@ async function doInlineFullUpdate(workspaceDir) {
|
|
|
1597
1607
|
finally {
|
|
1598
1608
|
// 8. Restart gateway regardless of success/failure
|
|
1599
1609
|
if (gatewayWasStopped) {
|
|
1600
|
-
|
|
1610
|
+
restartGatewayAfterUpdate(gatewayFlow);
|
|
1601
1611
|
}
|
|
1602
1612
|
}
|
|
1603
1613
|
}
|
|
@@ -1717,10 +1727,11 @@ function legacyApplyMutation(req, res, ctx) {
|
|
|
1717
1727
|
// ADR-0024 D-2 (PRI-709 P0-3): every runtime mutation is journaled.
|
|
1718
1728
|
// `planned` lands after all request validation, so a rejected request
|
|
1719
1729
|
// leaves no transaction behind.
|
|
1720
|
-
const
|
|
1730
|
+
const gatewayFlow = {};
|
|
1731
|
+
const { result, journal } = await runLegacyJournaledMutation({ kind: 'apply', pdHome, pluginDir }, () => doApplyUpdate({ targetDir, mergeStrategy, createBackup }, ctx.workspaceDir, gatewayFlow));
|
|
1721
1732
|
if (!journal.journaled)
|
|
1722
1733
|
logLegacyJournalGap('apply', journal.reason);
|
|
1723
|
-
sendSuccess(res, result);
|
|
1734
|
+
sendSuccess(res, gatewayFlow.notice ? { ...result, gatewayNotice: gatewayFlow.notice } : result);
|
|
1724
1735
|
}
|
|
1725
1736
|
catch (err) {
|
|
1726
1737
|
if (err instanceof SyntaxError) {
|
|
@@ -1790,10 +1801,11 @@ function legacyApplyFullMutation(req, res, ctx) {
|
|
|
1790
1801
|
}
|
|
1791
1802
|
const pluginDir = resolvePluginDir(ctx.workspaceDir);
|
|
1792
1803
|
try {
|
|
1793
|
-
const
|
|
1804
|
+
const gatewayFlow = {};
|
|
1805
|
+
const { result, journal } = await runLegacyJournaledMutation({ kind: 'apply-full', pdHome, pluginDir }, () => doInlineFullUpdate(ctx.workspaceDir, gatewayFlow));
|
|
1794
1806
|
if (!journal.journaled)
|
|
1795
1807
|
logLegacyJournalGap('apply-full', journal.reason);
|
|
1796
|
-
sendSuccess(res, result);
|
|
1808
|
+
sendSuccess(res, gatewayFlow.notice ? { ...result, gatewayNotice: gatewayFlow.notice } : result);
|
|
1797
1809
|
}
|
|
1798
1810
|
catch (err) {
|
|
1799
1811
|
sendError(res, 500, 'update_apply_full_error', err instanceof Error ? err.message : 'Unknown error');
|
|
@@ -16,6 +16,10 @@ export declare function checkOpenClawGateway(): Promise<OpenClawGatewayStatus>;
|
|
|
16
16
|
/**
|
|
17
17
|
* Stop the OpenClaw gateway service. Call before mutating the plugin ext dir
|
|
18
18
|
* to release file locks held on native modules (EPERM on backup copyfile).
|
|
19
|
+
*
|
|
20
|
+
* Tries a plain stop first, then `--force`: recent OpenClaw builds refuse an
|
|
21
|
+
* operator-gateway stop without the flag, while older builds reject the
|
|
22
|
+
* unknown option instead — only trying one shape breaks the other generation.
|
|
19
23
|
*/
|
|
20
24
|
export declare function stopOpenClawGateway(): GatewayControlResult;
|
|
21
25
|
/**
|
|
@@ -110,10 +110,20 @@ export async function checkOpenClawGateway() {
|
|
|
110
110
|
* rc-9: never throws — returns {ok:false, error} so the caller can degrade
|
|
111
111
|
* with a structured reason + nextAction instead of crashing mid-update.
|
|
112
112
|
*/
|
|
113
|
-
function runGatewayServiceCommand(subcommand) {
|
|
113
|
+
function runGatewayServiceCommand(subcommand, extraArgs = []) {
|
|
114
114
|
try {
|
|
115
|
-
// EP-08: argv array + typed subcommand union —
|
|
116
|
-
|
|
115
|
+
// EP-08: argv array + typed subcommand union — every argv is a constant
|
|
116
|
+
// literal, so no external input can reach the command line. shell:true is
|
|
117
|
+
// required on Windows: the npm-global `openclaw` resolves to a .cmd shim,
|
|
118
|
+
// and Node's CVE-2024-27980 hardening refuses to spawn .cmd targets
|
|
119
|
+
// without a shell (observed 2026-09-10 as a silent ENOENT that skipped
|
|
120
|
+
// every gateway stop/restart during console updates — PRI-723).
|
|
121
|
+
execFileSync('openclaw', ['gateway', subcommand, ...extraArgs], {
|
|
122
|
+
stdio: 'pipe',
|
|
123
|
+
encoding: 'utf-8',
|
|
124
|
+
timeout: 15000,
|
|
125
|
+
shell: process.platform === 'win32',
|
|
126
|
+
});
|
|
117
127
|
return { ok: true };
|
|
118
128
|
}
|
|
119
129
|
catch (e) {
|
|
@@ -124,9 +134,19 @@ function runGatewayServiceCommand(subcommand) {
|
|
|
124
134
|
/**
|
|
125
135
|
* Stop the OpenClaw gateway service. Call before mutating the plugin ext dir
|
|
126
136
|
* to release file locks held on native modules (EPERM on backup copyfile).
|
|
137
|
+
*
|
|
138
|
+
* Tries a plain stop first, then `--force`: recent OpenClaw builds refuse an
|
|
139
|
+
* operator-gateway stop without the flag, while older builds reject the
|
|
140
|
+
* unknown option instead — only trying one shape breaks the other generation.
|
|
127
141
|
*/
|
|
128
142
|
export function stopOpenClawGateway() {
|
|
129
|
-
|
|
143
|
+
const plain = runGatewayServiceCommand('stop');
|
|
144
|
+
if (plain.ok)
|
|
145
|
+
return plain;
|
|
146
|
+
const forced = runGatewayServiceCommand('stop', ['--force']);
|
|
147
|
+
if (forced.ok)
|
|
148
|
+
return forced;
|
|
149
|
+
return { ok: false, error: `${plain.error}; forced retry: ${forced.error}` };
|
|
130
150
|
}
|
|
131
151
|
/**
|
|
132
152
|
* Start the OpenClaw gateway service (inverse of stopOpenClawGateway).
|
|
@@ -111,12 +111,13 @@ export function UpdatePage() {
|
|
|
111
111
|
updatedFiles: data.updatedFiles,
|
|
112
112
|
fromVersion: statusData?.currentVersion,
|
|
113
113
|
partialUpdate: data.partialUpdate,
|
|
114
|
+
gatewayNotice: data.gatewayNotice,
|
|
114
115
|
});
|
|
115
116
|
toast.success(t('pages.update.updateSuccess', { version: data.newVersion ?? 'latest' }));
|
|
116
117
|
await loadData();
|
|
117
118
|
}
|
|
118
119
|
else {
|
|
119
|
-
setUpdateResult({ success: false, message: data.message, reason: data.reason, nextAction: data.nextAction });
|
|
120
|
+
setUpdateResult({ success: false, message: data.message, reason: data.reason, nextAction: data.nextAction, gatewayNotice: data.gatewayNotice });
|
|
120
121
|
toast.error(t('pages.update.updateFailed', { message: data.message }));
|
|
121
122
|
}
|
|
122
123
|
}, [t, loadData]);
|
|
@@ -140,12 +141,13 @@ export function UpdatePage() {
|
|
|
140
141
|
fromVersion: statusData?.currentVersion,
|
|
141
142
|
requiresRestart: data.requiresRestart,
|
|
142
143
|
partialUpdate: data.partialUpdate,
|
|
144
|
+
gatewayNotice: data.gatewayNotice,
|
|
143
145
|
});
|
|
144
146
|
toast.success(t('pages.update.fullUpdateSuccess'));
|
|
145
147
|
await loadData();
|
|
146
148
|
}
|
|
147
149
|
else {
|
|
148
|
-
setUpdateResult({ success: false, message: data.message, reason: data.reason, nextAction: data.nextAction });
|
|
150
|
+
setUpdateResult({ success: false, message: data.message, reason: data.reason, nextAction: data.nextAction, gatewayNotice: data.gatewayNotice });
|
|
149
151
|
toast.error(t('pages.update.updateFailed', { message: data.message }));
|
|
150
152
|
}
|
|
151
153
|
}, [t, loadData, statusData?.currentVersion]);
|
|
@@ -180,7 +182,7 @@ export function UpdatePage() {
|
|
|
180
182
|
}
|
|
181
183
|
// ── Loaded state ─────────────────────────────────────────────────────────
|
|
182
184
|
const isUpToDate = statusData ? !statusData.hasUpdate : true;
|
|
183
|
-
return (_jsxs(PageShell, { children: [_jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.update.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.update.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.update.subtitle") }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-update-status", children: [_jsx(SectionTitle, { id: "section-update-status", children: t("pages.update.currentVersion") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-ink-3 text-[13px]", children: t("pages.update.currentVersion") }), _jsx("span", { className: "font-mono text-[13px] text-ink", children: statusData?.currentVersion ?? "—" })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-ink-3 text-[13px]", children: t("pages.update.latestVersion") }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-mono text-[13px] text-ink", children: statusData?.latestVersion ?? "—" }), isUpToDate ? (_jsx("span", { className: "inline-flex items-center border border-green/35 text-green rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.update.upToDate") })) : (_jsx("span", { className: "inline-flex items-center border border-amber/35 text-amber rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.update.updateAvailable") }))] })] })] }), statusData?.error && (_jsxs("div", { className: "mt-4 pt-3 border-t border-line text-[12px] text-ink-4 font-mono", children: [t("pages.update.checkError"), ": ", statusData.error] })), statusData?.syncPending && (_jsx("div", { className: "mt-4 p-3 rounded-[4px] border border-amber/30 bg-amber/5", children: _jsx("p", { className: "text-[12px] text-amber leading-relaxed", children: t("pages.update.syncPending", { pluginVersion: statusData.pluginLatestVersion ?? "" }) }) })), statusData?.codexInstalled && (_jsx("div", { className: "mt-4 p-3 rounded-[4px] border border-amber/30 bg-amber/5", children: _jsx("p", { className: "text-[12px] text-amber leading-relaxed", children: t("pages.update.codexWarning") }) })), statusData?.changelog && statusData.hasUpdate && (_jsxs("div", { className: "mt-4 p-4 rounded-[4px] border border-line bg-surface/50", children: [_jsx("p", { className: "text-[12px] font-mono text-ink-3 uppercase tracking-wide mb-2", children: t("pages.update.whatsNew") }), _jsx("div", { className: "text-[13px] text-ink-2 leading-relaxed max-h-[300px] overflow-y-auto", children: _jsx(MarkdownRenderer, { content: statusData.changelog }) })] })), _jsxs("div", { className: "mt-5 pt-4 border-t border-line flex items-center gap-3 flex-wrap", children: [_jsx("button", { type: "button", onClick: handleCheckForUpdates, disabled: checking || fullUpdating, className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: checking ? t("pages.update.checking") : t("pages.update.checkForUpdates") }), !isUpToDate && (_jsx("button", { type: "button", onClick: () => setShowFullUpdateDialog(true), disabled: checking || fullUpdating, className: "bg-gov text-white rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: fullUpdating ? (_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }), t("pages.update.updating")] })) : (t("pages.update.applyUpdate")) }))] }), updateResult && (_jsx("div", { className: `mt-4 p-4 rounded-[6px] border animate-[pdFadeIn_400ms_ease-out] ${updateResult.success ? 'bg-green/5 border-green/20' : 'bg-red/5 border-red/20'}`, children: _jsxs("div", { className: "flex items-start gap-3", children: [updateResult.success ? (_jsx(CheckCircle2, { className: "h-6 w-6 text-green shrink-0 mt-0.5 animate-[pdFadeIn_600ms_ease-out]", style: { transform: 'scale(1)', animationFillMode: 'both' } })) : (_jsx(XCircle, { className: "h-6 w-6 text-red shrink-0 mt-0.5" })), _jsxs("div", { className: "flex-1 min-w-0", children: [updateResult.success && updateResult.fromVersion && updateResult.newVersion && (_jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [_jsx("span", { className: "font-mono text-[13px] text-ink-3 line-through", children: updateResult.fromVersion }), _jsx(ArrowRight, { className: "h-3.5 w-3.5 text-green" }), _jsx("span", { className: "font-mono text-[13px] text-green font-medium", children: updateResult.newVersion })] })), _jsx("p", { className: `text-[13px] ${updateResult.success ? 'text-green' : 'text-red'}`, children: updateResult.message }), updateResult.success && updateResult.updatedFiles && updateResult.updatedFiles.length > 0 && (_jsx("p", { className: "mt-1 text-[12px] text-ink-4 font-mono", children: t("pages.update.filesUpdated", { count: updateResult.updatedFiles.length }) })), updateResult.success && !updateResult.requiresRestart && (_jsx("p", { className: "mt-2 text-[12px] font-mono text-ink-4", children: t("pages.update.restartHint") })), updateResult.success && updateResult.requiresRestart && (_jsx("p", { className: "mt-2 p-2 rounded-[3px] bg-amber/5 border border-amber/20 text-[12px] text-amber leading-relaxed", children: t("pages.update.fullUpdateRestartPrompt") })), updateResult.success && updateResult.partialUpdate && (_jsx("p", { className: "mt-1 text-[12px] text-amber leading-relaxed", children: t("pages.update.partialUpdateHint") })), !updateResult.success && updateResult.nextAction && (_jsx("p", { className: "mt-1 text-[12px] text-ink-4 font-mono leading-relaxed", children: updateResult.nextAction })), !updateResult.success && (_jsxs("div", { className: "mt-2 flex items-center gap-2", children: [/network|fetch|timeout|ECONNREFUSED|ENOTFOUND/i.test(updateResult.message) && (_jsx("p", { className: "text-[12px] text-ink-4 font-mono", children: t("pages.update.networkErrorHint") })), _jsx("button", { type: "button", onClick: handleApplyUpdate, disabled: updating, className: "text-[12px] text-red underline hover:text-red/80 disabled:opacity-50", children: t("pages.update.retry") })] }))] })] }) }))] })] }), _jsxs("section", { "aria-labelledby": "section-update-history", children: [_jsx(SectionTitle, { id: "section-update-history", children: t("pages.update.history") }), historyErrorReason ? (_jsxs("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: [t("pages.update.loadError"), " (", historyErrorReason, ")"] })) : historyData && historyData.updates.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: historyData.updates.map((entry) => (_jsxs("article", { className: "bg-panel border border-line rounded-[6px] px-5 py-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "inline-flex items-center border border-line rounded-[2px] px-[7px] py-1 font-mono text-[11px] text-ink-3 bg-surface/80 uppercase", children: t("pages.update.version") }), _jsxs("span", { className: "font-mono text-[13px] text-ink", children: [entry.fromVersion, " \u2192 ", entry.toVersion === "failed" ? "—" : entry.toVersion] }), entry.kind !== "failure" && (_jsx("span", { className: "inline-flex items-center border border-line rounded-[2px] px-[7px] py-1 font-mono text-[11px] text-ink-3 bg-surface/80 uppercase", children: t(`pages.update.historyKind.${entry.kind}`) })), !entry.success && entry.kind !== 'refusal' && (_jsx("span", { className: "inline-flex items-center border border-red/35 text-red rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.update.failed") }))] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-ink-3 text-[13px]", children: formatDate(entry.timestamp, i18n.language, {
|
|
185
|
+
return (_jsxs(PageShell, { children: [_jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.update.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.update.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.update.subtitle") }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-update-status", children: [_jsx(SectionTitle, { id: "section-update-status", children: t("pages.update.currentVersion") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-ink-3 text-[13px]", children: t("pages.update.currentVersion") }), _jsx("span", { className: "font-mono text-[13px] text-ink", children: statusData?.currentVersion ?? "—" })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-ink-3 text-[13px]", children: t("pages.update.latestVersion") }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-mono text-[13px] text-ink", children: statusData?.latestVersion ?? "—" }), isUpToDate ? (_jsx("span", { className: "inline-flex items-center border border-green/35 text-green rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.update.upToDate") })) : (_jsx("span", { className: "inline-flex items-center border border-amber/35 text-amber rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.update.updateAvailable") }))] })] })] }), statusData?.error && (_jsxs("div", { className: "mt-4 pt-3 border-t border-line text-[12px] text-ink-4 font-mono", children: [t("pages.update.checkError"), ": ", statusData.error] })), statusData?.syncPending && (_jsx("div", { className: "mt-4 p-3 rounded-[4px] border border-amber/30 bg-amber/5", children: _jsx("p", { className: "text-[12px] text-amber leading-relaxed", children: t("pages.update.syncPending", { pluginVersion: statusData.pluginLatestVersion ?? "" }) }) })), statusData?.codexInstalled && (_jsx("div", { className: "mt-4 p-3 rounded-[4px] border border-amber/30 bg-amber/5", children: _jsx("p", { className: "text-[12px] text-amber leading-relaxed", children: t("pages.update.codexWarning") }) })), statusData?.changelog && statusData.hasUpdate && (_jsxs("div", { className: "mt-4 p-4 rounded-[4px] border border-line bg-surface/50", children: [_jsx("p", { className: "text-[12px] font-mono text-ink-3 uppercase tracking-wide mb-2", children: t("pages.update.whatsNew") }), _jsx("div", { className: "text-[13px] text-ink-2 leading-relaxed max-h-[300px] overflow-y-auto", children: _jsx(MarkdownRenderer, { content: statusData.changelog }) })] })), _jsxs("div", { className: "mt-5 pt-4 border-t border-line flex items-center gap-3 flex-wrap", children: [_jsx("button", { type: "button", onClick: handleCheckForUpdates, disabled: checking || fullUpdating, className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: checking ? t("pages.update.checking") : t("pages.update.checkForUpdates") }), !isUpToDate && (_jsx("button", { type: "button", onClick: () => setShowFullUpdateDialog(true), disabled: checking || fullUpdating, className: "bg-gov text-white rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: fullUpdating ? (_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }), t("pages.update.updating")] })) : (t("pages.update.applyUpdate")) }))] }), updateResult && (_jsx("div", { className: `mt-4 p-4 rounded-[6px] border animate-[pdFadeIn_400ms_ease-out] ${updateResult.success ? 'bg-green/5 border-green/20' : 'bg-red/5 border-red/20'}`, children: _jsxs("div", { className: "flex items-start gap-3", children: [updateResult.success ? (_jsx(CheckCircle2, { className: "h-6 w-6 text-green shrink-0 mt-0.5 animate-[pdFadeIn_600ms_ease-out]", style: { transform: 'scale(1)', animationFillMode: 'both' } })) : (_jsx(XCircle, { className: "h-6 w-6 text-red shrink-0 mt-0.5" })), _jsxs("div", { className: "flex-1 min-w-0", children: [updateResult.success && updateResult.fromVersion && updateResult.newVersion && (_jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [_jsx("span", { className: "font-mono text-[13px] text-ink-3 line-through", children: updateResult.fromVersion }), _jsx(ArrowRight, { className: "h-3.5 w-3.5 text-green" }), _jsx("span", { className: "font-mono text-[13px] text-green font-medium", children: updateResult.newVersion })] })), _jsx("p", { className: `text-[13px] ${updateResult.success ? 'text-green' : 'text-red'}`, children: updateResult.message }), updateResult.success && updateResult.updatedFiles && updateResult.updatedFiles.length > 0 && (_jsx("p", { className: "mt-1 text-[12px] text-ink-4 font-mono", children: t("pages.update.filesUpdated", { count: updateResult.updatedFiles.length }) })), updateResult.success && !updateResult.requiresRestart && (_jsx("p", { className: "mt-2 text-[12px] font-mono text-ink-4", children: t("pages.update.restartHint") })), updateResult.success && updateResult.requiresRestart && (_jsx("p", { className: "mt-2 p-2 rounded-[3px] bg-amber/5 border border-amber/20 text-[12px] text-amber leading-relaxed", children: t("pages.update.fullUpdateRestartPrompt") })), updateResult.success && updateResult.partialUpdate && (_jsx("p", { className: "mt-1 text-[12px] text-amber leading-relaxed", children: t("pages.update.partialUpdateHint") })), updateResult.gatewayNotice && (_jsx("p", { className: "mt-2 p-2 rounded-[3px] bg-amber/5 border border-amber/20 text-[12px] text-amber leading-relaxed font-mono", children: updateResult.gatewayNotice })), !updateResult.success && updateResult.nextAction && (_jsx("p", { className: "mt-1 text-[12px] text-ink-4 font-mono leading-relaxed", children: updateResult.nextAction })), !updateResult.success && (_jsxs("div", { className: "mt-2 flex items-center gap-2", children: [/network|fetch|timeout|ECONNREFUSED|ENOTFOUND/i.test(updateResult.message) && (_jsx("p", { className: "text-[12px] text-ink-4 font-mono", children: t("pages.update.networkErrorHint") })), _jsx("button", { type: "button", onClick: handleApplyUpdate, disabled: updating, className: "text-[12px] text-red underline hover:text-red/80 disabled:opacity-50", children: t("pages.update.retry") })] }))] })] }) }))] })] }), _jsxs("section", { "aria-labelledby": "section-update-history", children: [_jsx(SectionTitle, { id: "section-update-history", children: t("pages.update.history") }), historyErrorReason ? (_jsxs("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: [t("pages.update.loadError"), " (", historyErrorReason, ")"] })) : historyData && historyData.updates.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: historyData.updates.map((entry) => (_jsxs("article", { className: "bg-panel border border-line rounded-[6px] px-5 py-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "inline-flex items-center border border-line rounded-[2px] px-[7px] py-1 font-mono text-[11px] text-ink-3 bg-surface/80 uppercase", children: t("pages.update.version") }), _jsxs("span", { className: "font-mono text-[13px] text-ink", children: [entry.fromVersion, " \u2192 ", entry.toVersion === "failed" ? "—" : entry.toVersion] }), entry.kind !== "failure" && (_jsx("span", { className: "inline-flex items-center border border-line rounded-[2px] px-[7px] py-1 font-mono text-[11px] text-ink-3 bg-surface/80 uppercase", children: t(`pages.update.historyKind.${entry.kind}`) })), !entry.success && entry.kind !== 'refusal' && (_jsx("span", { className: "inline-flex items-center border border-red/35 text-red rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.update.failed") }))] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-ink-3 text-[13px]", children: formatDate(entry.timestamp, i18n.language, {
|
|
184
186
|
year: "numeric",
|
|
185
187
|
month: "short",
|
|
186
188
|
day: "numeric",
|
|
@@ -695,6 +695,8 @@ export interface ApplyUpdateResultData {
|
|
|
695
695
|
reason?: string;
|
|
696
696
|
/** Suggested next action when the update fails. */
|
|
697
697
|
nextAction?: string;
|
|
698
|
+
/** Present when the OpenClaw gateway could not be stopped/restarted around the update (PRI-723). */
|
|
699
|
+
gatewayNotice?: string;
|
|
698
700
|
}
|
|
699
701
|
export declare function validateApplyUpdateResult(v: unknown): ApplyUpdateResultData | null;
|
|
700
702
|
export interface RollbackResultData {
|
|
@@ -1971,6 +1971,9 @@ export function validateApplyUpdateResult(v) {
|
|
|
1971
1971
|
if (Object.hasOwn(v, 'nextAction') && isString(v.nextAction)) {
|
|
1972
1972
|
result.nextAction = v.nextAction;
|
|
1973
1973
|
}
|
|
1974
|
+
if (Object.hasOwn(v, 'gatewayNotice') && isString(v.gatewayNotice)) {
|
|
1975
|
+
result.gatewayNotice = v.gatewayNotice;
|
|
1976
|
+
}
|
|
1974
1977
|
return result;
|
|
1975
1978
|
}
|
|
1976
1979
|
export function validateRollbackResult(v) {
|