@perkos/perkos-a2a 0.12.66 → 0.12.68
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/dist/a2a-maintenance.d.ts +3 -5
- package/dist/a2a-maintenance.d.ts.map +1 -1
- package/dist/a2a-maintenance.js +37 -23
- package/dist/a2a-maintenance.js.map +1 -1
- package/dist/bridge-agent.js +49 -1
- package/dist/bridge-agent.js.map +1 -1
- package/dist/bridge-chat-reply.d.ts +4 -1
- package/dist/bridge-chat-reply.d.ts.map +1 -1
- package/dist/bridge-chat-reply.js +22 -13
- package/dist/bridge-chat-reply.js.map +1 -1
- package/dist/chat-client.d.ts +11 -4
- package/dist/chat-client.d.ts.map +1 -1
- package/dist/chat-client.js +57 -13
- package/dist/chat-client.js.map +1 -1
- package/dist/chat-outbox.d.ts +26 -0
- package/dist/chat-outbox.d.ts.map +1 -0
- package/dist/chat-outbox.js +73 -0
- package/dist/chat-outbox.js.map +1 -0
- package/dist/chat-runtime-http.d.ts +9 -0
- package/dist/chat-runtime-http.d.ts.map +1 -0
- package/dist/chat-runtime-http.js +86 -0
- package/dist/chat-runtime-http.js.map +1 -0
- package/dist/chat-store.d.ts.map +1 -1
- package/dist/chat-store.js +10 -2
- package/dist/chat-store.js.map +1 -1
- package/dist/chat-turns.d.ts +44 -0
- package/dist/chat-turns.d.ts.map +1 -0
- package/dist/chat-turns.js +146 -0
- package/dist/chat-turns.js.map +1 -0
- package/dist/chat-types.d.ts +4 -0
- package/dist/chat-types.d.ts.map +1 -1
- package/dist/hermes-connect.d.ts +2 -0
- package/dist/hermes-connect.d.ts.map +1 -1
- package/dist/hermes-connect.js +11 -0
- package/dist/hermes-connect.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +725 -148
- package/dist/index.js.map +4 -4
- package/dist/maintenance-result.d.ts +19 -0
- package/dist/maintenance-result.d.ts.map +1 -0
- package/dist/maintenance-result.js +38 -0
- package/dist/maintenance-result.js.map +1 -0
- package/dist/maintenance-runner.d.ts +15 -0
- package/dist/maintenance-runner.d.ts.map +1 -1
- package/dist/maintenance-runner.js +87 -62
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/maintenance-runner.test.d.ts +2 -0
- package/dist/maintenance-runner.test.d.ts.map +1 -0
- package/dist/maintenance-runner.test.js +153 -0
- package/dist/maintenance-runner.test.js.map +1 -0
- package/dist/openclaw-supervisor-client.d.ts +8 -0
- package/dist/openclaw-supervisor-client.d.ts.map +1 -1
- package/dist/openclaw-supervisor-client.js +3 -0
- package/dist/openclaw-supervisor-client.js.map +1 -1
- package/dist/openclaw-supervisor.d.ts.map +1 -1
- package/dist/openclaw-supervisor.js +9 -0
- package/dist/openclaw-supervisor.js.map +1 -1
- package/dist/private-chat-records.d.ts +12 -0
- package/dist/private-chat-records.d.ts.map +1 -0
- package/dist/private-chat-records.js +71 -0
- package/dist/private-chat-records.js.map +1 -0
- package/dist/service-environment.d.ts +3 -0
- package/dist/service-environment.d.ts.map +1 -0
- package/dist/service-environment.js +8 -0
- package/dist/service-environment.js.map +1 -0
- package/dist/supervisor-protocol.d.ts +1 -1
- package/dist/supervisor-protocol.d.ts.map +1 -1
- package/docs/chat-durable-delivery.md +55 -0
- package/docs/nexus-communications-server.md +1 -1
- package/docs/plans/2026-09-06-durable-chat-design.md +32 -0
- package/docs/plans/2026-09-06-managed-hermes-service-path-design.md +38 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const MAINTENANCE_ERRORS: readonly ["npx_unavailable", "npx_exec_failed", "invalid_update_receipt", "update_failed", "managed_install_not_found", "managed_config_invalid", "managed_identity_mismatch", "bridge_install_missing", "bridge_version_mismatch"];
|
|
2
|
+
export type MaintenanceError = typeof MAINTENANCE_ERRORS[number];
|
|
3
|
+
export type MaintenanceResult = {
|
|
4
|
+
schemaVersion: 2;
|
|
5
|
+
state: "completed";
|
|
6
|
+
installedVersion: string;
|
|
7
|
+
} | {
|
|
8
|
+
schemaVersion: 2;
|
|
9
|
+
state: "failed";
|
|
10
|
+
errorCode: MaintenanceError;
|
|
11
|
+
};
|
|
12
|
+
export declare const TARGET_VERSION: RegExp;
|
|
13
|
+
export declare const REQUEST_ID: RegExp;
|
|
14
|
+
export declare function safeMaintenanceError(value: unknown): MaintenanceError;
|
|
15
|
+
/** Construct a new allowlisted object; never replay raw child output or legacy metadata. */
|
|
16
|
+
export declare function parseMaintenanceResult(value: unknown): MaintenanceResult | null;
|
|
17
|
+
export declare function maintenanceReportBody(result: MaintenanceResult): Record<string, string>;
|
|
18
|
+
export declare function atomicPrivateJson(path: string, value: unknown): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=maintenance-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintenance-result.d.ts","sourceRoot":"","sources":["../src/maintenance-result.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,qOAIrB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACjE,MAAM,MAAM,iBAAiB,GACzB;IAAE,aAAa,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,aAAa,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAEvE,eAAO,MAAM,cAAc,QAAwC,CAAC;AACpE,eAAO,MAAM,UAAU,QAA+E,CAAC;AAEvG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAGrE;AAED,4FAA4F;AAC5F,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAQ/E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { chmod, mkdir, rename, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
export const MAINTENANCE_ERRORS = [
|
|
4
|
+
"npx_unavailable", "npx_exec_failed", "invalid_update_receipt", "update_failed",
|
|
5
|
+
"managed_install_not_found", "managed_config_invalid", "managed_identity_mismatch",
|
|
6
|
+
"bridge_install_missing", "bridge_version_mismatch",
|
|
7
|
+
];
|
|
8
|
+
export const TARGET_VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
|
|
9
|
+
export const REQUEST_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
10
|
+
export function safeMaintenanceError(value) {
|
|
11
|
+
return typeof value === "string" && MAINTENANCE_ERRORS.includes(value)
|
|
12
|
+
? value : "update_failed";
|
|
13
|
+
}
|
|
14
|
+
/** Construct a new allowlisted object; never replay raw child output or legacy metadata. */
|
|
15
|
+
export function parseMaintenanceResult(value) {
|
|
16
|
+
if (!value || typeof value !== "object")
|
|
17
|
+
return null;
|
|
18
|
+
const v = value;
|
|
19
|
+
if (v.state === "completed" && typeof v.installedVersion === "string" && TARGET_VERSION.test(v.installedVersion)) {
|
|
20
|
+
return { schemaVersion: 2, state: "completed", installedVersion: v.installedVersion };
|
|
21
|
+
}
|
|
22
|
+
if (v.state === "failed")
|
|
23
|
+
return { schemaVersion: 2, state: "failed", errorCode: safeMaintenanceError(v.errorCode) };
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
export function maintenanceReportBody(result) {
|
|
27
|
+
return result.state === "completed"
|
|
28
|
+
? { state: result.state, installedVersion: result.installedVersion }
|
|
29
|
+
: { state: result.state, errorCode: result.errorCode };
|
|
30
|
+
}
|
|
31
|
+
export async function atomicPrivateJson(path, value) {
|
|
32
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
33
|
+
const temporary = `${path}.${process.pid}.tmp`;
|
|
34
|
+
await writeFile(temporary, `${JSON.stringify(value)}\n`, { mode: 0o600 });
|
|
35
|
+
await chmod(temporary, 0o600);
|
|
36
|
+
await rename(temporary, path);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=maintenance-result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintenance-result.js","sourceRoot":"","sources":["../src/maintenance-result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,iBAAiB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,eAAe;IAC/E,2BAA2B,EAAE,wBAAwB,EAAE,2BAA2B;IAClF,wBAAwB,EAAE,yBAAyB;CAC3C,CAAC;AAMX,MAAM,CAAC,MAAM,cAAc,GAAG,qCAAqC,CAAC;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,4EAA4E,CAAC;AAEvG,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,kBAAwC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC3F,CAAC,CAAC,KAAyB,CAAC,CAAC,CAAC,eAAe,CAAC;AAClD,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,CAAC,CAAC,KAAK,KAAK,WAAW,IAAI,OAAO,CAAC,CAAC,gBAAgB,KAAK,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjH,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;IACrH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAyB;IAC7D,OAAO,MAAM,CAAC,KAAK,KAAK,WAAW;QACjC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE;QACpE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAAc;IAClE,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IAC/C,MAAM,SAAS,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,MAAM,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -1,3 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import type { MaintenanceJob } from "./a2a-maintenance.js";
|
|
3
|
+
import { type MaintenanceResult } from "./maintenance-result.js";
|
|
4
|
+
type NpxCommand = {
|
|
5
|
+
file: string;
|
|
6
|
+
cli: string;
|
|
7
|
+
env: NodeJS.ProcessEnv;
|
|
8
|
+
};
|
|
9
|
+
/** Resolve and probe the CLI with the same Node and environment used for execution. */
|
|
10
|
+
export declare function resolveNpx(nodePath?: string, env?: NodeJS.ProcessEnv, candidates?: string[]): Promise<NpxCommand>;
|
|
11
|
+
export declare function executeManagedUpdate(job: MaintenanceJob, command?: NpxCommand): Promise<MaintenanceResult>;
|
|
12
|
+
declare function report(job: MaintenanceJob, body: Record<string, string>): Promise<boolean>;
|
|
13
|
+
export declare function runMaintenanceJob(path: string, deps?: {
|
|
14
|
+
execute?: typeof executeManagedUpdate;
|
|
15
|
+
report?: typeof report;
|
|
16
|
+
}): Promise<void>;
|
|
2
17
|
export {};
|
|
3
18
|
//# sourceMappingURL=maintenance-runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintenance-runner.d.ts","sourceRoot":"","sources":["../src/maintenance-runner.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"maintenance-runner.d.ts","sourceRoot":"","sources":["../src/maintenance-runner.ts"],"names":[],"mappings":";AAMA,OAAO,KAAK,EAAE,cAAc,EAAsB,MAAM,sBAAsB,CAAC;AAE/E,OAAO,EACL,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG1D,KAAK,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,CAAC;AAExE,uFAAuF;AACvF,wBAAsB,UAAU,CAC9B,QAAQ,SAAmB,EAC3B,GAAG,oBAA+B,EAClC,UAAU,WAAkG,GAC3G,OAAO,CAAC,UAAU,CAAC,CAkBrB;AASD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAyBhH;AAED,iBAAe,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAOzF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAC1D,OAAO,CAAC,EAAE,OAAO,oBAAoB,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBrB"}
|
|
@@ -1,80 +1,105 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
|
-
import {
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
3
|
+
import { readFile, realpath, unlink } from "node:fs/promises";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
5
6
|
import { promisify } from "node:util";
|
|
7
|
+
import { serviceEnvironment } from "./service-environment.js";
|
|
8
|
+
import { atomicPrivateJson, maintenanceReportBody, REQUEST_ID, safeMaintenanceError, TARGET_VERSION } from "./maintenance-result.js";
|
|
6
9
|
const execFileAsync = promisify(execFile);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (!path)
|
|
11
|
-
throw new Error("job_missing");
|
|
12
|
-
return path;
|
|
13
|
-
}
|
|
14
|
-
async function atomicPrivateJson(path, value) {
|
|
15
|
-
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
16
|
-
const temporary = `${path}.${process.pid}.tmp`;
|
|
17
|
-
await writeFile(temporary, `${JSON.stringify(value)}\n`, { mode: 0o600 });
|
|
18
|
-
await chmod(temporary, 0o600);
|
|
19
|
-
await rename(temporary, path);
|
|
20
|
-
}
|
|
21
|
-
async function report(job, body) {
|
|
22
|
-
const response = await fetch(`${job.apiBaseUrl}/agents/${encodeURIComponent(job.agentId)}/maintenance/a2a-update/${job.requestId}/report`, {
|
|
23
|
-
method: "POST",
|
|
24
|
-
headers: { authorization: `Bearer ${job.relayApiKey}`, "content-type": "application/json" },
|
|
25
|
-
body: JSON.stringify(body),
|
|
26
|
-
signal: AbortSignal.timeout(15_000),
|
|
27
|
-
}).catch(() => null);
|
|
28
|
-
return response?.ok === true;
|
|
29
|
-
}
|
|
30
|
-
async function resolveNpx() {
|
|
31
|
-
const candidates = [
|
|
32
|
-
join(dirname(process.execPath), "npx"),
|
|
33
|
-
"/opt/homebrew/bin/npx",
|
|
34
|
-
"/usr/local/bin/npx",
|
|
35
|
-
"/usr/bin/npx",
|
|
36
|
-
];
|
|
10
|
+
/** Resolve and probe the CLI with the same Node and environment used for execution. */
|
|
11
|
+
export async function resolveNpx(nodePath = process.execPath, env = serviceEnvironment(nodePath), candidates = [join(dirname(nodePath), "npx"), "/opt/homebrew/bin/npx", "/usr/local/bin/npx", "/usr/bin/npx"]) {
|
|
12
|
+
let found = false;
|
|
37
13
|
for (const candidate of candidates) {
|
|
38
|
-
|
|
39
|
-
|
|
14
|
+
const cli = await realpath(candidate).catch(() => null);
|
|
15
|
+
if (!cli)
|
|
16
|
+
continue;
|
|
17
|
+
found = true;
|
|
18
|
+
try {
|
|
19
|
+
// A shell wrapper fails this probe rather than being passed to a shell.
|
|
20
|
+
const result = await execFileAsync(nodePath, [cli, "--version"], {
|
|
21
|
+
env, timeout: 15_000, maxBuffer: 64 * 1024, encoding: "utf8",
|
|
22
|
+
});
|
|
23
|
+
if (!/^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(result.stdout.trim()))
|
|
24
|
+
continue;
|
|
25
|
+
return { file: nodePath, cli, env };
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Never propagate raw command errors: they can include private paths.
|
|
29
|
+
}
|
|
40
30
|
}
|
|
41
|
-
throw new Error("npx_unavailable");
|
|
31
|
+
throw new Error(found ? "npx_exec_failed" : "npx_unavailable");
|
|
42
32
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
function lastJson(stdout) {
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(stdout.trim().split(/\r?\n/).filter(Boolean).at(-1) ?? "null");
|
|
36
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
48
40
|
}
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
}
|
|
42
|
+
export async function executeManagedUpdate(job, command) {
|
|
51
43
|
try {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
44
|
+
const npx = command ?? await resolveNpx();
|
|
45
|
+
let stdout;
|
|
46
|
+
try {
|
|
47
|
+
const result = await execFileAsync(npx.file, [npx.cli,
|
|
48
|
+
"--yes", `@perkos/perkos-a2a@${job.targetVersion}`, "update-hermes", "--agent-id", job.agentId, "--json",
|
|
49
|
+
], { env: npx.env, timeout: 8 * 60_000, maxBuffer: 1024 * 1024, encoding: "utf8" });
|
|
50
|
+
stdout = result.stdout;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// Preserve only explicitly recognized installer codes, never stdout/stderr.
|
|
54
|
+
const output = error.stdout;
|
|
55
|
+
const parsed = typeof output === "string" ? lastJson(output) : null;
|
|
56
|
+
const code = typeof parsed?.acceptanceBlockedReason === "string"
|
|
57
|
+
? safeMaintenanceError(parsed.acceptanceBlockedReason.toLowerCase()) : "update_failed";
|
|
58
|
+
throw new Error(code !== "update_failed" ? code : "npx_exec_failed");
|
|
59
|
+
}
|
|
60
|
+
const parsed = lastJson(stdout);
|
|
62
61
|
if (!parsed || parsed.ok !== true || parsed.version !== job.targetVersion || parsed.secretsRedacted !== true) {
|
|
63
62
|
throw new Error("invalid_update_receipt");
|
|
64
63
|
}
|
|
65
|
-
|
|
64
|
+
return { schemaVersion: 2, state: "completed", installedVersion: job.targetVersion };
|
|
66
65
|
}
|
|
67
|
-
catch {
|
|
68
|
-
|
|
66
|
+
catch (error) {
|
|
67
|
+
return { schemaVersion: 2, state: "failed", errorCode: safeMaintenanceError(error instanceof Error ? error.message : null) };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function report(job, body) {
|
|
71
|
+
const response = await fetch(`${job.apiBaseUrl}/agents/${encodeURIComponent(job.agentId)}/maintenance/a2a-update/${job.requestId}/report`, { method: "POST", headers: { authorization: `Bearer ${job.relayApiKey}`, "content-type": "application/json" },
|
|
72
|
+
body: JSON.stringify(body), signal: AbortSignal.timeout(15_000) }).catch(() => null);
|
|
73
|
+
return response?.ok === true;
|
|
74
|
+
}
|
|
75
|
+
export async function runMaintenanceJob(path, deps = {}) {
|
|
76
|
+
const job = JSON.parse(await readFile(path, "utf8"));
|
|
77
|
+
if (job.schemaVersion !== 1 || !REQUEST_ID.test(job.requestId) || !TARGET_VERSION.test(job.targetVersion)
|
|
78
|
+
|| typeof job.agentId !== "string" || typeof job.apiBaseUrl !== "string" || typeof job.relayApiKey !== "string") {
|
|
79
|
+
throw new Error("job_invalid");
|
|
69
80
|
}
|
|
70
|
-
const
|
|
81
|
+
const sendReport = deps.report ?? report;
|
|
82
|
+
await sendReport(job, { state: "running" }).catch(() => false);
|
|
83
|
+
const receipt = await (deps.execute ?? executeManagedUpdate)(job).catch(() => ({ schemaVersion: 2, state: "failed", errorCode: "update_failed" }));
|
|
84
|
+
const root = dirname(dirname(path));
|
|
85
|
+
const receiptPath = join(root, "receipts", `${job.requestId}.json`);
|
|
86
|
+
const routingPath = join(root, "pending-reports", `${job.requestId}.json`);
|
|
87
|
+
const routing = { schemaVersion: 1, requestId: job.requestId,
|
|
88
|
+
agentId: job.agentId, apiBaseUrl: job.apiBaseUrl };
|
|
89
|
+
// Routing is private and separate. Results never contain raw subprocess output.
|
|
90
|
+
await atomicPrivateJson(routingPath, routing);
|
|
71
91
|
await atomicPrivateJson(receiptPath, receipt);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
await unlink(
|
|
92
|
+
await unlink(path); // Discard the job credential once the result is durable.
|
|
93
|
+
if (await sendReport(job, maintenanceReportBody(receipt)).catch(() => false)) {
|
|
94
|
+
await unlink(receiptPath).catch(() => undefined);
|
|
95
|
+
await unlink(routingPath).catch(() => undefined);
|
|
76
96
|
}
|
|
77
|
-
await unlink(path).catch(() => undefined);
|
|
78
97
|
}
|
|
79
|
-
|
|
98
|
+
// Importable for tests; only the actual detached CLI runs a job.
|
|
99
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
|
|
100
|
+
const index = process.argv.indexOf("--job");
|
|
101
|
+
const path = index >= 0 ? process.argv[index + 1] : undefined;
|
|
102
|
+
(path ? runMaintenanceJob(path) : Promise.reject(new Error("job_missing")))
|
|
103
|
+
.catch(() => { process.exitCode = 1; });
|
|
104
|
+
}
|
|
80
105
|
//# sourceMappingURL=maintenance-runner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintenance-runner.js","sourceRoot":"","sources":["../src/maintenance-runner.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"maintenance-runner.js","sourceRoot":"","sources":["../src/maintenance-runner.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,UAAU,EAAE,oBAAoB,EAAE,cAAc,EACzE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAG1C,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAC3B,GAAG,GAAG,kBAAkB,CAAC,QAAQ,CAAC,EAClC,UAAU,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,cAAc,CAAC;IAE5G,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,KAAK,GAAG,IAAI,CAAC;QACb,IAAI,CAAC;YACH,wEAAwE;YACxE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE;gBAC/D,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM;aAC7D,CAAC,CAAC;YACH,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBAAE,SAAS;YACzE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,sEAAsE;QACxE,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,QAAQ,CAAC,MAAc;IAC9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;QAClG,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAiC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnH,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAmB,EAAE,OAAoB;IAClF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,IAAI,MAAM,UAAU,EAAE,CAAC;QAC1C,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG;gBACnD,OAAO,EAAE,sBAAsB,GAAG,CAAC,aAAa,EAAE,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ;aACzG,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACpF,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,4EAA4E;YAC5E,MAAM,MAAM,GAAI,KAA8B,CAAC,MAAM,CAAC;YACtD,MAAM,MAAM,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACpE,MAAM,IAAI,GAAG,OAAO,MAAM,EAAE,uBAAuB,KAAK,QAAQ;gBAC9D,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,uBAAuB,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;YACzF,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,EAAE,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,KAAK,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;YAC7G,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC;IACvF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/H,CAAC;AACH,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,GAAmB,EAAE,IAA4B;IACrE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,GAAG,CAAC,UAAU,WAAW,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,2BAA2B,GAAG,CAAC,SAAS,SAAS,EAC5G,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,GAAG,CAAC,WAAW,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC3G,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CACpE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACpB,OAAO,QAAQ,EAAE,EAAE,KAAK,IAAI,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAGlD,EAAE;IACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAmB,CAAC;IACvE,IAAI,GAAG,CAAC,aAAa,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;WACpG,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAClH,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC;IACzC,MAAM,UAAU,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAC3E,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAY,CAAA,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,SAAS,OAAO,CAAC,CAAC;IACpE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,GAAG,CAAC,SAAS,OAAO,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAuB,EAAE,aAAa,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS;QAC9E,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC;IACrD,gFAAgF;IAChF,MAAM,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,yDAAyD;IAC7E,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7E,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACxF,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;SACxE,KAAK,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintenance-runner.test.d.ts","sourceRoot":"","sources":["../src/maintenance-runner.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { chmod, mkdir, mkdtemp, readFile, readdir, realpath, rm, stat, symlink, writeFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { executeManagedUpdate, resolveNpx, runMaintenanceJob } from "./maintenance-runner.js";
|
|
8
|
+
import { flushMaintenanceReceipts } from "./a2a-maintenance.js";
|
|
9
|
+
import { atomicPrivateJson, safeMaintenanceError } from "./maintenance-result.js";
|
|
10
|
+
import { serviceEnvironment } from "./service-environment.js";
|
|
11
|
+
const exec = promisify(execFile);
|
|
12
|
+
const job = { schemaVersion: 1, requestId: "1e1719e8-7e50-4dad-a7cf-754a86699d7d",
|
|
13
|
+
agentId: "fixture-agent", targetVersion: "0.12.68", apiBaseUrl: "https://dev.example.test", relayApiKey: "fixture-secret" };
|
|
14
|
+
const config = { agentName: "fixture", port: 5050, skills: [], peers: {},
|
|
15
|
+
runtime: { kind: "hermes-api" }, relay: { enabled: true, url: "wss://relay.example.test", apiKey: job.relayApiKey },
|
|
16
|
+
platform: { agentId: job.agentId, heartbeatUrl: `${job.apiBaseUrl}/agents/${job.agentId}/heartbeat` } };
|
|
17
|
+
let root;
|
|
18
|
+
let node;
|
|
19
|
+
let npx;
|
|
20
|
+
beforeEach(async () => {
|
|
21
|
+
root = await mkdtemp(join(tmpdir(), "a2a-maintenance-test-"));
|
|
22
|
+
node = join(root, "bin", "node");
|
|
23
|
+
npx = join(root, "bin", "npx");
|
|
24
|
+
await mkdir(join(root, "bin"));
|
|
25
|
+
await symlink(process.execPath, node);
|
|
26
|
+
});
|
|
27
|
+
afterEach(async () => { vi.unstubAllGlobals(); vi.unstubAllEnvs(); await rm(root, { recursive: true, force: true }); });
|
|
28
|
+
async function cli(body) {
|
|
29
|
+
await writeFile(npx, `#!/usr/bin/env node\n${body}\n`);
|
|
30
|
+
await chmod(npx, 0o755);
|
|
31
|
+
}
|
|
32
|
+
function env() { return serviceEnvironment(node, { PATH: "/usr/bin:/bin:/usr/sbin:/sbin" }); }
|
|
33
|
+
const completed = { schemaVersion: 2, state: "completed", installedVersion: job.targetVersion };
|
|
34
|
+
const failed = { schemaVersion: 2, state: "failed", errorCode: "npx_exec_failed" };
|
|
35
|
+
describe("managed runner service environment", () => {
|
|
36
|
+
it("preserves env while prepending Node, removing relative/empty PATH entries and duplicates", () => {
|
|
37
|
+
expect(serviceEnvironment("/opt/node/bin/node", { PATH: ":.:/usr/bin:/opt/node/bin", KEEP: "yes" }))
|
|
38
|
+
.toEqual({ KEEP: "yes", PATH: "/opt/node/bin:/usr/bin:/bin:/usr/sbin:/sbin" });
|
|
39
|
+
expect(serviceEnvironment("/opt/node/bin/node", {}).PATH).toBe("/opt/node/bin:/usr/bin:/bin:/usr/sbin:/sbin");
|
|
40
|
+
});
|
|
41
|
+
it("reproduces env-node exit 127, then completes using absolute Node and the corrected child PATH", async () => {
|
|
42
|
+
// npm also starts child executables with env-node shebangs. Exercise both levels.
|
|
43
|
+
await cli(`const {execFileSync}=require('node:child_process');
|
|
44
|
+
execFileSync('node',['--version'],{env:process.env});
|
|
45
|
+
if(process.argv.includes('--version')) console.log('10.9.4');
|
|
46
|
+
else {
|
|
47
|
+
const expected=['--yes','@perkos/perkos-a2a@0.12.68','update-hermes','--agent-id','fixture-agent','--json'];
|
|
48
|
+
if(JSON.stringify(process.argv.slice(2))!==JSON.stringify(expected)) process.exit(9);
|
|
49
|
+
console.log(JSON.stringify({ok:true,version:'0.12.68',secretsRedacted:true}));
|
|
50
|
+
}`);
|
|
51
|
+
// Use an empty absolute directory for a deterministic baseline on Linux too,
|
|
52
|
+
// where /usr/bin/node may exist unlike the incident's macOS service.
|
|
53
|
+
const absent = join(root, "without-node");
|
|
54
|
+
await mkdir(absent);
|
|
55
|
+
await expect(exec(npx, ["--version"], { env: { PATH: absent } })).rejects.toMatchObject({ code: 127 });
|
|
56
|
+
const command = await resolveNpx(node, env(), [npx]);
|
|
57
|
+
expect(command.file).toBe(node);
|
|
58
|
+
expect(command.env.PATH).toBe(env().PATH);
|
|
59
|
+
await expect(executeManagedUpdate(job, command)).resolves.toEqual(completed);
|
|
60
|
+
});
|
|
61
|
+
it("distinguishes absent CLI from an existing but unrunnable CLI", async () => {
|
|
62
|
+
await expect(resolveNpx(node, env(), [npx])).rejects.toThrow("npx_unavailable");
|
|
63
|
+
await cli("process.exit(127)");
|
|
64
|
+
await expect(resolveNpx(node, env(), [npx])).rejects.toThrow("npx_exec_failed");
|
|
65
|
+
});
|
|
66
|
+
it("continues to a runnable candidate when an earlier CLI fails its probe", async () => {
|
|
67
|
+
await cli("console.log('10.9.4')");
|
|
68
|
+
const broken = join(root, "broken");
|
|
69
|
+
await writeFile(broken, "not javascript");
|
|
70
|
+
expect((await resolveNpx(node, env(), [broken, npx])).cli).toBe(await realpath(npx));
|
|
71
|
+
});
|
|
72
|
+
it("reports execution failure without exposing child output or touching the prior install", async () => {
|
|
73
|
+
const installed = join(root, "installed-version");
|
|
74
|
+
await writeFile(installed, "0.12.66");
|
|
75
|
+
await cli("if(process.argv.includes('--version')) console.log('10.9.4'); else {console.error('fixture-secret /private/fixture');process.exit(127)}");
|
|
76
|
+
const command = await resolveNpx(node, env(), [npx]);
|
|
77
|
+
await expect(executeManagedUpdate(job, command)).resolves.toEqual(failed);
|
|
78
|
+
expect(await readFile(installed, "utf8")).toBe("0.12.66");
|
|
79
|
+
});
|
|
80
|
+
it.each(["not-json", "null", "[]", '{"ok":true,"version":"0.12.66","secretsRedacted":true}',
|
|
81
|
+
'{"ok":true,"version":"0.12.68"}'])("rejects invalid/mismatching receipt %s", async (output) => {
|
|
82
|
+
await cli(`console.log(${JSON.stringify(output)})`);
|
|
83
|
+
await expect(executeManagedUpdate(job, { file: node, cli: npx, env: env() }))
|
|
84
|
+
.resolves.toEqual({ schemaVersion: 2, state: "failed", errorCode: "invalid_update_receipt" });
|
|
85
|
+
});
|
|
86
|
+
it("keeps only known installer codes and uses a safe last resort", async () => {
|
|
87
|
+
await cli("console.log(JSON.stringify({acceptanceBlockedReason:'MANAGED_IDENTITY_MISMATCH',errors:['fixture-secret']}));process.exit(1)");
|
|
88
|
+
await expect(executeManagedUpdate(job, { file: node, cli: npx, env: env() }))
|
|
89
|
+
.resolves.toEqual({ schemaVersion: 2, state: "failed", errorCode: "managed_identity_mismatch" });
|
|
90
|
+
expect(safeMaintenanceError("/private/fixture")).toBe("update_failed");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe("durable sanitized maintenance results", () => {
|
|
94
|
+
const filename = `${job.requestId}.json`;
|
|
95
|
+
async function run(report = vi.fn().mockResolvedValue(false)) {
|
|
96
|
+
const path = join(root, "jobs", filename);
|
|
97
|
+
await atomicPrivateJson(path, job);
|
|
98
|
+
await runMaintenanceJob(path, { execute: async () => failed, report });
|
|
99
|
+
return report;
|
|
100
|
+
}
|
|
101
|
+
it("retains only a sanitized private result after failed report and removes the credential-bearing job", async () => {
|
|
102
|
+
const report = await run();
|
|
103
|
+
const path = join(root, "receipts", filename);
|
|
104
|
+
expect(JSON.parse(await readFile(path, "utf8"))).toEqual(failed);
|
|
105
|
+
expect((await stat(path)).mode & 0o777).toBe(0o600);
|
|
106
|
+
expect((await stat(join(root, "receipts"))).mode & 0o777).toBe(0o700);
|
|
107
|
+
expect(await readdir(join(root, "jobs"))).toEqual([]);
|
|
108
|
+
expect(await readFile(join(root, "pending-reports", filename), "utf8")).not.toContain(job.relayApiKey);
|
|
109
|
+
expect(report.mock.calls.at(-1)?.[1]).toEqual({ state: "failed", errorCode: "npx_exec_failed" });
|
|
110
|
+
});
|
|
111
|
+
it("cleans the result and routing after a successful terminal report", async () => {
|
|
112
|
+
await run(vi.fn().mockResolvedValue(true));
|
|
113
|
+
expect(await readdir(join(root, "receipts"))).toEqual([]);
|
|
114
|
+
expect(await readdir(join(root, "pending-reports"))).toEqual([]);
|
|
115
|
+
});
|
|
116
|
+
it("replays after restart with current authentication, retaining the result while offline", async () => {
|
|
117
|
+
await run();
|
|
118
|
+
const fetchMock = vi.fn().mockRejectedValue(new Error("offline"));
|
|
119
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
120
|
+
await flushMaintenanceReceipts(config, root);
|
|
121
|
+
expect(await readdir(join(root, "receipts"))).toEqual([filename]);
|
|
122
|
+
fetchMock.mockResolvedValue({ ok: true, json: async () => ({ ok: true }) });
|
|
123
|
+
await flushMaintenanceReceipts(config, root);
|
|
124
|
+
expect(JSON.parse(fetchMock.mock.calls.at(-1)?.[1].body)).toEqual({ state: "failed", errorCode: "npx_exec_failed" });
|
|
125
|
+
expect(await readdir(join(root, "receipts"))).toEqual([]);
|
|
126
|
+
});
|
|
127
|
+
it("never replays into a different environment or identity", async () => {
|
|
128
|
+
await run();
|
|
129
|
+
const fetchMock = vi.fn();
|
|
130
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
131
|
+
await flushMaintenanceReceipts({ ...config, platform: { agentId: job.agentId,
|
|
132
|
+
heartbeatUrl: `https://prod.example.test/agents/${job.agentId}/heartbeat` } }, root);
|
|
133
|
+
await flushMaintenanceReceipts({ ...config, platform: { agentId: "other-fixture",
|
|
134
|
+
heartbeatUrl: `${job.apiBaseUrl}/agents/other-fixture/heartbeat` } }, root);
|
|
135
|
+
expect(fetchMock).not.toHaveBeenCalled();
|
|
136
|
+
expect(await readdir(join(root, "receipts"))).toEqual([filename]);
|
|
137
|
+
});
|
|
138
|
+
it("migrates legacy receipts before reporting, stripping unknown errors and metadata even offline", async () => {
|
|
139
|
+
await atomicPrivateJson(join(root, "receipts", filename), { ...job, state: "failed", errorCode: "fixture-secret" });
|
|
140
|
+
vi.stubGlobal("fetch", vi.fn().mockRejectedValue(new Error("offline")));
|
|
141
|
+
await flushMaintenanceReceipts(config, root);
|
|
142
|
+
expect(JSON.parse(await readFile(join(root, "receipts", filename), "utf8")))
|
|
143
|
+
.toEqual({ schemaVersion: 2, state: "failed", errorCode: "update_failed" });
|
|
144
|
+
});
|
|
145
|
+
it("does not execute malformed jobs or permit a non-exact target", async () => {
|
|
146
|
+
const path = join(root, "jobs", filename);
|
|
147
|
+
const execute = vi.fn();
|
|
148
|
+
await atomicPrivateJson(path, { ...job, targetVersion: "0.12.68 --extra" });
|
|
149
|
+
await expect(runMaintenanceJob(path, { execute })).rejects.toThrow("job_invalid");
|
|
150
|
+
expect(execute).not.toHaveBeenCalled();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=maintenance-runner.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintenance-runner.test.js","sourceRoot":"","sources":["../src/maintenance-runner.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,10 +67,18 @@ export declare class OpenClawSupervisorClient {
|
|
|
67
67
|
walletAddress: string;
|
|
68
68
|
text: string;
|
|
69
69
|
replyTo?: string | null;
|
|
70
|
+
id?: string;
|
|
71
|
+
timestamp?: string;
|
|
70
72
|
}): Promise<{
|
|
71
73
|
id: string;
|
|
72
74
|
delivered: boolean;
|
|
73
75
|
}>;
|
|
76
|
+
sendChatProgress(payload: {
|
|
77
|
+
convId: string;
|
|
78
|
+
walletAddress: string;
|
|
79
|
+
replyTo: string;
|
|
80
|
+
phase: string;
|
|
81
|
+
}): Promise<void>;
|
|
74
82
|
private request;
|
|
75
83
|
private requestWithMessage;
|
|
76
84
|
private freshLease;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openclaw-supervisor-client.d.ts","sourceRoot":"","sources":["../src/openclaw-supervisor-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"openclaw-supervisor-client.d.ts","sourceRoot":"","sources":["../src/openclaw-supervisor-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -324,6 +324,9 @@ export class OpenClawSupervisorClient {
|
|
|
324
324
|
async sendChatReply(payload) {
|
|
325
325
|
return await this.request("chatReply", payload, 15_000);
|
|
326
326
|
}
|
|
327
|
+
async sendChatProgress(payload) {
|
|
328
|
+
await this.request("chatProgress", payload, 5_000);
|
|
329
|
+
}
|
|
327
330
|
async request(method, payload, timeoutMs) {
|
|
328
331
|
const requestId = randomUUID();
|
|
329
332
|
return this.requestWithMessage({ protocolVersion: 2, type: "request", requestId, lease: this.freshLease(), method, payload }, timeoutMs);
|