create-principles-disciple 1.127.2 → 1.129.0
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/models/HealthCheckModel.d.ts +4 -1
- package/console/dist/server/models/HealthCheckModel.js +6 -5
- package/console/dist/server/routes/update.js +8 -83
- package/console/dist/server/utils/installed-layout.d.ts +21 -0
- package/console/dist/server/utils/installed-layout.js +92 -0
- package/console/dist/server/utils/pd-backups.d.ts +9 -0
- package/console/dist/server/utils/pd-backups.js +5 -1
- package/console/dist/ui/pages/settings/UpdatePage.js +2 -1
- package/console/dist/web/assets/app.js +975 -824
- package/console/dist/web/index.html +4 -0
- package/core/dist/runtime-v2/index.d.ts +2 -2
- 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__/context-resolution.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/context-resolution.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/context-resolution.test.js +377 -0
- package/core/dist/runtime-v2/internalization/__tests__/context-resolution.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/progressive-disclosure-spike.test.js +8 -8
- package/core/dist/runtime-v2/internalization/__tests__/progressive-disclosure-spike.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js +628 -0
- package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts +23 -0
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.js +104 -13
- package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/context-manifests.d.ts +90 -17
- package/core/dist/runtime-v2/internalization/context-manifests.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/context-manifests.js +124 -27
- package/core/dist/runtime-v2/internalization/context-manifests.js.map +1 -1
- package/core/dist/runtime-v2/internalization/context-resolution.d.ts +189 -0
- package/core/dist/runtime-v2/internalization/context-resolution.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/context-resolution.js +317 -0
- package/core/dist/runtime-v2/internalization/context-resolution.js.map +1 -0
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +32 -0
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +72 -7
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/runner/base-peer-runner.d.ts +62 -17
- package/core/dist/runtime-v2/runner/base-peer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/runner/base-peer-runner.js +116 -10
- package/core/dist/runtime-v2/runner/base-peer-runner.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +27 -3
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +6 -0
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/dist/runtime-v2/types/index.d.ts +2 -2
- package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/index.js +1 -1
- package/core/dist/runtime-v2/types/index.js.map +1 -1
- package/core/dist/telemetry-event.d.ts +2 -2
- package/core/dist/telemetry-event.d.ts.map +1 -1
- package/core/dist/telemetry-event.js +47 -0
- package/core/dist/telemetry-event.js.map +1 -1
- package/core/package.json +1 -1
- package/host-runtime/package.json +1 -1
- package/install-layout/package.json +7 -3
- package/package.json +2 -2
- package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js +7 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +412 -412
- package/plugin/dist/core/event-log.d.ts +8 -1
- package/plugin/dist/core/trajectory.d.ts +11 -0
- package/plugin/dist/core/workspace-context.d.ts +7 -0
- package/plugin/dist/governance-audit.js +136 -136
- package/plugin/dist/rulehost-evidence.js +136 -136
- package/plugin/dist/types/event-types.d.ts +1 -1
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
|
@@ -38,7 +38,10 @@ export declare class HealthCheckModel {
|
|
|
38
38
|
constructor(workspaceDir: string);
|
|
39
39
|
checkSystemHealth(): Promise<SystemHealthStatus>;
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
41
|
+
* Read the installed PD plugin version — the same authority the update
|
|
42
|
+
* page shows as "当前版本" (utils/installed-layout.ts resolves the install
|
|
43
|
+
* layout; a fixed relative path cannot work because the dev tree and the
|
|
44
|
+
* installed legacy layout have different depths).
|
|
42
45
|
* Returns 'unknown' on any resolution/parse failure (rc-9: no silent throw).
|
|
43
46
|
*/
|
|
44
47
|
private static readPdVersion;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { OperatorHealthReadModel, PainChainReadModel, PruningReadModel, RuntimeStateManager, } from '@principles/core/runtime-v2';
|
|
3
|
+
import { readInstalledPdVersion } from '../utils/installed-layout.js';
|
|
3
4
|
// P0-2: createRequire lets us read package.json via Node's module resolution
|
|
4
5
|
// in ESM context. Resolves relative to this module's URL in both tsx (dev)
|
|
5
6
|
// and compiled JS (prod) since both mirror the same directory depth.
|
|
@@ -45,15 +46,15 @@ export class HealthCheckModel {
|
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
/**
|
|
48
|
-
*
|
|
49
|
+
* Read the installed PD plugin version — the same authority the update
|
|
50
|
+
* page shows as "当前版本" (utils/installed-layout.ts resolves the install
|
|
51
|
+
* layout; a fixed relative path cannot work because the dev tree and the
|
|
52
|
+
* installed legacy layout have different depths).
|
|
49
53
|
* Returns 'unknown' on any resolution/parse failure (rc-9: no silent throw).
|
|
50
54
|
*/
|
|
51
55
|
static readPdVersion() {
|
|
52
56
|
try {
|
|
53
|
-
|
|
54
|
-
// reaches the monorepo root package.json.
|
|
55
|
-
const pkg = moduleRequire('../../../../../package.json');
|
|
56
|
-
return typeof pkg.version === 'string' ? pkg.version : 'unknown';
|
|
57
|
+
return readInstalledPdVersion() ?? 'unknown';
|
|
57
58
|
}
|
|
58
59
|
catch {
|
|
59
60
|
return 'unknown';
|
|
@@ -7,8 +7,8 @@ import { sendSuccess, sendError, sendMethodNotAllowed, sendBadRequest, sendNotFo
|
|
|
7
7
|
import { appendUpdateHistory } from './update-history.js';
|
|
8
8
|
import { checkOpenClawGateway, stopOpenClawGateway, restartOpenClawGateway, } from '../utils/gateway.js';
|
|
9
9
|
import { migrateLegacyExtensionBackups, reservePdBackupDestination, resolvePdBackupsRoot, } from '../utils/pd-backups.js';
|
|
10
|
+
import { resolveExtensionsDir, resolveUpdateLayout, resolvePluginDir, readCurrentVersion, } from '../utils/installed-layout.js';
|
|
10
11
|
import { ActivationCompatibilityReadModel } from '@principles/core/runtime-v2';
|
|
11
|
-
import { getInstallLayoutPaths, resolveInstallLayout } from '@principles/install-layout';
|
|
12
12
|
import { collectFileDepLinkSpecs } from '../utils/update-links.js';
|
|
13
13
|
/**
|
|
14
14
|
* Legacy rule contract preflight (2026-08-19): refuse to swap the runtime
|
|
@@ -49,88 +49,13 @@ const SKIP_DIRS = new Set(['node_modules']);
|
|
|
49
49
|
// ---------------------------------------------------------------------------
|
|
50
50
|
// Helpers
|
|
51
51
|
// ---------------------------------------------------------------------------
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* Note: the workspace (where PD state lives) and the OpenClaw install home
|
|
60
|
-
* (where extensions live) are NOT necessarily the same directory or even
|
|
61
|
-
* siblings — the workspace can be on a different drive. Do not derive the
|
|
62
|
-
* extensions dir from `path.dirname(workspaceDir)`.
|
|
63
|
-
*/
|
|
64
|
-
function resolveOpenclawHome() {
|
|
65
|
-
const envHome = process.env.OPENCLAW_HOME;
|
|
66
|
-
if (envHome && envHome.trim().length > 0)
|
|
67
|
-
return path.resolve(envHome);
|
|
68
|
-
return path.join(os.homedir(), '.openclaw');
|
|
69
|
-
}
|
|
70
|
-
function resolveExtensionsDir() {
|
|
71
|
-
return path.join(resolveOpenclawHome(), 'extensions');
|
|
72
|
-
}
|
|
73
|
-
function resolveUpdateLayout() {
|
|
74
|
-
const homeDir = os.homedir();
|
|
75
|
-
const paths = getInstallLayoutPaths(homeDir);
|
|
76
|
-
const legacyPluginDir = path.join(resolveExtensionsDir(), 'principles-disciple');
|
|
77
|
-
let manifest;
|
|
78
|
-
try {
|
|
79
|
-
manifest = JSON.parse(fs.readFileSync(paths.manifest, 'utf8'));
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
manifest = undefined;
|
|
83
|
-
}
|
|
84
|
-
const resolution = resolveInstallLayout({
|
|
85
|
-
homeDir,
|
|
86
|
-
manifest,
|
|
87
|
-
canonicalRuntimeExists: fs.existsSync(paths.runtimeDir),
|
|
88
|
-
legacyExtensionExists: fs.existsSync(legacyPluginDir),
|
|
89
|
-
});
|
|
90
|
-
if (resolution.mode === 'missing')
|
|
91
|
-
return undefined;
|
|
92
|
-
if (resolution.mode === 'canonical') {
|
|
93
|
-
return {
|
|
94
|
-
pluginDir: paths.pluginDir,
|
|
95
|
-
consoleDir: paths.consoleDir,
|
|
96
|
-
coreDir: paths.coreDir,
|
|
97
|
-
hostRuntimeDir: paths.hostRuntimeDir,
|
|
98
|
-
pdCliDir: paths.pdCliDir,
|
|
99
|
-
installLayoutDir: paths.installLayoutDir,
|
|
100
|
-
hosts: resolution.manifest?.hosts ?? [],
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
pluginDir: legacyPluginDir,
|
|
105
|
-
consoleDir: path.join(legacyPluginDir, 'console'),
|
|
106
|
-
coreDir: path.join(legacyPluginDir, 'core'),
|
|
107
|
-
hostRuntimeDir: path.join(legacyPluginDir, 'host-runtime'),
|
|
108
|
-
pdCliDir: path.join(legacyPluginDir, 'pd-cli'),
|
|
109
|
-
installLayoutDir: path.join(legacyPluginDir, 'install-layout'),
|
|
110
|
-
hosts: ['openclaw'],
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function resolvePluginDir(_workspaceDir) {
|
|
114
|
-
return resolveUpdateLayout()?.pluginDir ?? path.join(resolveExtensionsDir(), 'principles-disciple');
|
|
115
|
-
}
|
|
116
|
-
function readCurrentVersion(pluginDir) {
|
|
117
|
-
const pkgPath = path.join(pluginDir, 'package.json');
|
|
118
|
-
try {
|
|
119
|
-
if (!fs.existsSync(pkgPath))
|
|
120
|
-
return undefined;
|
|
121
|
-
const raw = fs.readFileSync(pkgPath, 'utf-8');
|
|
122
|
-
const parsed = JSON.parse(raw);
|
|
123
|
-
if (typeof parsed === 'object' && parsed !== null && Object.hasOwn(parsed, 'version')) {
|
|
124
|
-
const { version } = parsed;
|
|
125
|
-
if (typeof version === 'string')
|
|
126
|
-
return version;
|
|
127
|
-
}
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
return undefined;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
52
|
+
// Installed-layout resolution (OpenClaw home, extensions dir, plugin dir,
|
|
53
|
+
// installed version) moved verbatim to utils/installed-layout.ts so the
|
|
54
|
+
// health diagnostics read the SAME authority as the update page (P4).
|
|
55
|
+
// The workspace (where PD state lives) and the OpenClaw install home (where
|
|
56
|
+
// extensions live) are NOT necessarily the same directory or even siblings —
|
|
57
|
+
// the workspace can be on a different drive — so the extensions dir is never
|
|
58
|
+
// derived from `path.dirname(workspaceDir)`.
|
|
134
59
|
async function readJsonBody(req) {
|
|
135
60
|
let body = '';
|
|
136
61
|
req.on('data', (chunk) => { body += chunk.toString(); });
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type InstallHost } from '@principles/install-layout';
|
|
2
|
+
export declare function resolveExtensionsDir(): string;
|
|
3
|
+
export interface UpdateLayout {
|
|
4
|
+
pluginDir: string;
|
|
5
|
+
consoleDir: string;
|
|
6
|
+
coreDir: string;
|
|
7
|
+
hostRuntimeDir: string;
|
|
8
|
+
pdCliDir: string;
|
|
9
|
+
installLayoutDir: string;
|
|
10
|
+
hosts: InstallHost[];
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveUpdateLayout(): UpdateLayout | undefined;
|
|
13
|
+
export declare function resolvePluginDir(_workspaceDir: string): string;
|
|
14
|
+
export declare function readCurrentVersion(pluginDir: string): string | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* The PD version this console governs — the installed plugin's package.json
|
|
17
|
+
* version, i.e. the same "当前版本" the update page shows. Returns undefined
|
|
18
|
+
* when no installation can be resolved (dev tree without a local install);
|
|
19
|
+
* callers decide their own fallback display (rc-9).
|
|
20
|
+
*/
|
|
21
|
+
export declare function readInstalledPdVersion(): string | undefined;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installed PD layout resolution — where the PD plugin (and its bundled
|
|
3
|
+
* components) live on this machine, and which version they report.
|
|
4
|
+
*
|
|
5
|
+
* Single authority (P4) for the "installed PD version": both the update page
|
|
6
|
+
* (`routes/update.ts`) and the health diagnostics
|
|
7
|
+
* (`models/HealthCheckModel.ts`) read the same plugin package.json through
|
|
8
|
+
* `readInstalledPdVersion()`. The previous health implementation resolved a
|
|
9
|
+
* monorepo-root package.json via a fixed five-level relative path, which only
|
|
10
|
+
* worked in the dev tree — in the installed legacy layout it resolved into
|
|
11
|
+
* `<openclawHome>/extensions/` and returned 'unknown' forever.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import * as os from 'os';
|
|
16
|
+
import { getInstallLayoutPaths, resolveInstallLayout } from '@principles/install-layout';
|
|
17
|
+
import { resolveOpenClawHome } from './pd-backups.js';
|
|
18
|
+
export function resolveExtensionsDir() {
|
|
19
|
+
return path.join(resolveOpenClawHome(), 'extensions');
|
|
20
|
+
}
|
|
21
|
+
export function resolveUpdateLayout() {
|
|
22
|
+
const homeDir = os.homedir();
|
|
23
|
+
const paths = getInstallLayoutPaths(homeDir);
|
|
24
|
+
const legacyPluginDir = path.join(resolveExtensionsDir(), 'principles-disciple');
|
|
25
|
+
let manifest;
|
|
26
|
+
try {
|
|
27
|
+
manifest = JSON.parse(fs.readFileSync(paths.manifest, 'utf8'));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
manifest = undefined;
|
|
31
|
+
}
|
|
32
|
+
const resolution = resolveInstallLayout({
|
|
33
|
+
homeDir,
|
|
34
|
+
manifest,
|
|
35
|
+
canonicalRuntimeExists: fs.existsSync(paths.runtimeDir),
|
|
36
|
+
legacyExtensionExists: fs.existsSync(legacyPluginDir),
|
|
37
|
+
});
|
|
38
|
+
if (resolution.mode === 'missing')
|
|
39
|
+
return undefined;
|
|
40
|
+
if (resolution.mode === 'canonical') {
|
|
41
|
+
return {
|
|
42
|
+
pluginDir: paths.pluginDir,
|
|
43
|
+
consoleDir: paths.consoleDir,
|
|
44
|
+
coreDir: paths.coreDir,
|
|
45
|
+
hostRuntimeDir: paths.hostRuntimeDir,
|
|
46
|
+
pdCliDir: paths.pdCliDir,
|
|
47
|
+
installLayoutDir: paths.installLayoutDir,
|
|
48
|
+
hosts: resolution.manifest?.hosts ?? [],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
pluginDir: legacyPluginDir,
|
|
53
|
+
consoleDir: path.join(legacyPluginDir, 'console'),
|
|
54
|
+
coreDir: path.join(legacyPluginDir, 'core'),
|
|
55
|
+
hostRuntimeDir: path.join(legacyPluginDir, 'host-runtime'),
|
|
56
|
+
pdCliDir: path.join(legacyPluginDir, 'pd-cli'),
|
|
57
|
+
installLayoutDir: path.join(legacyPluginDir, 'install-layout'),
|
|
58
|
+
hosts: ['openclaw'],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function resolvePluginDir(_workspaceDir) {
|
|
62
|
+
return resolveUpdateLayout()?.pluginDir ?? path.join(resolveExtensionsDir(), 'principles-disciple');
|
|
63
|
+
}
|
|
64
|
+
// rc-2: type-guard the parsed JSON instead of an `as` cast (ERR-001).
|
|
65
|
+
function isRecord(value) {
|
|
66
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
67
|
+
}
|
|
68
|
+
export function readCurrentVersion(pluginDir) {
|
|
69
|
+
const pkgPath = path.join(pluginDir, 'package.json');
|
|
70
|
+
try {
|
|
71
|
+
if (!fs.existsSync(pkgPath))
|
|
72
|
+
return undefined;
|
|
73
|
+
const raw = fs.readFileSync(pkgPath, 'utf-8');
|
|
74
|
+
const parsed = JSON.parse(raw);
|
|
75
|
+
if (!isRecord(parsed) || !Object.hasOwn(parsed, 'version'))
|
|
76
|
+
return undefined;
|
|
77
|
+
const { version } = parsed;
|
|
78
|
+
return typeof version === 'string' ? version : undefined;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The PD version this console governs — the installed plugin's package.json
|
|
86
|
+
* version, i.e. the same "当前版本" the update page shows. Returns undefined
|
|
87
|
+
* when no installation can be resolved (dev tree without a local install);
|
|
88
|
+
* callers decide their own fallback display (rc-9).
|
|
89
|
+
*/
|
|
90
|
+
export function readInstalledPdVersion() {
|
|
91
|
+
return readCurrentVersion(resolvePluginDir(''));
|
|
92
|
+
}
|
|
@@ -5,6 +5,15 @@ export interface LegacyBackupMigrationResult {
|
|
|
5
5
|
reason: string;
|
|
6
6
|
}[];
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the OpenClaw install home.
|
|
10
|
+
* Priority: OPENCLAW_HOME env var (explicit override) > ~/.openclaw
|
|
11
|
+
*
|
|
12
|
+
* Single authority for home resolution — backup placement
|
|
13
|
+
* (`resolvePdBackupsRoot`) and installed-layout resolution
|
|
14
|
+
* (`utils/installed-layout.ts`) both derive from it.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveOpenClawHome(): string;
|
|
8
17
|
/** Backups root — outside the extensions dir OpenClaw scans for plugins. */
|
|
9
18
|
export declare function resolvePdBackupsRoot(): string;
|
|
10
19
|
/**
|
|
@@ -20,8 +20,12 @@ import * as os from 'os';
|
|
|
20
20
|
/**
|
|
21
21
|
* Resolve the OpenClaw install home.
|
|
22
22
|
* Priority: OPENCLAW_HOME env var (explicit override) > ~/.openclaw
|
|
23
|
+
*
|
|
24
|
+
* Single authority for home resolution — backup placement
|
|
25
|
+
* (`resolvePdBackupsRoot`) and installed-layout resolution
|
|
26
|
+
* (`utils/installed-layout.ts`) both derive from it.
|
|
23
27
|
*/
|
|
24
|
-
function resolveOpenClawHome() {
|
|
28
|
+
export function resolveOpenClawHome() {
|
|
25
29
|
const envHome = process.env.OPENCLAW_HOME;
|
|
26
30
|
if (envHome && envHome.trim().length > 0)
|
|
27
31
|
return path.resolve(envHome);
|
|
@@ -19,6 +19,7 @@ import { validateUpdateStatus, validateUpdateHistory } from "../../utils/validat
|
|
|
19
19
|
import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, } from "../../components/ui/alert-dialog.js";
|
|
20
20
|
import { Loader2, RotateCcw, CheckCircle2, XCircle, ArrowRight } from "lucide-react";
|
|
21
21
|
import { formatDate } from "../../utils/format-date.js";
|
|
22
|
+
import { MarkdownRenderer } from "../../components/ui/markdown.js";
|
|
22
23
|
export function UpdatePage() {
|
|
23
24
|
const { t, i18n } = useTranslation();
|
|
24
25
|
const [statusData, setStatusData] = useState(null);
|
|
@@ -179,7 +180,7 @@ export function UpdatePage() {
|
|
|
179
180
|
}
|
|
180
181
|
// ── Loaded state ─────────────────────────────────────────────────────────
|
|
181
182
|
const isUpToDate = statusData ? !statusData.hasUpdate : true;
|
|
182
|
-
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
|
|
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, {
|
|
183
184
|
year: "numeric",
|
|
184
185
|
month: "short",
|
|
185
186
|
day: "numeric",
|