@zhushanwen/subagent-engine-sdk 0.2.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/dist/best-effort.cjs +88 -0
- package/dist/best-effort.d.cts +14 -0
- package/dist/best-effort.d.ts +14 -0
- package/dist/best-effort.js +8 -0
- package/dist/chunk-2DIMPZCQ.js +0 -0
- package/dist/chunk-365AUV6N.js +67 -0
- package/dist/chunk-3K2P2CM2.js +127 -0
- package/dist/chunk-75QEMUGV.js +58 -0
- package/dist/chunk-7I4XGL5J.js +95 -0
- package/dist/chunk-A75XDJIC.js +227 -0
- package/dist/chunk-DSQ7JQKM.js +39 -0
- package/dist/chunk-EJMF63R5.js +19 -0
- package/dist/chunk-GT6YLLN4.js +46 -0
- package/dist/chunk-HYES77BR.js +109 -0
- package/dist/chunk-JSBRDJBE.js +30 -0
- package/dist/chunk-LEOBWKRM.js +128 -0
- package/dist/chunk-N3RL6OVM.js +38 -0
- package/dist/chunk-OPMY4G4M.js +27 -0
- package/dist/chunk-PPEPBVCC.js +120 -0
- package/dist/chunk-PYO3YR7W.js +16 -0
- package/dist/chunk-RDH3ZOV6.js +46 -0
- package/dist/chunk-RULLX6C6.js +11 -0
- package/dist/chunk-X24SFZYW.js +6646 -0
- package/dist/chunk-YFSN3D5N.js +216 -0
- package/dist/chunk-ZOFFJNJD.js +136 -0
- package/dist/chunk-ZXEAW25V.js +132 -0
- package/dist/cli-entry.cjs +119 -0
- package/dist/cli-entry.d.cts +24 -0
- package/dist/cli-entry.d.ts +24 -0
- package/dist/cli-entry.js +8 -0
- package/dist/contract-types-sSlgppBC.d.cts +352 -0
- package/dist/contract-types-sSlgppBC.d.ts +352 -0
- package/dist/data-dir.cjs +117 -0
- package/dist/data-dir.d.cts +20 -0
- package/dist/data-dir.d.ts +20 -0
- package/dist/data-dir.js +12 -0
- package/dist/env.cjs +205 -0
- package/dist/env.d.cts +73 -0
- package/dist/env.d.ts +73 -0
- package/dist/env.js +16 -0
- package/dist/error-codes-DHco5-i_.d.cts +118 -0
- package/dist/error-codes-Dhss2Kmk.d.ts +118 -0
- package/dist/error-message.cjs +40 -0
- package/dist/error-message.d.cts +3 -0
- package/dist/error-message.d.ts +3 -0
- package/dist/error-message.js +7 -0
- package/dist/index.cjs +8375 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +268 -0
- package/dist/journal-io.cjs +70 -0
- package/dist/journal-io.d.cts +12 -0
- package/dist/journal-io.d.ts +12 -0
- package/dist/journal-io.js +7 -0
- package/dist/journal-replay.cjs +256 -0
- package/dist/journal-replay.d.cts +45 -0
- package/dist/journal-replay.d.ts +45 -0
- package/dist/journal-replay.js +17 -0
- package/dist/kill-chain.cjs +221 -0
- package/dist/kill-chain.d.cts +74 -0
- package/dist/kill-chain.d.ts +74 -0
- package/dist/kill-chain.js +23 -0
- package/dist/logger.cjs +84 -0
- package/dist/logger.d.cts +24 -0
- package/dist/logger.d.ts +24 -0
- package/dist/logger.js +11 -0
- package/dist/logs/stderr-rotation.cjs +151 -0
- package/dist/logs/stderr-rotation.d.cts +37 -0
- package/dist/logs/stderr-rotation.d.ts +37 -0
- package/dist/logs/stderr-rotation.js +23 -0
- package/dist/nesting-guard.cjs +95 -0
- package/dist/nesting-guard.d.cts +65 -0
- package/dist/nesting-guard.d.ts +65 -0
- package/dist/nesting-guard.js +15 -0
- package/dist/node-executor.cjs +180 -0
- package/dist/node-executor.d.cts +63 -0
- package/dist/node-executor.d.ts +63 -0
- package/dist/node-executor.js +16 -0
- package/dist/paths.cjs +55 -0
- package/dist/paths.d.cts +8 -0
- package/dist/paths.d.ts +8 -0
- package/dist/paths.js +15 -0
- package/dist/port-contract.cjs +35 -0
- package/dist/port-contract.d.cts +88 -0
- package/dist/port-contract.d.ts +88 -0
- package/dist/port-contract.js +7 -0
- package/dist/protocol/index.cjs +400 -0
- package/dist/protocol/index.d.cts +685 -0
- package/dist/protocol/index.d.ts +685 -0
- package/dist/protocol/index.js +89 -0
- package/dist/relay-env.cjs +71 -0
- package/dist/relay-env.d.cts +37 -0
- package/dist/relay-env.d.ts +37 -0
- package/dist/relay-env.js +23 -0
- package/dist/schema-emulation.cjs +6680 -0
- package/dist/schema-emulation.d.cts +39 -0
- package/dist/schema-emulation.d.ts +39 -0
- package/dist/schema-emulation.js +11 -0
- package/dist/spawn.cjs +200 -0
- package/dist/spawn.d.cts +80 -0
- package/dist/spawn.d.ts +80 -0
- package/dist/spawn.js +16 -0
- package/dist/ui-channels.cjs +120 -0
- package/dist/ui-channels.d.cts +60 -0
- package/dist/ui-channels.d.ts +60 -0
- package/dist/ui-channels.js +9 -0
- package/dist/ui-types.cjs +18 -0
- package/dist/ui-types.d.cts +62 -0
- package/dist/ui-types.d.ts +62 -0
- package/dist/ui-types.js +1 -0
- package/package.json +58 -0
- package/src/best-effort.ts +37 -0
- package/src/cli-entry.ts +77 -0
- package/src/data-dir.ts +88 -0
- package/src/env.ts +265 -0
- package/src/error-message.ts +22 -0
- package/src/index.ts +63 -0
- package/src/journal-io.ts +82 -0
- package/src/journal-replay.ts +432 -0
- package/src/kill-chain.ts +265 -0
- package/src/logger.ts +105 -0
- package/src/logs/stderr-rotation.ts +166 -0
- package/src/nesting-guard.ts +140 -0
- package/src/node-executor.ts +272 -0
- package/src/paths.ts +48 -0
- package/src/port-contract.ts +117 -0
- package/src/protocol/contract-types.ts +378 -0
- package/src/protocol/engine-protocol.ts +81 -0
- package/src/protocol/error-codes.ts +179 -0
- package/src/protocol/frames.ts +145 -0
- package/src/protocol/index.ts +12 -0
- package/src/protocol/methods.ts +229 -0
- package/src/protocol/reverse-channels.ts +274 -0
- package/src/protocol/schema.ts +154 -0
- package/src/relay-env.ts +60 -0
- package/src/schema-emulation.ts +192 -0
- package/src/spawn.ts +246 -0
- package/src/ui-channels.ts +219 -0
- package/src/ui-types.ts +84 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/logs/stderr-rotation.ts
|
|
31
|
+
var stderr_rotation_exports = {};
|
|
32
|
+
__export(stderr_rotation_exports, {
|
|
33
|
+
DEFAULT_STDERR_KEEP_DAYS: () => DEFAULT_STDERR_KEEP_DAYS,
|
|
34
|
+
DEFAULT_STDERR_MAX_BYTES: () => DEFAULT_STDERR_MAX_BYTES,
|
|
35
|
+
cleanupSiblingStderrLogs: () => cleanupSiblingStderrLogs,
|
|
36
|
+
cleanupStaleStderrLogs: () => cleanupStaleStderrLogs,
|
|
37
|
+
isPidAlive: () => isPidAlive,
|
|
38
|
+
rotateStderrLogIfNeeded: () => rotateStderrLogIfNeeded,
|
|
39
|
+
stderrLogPathFor: () => stderrLogPathFor,
|
|
40
|
+
stderrLogPidOf: () => stderrLogPidOf,
|
|
41
|
+
stderrRotationParams: () => stderrRotationParams
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(stderr_rotation_exports);
|
|
44
|
+
var fs = __toESM(require("fs"), 1);
|
|
45
|
+
var import_node_path = require("path");
|
|
46
|
+
var BYTES_PER_KB = 1024;
|
|
47
|
+
var DEFAULT_MAX_FILE_MB = 50;
|
|
48
|
+
var MS_PER_SECOND = 1e3;
|
|
49
|
+
var SECONDS_PER_MINUTE = 60;
|
|
50
|
+
var MINUTES_PER_HOUR = 60;
|
|
51
|
+
var HOURS_PER_DAY = 24;
|
|
52
|
+
var DEFAULT_STDERR_MAX_BYTES = DEFAULT_MAX_FILE_MB * BYTES_PER_KB * BYTES_PER_KB;
|
|
53
|
+
var DAY_MS = HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;
|
|
54
|
+
var DEFAULT_STDERR_KEEP_DAYS = 7;
|
|
55
|
+
function positiveIntEnv(env, key) {
|
|
56
|
+
const raw = env[key];
|
|
57
|
+
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
58
|
+
const n = Number(raw);
|
|
59
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
60
|
+
}
|
|
61
|
+
function stderrRotationParams(env) {
|
|
62
|
+
return {
|
|
63
|
+
maxBytes: positiveIntEnv(env, "XYZ_LOG_MAX_BYTES") ?? DEFAULT_STDERR_MAX_BYTES,
|
|
64
|
+
keepDays: positiveIntEnv(env, "XYZ_LOG_KEEP_DAYS") ?? DEFAULT_STDERR_KEEP_DAYS
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function stderrLogPathFor(engineDataDir, pid, prefix) {
|
|
68
|
+
return (0, import_node_path.join)(engineDataDir, "logs", `${prefix}${pid}.log`);
|
|
69
|
+
}
|
|
70
|
+
function stderrLogPidOf(fileName, prefix) {
|
|
71
|
+
if (!fileName.startsWith(prefix)) return void 0;
|
|
72
|
+
const rest = fileName.slice(prefix.length);
|
|
73
|
+
const pidToken = rest.split(".", 1)[0] ?? "";
|
|
74
|
+
if (!/^\d+$/.test(pidToken)) return void 0;
|
|
75
|
+
return Number(pidToken);
|
|
76
|
+
}
|
|
77
|
+
function isPidAlive(pid) {
|
|
78
|
+
try {
|
|
79
|
+
process.kill(pid, 0);
|
|
80
|
+
return true;
|
|
81
|
+
} catch (err) {
|
|
82
|
+
return err.code === "EPERM";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function rotateStderrLogIfNeeded(path, params) {
|
|
86
|
+
let size;
|
|
87
|
+
try {
|
|
88
|
+
size = fs.statSync(path).size;
|
|
89
|
+
} catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (size <= params.maxBytes) return false;
|
|
93
|
+
const rotated = `${path}.${Date.now()}`;
|
|
94
|
+
try {
|
|
95
|
+
fs.renameSync(path, rotated);
|
|
96
|
+
return true;
|
|
97
|
+
} catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function cleanupStaleStderrLogs(logsDir, env, prefix, now = Date.now()) {
|
|
102
|
+
const params = stderrRotationParams(env);
|
|
103
|
+
const expiryMs = params.keepDays * DAY_MS;
|
|
104
|
+
let deleted = 0;
|
|
105
|
+
let skipped = 0;
|
|
106
|
+
let names;
|
|
107
|
+
try {
|
|
108
|
+
names = fs.readdirSync(logsDir);
|
|
109
|
+
} catch {
|
|
110
|
+
return { deleted, skipped };
|
|
111
|
+
}
|
|
112
|
+
for (const name of names) {
|
|
113
|
+
const pid = stderrLogPidOf(name, prefix);
|
|
114
|
+
if (pid === void 0) continue;
|
|
115
|
+
if (isPidAlive(pid)) {
|
|
116
|
+
skipped += 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const full = (0, import_node_path.join)(logsDir, name);
|
|
120
|
+
try {
|
|
121
|
+
if (fs.statSync(full).mtimeMs > now - expiryMs) {
|
|
122
|
+
skipped += 1;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
} catch {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
fs.rmSync(full, { force: true });
|
|
130
|
+
deleted += 1;
|
|
131
|
+
} catch {
|
|
132
|
+
skipped += 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { deleted, skipped };
|
|
136
|
+
}
|
|
137
|
+
function cleanupSiblingStderrLogs(logPath, env, prefix, now) {
|
|
138
|
+
return cleanupStaleStderrLogs((0, import_node_path.dirname)(logPath), env, prefix, now);
|
|
139
|
+
}
|
|
140
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
141
|
+
0 && (module.exports = {
|
|
142
|
+
DEFAULT_STDERR_KEEP_DAYS,
|
|
143
|
+
DEFAULT_STDERR_MAX_BYTES,
|
|
144
|
+
cleanupSiblingStderrLogs,
|
|
145
|
+
cleanupStaleStderrLogs,
|
|
146
|
+
isPidAlive,
|
|
147
|
+
rotateStderrLogIfNeeded,
|
|
148
|
+
stderrLogPathFor,
|
|
149
|
+
stderrLogPidOf,
|
|
150
|
+
stderrRotationParams
|
|
151
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
declare const DEFAULT_STDERR_MAX_BYTES: number;
|
|
2
|
+
/** 缺省保留天数(与宿主 logger 同源缺省:7 天)。 */
|
|
3
|
+
declare const DEFAULT_STDERR_KEEP_DAYS = 7;
|
|
4
|
+
/** 轮转参数(env 覆盖面 = 宿主 logger 同款 XYZ_LOG_* 两键)。 */
|
|
5
|
+
interface StderrRotationParams {
|
|
6
|
+
maxBytes: number;
|
|
7
|
+
keepDays: number;
|
|
8
|
+
}
|
|
9
|
+
/** 读 env 解析轮转参数(非法值回缺省——取证面配置不拖垮主通道)。 */
|
|
10
|
+
declare function stderrRotationParams(env: NodeJS.ProcessEnv): StderrRotationParams;
|
|
11
|
+
/** 实例维度 stderr tee 路径:<engineDataDir>/logs/<prefix><pid>.log。 */
|
|
12
|
+
declare function stderrLogPathFor(engineDataDir: string, pid: number, prefix: string): string;
|
|
13
|
+
/** 从文件名解析实例 pid(非本前缀形态返回 undefined——调用方跳过)。 */
|
|
14
|
+
declare function stderrLogPidOf(fileName: string, prefix: string): number | undefined;
|
|
15
|
+
/** pid 存活探测(跨实例:ESRCH = 死;EPERM = 存活但非属主,按存活保守处理)。 */
|
|
16
|
+
declare function isPidAlive(pid: number): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* 尺寸轮转:当前文件超过 maxBytes 时 rename 为 `<path>.<时间戳>` 副本并返回
|
|
19
|
+
* true(调用方懒重开新文件继续 append)。rename 失败返回 false(继续 append 原
|
|
20
|
+
* 文件——轮转是取证面优化,不是主通道)。
|
|
21
|
+
*/
|
|
22
|
+
declare function rotateStderrLogIfNeeded(path: string, params: StderrRotationParams): boolean;
|
|
23
|
+
interface CleanupResult {
|
|
24
|
+
/** 已删除文件数。 */
|
|
25
|
+
deleted: number;
|
|
26
|
+
/** 命中前缀但跳过(pid 存活 / mtime 未过期 / 探测不确定)的文件数。 */
|
|
27
|
+
skipped: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 过期清理:扫描 logsDir 下同前缀文件,三判据同时成立才删。目录缺失/读失败返回
|
|
31
|
+
* 零删除(取证面 best-effort)。
|
|
32
|
+
*/
|
|
33
|
+
declare function cleanupStaleStderrLogs(logsDir: string, env: NodeJS.ProcessEnv, prefix: string, now?: number): CleanupResult;
|
|
34
|
+
/** 便捷入口:对 tee 路径所在 logs 目录做过期清理(流打开时机调用,每代一次)。 */
|
|
35
|
+
declare function cleanupSiblingStderrLogs(logPath: string, env: NodeJS.ProcessEnv, prefix: string, now?: number): CleanupResult;
|
|
36
|
+
|
|
37
|
+
export { type CleanupResult, DEFAULT_STDERR_KEEP_DAYS, DEFAULT_STDERR_MAX_BYTES, type StderrRotationParams, cleanupSiblingStderrLogs, cleanupStaleStderrLogs, isPidAlive, rotateStderrLogIfNeeded, stderrLogPathFor, stderrLogPidOf, stderrRotationParams };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
declare const DEFAULT_STDERR_MAX_BYTES: number;
|
|
2
|
+
/** 缺省保留天数(与宿主 logger 同源缺省:7 天)。 */
|
|
3
|
+
declare const DEFAULT_STDERR_KEEP_DAYS = 7;
|
|
4
|
+
/** 轮转参数(env 覆盖面 = 宿主 logger 同款 XYZ_LOG_* 两键)。 */
|
|
5
|
+
interface StderrRotationParams {
|
|
6
|
+
maxBytes: number;
|
|
7
|
+
keepDays: number;
|
|
8
|
+
}
|
|
9
|
+
/** 读 env 解析轮转参数(非法值回缺省——取证面配置不拖垮主通道)。 */
|
|
10
|
+
declare function stderrRotationParams(env: NodeJS.ProcessEnv): StderrRotationParams;
|
|
11
|
+
/** 实例维度 stderr tee 路径:<engineDataDir>/logs/<prefix><pid>.log。 */
|
|
12
|
+
declare function stderrLogPathFor(engineDataDir: string, pid: number, prefix: string): string;
|
|
13
|
+
/** 从文件名解析实例 pid(非本前缀形态返回 undefined——调用方跳过)。 */
|
|
14
|
+
declare function stderrLogPidOf(fileName: string, prefix: string): number | undefined;
|
|
15
|
+
/** pid 存活探测(跨实例:ESRCH = 死;EPERM = 存活但非属主,按存活保守处理)。 */
|
|
16
|
+
declare function isPidAlive(pid: number): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* 尺寸轮转:当前文件超过 maxBytes 时 rename 为 `<path>.<时间戳>` 副本并返回
|
|
19
|
+
* true(调用方懒重开新文件继续 append)。rename 失败返回 false(继续 append 原
|
|
20
|
+
* 文件——轮转是取证面优化,不是主通道)。
|
|
21
|
+
*/
|
|
22
|
+
declare function rotateStderrLogIfNeeded(path: string, params: StderrRotationParams): boolean;
|
|
23
|
+
interface CleanupResult {
|
|
24
|
+
/** 已删除文件数。 */
|
|
25
|
+
deleted: number;
|
|
26
|
+
/** 命中前缀但跳过(pid 存活 / mtime 未过期 / 探测不确定)的文件数。 */
|
|
27
|
+
skipped: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 过期清理:扫描 logsDir 下同前缀文件,三判据同时成立才删。目录缺失/读失败返回
|
|
31
|
+
* 零删除(取证面 best-effort)。
|
|
32
|
+
*/
|
|
33
|
+
declare function cleanupStaleStderrLogs(logsDir: string, env: NodeJS.ProcessEnv, prefix: string, now?: number): CleanupResult;
|
|
34
|
+
/** 便捷入口:对 tee 路径所在 logs 目录做过期清理(流打开时机调用,每代一次)。 */
|
|
35
|
+
declare function cleanupSiblingStderrLogs(logPath: string, env: NodeJS.ProcessEnv, prefix: string, now?: number): CleanupResult;
|
|
36
|
+
|
|
37
|
+
export { type CleanupResult, DEFAULT_STDERR_KEEP_DAYS, DEFAULT_STDERR_MAX_BYTES, type StderrRotationParams, cleanupSiblingStderrLogs, cleanupStaleStderrLogs, isPidAlive, rotateStderrLogIfNeeded, stderrLogPathFor, stderrLogPidOf, stderrRotationParams };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_STDERR_KEEP_DAYS,
|
|
3
|
+
DEFAULT_STDERR_MAX_BYTES,
|
|
4
|
+
cleanupSiblingStderrLogs,
|
|
5
|
+
cleanupStaleStderrLogs,
|
|
6
|
+
isPidAlive,
|
|
7
|
+
rotateStderrLogIfNeeded,
|
|
8
|
+
stderrLogPathFor,
|
|
9
|
+
stderrLogPidOf,
|
|
10
|
+
stderrRotationParams
|
|
11
|
+
} from "../chunk-HYES77BR.js";
|
|
12
|
+
import "../chunk-JSBRDJBE.js";
|
|
13
|
+
export {
|
|
14
|
+
DEFAULT_STDERR_KEEP_DAYS,
|
|
15
|
+
DEFAULT_STDERR_MAX_BYTES,
|
|
16
|
+
cleanupSiblingStderrLogs,
|
|
17
|
+
cleanupStaleStderrLogs,
|
|
18
|
+
isPidAlive,
|
|
19
|
+
rotateStderrLogIfNeeded,
|
|
20
|
+
stderrLogPathFor,
|
|
21
|
+
stderrLogPidOf,
|
|
22
|
+
stderrRotationParams
|
|
23
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/nesting-guard.ts
|
|
21
|
+
var nesting_guard_exports = {};
|
|
22
|
+
__export(nesting_guard_exports, {
|
|
23
|
+
ExecutionNestingContext: () => ExecutionNestingContext,
|
|
24
|
+
NESTED_SPAWN_ENV: () => NESTED_SPAWN_ENV,
|
|
25
|
+
NestedSpawnRejectedError: () => NestedSpawnRejectedError,
|
|
26
|
+
assertNotNestedSpawn: () => assertNotNestedSpawn,
|
|
27
|
+
buildNestedSpawnEnv: () => buildNestedSpawnEnv
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(nesting_guard_exports);
|
|
30
|
+
var import_node_async_hooks = require("async_hooks");
|
|
31
|
+
var NESTED_SPAWN_ENV = "XYZ_AGENT_SUBAGENT";
|
|
32
|
+
var NATIVE_NESTED_KEYS = ["CLAUDECODE", "ZSW_NESTED"];
|
|
33
|
+
var NATIVE_NESTED_PREFIXES = ["PI_SUBAGENT_"];
|
|
34
|
+
var NestedSpawnRejectedError = class extends Error {
|
|
35
|
+
code = "nested_spawn_rejected";
|
|
36
|
+
/** 恢复指引:指向具体下一步,非安慰性文案。 */
|
|
37
|
+
recovery;
|
|
38
|
+
constructor() {
|
|
39
|
+
super(
|
|
40
|
+
"nested_spawn_rejected: this process is already a subagent (XYZ_AGENT_SUBAGENT=1)"
|
|
41
|
+
);
|
|
42
|
+
this.name = "NestedSpawnRejectedError";
|
|
43
|
+
this.recovery = "Subagents must not spawn further subagents (unbounded recursion guard). Do the work directly inside the current task instead of delegating.";
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function buildNestedSpawnEnv(baseEnv) {
|
|
47
|
+
const env = {};
|
|
48
|
+
for (const [key, value] of Object.entries(baseEnv)) {
|
|
49
|
+
if (NATIVE_NESTED_KEYS.includes(key)) continue;
|
|
50
|
+
if (NATIVE_NESTED_PREFIXES.some((prefix) => key.startsWith(prefix))) continue;
|
|
51
|
+
env[key] = value;
|
|
52
|
+
}
|
|
53
|
+
env[NESTED_SPAWN_ENV] = "1";
|
|
54
|
+
return env;
|
|
55
|
+
}
|
|
56
|
+
function assertNotNestedSpawn(env) {
|
|
57
|
+
if (env[NESTED_SPAWN_ENV] === "1") {
|
|
58
|
+
throw new NestedSpawnRejectedError();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
var ExecutionNestingContext = class {
|
|
62
|
+
als = new import_node_async_hooks.AsyncLocalStorage();
|
|
63
|
+
baselineState = null;
|
|
64
|
+
/** 建立进程级基线(initSession:有 env 自我标记 → env 身份;根进程 → null 顶层)。 */
|
|
65
|
+
setBaseline(state) {
|
|
66
|
+
this.baselineState = state;
|
|
67
|
+
}
|
|
68
|
+
/** 读当前嵌套状态:ALS store 优先,断裂时基线兜底(顶层 = null)。 */
|
|
69
|
+
current() {
|
|
70
|
+
return this.als.getStore() ?? this.baselineState;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 读进程级基线(与 current() 的差异:不看 ALS store——直接父归属校验等场景要的是
|
|
74
|
+
* 「本进程自己的身份」而非「当前异步链正在跑的 record 身份」)。
|
|
75
|
+
*/
|
|
76
|
+
baseline() {
|
|
77
|
+
return this.baselineState;
|
|
78
|
+
}
|
|
79
|
+
/** 包裹执行(B run() 期间挂 B 身份——内层创建 C 时 current() 读到 B)。 */
|
|
80
|
+
run(state, fn) {
|
|
81
|
+
return this.als.run(state, fn);
|
|
82
|
+
}
|
|
83
|
+
/** 顶层 enterWith(initSession 建立基线身份后挂入当前异步链)。 */
|
|
84
|
+
enterWith(state) {
|
|
85
|
+
this.als.enterWith(state);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
89
|
+
0 && (module.exports = {
|
|
90
|
+
ExecutionNestingContext,
|
|
91
|
+
NESTED_SPAWN_ENV,
|
|
92
|
+
NestedSpawnRejectedError,
|
|
93
|
+
assertNotNestedSpawn,
|
|
94
|
+
buildNestedSpawnEnv
|
|
95
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** 统一嵌套标记 env 名(D8)。值恒 '1'。 */
|
|
2
|
+
declare const NESTED_SPAWN_ENV = "XYZ_AGENT_SUBAGENT";
|
|
3
|
+
/** env 对象形状(NodeJS.ProcessEnv 的结构子集,测试可传普通对象)。 */
|
|
4
|
+
type SpawnEnv = Record<string, string | undefined>;
|
|
5
|
+
/**
|
|
6
|
+
* nested_spawn_rejected 的结构化错误(自 core errors.ts 内联;code/recovery 与 core
|
|
7
|
+
* 词表逐字一致,EngineError 类形态对齐 SDK protocol/error-codes.ts 的 EngineSdkError)。
|
|
8
|
+
*/
|
|
9
|
+
declare class NestedSpawnRejectedError extends Error {
|
|
10
|
+
readonly code = "nested_spawn_rejected";
|
|
11
|
+
/** 恢复指引:指向具体下一步,非安慰性文案。 */
|
|
12
|
+
readonly recovery: string;
|
|
13
|
+
constructor();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 构造子代理 spawn env:注入 XYZ_AGENT_SUBAGENT=1 + 剥离引擎原生嵌套标记。
|
|
17
|
+
* 返回新对象,不改入参(spawn env 组装链中的多层 spread 安全)。
|
|
18
|
+
*/
|
|
19
|
+
declare function buildNestedSpawnEnv(baseEnv: SpawnEnv): SpawnEnv;
|
|
20
|
+
/**
|
|
21
|
+
* 嵌套 spawn 防护断言:检测到统一标记(本进程已是 subagent)抛
|
|
22
|
+
* nested_spawn_rejected——文案说明防护规则、指向 task 内自行完成。
|
|
23
|
+
* 调用点:subagent 工具入口(进程创建前拒绝,D11 处置三级)。
|
|
24
|
+
*/
|
|
25
|
+
declare function assertNotNestedSpawn(env: SpawnEnv): void;
|
|
26
|
+
/** 执行嵌套状态:当前正在跑的 record 身份 + 递归深度(D-033 通用嵌套深度护栏的计数载体)。 */
|
|
27
|
+
interface ExecutionNestingState {
|
|
28
|
+
recordId: string | undefined;
|
|
29
|
+
depth: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 进程内执行嵌套上下文([D3-⑤] 从 SubagentService 的 execCtxAls 私有字段并入公共层)。
|
|
33
|
+
*
|
|
34
|
+
* 机制(原样迁移,行为零变化):
|
|
35
|
+
* - ALS 按异步调用链传递当前 record 身份:B run() 期间包 this 上下文,B 内创建 C 时
|
|
36
|
+
* 读到 B → C.parentRecordId=B.id、C.depth=B.depth+1;主 session 链上无 store → 顶层。
|
|
37
|
+
* - 进程级基线兜底 [ALS 断裂修复]:pi RPC mode 的 stdin JSONL 是事件回调式
|
|
38
|
+
* (attachJsonlLineReader stream.on("data")),每个命令是独立异步链,enterWith 的
|
|
39
|
+
* store 不会贯穿到后续 tool 调用事件(实测:递归第二层 parentRecordId/depth 丢失
|
|
40
|
+
* 而 rootSessionId 正确)。基线 = 本进程自己的身份(initSession 从 env 读取):
|
|
41
|
+
* 读 ALS store 失败时兜底,保证「本进程派发的 subagent 都是本进程记录的孩子」。
|
|
42
|
+
*
|
|
43
|
+
* 实例归属:per-Service(基线随宿主进程身份而异),Service 构造时创建并持有。
|
|
44
|
+
* 深度上限判据(MAX_FORK_DEPTH)留在调用方——上限常量属 execution 层
|
|
45
|
+
* (session-context-resolver),公共层只提供状态存取单点。
|
|
46
|
+
*/
|
|
47
|
+
declare class ExecutionNestingContext {
|
|
48
|
+
private readonly als;
|
|
49
|
+
private baselineState;
|
|
50
|
+
/** 建立进程级基线(initSession:有 env 自我标记 → env 身份;根进程 → null 顶层)。 */
|
|
51
|
+
setBaseline(state: ExecutionNestingState | null): void;
|
|
52
|
+
/** 读当前嵌套状态:ALS store 优先,断裂时基线兜底(顶层 = null)。 */
|
|
53
|
+
current(): ExecutionNestingState | null;
|
|
54
|
+
/**
|
|
55
|
+
* 读进程级基线(与 current() 的差异:不看 ALS store——直接父归属校验等场景要的是
|
|
56
|
+
* 「本进程自己的身份」而非「当前异步链正在跑的 record 身份」)。
|
|
57
|
+
*/
|
|
58
|
+
baseline(): ExecutionNestingState | null;
|
|
59
|
+
/** 包裹执行(B run() 期间挂 B 身份——内层创建 C 时 current() 读到 B)。 */
|
|
60
|
+
run<T>(state: ExecutionNestingState, fn: () => T): T;
|
|
61
|
+
/** 顶层 enterWith(initSession 建立基线身份后挂入当前异步链)。 */
|
|
62
|
+
enterWith(state: ExecutionNestingState): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { ExecutionNestingContext, type ExecutionNestingState, NESTED_SPAWN_ENV, NestedSpawnRejectedError, type SpawnEnv, assertNotNestedSpawn, buildNestedSpawnEnv };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** 统一嵌套标记 env 名(D8)。值恒 '1'。 */
|
|
2
|
+
declare const NESTED_SPAWN_ENV = "XYZ_AGENT_SUBAGENT";
|
|
3
|
+
/** env 对象形状(NodeJS.ProcessEnv 的结构子集,测试可传普通对象)。 */
|
|
4
|
+
type SpawnEnv = Record<string, string | undefined>;
|
|
5
|
+
/**
|
|
6
|
+
* nested_spawn_rejected 的结构化错误(自 core errors.ts 内联;code/recovery 与 core
|
|
7
|
+
* 词表逐字一致,EngineError 类形态对齐 SDK protocol/error-codes.ts 的 EngineSdkError)。
|
|
8
|
+
*/
|
|
9
|
+
declare class NestedSpawnRejectedError extends Error {
|
|
10
|
+
readonly code = "nested_spawn_rejected";
|
|
11
|
+
/** 恢复指引:指向具体下一步,非安慰性文案。 */
|
|
12
|
+
readonly recovery: string;
|
|
13
|
+
constructor();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 构造子代理 spawn env:注入 XYZ_AGENT_SUBAGENT=1 + 剥离引擎原生嵌套标记。
|
|
17
|
+
* 返回新对象,不改入参(spawn env 组装链中的多层 spread 安全)。
|
|
18
|
+
*/
|
|
19
|
+
declare function buildNestedSpawnEnv(baseEnv: SpawnEnv): SpawnEnv;
|
|
20
|
+
/**
|
|
21
|
+
* 嵌套 spawn 防护断言:检测到统一标记(本进程已是 subagent)抛
|
|
22
|
+
* nested_spawn_rejected——文案说明防护规则、指向 task 内自行完成。
|
|
23
|
+
* 调用点:subagent 工具入口(进程创建前拒绝,D11 处置三级)。
|
|
24
|
+
*/
|
|
25
|
+
declare function assertNotNestedSpawn(env: SpawnEnv): void;
|
|
26
|
+
/** 执行嵌套状态:当前正在跑的 record 身份 + 递归深度(D-033 通用嵌套深度护栏的计数载体)。 */
|
|
27
|
+
interface ExecutionNestingState {
|
|
28
|
+
recordId: string | undefined;
|
|
29
|
+
depth: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 进程内执行嵌套上下文([D3-⑤] 从 SubagentService 的 execCtxAls 私有字段并入公共层)。
|
|
33
|
+
*
|
|
34
|
+
* 机制(原样迁移,行为零变化):
|
|
35
|
+
* - ALS 按异步调用链传递当前 record 身份:B run() 期间包 this 上下文,B 内创建 C 时
|
|
36
|
+
* 读到 B → C.parentRecordId=B.id、C.depth=B.depth+1;主 session 链上无 store → 顶层。
|
|
37
|
+
* - 进程级基线兜底 [ALS 断裂修复]:pi RPC mode 的 stdin JSONL 是事件回调式
|
|
38
|
+
* (attachJsonlLineReader stream.on("data")),每个命令是独立异步链,enterWith 的
|
|
39
|
+
* store 不会贯穿到后续 tool 调用事件(实测:递归第二层 parentRecordId/depth 丢失
|
|
40
|
+
* 而 rootSessionId 正确)。基线 = 本进程自己的身份(initSession 从 env 读取):
|
|
41
|
+
* 读 ALS store 失败时兜底,保证「本进程派发的 subagent 都是本进程记录的孩子」。
|
|
42
|
+
*
|
|
43
|
+
* 实例归属:per-Service(基线随宿主进程身份而异),Service 构造时创建并持有。
|
|
44
|
+
* 深度上限判据(MAX_FORK_DEPTH)留在调用方——上限常量属 execution 层
|
|
45
|
+
* (session-context-resolver),公共层只提供状态存取单点。
|
|
46
|
+
*/
|
|
47
|
+
declare class ExecutionNestingContext {
|
|
48
|
+
private readonly als;
|
|
49
|
+
private baselineState;
|
|
50
|
+
/** 建立进程级基线(initSession:有 env 自我标记 → env 身份;根进程 → null 顶层)。 */
|
|
51
|
+
setBaseline(state: ExecutionNestingState | null): void;
|
|
52
|
+
/** 读当前嵌套状态:ALS store 优先,断裂时基线兜底(顶层 = null)。 */
|
|
53
|
+
current(): ExecutionNestingState | null;
|
|
54
|
+
/**
|
|
55
|
+
* 读进程级基线(与 current() 的差异:不看 ALS store——直接父归属校验等场景要的是
|
|
56
|
+
* 「本进程自己的身份」而非「当前异步链正在跑的 record 身份」)。
|
|
57
|
+
*/
|
|
58
|
+
baseline(): ExecutionNestingState | null;
|
|
59
|
+
/** 包裹执行(B run() 期间挂 B 身份——内层创建 C 时 current() 读到 B)。 */
|
|
60
|
+
run<T>(state: ExecutionNestingState, fn: () => T): T;
|
|
61
|
+
/** 顶层 enterWith(initSession 建立基线身份后挂入当前异步链)。 */
|
|
62
|
+
enterWith(state: ExecutionNestingState): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { ExecutionNestingContext, type ExecutionNestingState, NESTED_SPAWN_ENV, NestedSpawnRejectedError, type SpawnEnv, assertNotNestedSpawn, buildNestedSpawnEnv };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExecutionNestingContext,
|
|
3
|
+
NESTED_SPAWN_ENV,
|
|
4
|
+
NestedSpawnRejectedError,
|
|
5
|
+
assertNotNestedSpawn,
|
|
6
|
+
buildNestedSpawnEnv
|
|
7
|
+
} from "./chunk-365AUV6N.js";
|
|
8
|
+
import "./chunk-JSBRDJBE.js";
|
|
9
|
+
export {
|
|
10
|
+
ExecutionNestingContext,
|
|
11
|
+
NESTED_SPAWN_ENV,
|
|
12
|
+
NestedSpawnRejectedError,
|
|
13
|
+
assertNotNestedSpawn,
|
|
14
|
+
buildNestedSpawnEnv
|
|
15
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/node-executor.ts
|
|
21
|
+
var node_executor_exports = {};
|
|
22
|
+
__export(node_executor_exports, {
|
|
23
|
+
ENGINE_NODE_ENV: () => ENGINE_NODE_ENV,
|
|
24
|
+
hostKindOf: () => hostKindOf,
|
|
25
|
+
probeNodeExecutor: () => probeNodeExecutor,
|
|
26
|
+
resetEngineNodeProbeCache: () => resetEngineNodeProbeCache,
|
|
27
|
+
resolveEngineNodeLaunch: () => resolveEngineNodeLaunch
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(node_executor_exports);
|
|
30
|
+
var import_node_child_process = require("child_process");
|
|
31
|
+
|
|
32
|
+
// src/protocol/error-codes.ts
|
|
33
|
+
var EngineSdkError = class extends Error {
|
|
34
|
+
code;
|
|
35
|
+
recovery;
|
|
36
|
+
data;
|
|
37
|
+
constructor(code, detail, recovery, data) {
|
|
38
|
+
super(`${code}: ${detail}`);
|
|
39
|
+
this.name = "EngineSdkError";
|
|
40
|
+
this.code = code;
|
|
41
|
+
this.recovery = recovery;
|
|
42
|
+
this.data = data;
|
|
43
|
+
}
|
|
44
|
+
/** 协议 error 帧载荷投影。 */
|
|
45
|
+
toStructured() {
|
|
46
|
+
return { code: this.code, message: this.message, recovery: this.recovery, data: this.data };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/node-executor.ts
|
|
51
|
+
var ENGINE_NODE_ENV = "XYZ_AGENT_ENGINE_NODE";
|
|
52
|
+
var PROBE_TIMEOUT_MS = 5e3;
|
|
53
|
+
function probeNodeExecutor(execPath, isElectron) {
|
|
54
|
+
return new Promise((resolve) => {
|
|
55
|
+
let settled = false;
|
|
56
|
+
let child = null;
|
|
57
|
+
const finish = (ok) => {
|
|
58
|
+
if (settled) return;
|
|
59
|
+
settled = true;
|
|
60
|
+
clearTimeout(timer);
|
|
61
|
+
try {
|
|
62
|
+
child?.kill("SIGKILL");
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
resolve(ok);
|
|
66
|
+
};
|
|
67
|
+
const env = {};
|
|
68
|
+
if (process.env.PATH !== void 0) env.PATH = process.env.PATH;
|
|
69
|
+
if (process.env.HOME !== void 0) env.HOME = process.env.HOME;
|
|
70
|
+
if (isElectron) env.ELECTRON_RUN_AS_NODE = "1";
|
|
71
|
+
try {
|
|
72
|
+
child = (0, import_node_child_process.spawn)(execPath, ["--eval", "process.exit(0)"], {
|
|
73
|
+
env,
|
|
74
|
+
stdio: "ignore",
|
|
75
|
+
windowsHide: true
|
|
76
|
+
});
|
|
77
|
+
} catch {
|
|
78
|
+
resolve(false);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const timer = setTimeout(() => finish(false), PROBE_TIMEOUT_MS);
|
|
82
|
+
timer.unref();
|
|
83
|
+
child.on("error", () => finish(false));
|
|
84
|
+
child.on("exit", (code) => finish(code === 0));
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
var probeCache = /* @__PURE__ */ new Map();
|
|
88
|
+
function probeCached(execPath, isElectron) {
|
|
89
|
+
const key = `${execPath}:${isElectron}`;
|
|
90
|
+
let p = probeCache.get(key);
|
|
91
|
+
if (!p) {
|
|
92
|
+
p = probeNodeExecutor(execPath, isElectron);
|
|
93
|
+
probeCache.set(key, p);
|
|
94
|
+
}
|
|
95
|
+
return p;
|
|
96
|
+
}
|
|
97
|
+
function resetEngineNodeProbeCache() {
|
|
98
|
+
probeCache.clear();
|
|
99
|
+
}
|
|
100
|
+
function engineNotFound(detail, recovery) {
|
|
101
|
+
return new EngineSdkError("engine_not_found", detail, recovery);
|
|
102
|
+
}
|
|
103
|
+
function launchEnvOf(opts) {
|
|
104
|
+
return opts.env ?? process.env;
|
|
105
|
+
}
|
|
106
|
+
async function resolvePiExtensionLaunch(entryPath, entryArgs, env) {
|
|
107
|
+
const engineNode = env[ENGINE_NODE_ENV]?.trim();
|
|
108
|
+
if (engineNode === void 0 || engineNode === "") {
|
|
109
|
+
throw engineNotFound(
|
|
110
|
+
`pi extension host must spawn engines via injected executor ${ENGINE_NODE_ENV}, but it is not set (host process.execPath is the pi binary, not a node executor)`,
|
|
111
|
+
`The xyz-agent runtime injects ${ENGINE_NODE_ENV} when spawning the pi host. If you are running the extension inside a packaged app, report this as a packaging regression; standalone pi installs do not use the pi-extension host kind.`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
const isElectron = env.ELECTRON_RUN_AS_NODE === "1";
|
|
115
|
+
if (!await probeCached(engineNode, isElectron)) {
|
|
116
|
+
throw engineNotFound(
|
|
117
|
+
`injected node executor failed the probe: ${engineNode} (isElectron=${isElectron})`,
|
|
118
|
+
`Verify the executor exists and can run plain node semantics (Electron binaries need ELECTRON_RUN_AS_NODE=1). The host re-probes after restart.`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return { command: engineNode, args: [entryPath, ...entryArgs], electronRunAsNode: isElectron };
|
|
122
|
+
}
|
|
123
|
+
async function resolveRuntimeSidecarLaunch(entryPath, entryArgs, opts) {
|
|
124
|
+
const execPath = opts.execPath ?? process.execPath;
|
|
125
|
+
const isElectron = opts.isElectronHost ?? process.versions.electron !== void 0;
|
|
126
|
+
if (!await probeCached(execPath, isElectron)) {
|
|
127
|
+
throw engineNotFound(
|
|
128
|
+
`runtime sidecar executor failed the probe: ${execPath} (isElectron=${isElectron})`,
|
|
129
|
+
`The sidecar process.execPath must run plain node semantics (ELECTRON_RUN_AS_NODE=1 for Electron binaries). Check how the runtime sidecar was spawned.`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
return { command: execPath, args: [entryPath, ...entryArgs], electronRunAsNode: isElectron };
|
|
133
|
+
}
|
|
134
|
+
async function resolveStandaloneLaunch(entryPath, entryArgs) {
|
|
135
|
+
if (!await probeCached("node", false)) {
|
|
136
|
+
throw engineNotFound(
|
|
137
|
+
`no usable 'node' on PATH for standalone engine launch (entry: ${entryPath})`,
|
|
138
|
+
`Install Node.js >= 22 and ensure 'node' is on PATH (https://nodejs.org/), or configure the engine explicitly via subagents/config.json.`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
return { command: "node", args: [entryPath, ...entryArgs], electronRunAsNode: false };
|
|
142
|
+
}
|
|
143
|
+
async function resolveEngineNodeLaunch(opts) {
|
|
144
|
+
const platform = opts.platform ?? process.platform;
|
|
145
|
+
const entryArgs = [...opts.args ?? []];
|
|
146
|
+
if (platform === "win32" && opts.entryPath.toLowerCase().endsWith(".cmd")) {
|
|
147
|
+
return {
|
|
148
|
+
command: "cmd.exe",
|
|
149
|
+
args: ["/c", opts.entryPath, ...entryArgs],
|
|
150
|
+
electronRunAsNode: false
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (!/\.(?:js|mjs|cjs|ts)$/i.test(opts.entryPath)) {
|
|
154
|
+
return { command: opts.entryPath, args: entryArgs, electronRunAsNode: false };
|
|
155
|
+
}
|
|
156
|
+
if (opts.hostKind === "pi-extension") {
|
|
157
|
+
return resolvePiExtensionLaunch(opts.entryPath, entryArgs, launchEnvOf(opts));
|
|
158
|
+
}
|
|
159
|
+
if (opts.hostKind === "runtime-sidecar") {
|
|
160
|
+
return resolveRuntimeSidecarLaunch(opts.entryPath, entryArgs, opts);
|
|
161
|
+
}
|
|
162
|
+
if (opts.hostKind === "standalone") {
|
|
163
|
+
return resolveStandaloneLaunch(opts.entryPath, entryArgs);
|
|
164
|
+
}
|
|
165
|
+
return { command: opts.entryPath, args: entryArgs, electronRunAsNode: false };
|
|
166
|
+
}
|
|
167
|
+
function hostKindOf(hostKind, env = process.env) {
|
|
168
|
+
if (hostKind.startsWith("runtime")) return "runtime-sidecar";
|
|
169
|
+
const engineNode = env[ENGINE_NODE_ENV]?.trim();
|
|
170
|
+
if (engineNode !== void 0 && engineNode !== "") return "pi-extension";
|
|
171
|
+
return "standalone";
|
|
172
|
+
}
|
|
173
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
174
|
+
0 && (module.exports = {
|
|
175
|
+
ENGINE_NODE_ENV,
|
|
176
|
+
hostKindOf,
|
|
177
|
+
probeNodeExecutor,
|
|
178
|
+
resetEngineNodeProbeCache,
|
|
179
|
+
resolveEngineNodeLaunch
|
|
180
|
+
});
|