@bf-meishijian/aip 0.0.6 → 0.0.8
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/README.md +118 -1
- package/dist/agent-harness/index.d.ts +4 -0
- package/dist/agent-harness/index.d.ts.map +1 -0
- package/dist/agent-harness/index.js +4 -0
- package/dist/agent-harness/index.js.map +1 -0
- package/dist/agent-harness/pi-chat-model.d.ts +35 -0
- package/dist/agent-harness/pi-chat-model.d.ts.map +1 -0
- package/dist/agent-harness/pi-chat-model.js +285 -0
- package/dist/agent-harness/pi-chat-model.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +60 -23
- package/dist/cli.js.map +1 -1
- package/dist/coding-run-manager.d.ts +76 -16
- package/dist/coding-run-manager.d.ts.map +1 -1
- package/dist/coding-run-manager.js +550 -439
- package/dist/coding-run-manager.js.map +1 -1
- package/dist/coding-subagent-child.d.ts +1 -1
- package/dist/coding-subagent-child.d.ts.map +1 -1
- package/dist/coding-subagent-child.js +14 -21
- package/dist/coding-subagent-child.js.map +1 -1
- package/dist/coding-subagents.d.ts +2 -0
- package/dist/coding-subagents.d.ts.map +1 -1
- package/dist/coding-subagents.js +103 -119
- package/dist/coding-subagents.js.map +1 -1
- package/dist/daemon.d.ts +4 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +155 -43
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-files.d.ts +15 -12
- package/dist/delivery-files.d.ts.map +1 -1
- package/dist/delivery-files.js +124 -78
- package/dist/delivery-files.js.map +1 -1
- package/dist/delivery-tools.d.ts +28 -0
- package/dist/delivery-tools.d.ts.map +1 -0
- package/dist/delivery-tools.js +167 -0
- package/dist/delivery-tools.js.map +1 -0
- package/dist/diagnostics.d.ts +1 -0
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +48 -14
- package/dist/diagnostics.js.map +1 -1
- package/dist/host-update.d.ts +3 -0
- package/dist/host-update.d.ts.map +1 -0
- package/dist/host-update.js +70 -0
- package/dist/host-update.js.map +1 -0
- package/dist/installer.d.ts +5 -8
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +155 -65
- package/dist/installer.js.map +1 -1
- package/dist/linux-service.d.ts +14 -0
- package/dist/linux-service.d.ts.map +1 -0
- package/dist/linux-service.js +63 -0
- package/dist/linux-service.js.map +1 -0
- package/dist/live-employee.d.ts +4 -3
- package/dist/live-employee.d.ts.map +1 -1
- package/dist/live-employee.js +222 -60
- package/dist/live-employee.js.map +1 -1
- package/dist/local-handoff-workspace.d.ts +20 -0
- package/dist/local-handoff-workspace.d.ts.map +1 -0
- package/dist/local-handoff-workspace.js +80 -0
- package/dist/local-handoff-workspace.js.map +1 -0
- package/dist/local-model-usage.d.ts +6 -0
- package/dist/local-model-usage.d.ts.map +1 -0
- package/dist/local-model-usage.js +40 -0
- package/dist/local-model-usage.js.map +1 -0
- package/dist/login-url.d.ts +3 -0
- package/dist/login-url.d.ts.map +1 -0
- package/dist/login-url.js +30 -0
- package/dist/login-url.js.map +1 -0
- package/dist/paths.d.ts +9 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +27 -3
- package/dist/paths.js.map +1 -1
- package/dist/pi-model-service.d.ts +11 -0
- package/dist/pi-model-service.d.ts.map +1 -1
- package/dist/pi-model-service.js +28 -11
- package/dist/pi-model-service.js.map +1 -1
- package/dist/platform-client.d.ts +214 -6
- package/dist/platform-client.d.ts.map +1 -1
- package/dist/platform-client.js +66 -0
- package/dist/platform-client.js.map +1 -1
- package/dist/profile.d.ts +9 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +43 -0
- package/dist/profile.js.map +1 -0
- package/dist/project-facts.d.ts +19 -0
- package/dist/project-facts.d.ts.map +1 -0
- package/dist/project-facts.js +91 -0
- package/dist/project-facts.js.map +1 -0
- package/dist/provider-auth-error.d.ts +3 -0
- package/dist/provider-auth-error.d.ts.map +1 -0
- package/dist/provider-auth-error.js +12 -0
- package/dist/provider-auth-error.js.map +1 -0
- package/dist/qa-contract.d.ts +2 -0
- package/dist/qa-contract.d.ts.map +1 -0
- package/dist/qa-contract.js +165 -0
- package/dist/qa-contract.js.map +1 -0
- package/dist/qa-http-validation.js +145 -0
- package/dist/qa-project-checkout.d.ts +12 -0
- package/dist/qa-project-checkout.d.ts.map +1 -0
- package/dist/qa-project-checkout.js +68 -0
- package/dist/qa-project-checkout.js.map +1 -0
- package/dist/qa-session-manager.d.ts +101 -0
- package/dist/qa-session-manager.d.ts.map +1 -0
- package/dist/qa-session-manager.js +581 -0
- package/dist/qa-session-manager.js.map +1 -0
- package/dist/review-report.d.ts +3 -4
- package/dist/review-report.d.ts.map +1 -1
- package/dist/review-report.js +14 -12
- package/dist/review-report.js.map +1 -1
- package/dist/secure-json.d.ts.map +1 -1
- package/dist/secure-json.js +64 -2
- package/dist/secure-json.js.map +1 -1
- package/dist/stage-delivery.js +42 -25
- package/dist/state.d.ts +2 -2
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +6 -4
- package/dist/state.js.map +1 -1
- package/dist/test-cli.d.ts +2 -0
- package/dist/test-cli.d.ts.map +1 -0
- package/dist/test-cli.js +50 -0
- package/dist/test-cli.js.map +1 -0
- package/dist/test-executor.d.ts +44 -0
- package/dist/test-executor.d.ts.map +1 -0
- package/dist/test-executor.js +474 -0
- package/dist/test-executor.js.map +1 -0
- package/dist/test-reports.d.ts +13 -0
- package/dist/test-reports.d.ts.map +1 -0
- package/dist/test-reports.js +129 -0
- package/dist/test-reports.js.map +1 -0
- package/dist/test-run-manager.d.ts +24 -0
- package/dist/test-run-manager.d.ts.map +1 -0
- package/dist/test-run-manager.js +121 -0
- package/dist/test-run-manager.js.map +1 -0
- package/dist/tool-dispatch.d.ts +14 -0
- package/dist/tool-dispatch.d.ts.map +1 -0
- package/dist/tool-dispatch.js +56 -0
- package/dist/tool-dispatch.js.map +1 -0
- package/dist/windows-runtime.d.ts +9 -0
- package/dist/windows-runtime.d.ts.map +1 -0
- package/dist/windows-runtime.js +64 -0
- package/dist/windows-runtime.js.map +1 -0
- package/dist/windows-service.d.ts +20 -0
- package/dist/windows-service.d.ts.map +1 -0
- package/dist/windows-service.js +96 -0
- package/dist/windows-service.js.map +1 -0
- package/package.json +17 -10
package/dist/diagnostics.js
CHANGED
|
@@ -3,13 +3,14 @@ import { constants } from "node:fs";
|
|
|
3
3
|
import { access, lstat, mkdir, readFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { launchAgentDefinition, verifyManifest, windowsTaskDefinition, } from "./installer.js";
|
|
6
|
-
import {
|
|
6
|
+
import { linuxServiceDefinition } from "./linux-service.js";
|
|
7
|
+
import { activeProfile, aipCommand, paths, windowsTaskName } from "./paths.js";
|
|
7
8
|
import { runtimeArchitecture } from "./platform.js";
|
|
8
9
|
import { isSecureFile, readJson } from "./secure-json.js";
|
|
9
10
|
export async function runDiagnostics(options, dependencies = {}) {
|
|
10
11
|
const local = paths();
|
|
11
12
|
const checks = [];
|
|
12
|
-
checks.push(await runtimeCheck(local.runtimeCurrent));
|
|
13
|
+
checks.push(await runtimeCheck(local.runtimeCurrent, options.runtimeVerification));
|
|
13
14
|
checks.push(await backgroundCheck(dependencies.captureCommand ?? captureCommand));
|
|
14
15
|
checks.push(await deviceCredentialCheck(options.deviceCredentialValid));
|
|
15
16
|
checks.push({
|
|
@@ -28,7 +29,7 @@ export async function runDiagnostics(options, dependencies = {}) {
|
|
|
28
29
|
id: "HOST_GENERATION",
|
|
29
30
|
status: options.generationValid ? "PASS" : "FAIL",
|
|
30
31
|
code: options.generationValid ? "HOST_GENERATION_OK" : "HOST_FENCED",
|
|
31
|
-
nextAction:
|
|
32
|
+
nextAction: `执行 ${aipCommand()} host register`,
|
|
32
33
|
});
|
|
33
34
|
checks.push(await workspaceCheck(local.workspaceRoot));
|
|
34
35
|
checks.push({
|
|
@@ -39,12 +40,33 @@ export async function runDiagnostics(options, dependencies = {}) {
|
|
|
39
40
|
});
|
|
40
41
|
return checks;
|
|
41
42
|
}
|
|
42
|
-
async function runtimeCheck(path) {
|
|
43
|
+
async function runtimeCheck(path, verification = "full") {
|
|
43
44
|
try {
|
|
44
45
|
const manifest = JSON.parse(await readFile(join(path, "runtime-manifest.json"), "utf8"));
|
|
45
46
|
if (manifest.platform !== process.platform || manifest.arch !== runtimeArchitecture())
|
|
46
47
|
throw new Error("runtime platform mismatch");
|
|
47
|
-
await
|
|
48
|
+
const archiveDigest = await readFile(join(path, ".archive-sha256"), "utf8").catch(() => "");
|
|
49
|
+
if (verification === "installed-package" && /^[a-f0-9]{64}$/iu.test(archiveDigest.trim())) {
|
|
50
|
+
// 安装脚本已校验整个压缩包;页面诊断只重验启动关键文件,避免冷盘扫描上万文件。
|
|
51
|
+
const criticalPaths = [
|
|
52
|
+
process.platform === "win32" ? "bin/node.exe" : "bin/node",
|
|
53
|
+
"app/dist/cli.js",
|
|
54
|
+
"app/dist/daemon.js",
|
|
55
|
+
"app/dist/diagnostics.js",
|
|
56
|
+
"app/dist/installer.js",
|
|
57
|
+
"app/dist/self-check.js",
|
|
58
|
+
];
|
|
59
|
+
const files = criticalPaths.map((criticalPath) => {
|
|
60
|
+
const file = manifest.files.find((entry) => entry.path.replaceAll("\\", "/") === criticalPath);
|
|
61
|
+
if (!file)
|
|
62
|
+
throw new Error(`missing runtime file: ${criticalPath}`);
|
|
63
|
+
return file;
|
|
64
|
+
});
|
|
65
|
+
await verifyManifest(path, { ...manifest, files });
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
await verifyManifest(path, manifest);
|
|
69
|
+
}
|
|
48
70
|
return {
|
|
49
71
|
id: "RUNTIME_INTEGRITY",
|
|
50
72
|
status: "PASS",
|
|
@@ -57,7 +79,7 @@ async function runtimeCheck(path) {
|
|
|
57
79
|
id: "RUNTIME_INTEGRITY",
|
|
58
80
|
status: "FAIL",
|
|
59
81
|
code: "RUNTIME_INTEGRITY_FAILED",
|
|
60
|
-
nextAction:
|
|
82
|
+
nextAction: `重新执行 ${aipCommand()} host install`,
|
|
61
83
|
};
|
|
62
84
|
}
|
|
63
85
|
}
|
|
@@ -83,17 +105,24 @@ async function deviceCredentialCheck(platformValid) {
|
|
|
83
105
|
: expired
|
|
84
106
|
? "DEVICE_CREDENTIAL_EXPIRED"
|
|
85
107
|
: "DEVICE_CREDENTIAL_REJECTED",
|
|
86
|
-
nextAction: valid ? "无需处理" :
|
|
108
|
+
nextAction: valid ? "无需处理" : `执行 ${aipCommand()} login`,
|
|
87
109
|
};
|
|
88
110
|
}
|
|
89
111
|
async function backgroundCheck(runCommand) {
|
|
90
112
|
const local = paths();
|
|
91
113
|
const state = await readJson(local.daemonState);
|
|
92
|
-
const processRunning = Boolean(state?.pid &&
|
|
114
|
+
const processRunning = Boolean(state?.pid &&
|
|
115
|
+
state.profile === activeProfile() &&
|
|
116
|
+
state.root === local.root &&
|
|
117
|
+
processExists(state.pid));
|
|
93
118
|
let configuredAndLoaded = processRunning;
|
|
94
119
|
if (process.platform === "darwin") {
|
|
95
120
|
const expected = launchAgentDefinition(local.runtimeCurrent);
|
|
96
|
-
|
|
121
|
+
// PATH 是安装时保存的执行环境;终端、pnpm 和 daemon 的 PATH 可以不同。
|
|
122
|
+
// 仅忽略其值,仍比较服务身份、Runtime、profile、基础目录及 PATH 字段是否存在。
|
|
123
|
+
const withoutPathValue = (xml) => xml.replace(/<key>PATH<\/key><string>[^<]*<\/string>/u, "<key>PATH</key><string></string>");
|
|
124
|
+
const configured = withoutPathValue(await readFile(expected.plist, "utf8").catch(() => "")) ===
|
|
125
|
+
withoutPathValue(expected.xml);
|
|
97
126
|
const launchd = await runCommand("launchctl", [
|
|
98
127
|
"print",
|
|
99
128
|
`${expected.domain}/${expected.label}`,
|
|
@@ -107,18 +136,23 @@ async function backgroundCheck(runCommand) {
|
|
|
107
136
|
configuredAndLoaded = configured && loaded;
|
|
108
137
|
}
|
|
109
138
|
else if (process.platform === "win32") {
|
|
110
|
-
const expected = windowsTaskDefinition(local.runtimeCurrent, local.
|
|
139
|
+
const expected = windowsTaskDefinition(local.runtimeCurrent, local.base);
|
|
111
140
|
const configured = await readJson(join(local.root, "state", "windows-task.json"));
|
|
112
|
-
const loaded = (await runCommand("schtasks.exe", ["/Query", "/TN",
|
|
113
|
-
.code === 0;
|
|
141
|
+
const loaded = (await runCommand("schtasks.exe", ["/Query", "/TN", windowsTaskName()])).code === 0;
|
|
114
142
|
configuredAndLoaded = JSON.stringify(configured) === JSON.stringify(expected) && loaded;
|
|
115
143
|
}
|
|
144
|
+
else if (process.platform === "linux") {
|
|
145
|
+
const expected = linuxServiceDefinition(local.runtimeCurrent, local.base);
|
|
146
|
+
const configured = (await readFile(expected.path, "utf8").catch(() => "")) === expected.contents;
|
|
147
|
+
const active = await runCommand("systemctl", ["--user", "is-active", expected.unit]);
|
|
148
|
+
configuredAndLoaded = configured && active.code === 0 && active.output.trim() === "active";
|
|
149
|
+
}
|
|
116
150
|
const running = processRunning && configuredAndLoaded;
|
|
117
151
|
return {
|
|
118
152
|
id: "BACKGROUND_SERVICE",
|
|
119
153
|
status: running ? "PASS" : "FAIL",
|
|
120
154
|
code: running ? "BACKGROUND_SERVICE_OK" : "BACKGROUND_SERVICE_STOPPED",
|
|
121
|
-
nextAction:
|
|
155
|
+
nextAction: `执行 ${aipCommand()} host restart`,
|
|
122
156
|
};
|
|
123
157
|
}
|
|
124
158
|
function captureCommand(command, args) {
|
|
@@ -151,7 +185,7 @@ export async function workspaceCheck(root) {
|
|
|
151
185
|
id: "WORKSPACE_ROOT",
|
|
152
186
|
status: "FAIL",
|
|
153
187
|
code: "WORKSPACE_ROOT_UNAVAILABLE",
|
|
154
|
-
nextAction:
|
|
188
|
+
nextAction: `修复 ~/.aip/profiles/${activeProfile()}/workspaces 目录权限`,
|
|
155
189
|
};
|
|
156
190
|
}
|
|
157
191
|
}
|
package/dist/diagnostics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EACL,qBAAqB,EAErB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EACL,qBAAqB,EAErB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAOC,EACD,eAA2D,EAAE;IAE7D,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC;IACtB,MAAM,MAAM,GAAqC,EAAE,CAAC;IACpD,MAAM,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,YAAY,CAAC,cAAc,IAAI,cAAc,CAAC,CAAC,CAAC;IAClF,MAAM,CAAC,IAAI,CAAC,MAAM,qBAAqB,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC;IACxE,MAAM,CAAC,IAAI,CAAC;QACV,EAAE,EAAE,eAAe;QACnB,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB;QAC1D,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,yBAAyB;QAC5E,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe;KAC7D,CAAC,CAAC;IACH,MAAM,CAAC,IAAI,CAAC;QACV,EAAE,EAAE,uBAAuB;QAC3B,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACnD,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,sBAAsB;QAC/E,UAAU,EAAE,SAAS;KACtB,CAAC,CAAC;IACH,MAAM,CAAC,IAAI,CAAC;QACV,EAAE,EAAE,iBAAiB;QACrB,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACjD,IAAI,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa;QACpE,UAAU,EAAE,MAAM,UAAU,EAAE,gBAAgB;KAC/C,CAAC,CAAC;IACH,MAAM,CAAC,IAAI,CAAC,MAAM,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IACvD,MAAM,CAAC,IAAI,CAAC;QACV,EAAE,EAAE,eAAe;QACnB,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB;QAC9D,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,uBAAuB;QAC9E,UAAU,EAAE,aAAa;KAC1B,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,IAAY,EACZ,eAA6C,MAAM;IAEnD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,uBAAuB,CAAC,EAAE,MAAM,CAAC,CACzC,CAAC;QACrB,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,mBAAmB,EAAE;YACnF,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5F,IAAI,YAAY,KAAK,mBAAmB,IAAI,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1F,yCAAyC;YACzC,MAAM,aAAa,GAAG;gBACpB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU;gBAC1D,iBAAiB;gBACjB,oBAAoB;gBACpB,yBAAyB;gBACzB,uBAAuB;gBACvB,wBAAwB;aACzB,CAAC;YACF,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAC9B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,YAAY,CAC7D,CAAC;gBACF,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,YAAY,EAAE,CAAC,CAAC;gBACpE,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;QACD,OAAO;YACL,EAAE,EAAE,mBAAmB;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,sBAAsB;YAC5B,UAAU,EAAE,MAAM;SACnB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,EAAE,EAAE,mBAAmB;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,0BAA0B;YAChC,UAAU,EAAE,QAAQ,UAAU,EAAE,eAAe;SAChD,CAAC;IACJ,CAAC;AACH,CAAC;AACD,KAAK,UAAU,qBAAqB,CAClC,aAAsB;IAEtB,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC;IACtB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAyB,KAAK,CAAC,UAAU,CAAC,CAAC;QAC5E,OAAO,GAAG,CAAC,UAAU,EAAE,SAAS,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,IAAI,aAAa,CAAC;IAClD,OAAO;QACL,EAAE,EAAE,mBAAmB;QACvB,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QAC/B,IAAI,EAAE,KAAK;YACT,CAAC,CAAC,sBAAsB;YACxB,CAAC,CAAC,CAAC,MAAM;gBACP,CAAC,CAAC,sCAAsC;gBACxC,CAAC,CAAC,OAAO;oBACP,CAAC,CAAC,2BAA2B;oBAC7B,CAAC,CAAC,4BAA4B;QACpC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,UAAU,EAAE,QAAQ;KACxD,CAAC;AACJ,CAAC;AACD,KAAK,UAAU,eAAe,CAC5B,UAAiC;IAEjC,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC;IACtB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAC1B,KAAK,CAAC,WAAW,CAClB,CAAC;IACF,MAAM,cAAc,GAAG,OAAO,CAC5B,KAAK,EAAE,GAAG;QACR,KAAK,CAAC,OAAO,KAAK,aAAa,EAAE;QACjC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;QACzB,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAC3B,CAAC;IACF,IAAI,mBAAmB,GAAG,cAAc,CAAC;IACzC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC7D,iDAAiD;QACjD,mDAAmD;QACnD,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,EAAE,CACvC,GAAG,CAAC,OAAO,CAAC,0CAA0C,EAAE,kCAAkC,CAAC,CAAC;QAC9F,MAAM,UAAU,GACd,gBAAgB,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACxE,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,WAAW,EAAE;YAC5C,OAAO;YACP,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,EAAE;SACvC,CAAC,CAAC;QACH,MAAM,eAAe,GAAG;YACtB,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC;YACzC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC;YACtD,KAAK,CAAC,IAAI;SACX,CAAC;QACF,MAAM,MAAM,GACV,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACzF,mBAAmB,GAAG,UAAU,IAAI,MAAM,CAAC;IAC7C,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAClF,MAAM,MAAM,GACV,CAAC,MAAM,UAAU,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;QACtF,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC;IAC1F,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1E,MAAM,UAAU,GACd,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC;QAChF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,mBAAmB,GAAG,UAAU,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC;IAC7F,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,IAAI,mBAAmB,CAAC;IACtD,OAAO;QACL,EAAE,EAAE,oBAAoB;QACxB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACjC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,4BAA4B;QACtE,UAAU,EAAE,MAAM,UAAU,EAAE,eAAe;KAC9C,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,IAAc;IACrD,OAAO,IAAI,OAAO,CAAmC,CAAC,aAAa,EAAE,EAAE;QACrE,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1E,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YAC/C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,MAAM,GAAG,GAAG,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;QACL,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACzE,MAAM,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO;YACL,EAAE,EAAE,gBAAgB;YACpB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,mBAAmB;YACzB,UAAU,EAAE,MAAM;SACnB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,EAAE,EAAE,gBAAgB;YACpB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B;YAClC,UAAU,EAAE,sBAAsB,aAAa,EAAE,kBAAkB;SACpE,CAAC;IACJ,CAAC;AACH,CAAC;AACD,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-update.d.ts","sourceRoot":"","sources":["../src/host-update.ts"],"names":[],"mappings":"AAOA,wBAAsB,iBAAiB,iCAMtC;AAED,wBAAsB,UAAU,kBAqD/B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { mkdir, mkdtemp, readFile, rm } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import lockfile from "proper-lockfile";
|
|
5
|
+
import { activeProfile, paths } from "./paths.js";
|
|
6
|
+
import { runtimeArchitecture } from "./platform.js";
|
|
7
|
+
export async function lockHostExecution() {
|
|
8
|
+
await mkdir(paths().root, { recursive: true });
|
|
9
|
+
return lockfile.lock(paths().root, {
|
|
10
|
+
lockfilePath: join(paths().root, "execution.lock"),
|
|
11
|
+
retries: 0,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export async function updateHost() {
|
|
15
|
+
const current = paths().runtimeCurrent;
|
|
16
|
+
const manifest = JSON.parse(await readFile(join(current, "runtime-manifest.json"), "utf8"));
|
|
17
|
+
const response = await fetch("https://registry.npmjs.org/@bf-meishijian/aip/latest", {
|
|
18
|
+
signal: AbortSignal.timeout(30_000),
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok)
|
|
21
|
+
throw new Error(`检查更新失败:npm HTTP ${response.status}`);
|
|
22
|
+
const { version } = (await response.json());
|
|
23
|
+
if (!/^\d+\.\d+\.\d+$/u.test(version))
|
|
24
|
+
throw new Error("npm 返回了无效版本");
|
|
25
|
+
if (version === manifest.version) {
|
|
26
|
+
process.stdout.write(`已是最新版本 ${version}\n`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const release = await lockHostExecution().catch(() => {
|
|
30
|
+
throw new Error("Host 正在处理请求或任务,请稍后再执行更新");
|
|
31
|
+
});
|
|
32
|
+
let staging;
|
|
33
|
+
try {
|
|
34
|
+
staging = await mkdtemp(join(paths().runtime, "update-"));
|
|
35
|
+
process.stdout.write(`正在更新 ${manifest.version} → ${version}\n`);
|
|
36
|
+
const node = join(current, "bin", process.platform === "win32" ? "node.exe" : "node");
|
|
37
|
+
await run(node, [
|
|
38
|
+
join(current, "app/node_modules/npm/bin/npm-cli.js"),
|
|
39
|
+
"install",
|
|
40
|
+
"--prefix",
|
|
41
|
+
staging,
|
|
42
|
+
`@bf-meishijian/aip-runtime-${process.platform}-${runtimeArchitecture()}@${version}`,
|
|
43
|
+
"--registry=https://registry.npmjs.org",
|
|
44
|
+
"--ignore-scripts",
|
|
45
|
+
"--no-audit",
|
|
46
|
+
"--no-fund",
|
|
47
|
+
]);
|
|
48
|
+
const runtime = join(staging, "node_modules/@bf-meishijian", `aip-runtime-${process.platform}-${runtimeArchitecture()}`, "runtime");
|
|
49
|
+
await run(join(runtime, "bin", process.platform === "win32" ? "node.exe" : "node"), [
|
|
50
|
+
join(runtime, "app/dist/cli.js"),
|
|
51
|
+
...(activeProfile() === "local" ? ["--local"] : []),
|
|
52
|
+
"host",
|
|
53
|
+
"install",
|
|
54
|
+
], { ...process.env, AIP_RUNTIME_PACKAGE_DIR: runtime });
|
|
55
|
+
process.stdout.write(`已更新至 ${version}\n`);
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
await release();
|
|
59
|
+
if (staging)
|
|
60
|
+
await rm(staging, { recursive: true, force: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function run(command, args, env = process.env) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const child = spawn(command, args, { env, stdio: "inherit", windowsHide: true });
|
|
66
|
+
child.once("error", reject);
|
|
67
|
+
child.once("exit", (code) => code === 0 ? resolve() : reject(new Error(`更新命令失败 (${code})`)));
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=host-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-update.js","sourceRoot":"","sources":["../src/host-update.ts"],"names":[],"mappings":"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"}
|
package/dist/installer.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { windowsTaskDefinition } from "./windows-service.js";
|
|
1
2
|
export interface RuntimeManifest {
|
|
2
3
|
version: string;
|
|
3
4
|
platform: string;
|
|
@@ -9,10 +10,13 @@ export interface RuntimeManifest {
|
|
|
9
10
|
sha256: string;
|
|
10
11
|
}>;
|
|
11
12
|
}
|
|
12
|
-
export declare function installRuntime(
|
|
13
|
+
export declare function installRuntime(options?: {
|
|
14
|
+
preparedRuntime?: string;
|
|
15
|
+
}): Promise<{
|
|
13
16
|
version: string;
|
|
14
17
|
runtime: string;
|
|
15
18
|
}>;
|
|
19
|
+
export declare function stableCliContents(platform?: NodeJS.Platform): string;
|
|
16
20
|
export declare function verifyManifest(root: string, manifest: RuntimeManifest): Promise<void>;
|
|
17
21
|
export declare function launchAgentDefinition(runtime: string): {
|
|
18
22
|
label: string;
|
|
@@ -21,11 +25,4 @@ export declare function launchAgentDefinition(runtime: string): {
|
|
|
21
25
|
xml: string;
|
|
22
26
|
domain: string;
|
|
23
27
|
};
|
|
24
|
-
export declare function windowsTaskDefinition(runtime: string, root: string): {
|
|
25
|
-
executable: string;
|
|
26
|
-
arguments: string[];
|
|
27
|
-
environment: {
|
|
28
|
-
AIP_HOME: string;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
28
|
//# sourceMappingURL=installer.d.ts.map
|
package/dist/installer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO;;;GA8G9E;AAwBD,wBAAgB,iBAAiB,CAAC,QAAQ,kBAAmB,UA6B5D;AAkED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,iBAkB3E;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM;;;;;;EAkBpD"}
|
package/dist/installer.js
CHANGED
|
@@ -3,43 +3,95 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
3
3
|
import { chmod, cp, lstat, mkdir, readFile, readlink, rename, rm, stat, symlink, writeFile, } from "node:fs/promises";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
|
-
import { dirname, join,
|
|
7
|
-
import {
|
|
6
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
7
|
+
import { installLinuxService } from "./linux-service.js";
|
|
8
|
+
import { activeProfile, aipCommand, launchAgentLabel, paths, windowsTaskName } from "./paths.js";
|
|
8
9
|
import { runtimeArchitecture } from "./platform.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
import { activateWindowsRuntime } from "./windows-runtime.js";
|
|
11
|
+
import { installWindowsTask, stopWindowsTask } from "./windows-service.js";
|
|
12
|
+
export { windowsTaskDefinition } from "./windows-service.js";
|
|
13
|
+
export async function installRuntime(options = {}) {
|
|
14
|
+
const prepared = Boolean(options.preparedRuntime);
|
|
15
|
+
const source = options.preparedRuntime
|
|
16
|
+
? await requirePreparedRuntime(options.preparedRuntime)
|
|
17
|
+
: await resolveRuntimePackage();
|
|
18
|
+
const manifestContents = await readFile(join(source, "runtime-manifest.json"), "utf8");
|
|
19
|
+
const manifest = JSON.parse(manifestContents);
|
|
12
20
|
const architecture = runtimeArchitecture();
|
|
13
21
|
if (manifest.platform !== process.platform || manifest.arch !== architecture)
|
|
14
22
|
throw new Error(`Runtime 架构不匹配:需要 ${process.platform}-${architecture}`);
|
|
15
|
-
|
|
23
|
+
if (!prepared)
|
|
24
|
+
await verifyManifest(source, manifest);
|
|
16
25
|
const local = paths();
|
|
17
26
|
const versions = join(local.runtime, "versions");
|
|
18
27
|
const staging = join(versions, `${manifest.version}.staging-${randomBytes(6).toString("hex")}`);
|
|
19
|
-
const target =
|
|
28
|
+
const target = prepared
|
|
29
|
+
? source
|
|
30
|
+
: join(versions, process.platform === "win32"
|
|
31
|
+
? `${manifest.version}-${createHash("sha256").update(manifestContents).digest("hex").slice(0, 12)}`
|
|
32
|
+
: manifest.version);
|
|
33
|
+
// Windows 会在复制完成后短暂扫描新文件,此时重命名整个目录可能持续返回 EPERM。
|
|
34
|
+
// target 带清单摘要后缀,且在 current 切换前没有任何读者,因此可直接复制到最终目录。
|
|
35
|
+
const candidate = prepared || process.platform === "win32" ? target : staging;
|
|
20
36
|
const replacedTarget = join(versions, `${manifest.version}.previous-${randomBytes(6).toString("hex")}`);
|
|
21
37
|
const previous = await readlink(local.runtimeCurrent).catch(() => null);
|
|
22
38
|
let targetWasReplaced = false;
|
|
23
39
|
let targetActivated = false;
|
|
40
|
+
let windowsCandidateCreated = false;
|
|
41
|
+
let windowsActivationStarted = false;
|
|
24
42
|
await mkdir(versions, { recursive: true, mode: 0o700 });
|
|
25
43
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
if (prepared) {
|
|
45
|
+
// 下载脚本已对完整压缩包做 SHA-256 校验。这里只运行 Runtime 自检并直接激活,
|
|
46
|
+
// 避免再次遍历和复制数万个依赖文件。
|
|
47
|
+
}
|
|
48
|
+
else if (process.platform === "win32" && (await exists(target))) {
|
|
49
|
+
// 同一清单对应同一不可变目录。验证后复用,避免重复安装再次复制数万个文件。
|
|
50
|
+
await verifyManifest(target, manifest);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
await cp(source, candidate, { recursive: true });
|
|
54
|
+
windowsCandidateCreated = process.platform === "win32";
|
|
55
|
+
}
|
|
56
|
+
await run(join(candidate, "bin", process.platform === "win32" ? "node.exe" : "node"), [join(candidate, "app", "dist", "self-check.js")], { AIP_RUNTIME_ROOT: candidate });
|
|
57
|
+
if (process.platform === "win32") {
|
|
58
|
+
windowsActivationStarted = true;
|
|
59
|
+
await activateWindowsRuntime({ candidate: target, current: local.runtimeCurrent }, {
|
|
60
|
+
stop: async () => {
|
|
61
|
+
if (process.env.AIP_SKIP_SERVICE !== "1")
|
|
62
|
+
await stopWindowsTask(local.runtimeCurrent);
|
|
63
|
+
},
|
|
64
|
+
start: async () => {
|
|
65
|
+
const startedAfter = Date.now();
|
|
66
|
+
const task = await installWindowsTask(local.runtimeCurrent, local.base);
|
|
67
|
+
const { writeSecureJson } = await import("./secure-json.js");
|
|
68
|
+
await writeSecureJson(join(local.root, "state", "windows-task.json"), task);
|
|
69
|
+
if (process.env.AIP_SKIP_SERVICE !== "1")
|
|
70
|
+
await waitForDaemon(startedAfter, local.runtimeCurrent);
|
|
71
|
+
await installStableCli();
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
return { version: manifest.version, runtime: target };
|
|
75
|
+
}
|
|
76
|
+
if (!prepared) {
|
|
77
|
+
if (await exists(target)) {
|
|
78
|
+
await rename(target, replacedTarget);
|
|
79
|
+
targetWasReplaced = true;
|
|
80
|
+
}
|
|
81
|
+
await rename(staging, target);
|
|
31
82
|
}
|
|
32
|
-
await rename(staging, target);
|
|
33
83
|
targetActivated = true;
|
|
34
84
|
const pending = `${local.runtimeCurrent}.pending`;
|
|
35
85
|
await rm(pending, { force: true });
|
|
36
|
-
await symlink(target, pending,
|
|
86
|
+
await symlink(target, pending, "dir");
|
|
37
87
|
await rename(pending, local.runtimeCurrent);
|
|
38
88
|
const serviceStartedAfter = Date.now();
|
|
39
89
|
if (process.platform === "darwin")
|
|
40
90
|
await installLaunchAgent(local.runtimeCurrent);
|
|
41
|
-
else if (process.platform === "
|
|
42
|
-
await
|
|
91
|
+
else if (process.platform === "linux")
|
|
92
|
+
await installLinuxService(local.runtimeCurrent, local.base);
|
|
93
|
+
else
|
|
94
|
+
throw new Error(`当前平台不支持后台服务安装:${process.platform}`);
|
|
43
95
|
if (process.env.AIP_SKIP_SERVICE !== "1")
|
|
44
96
|
await waitForDaemon(serviceStartedAfter, local.runtimeCurrent);
|
|
45
97
|
await installStableCli();
|
|
@@ -48,7 +100,9 @@ export async function installRuntime() {
|
|
|
48
100
|
}
|
|
49
101
|
catch (error) {
|
|
50
102
|
await rm(staging, { recursive: true, force: true });
|
|
51
|
-
if (
|
|
103
|
+
if (process.platform === "win32" && windowsCandidateCreated && !windowsActivationStarted)
|
|
104
|
+
await rm(target, { recursive: true, force: true });
|
|
105
|
+
if (targetActivated && !prepared)
|
|
52
106
|
await rm(target, { recursive: true, force: true });
|
|
53
107
|
if (targetWasReplaced && !(await exists(target)))
|
|
54
108
|
await rename(replacedTarget, target);
|
|
@@ -56,7 +110,7 @@ export async function installRuntime() {
|
|
|
56
110
|
if (previous) {
|
|
57
111
|
const rollback = `${local.runtimeCurrent}.rollback`;
|
|
58
112
|
await rm(rollback, { force: true });
|
|
59
|
-
await symlink(previous, rollback,
|
|
113
|
+
await symlink(previous, rollback, "dir");
|
|
60
114
|
await rename(rollback, local.runtimeCurrent);
|
|
61
115
|
}
|
|
62
116
|
else
|
|
@@ -65,31 +119,65 @@ export async function installRuntime() {
|
|
|
65
119
|
throw error;
|
|
66
120
|
}
|
|
67
121
|
}
|
|
122
|
+
async function requirePreparedRuntime(input) {
|
|
123
|
+
const source = resolve(input);
|
|
124
|
+
const versions = resolve(paths().runtime, "versions");
|
|
125
|
+
const pathFromVersions = relative(versions, source);
|
|
126
|
+
if (!pathFromVersions || pathFromVersions.startsWith("..") || isAbsolute(pathFromVersions))
|
|
127
|
+
throw new Error("预解压 Runtime 必须位于 当前 profile 的 runtime/versions 下");
|
|
128
|
+
const archiveHash = (await readFile(join(source, ".archive-sha256"), "utf8")).trim();
|
|
129
|
+
if (!/^[a-f0-9]{64}$/u.test(archiveHash))
|
|
130
|
+
throw new Error("预解压 Runtime 缺少有效的归档校验标记");
|
|
131
|
+
return source;
|
|
132
|
+
}
|
|
68
133
|
async function installStableCli() {
|
|
69
134
|
const local = paths();
|
|
70
135
|
await mkdir(local.bin, { recursive: true, mode: 0o700 });
|
|
71
136
|
const temporary = `${local.stableCli}.${randomBytes(6).toString("hex")}.tmp`;
|
|
72
|
-
const contents =
|
|
73
|
-
? '@echo off\r\n"%~dp0..\\runtime\\current\\bin\\node.exe" "%~dp0..\\runtime\\current\\app\\dist\\cli.js" %*\r\n'
|
|
74
|
-
: [
|
|
75
|
-
"#!/bin/sh",
|
|
76
|
-
"aip_bin_dir=$" + "{0%/*}",
|
|
77
|
-
'if [ "$aip_bin_dir" = "$0" ]; then aip_bin_dir=.; fi',
|
|
78
|
-
'exec "$aip_bin_dir/../runtime/current/bin/node" "$aip_bin_dir/../runtime/current/app/dist/cli.js" "$@"',
|
|
79
|
-
"",
|
|
80
|
-
].join("\n");
|
|
137
|
+
const contents = stableCliContents();
|
|
81
138
|
await writeFile(temporary, contents, { mode: process.platform === "win32" ? 0o600 : 0o700 });
|
|
82
139
|
await rename(temporary, local.stableCli);
|
|
83
140
|
if (process.platform !== "win32")
|
|
84
141
|
await chmod(local.stableCli, 0o700);
|
|
85
142
|
}
|
|
143
|
+
export function stableCliContents(platform = process.platform) {
|
|
144
|
+
if (platform === "win32")
|
|
145
|
+
return [
|
|
146
|
+
"@echo off",
|
|
147
|
+
"setlocal",
|
|
148
|
+
'if not defined AIP_HOME set "AIP_HOME=%~dp0.."',
|
|
149
|
+
'if not defined AIP_PROFILE set "AIP_PROFILE=default"',
|
|
150
|
+
'for %%a in (%*) do if "%%~a"=="--local" set "AIP_PROFILE=local"',
|
|
151
|
+
'if not "%AIP_PROFILE%"=="default" if not "%AIP_PROFILE%"=="local" exit /b 1',
|
|
152
|
+
'set "aip_runtime=%AIP_HOME%\\profiles\\%AIP_PROFILE%\\runtime\\current"',
|
|
153
|
+
'if not exist "%aip_runtime%\\bin\\node.exe" (echo Host Runtime [%AIP_PROFILE%] is not installed. 1>&2 & exit /b 1)',
|
|
154
|
+
'"%aip_runtime%\\bin\\node.exe" "%aip_runtime%\\app\\dist\\cli.js" %*',
|
|
155
|
+
"exit /b %errorlevel%",
|
|
156
|
+
"",
|
|
157
|
+
].join("\r\n");
|
|
158
|
+
return [
|
|
159
|
+
"#!/bin/sh",
|
|
160
|
+
"aip_bin_dir=$" + "{0%/*}",
|
|
161
|
+
'if [ "$aip_bin_dir" = "$0" ]; then aip_bin_dir=.; fi',
|
|
162
|
+
'if [ -z "$AIP_HOME" ]; then AIP_HOME=$(CDPATH= cd -- "$aip_bin_dir/.." && pwd); fi',
|
|
163
|
+
'if [ -z "$AIP_PROFILE" ]; then AIP_PROFILE=default; fi',
|
|
164
|
+
'for aip_arg in "$@"; do [ "$aip_arg" != "--local" ] || AIP_PROFILE=local; done',
|
|
165
|
+
'case "$AIP_PROFILE" in default|local) ;; *) echo "Unsupported AIP_PROFILE" >&2; exit 1 ;; esac',
|
|
166
|
+
"export AIP_HOME AIP_PROFILE",
|
|
167
|
+
'aip_runtime="$AIP_HOME/profiles/$AIP_PROFILE/runtime/current"',
|
|
168
|
+
'if [ ! -x "$aip_runtime/bin/node" ]; then echo "Host Runtime [$AIP_PROFILE] is not installed." >&2; exit 1; fi',
|
|
169
|
+
'exec "$aip_runtime/bin/node" "$aip_runtime/app/dist/cli.js" "$@"',
|
|
170
|
+
"",
|
|
171
|
+
].join("\n");
|
|
172
|
+
}
|
|
86
173
|
async function exists(path) {
|
|
87
174
|
return lstat(path)
|
|
88
175
|
.then(() => true)
|
|
89
176
|
.catch(() => false);
|
|
90
177
|
}
|
|
91
178
|
async function waitForDaemon(startedAfter, runtime) {
|
|
92
|
-
|
|
179
|
+
// Windows 计划任务在实时防护扫描 Runtime 时可能需要 30 秒以上才写入 daemon 状态。
|
|
180
|
+
const deadline = Date.now() + 120_000;
|
|
93
181
|
while (Date.now() < deadline) {
|
|
94
182
|
const state = await import("./secure-json.js").then(({ readJson }) => readJson(paths().daemonState));
|
|
95
183
|
if (state?.pid && state.startedAt && new Date(state.startedAt).getTime() >= startedAfter) {
|
|
@@ -101,15 +189,26 @@ async function waitForDaemon(startedAfter, runtime) {
|
|
|
101
189
|
}
|
|
102
190
|
await new Promise((resolveWait) => setTimeout(resolveWait, 100));
|
|
103
191
|
}
|
|
104
|
-
throw new Error(`后台 Host 未能启动;${await backgroundStartFailure(runtime)};请执行
|
|
192
|
+
throw new Error(`后台 Host 未能启动;${await backgroundStartFailure(runtime)};请执行 ${aipCommand()} doctor`);
|
|
105
193
|
}
|
|
106
194
|
async function backgroundStartFailure(runtime) {
|
|
107
|
-
const node = join(runtime, "bin", "node");
|
|
195
|
+
const node = join(runtime, "bin", process.platform === "win32" ? "node.exe" : "node");
|
|
108
196
|
const executableExists = await exists(node);
|
|
109
197
|
const architecture = executableExists
|
|
110
198
|
? (await capture(node, ["-p", "process.arch"])).trim() || "unknown"
|
|
111
199
|
: "missing";
|
|
112
|
-
|
|
200
|
+
if (process.platform === "win32") {
|
|
201
|
+
const task = await capture("schtasks.exe", [
|
|
202
|
+
"/Query",
|
|
203
|
+
"/TN",
|
|
204
|
+
windowsTaskName(),
|
|
205
|
+
"/V",
|
|
206
|
+
"/FO",
|
|
207
|
+
"LIST",
|
|
208
|
+
]);
|
|
209
|
+
return `executable=${executableExists ? "present" : "missing"}, architecture=${architecture}, scheduled task=${task.trim() || "unavailable"}`;
|
|
210
|
+
}
|
|
211
|
+
const label = launchAgentLabel();
|
|
113
212
|
const launchd = await capture("launchctl", ["print", `gui/${process.getuid?.() ?? 0}/${label}`]);
|
|
114
213
|
const launchState = /state = ([^\n]+)/u.exec(launchd)?.[1]?.trim() ?? "unavailable";
|
|
115
214
|
const launchExit = /last exit code = ([^\n]+)/u.exec(launchd)?.[1]?.trim() ?? "unavailable";
|
|
@@ -134,22 +233,37 @@ export async function verifyManifest(root, manifest) {
|
|
|
134
233
|
for (const file of manifest.files) {
|
|
135
234
|
if (file.path.includes("..") || file.path.startsWith("/"))
|
|
136
235
|
throw new Error("Runtime 清单包含非法路径");
|
|
137
|
-
const digest = createHash("sha256")
|
|
138
|
-
.update(await readFile(join(root, file.path)))
|
|
139
|
-
.digest("hex");
|
|
140
|
-
if (digest !== file.sha256)
|
|
141
|
-
throw new Error(`Runtime 文件校验失败:${file.path}`);
|
|
142
236
|
}
|
|
237
|
+
let nextFile = 0;
|
|
238
|
+
await Promise.all(Array.from({ length: Math.min(32, manifest.files.length) }, async () => {
|
|
239
|
+
while (nextFile < manifest.files.length) {
|
|
240
|
+
const file = manifest.files[nextFile++];
|
|
241
|
+
if (!file)
|
|
242
|
+
return;
|
|
243
|
+
const digest = createHash("sha256")
|
|
244
|
+
.update(await readFile(join(root, file.path)))
|
|
245
|
+
.digest("hex");
|
|
246
|
+
if (digest !== file.sha256)
|
|
247
|
+
throw new Error(`Runtime 文件校验失败:${file.path}`);
|
|
248
|
+
}
|
|
249
|
+
}));
|
|
143
250
|
}
|
|
144
251
|
export function launchAgentDefinition(runtime) {
|
|
145
252
|
const local = paths();
|
|
146
|
-
const label =
|
|
253
|
+
const label = launchAgentLabel();
|
|
147
254
|
const launchDir = process.env.AIP_LAUNCH_AGENT_DIR || join(homedir(), "Library", "LaunchAgents");
|
|
148
255
|
const plist = join(launchDir, `${label}.plist`);
|
|
149
256
|
const node = join(runtime, "bin", "node");
|
|
150
257
|
const daemon = join(runtime, "app", "dist", "daemon.js");
|
|
151
|
-
const
|
|
152
|
-
|
|
258
|
+
const xmlEscapes = {
|
|
259
|
+
"&": "&",
|
|
260
|
+
"<": "<",
|
|
261
|
+
">": ">",
|
|
262
|
+
'"': """,
|
|
263
|
+
"'": "'",
|
|
264
|
+
};
|
|
265
|
+
const escapeXml = (value) => value.replace(/[&<>"']/g, (character) => xmlEscapes[character] ?? character);
|
|
266
|
+
const xml = `<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0"><dict><key>Label</key><string>${escapeXml(label)}</string><key>ProgramArguments</key><array><string>${escapeXml(node)}</string><string>${escapeXml(daemon)}</string></array><key>EnvironmentVariables</key><dict><key>AIP_HOME</key><string>${escapeXml(local.base)}</string><key>AIP_PROFILE</key><string>${activeProfile()}</string><key>PATH</key><string>${escapeXml(process.env.PATH ?? "")}</string>${process.env.AIP_TEST_PI === "1" ? "<key>AIP_TEST_PI</key><string>1</string>" : ""}</dict><key>RunAtLoad</key><true/><key>KeepAlive</key><true/><key>StandardOutPath</key><string>${escapeXml(local.log)}</string><key>StandardErrorPath</key><string>${escapeXml(local.log)}</string></dict></plist>\n`;
|
|
153
267
|
return { label, launchDir, plist, xml, domain: `gui/${process.getuid?.() ?? 0}` };
|
|
154
268
|
}
|
|
155
269
|
async function installLaunchAgent(runtime) {
|
|
@@ -175,34 +289,10 @@ async function rotateLog(log) {
|
|
|
175
289
|
await rename(`${log}.1`, `${log}.2`).catch(() => undefined);
|
|
176
290
|
await rename(log, `${log}.1`).catch(() => undefined);
|
|
177
291
|
}
|
|
178
|
-
async function installWindowsTask(runtime) {
|
|
179
|
-
const task = windowsTaskDefinition(runtime, paths().root);
|
|
180
|
-
const { writeSecureJson } = await import("./secure-json.js");
|
|
181
|
-
await writeSecureJson(join(paths().root, "state", "windows-task.json"), task);
|
|
182
|
-
if (process.env.AIP_SKIP_SERVICE !== "1") {
|
|
183
|
-
await run("schtasks.exe", [
|
|
184
|
-
"/Create",
|
|
185
|
-
"/F",
|
|
186
|
-
"/SC",
|
|
187
|
-
"ONLOGON",
|
|
188
|
-
"/TN",
|
|
189
|
-
"AI Platform Local Coding Host",
|
|
190
|
-
"/TR",
|
|
191
|
-
`"${task.executable}" "${task.arguments[0]}"`,
|
|
192
|
-
]);
|
|
193
|
-
await run("schtasks.exe", ["/Run", "/TN", "AI Platform Local Coding Host"]);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
export function windowsTaskDefinition(runtime, root) {
|
|
197
|
-
return {
|
|
198
|
-
executable: win32.join(runtime, "bin", "node.exe"),
|
|
199
|
-
arguments: [win32.join(runtime, "app", "dist", "daemon.js")],
|
|
200
|
-
environment: { AIP_HOME: root },
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
292
|
async function run(command, args, env, ignoreFailure = false) {
|
|
204
293
|
const code = await new Promise((resolveCode, reject) => {
|
|
205
294
|
const child = spawn(command, args, {
|
|
295
|
+
windowsHide: true,
|
|
206
296
|
stdio: "ignore",
|
|
207
297
|
env: env ? { ...process.env, ...env } : process.env,
|
|
208
298
|
});
|
|
@@ -215,7 +305,7 @@ async function run(command, args, env, ignoreFailure = false) {
|
|
|
215
305
|
function capture(command, args) {
|
|
216
306
|
return new Promise((resolveOutput) => {
|
|
217
307
|
let output = "";
|
|
218
|
-
const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
308
|
+
const child = spawn(command, args, { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
|
|
219
309
|
for (const stream of [child.stdout, child.stderr])
|
|
220
310
|
stream.on("data", (chunk) => {
|
|
221
311
|
output = `${output}${chunk.toString()}`.slice(-16_000);
|