@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.
Files changed (139) hide show
  1. package/dist/best-effort.cjs +88 -0
  2. package/dist/best-effort.d.cts +14 -0
  3. package/dist/best-effort.d.ts +14 -0
  4. package/dist/best-effort.js +8 -0
  5. package/dist/chunk-2DIMPZCQ.js +0 -0
  6. package/dist/chunk-365AUV6N.js +67 -0
  7. package/dist/chunk-3K2P2CM2.js +127 -0
  8. package/dist/chunk-75QEMUGV.js +58 -0
  9. package/dist/chunk-7I4XGL5J.js +95 -0
  10. package/dist/chunk-A75XDJIC.js +227 -0
  11. package/dist/chunk-DSQ7JQKM.js +39 -0
  12. package/dist/chunk-EJMF63R5.js +19 -0
  13. package/dist/chunk-GT6YLLN4.js +46 -0
  14. package/dist/chunk-HYES77BR.js +109 -0
  15. package/dist/chunk-JSBRDJBE.js +30 -0
  16. package/dist/chunk-LEOBWKRM.js +128 -0
  17. package/dist/chunk-N3RL6OVM.js +38 -0
  18. package/dist/chunk-OPMY4G4M.js +27 -0
  19. package/dist/chunk-PPEPBVCC.js +120 -0
  20. package/dist/chunk-PYO3YR7W.js +16 -0
  21. package/dist/chunk-RDH3ZOV6.js +46 -0
  22. package/dist/chunk-RULLX6C6.js +11 -0
  23. package/dist/chunk-X24SFZYW.js +6646 -0
  24. package/dist/chunk-YFSN3D5N.js +216 -0
  25. package/dist/chunk-ZOFFJNJD.js +136 -0
  26. package/dist/chunk-ZXEAW25V.js +132 -0
  27. package/dist/cli-entry.cjs +119 -0
  28. package/dist/cli-entry.d.cts +24 -0
  29. package/dist/cli-entry.d.ts +24 -0
  30. package/dist/cli-entry.js +8 -0
  31. package/dist/contract-types-sSlgppBC.d.cts +352 -0
  32. package/dist/contract-types-sSlgppBC.d.ts +352 -0
  33. package/dist/data-dir.cjs +117 -0
  34. package/dist/data-dir.d.cts +20 -0
  35. package/dist/data-dir.d.ts +20 -0
  36. package/dist/data-dir.js +12 -0
  37. package/dist/env.cjs +205 -0
  38. package/dist/env.d.cts +73 -0
  39. package/dist/env.d.ts +73 -0
  40. package/dist/env.js +16 -0
  41. package/dist/error-codes-DHco5-i_.d.cts +118 -0
  42. package/dist/error-codes-Dhss2Kmk.d.ts +118 -0
  43. package/dist/error-message.cjs +40 -0
  44. package/dist/error-message.d.cts +3 -0
  45. package/dist/error-message.d.ts +3 -0
  46. package/dist/error-message.js +7 -0
  47. package/dist/index.cjs +8375 -0
  48. package/dist/index.d.cts +23 -0
  49. package/dist/index.d.ts +23 -0
  50. package/dist/index.js +268 -0
  51. package/dist/journal-io.cjs +70 -0
  52. package/dist/journal-io.d.cts +12 -0
  53. package/dist/journal-io.d.ts +12 -0
  54. package/dist/journal-io.js +7 -0
  55. package/dist/journal-replay.cjs +256 -0
  56. package/dist/journal-replay.d.cts +45 -0
  57. package/dist/journal-replay.d.ts +45 -0
  58. package/dist/journal-replay.js +17 -0
  59. package/dist/kill-chain.cjs +221 -0
  60. package/dist/kill-chain.d.cts +74 -0
  61. package/dist/kill-chain.d.ts +74 -0
  62. package/dist/kill-chain.js +23 -0
  63. package/dist/logger.cjs +84 -0
  64. package/dist/logger.d.cts +24 -0
  65. package/dist/logger.d.ts +24 -0
  66. package/dist/logger.js +11 -0
  67. package/dist/logs/stderr-rotation.cjs +151 -0
  68. package/dist/logs/stderr-rotation.d.cts +37 -0
  69. package/dist/logs/stderr-rotation.d.ts +37 -0
  70. package/dist/logs/stderr-rotation.js +23 -0
  71. package/dist/nesting-guard.cjs +95 -0
  72. package/dist/nesting-guard.d.cts +65 -0
  73. package/dist/nesting-guard.d.ts +65 -0
  74. package/dist/nesting-guard.js +15 -0
  75. package/dist/node-executor.cjs +180 -0
  76. package/dist/node-executor.d.cts +63 -0
  77. package/dist/node-executor.d.ts +63 -0
  78. package/dist/node-executor.js +16 -0
  79. package/dist/paths.cjs +55 -0
  80. package/dist/paths.d.cts +8 -0
  81. package/dist/paths.d.ts +8 -0
  82. package/dist/paths.js +15 -0
  83. package/dist/port-contract.cjs +35 -0
  84. package/dist/port-contract.d.cts +88 -0
  85. package/dist/port-contract.d.ts +88 -0
  86. package/dist/port-contract.js +7 -0
  87. package/dist/protocol/index.cjs +400 -0
  88. package/dist/protocol/index.d.cts +685 -0
  89. package/dist/protocol/index.d.ts +685 -0
  90. package/dist/protocol/index.js +89 -0
  91. package/dist/relay-env.cjs +71 -0
  92. package/dist/relay-env.d.cts +37 -0
  93. package/dist/relay-env.d.ts +37 -0
  94. package/dist/relay-env.js +23 -0
  95. package/dist/schema-emulation.cjs +6680 -0
  96. package/dist/schema-emulation.d.cts +39 -0
  97. package/dist/schema-emulation.d.ts +39 -0
  98. package/dist/schema-emulation.js +11 -0
  99. package/dist/spawn.cjs +200 -0
  100. package/dist/spawn.d.cts +80 -0
  101. package/dist/spawn.d.ts +80 -0
  102. package/dist/spawn.js +16 -0
  103. package/dist/ui-channels.cjs +120 -0
  104. package/dist/ui-channels.d.cts +60 -0
  105. package/dist/ui-channels.d.ts +60 -0
  106. package/dist/ui-channels.js +9 -0
  107. package/dist/ui-types.cjs +18 -0
  108. package/dist/ui-types.d.cts +62 -0
  109. package/dist/ui-types.d.ts +62 -0
  110. package/dist/ui-types.js +1 -0
  111. package/package.json +58 -0
  112. package/src/best-effort.ts +37 -0
  113. package/src/cli-entry.ts +77 -0
  114. package/src/data-dir.ts +88 -0
  115. package/src/env.ts +265 -0
  116. package/src/error-message.ts +22 -0
  117. package/src/index.ts +63 -0
  118. package/src/journal-io.ts +82 -0
  119. package/src/journal-replay.ts +432 -0
  120. package/src/kill-chain.ts +265 -0
  121. package/src/logger.ts +105 -0
  122. package/src/logs/stderr-rotation.ts +166 -0
  123. package/src/nesting-guard.ts +140 -0
  124. package/src/node-executor.ts +272 -0
  125. package/src/paths.ts +48 -0
  126. package/src/port-contract.ts +117 -0
  127. package/src/protocol/contract-types.ts +378 -0
  128. package/src/protocol/engine-protocol.ts +81 -0
  129. package/src/protocol/error-codes.ts +179 -0
  130. package/src/protocol/frames.ts +145 -0
  131. package/src/protocol/index.ts +12 -0
  132. package/src/protocol/methods.ts +229 -0
  133. package/src/protocol/reverse-channels.ts +274 -0
  134. package/src/protocol/schema.ts +154 -0
  135. package/src/relay-env.ts +60 -0
  136. package/src/schema-emulation.ts +192 -0
  137. package/src/spawn.ts +246 -0
  138. package/src/ui-channels.ts +219 -0
  139. package/src/ui-types.ts +84 -0
@@ -0,0 +1,216 @@
1
+ // src/protocol/frames.ts
2
+ function isRecord(v) {
3
+ return typeof v === "object" && v !== null;
4
+ }
5
+ function isRequestFrame(frame) {
6
+ return isRecord(frame) && typeof frame.id === "number" && typeof frame.method === "string" && "params" in frame && !("result" in frame) && !("error" in frame);
7
+ }
8
+ function isResponseFrame(frame) {
9
+ if (!isRecord(frame) || !("id" in frame)) return false;
10
+ const idOk = typeof frame.id === "number" || typeof frame.id === "string";
11
+ if (!idOk) return false;
12
+ const hasResult = "result" in frame;
13
+ const hasError = "error" in frame;
14
+ return hasResult !== hasError;
15
+ }
16
+ function isNotificationFrame(frame) {
17
+ return isRecord(frame) && !("id" in frame) && frame.method === "event" && isRecord(frame.params) && typeof frame.params.runId === "string" && typeof frame.params.seq === "number" && isRecord(frame.params.event) && typeof frame.params.event.type === "string";
18
+ }
19
+ function isReverseRequestFrame(frame) {
20
+ return isRecord(frame) && typeof frame.id === "string" && typeof frame.method === "string" && frame.method.startsWith("host/") && "params" in frame;
21
+ }
22
+
23
+ // src/protocol/methods.ts
24
+ var PROTOCOL_METHODS = [
25
+ "initialize",
26
+ "probe",
27
+ "run",
28
+ "cancel",
29
+ "interact",
30
+ "read",
31
+ "listModels",
32
+ "validateModel",
33
+ "dispose",
34
+ "ping"
35
+ ];
36
+
37
+ // src/protocol/reverse-channels.ts
38
+ var REVERSE_CHANNELS = [
39
+ "host/log",
40
+ "host/askUser",
41
+ "host/permission",
42
+ "host/streamDelta",
43
+ "host/poolResolved",
44
+ "host/handleReady",
45
+ "host/childSpawned",
46
+ "host/childStateChanged",
47
+ "host/roundLifecycle"
48
+ ];
49
+ var REVERSE_CHANNEL_TIMEOUT_CLASS = {
50
+ "host/log": "data-plane",
51
+ "host/streamDelta": "data-plane",
52
+ "host/poolResolved": "data-plane",
53
+ "host/handleReady": "data-plane",
54
+ "host/childSpawned": "data-plane",
55
+ "host/childStateChanged": "data-plane",
56
+ "host/roundLifecycle": "data-plane",
57
+ "host/askUser": "interaction",
58
+ "host/permission": "interaction"
59
+ };
60
+ function isHostStreamDeltaParams(value) {
61
+ if (typeof value !== "object" || value === null) return false;
62
+ const v = value;
63
+ const hasRunId = typeof v.runId === "string";
64
+ const hasRecordId = typeof v.recordId === "string";
65
+ if (hasRunId === hasRecordId) return false;
66
+ return typeof v.delta === "string";
67
+ }
68
+ function isHostRoundLifecycleParams(value) {
69
+ if (typeof value !== "object" || value === null) return false;
70
+ const v = value;
71
+ const hasRunId = typeof v.runId === "string";
72
+ const hasRecordId = typeof v.recordId === "string";
73
+ if (hasRunId === hasRecordId) return false;
74
+ if (v.phase === "settled" || v.phase === "idle") return true;
75
+ if (v.phase !== "failed") return false;
76
+ const err = v.error;
77
+ return typeof err === "object" && err !== null && typeof err.code === "string" && typeof err.message === "string";
78
+ }
79
+
80
+ // src/protocol/schema.ts
81
+ var ANY_JSON = {};
82
+ var protocolErrorSchema = {
83
+ $schema: "http://json-schema.org/draft-07/schema#",
84
+ title: "EngineProtocolError",
85
+ type: "object",
86
+ additionalProperties: false,
87
+ required: ["code", "message", "recovery"],
88
+ properties: {
89
+ code: { type: "string", pattern: "^engine_" },
90
+ message: { type: "string" },
91
+ recovery: { type: "string" },
92
+ data: { type: "object" }
93
+ }
94
+ };
95
+ var requestFrameSchema = {
96
+ $schema: "http://json-schema.org/draft-07/schema#",
97
+ title: "EngineProtocolRequestFrame",
98
+ type: "object",
99
+ additionalProperties: false,
100
+ required: ["id", "method", "params"],
101
+ properties: {
102
+ id: { type: "number" },
103
+ method: { type: "string", enum: [...PROTOCOL_METHODS] },
104
+ params: ANY_JSON
105
+ }
106
+ };
107
+ var successResponseFrameSchema = {
108
+ $schema: "http://json-schema.org/draft-07/schema#",
109
+ title: "EngineProtocolSuccessResponseFrame",
110
+ type: "object",
111
+ additionalProperties: false,
112
+ required: ["id", "result"],
113
+ properties: {
114
+ id: { type: ["number", "string"] },
115
+ result: ANY_JSON
116
+ }
117
+ };
118
+ var errorResponseFrameSchema = {
119
+ $schema: "http://json-schema.org/draft-07/schema#",
120
+ title: "EngineProtocolErrorResponseFrame",
121
+ type: "object",
122
+ additionalProperties: false,
123
+ required: ["id", "error"],
124
+ properties: {
125
+ id: { type: ["number", "string"] },
126
+ error: protocolErrorSchema
127
+ }
128
+ };
129
+ var notificationFrameSchema = {
130
+ $schema: "http://json-schema.org/draft-07/schema#",
131
+ title: "EngineProtocolNotificationFrame",
132
+ type: "object",
133
+ additionalProperties: false,
134
+ required: ["method", "params"],
135
+ properties: {
136
+ method: { type: "string", const: "event" },
137
+ params: {
138
+ type: "object",
139
+ additionalProperties: false,
140
+ required: ["runId", "seq", "event"],
141
+ properties: {
142
+ runId: { type: "string" },
143
+ seq: { type: "number" },
144
+ event: {
145
+ type: "object",
146
+ required: ["type"],
147
+ properties: {
148
+ type: {
149
+ type: "string",
150
+ enum: [
151
+ "tool_start",
152
+ "tool_end",
153
+ "text_delta",
154
+ "thinking_delta",
155
+ "turn_end",
156
+ "message_end",
157
+ "compaction",
158
+ "error"
159
+ ]
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ };
167
+ var reverseRequestFrameSchema = {
168
+ $schema: "http://json-schema.org/draft-07/schema#",
169
+ title: "EngineProtocolReverseRequestFrame",
170
+ type: "object",
171
+ additionalProperties: false,
172
+ required: ["id", "method", "params"],
173
+ properties: {
174
+ id: { type: "string" },
175
+ method: { type: "string", enum: [...REVERSE_CHANNELS] },
176
+ params: ANY_JSON
177
+ }
178
+ };
179
+ var ENGINE_PROTOCOL_SCHEMAS = {
180
+ request: requestFrameSchema,
181
+ successResponse: successResponseFrameSchema,
182
+ errorResponse: errorResponseFrameSchema,
183
+ notification: notificationFrameSchema,
184
+ reverseRequest: reverseRequestFrameSchema,
185
+ protocolError: protocolErrorSchema
186
+ };
187
+ var FORBIDDEN_CREDENTIAL_KEY_FRAGMENTS = [
188
+ "apikey",
189
+ "api_key",
190
+ "token",
191
+ "credential",
192
+ "password",
193
+ "secret"
194
+ ];
195
+ var REVERSE_CHANNEL_NAMES = REVERSE_CHANNELS;
196
+
197
+ export {
198
+ isRequestFrame,
199
+ isResponseFrame,
200
+ isNotificationFrame,
201
+ isReverseRequestFrame,
202
+ PROTOCOL_METHODS,
203
+ REVERSE_CHANNELS,
204
+ REVERSE_CHANNEL_TIMEOUT_CLASS,
205
+ isHostStreamDeltaParams,
206
+ isHostRoundLifecycleParams,
207
+ protocolErrorSchema,
208
+ requestFrameSchema,
209
+ successResponseFrameSchema,
210
+ errorResponseFrameSchema,
211
+ notificationFrameSchema,
212
+ reverseRequestFrameSchema,
213
+ ENGINE_PROTOCOL_SCHEMAS,
214
+ FORBIDDEN_CREDENTIAL_KEY_FRAGMENTS,
215
+ REVERSE_CHANNEL_NAMES
216
+ };
@@ -0,0 +1,136 @@
1
+ import {
2
+ EngineSdkError
3
+ } from "./chunk-PPEPBVCC.js";
4
+
5
+ // src/node-executor.ts
6
+ import { spawn } from "child_process";
7
+ var ENGINE_NODE_ENV = "XYZ_AGENT_ENGINE_NODE";
8
+ var PROBE_TIMEOUT_MS = 5e3;
9
+ function probeNodeExecutor(execPath, isElectron) {
10
+ return new Promise((resolve) => {
11
+ let settled = false;
12
+ let child = null;
13
+ const finish = (ok) => {
14
+ if (settled) return;
15
+ settled = true;
16
+ clearTimeout(timer);
17
+ try {
18
+ child?.kill("SIGKILL");
19
+ } catch {
20
+ }
21
+ resolve(ok);
22
+ };
23
+ const env = {};
24
+ if (process.env.PATH !== void 0) env.PATH = process.env.PATH;
25
+ if (process.env.HOME !== void 0) env.HOME = process.env.HOME;
26
+ if (isElectron) env.ELECTRON_RUN_AS_NODE = "1";
27
+ try {
28
+ child = spawn(execPath, ["--eval", "process.exit(0)"], {
29
+ env,
30
+ stdio: "ignore",
31
+ windowsHide: true
32
+ });
33
+ } catch {
34
+ resolve(false);
35
+ return;
36
+ }
37
+ const timer = setTimeout(() => finish(false), PROBE_TIMEOUT_MS);
38
+ timer.unref();
39
+ child.on("error", () => finish(false));
40
+ child.on("exit", (code) => finish(code === 0));
41
+ });
42
+ }
43
+ var probeCache = /* @__PURE__ */ new Map();
44
+ function probeCached(execPath, isElectron) {
45
+ const key = `${execPath}:${isElectron}`;
46
+ let p = probeCache.get(key);
47
+ if (!p) {
48
+ p = probeNodeExecutor(execPath, isElectron);
49
+ probeCache.set(key, p);
50
+ }
51
+ return p;
52
+ }
53
+ function resetEngineNodeProbeCache() {
54
+ probeCache.clear();
55
+ }
56
+ function engineNotFound(detail, recovery) {
57
+ return new EngineSdkError("engine_not_found", detail, recovery);
58
+ }
59
+ function launchEnvOf(opts) {
60
+ return opts.env ?? process.env;
61
+ }
62
+ async function resolvePiExtensionLaunch(entryPath, entryArgs, env) {
63
+ const engineNode = env[ENGINE_NODE_ENV]?.trim();
64
+ if (engineNode === void 0 || engineNode === "") {
65
+ throw engineNotFound(
66
+ `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)`,
67
+ `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.`
68
+ );
69
+ }
70
+ const isElectron = env.ELECTRON_RUN_AS_NODE === "1";
71
+ if (!await probeCached(engineNode, isElectron)) {
72
+ throw engineNotFound(
73
+ `injected node executor failed the probe: ${engineNode} (isElectron=${isElectron})`,
74
+ `Verify the executor exists and can run plain node semantics (Electron binaries need ELECTRON_RUN_AS_NODE=1). The host re-probes after restart.`
75
+ );
76
+ }
77
+ return { command: engineNode, args: [entryPath, ...entryArgs], electronRunAsNode: isElectron };
78
+ }
79
+ async function resolveRuntimeSidecarLaunch(entryPath, entryArgs, opts) {
80
+ const execPath = opts.execPath ?? process.execPath;
81
+ const isElectron = opts.isElectronHost ?? process.versions.electron !== void 0;
82
+ if (!await probeCached(execPath, isElectron)) {
83
+ throw engineNotFound(
84
+ `runtime sidecar executor failed the probe: ${execPath} (isElectron=${isElectron})`,
85
+ `The sidecar process.execPath must run plain node semantics (ELECTRON_RUN_AS_NODE=1 for Electron binaries). Check how the runtime sidecar was spawned.`
86
+ );
87
+ }
88
+ return { command: execPath, args: [entryPath, ...entryArgs], electronRunAsNode: isElectron };
89
+ }
90
+ async function resolveStandaloneLaunch(entryPath, entryArgs) {
91
+ if (!await probeCached("node", false)) {
92
+ throw engineNotFound(
93
+ `no usable 'node' on PATH for standalone engine launch (entry: ${entryPath})`,
94
+ `Install Node.js >= 22 and ensure 'node' is on PATH (https://nodejs.org/), or configure the engine explicitly via subagents/config.json.`
95
+ );
96
+ }
97
+ return { command: "node", args: [entryPath, ...entryArgs], electronRunAsNode: false };
98
+ }
99
+ async function resolveEngineNodeLaunch(opts) {
100
+ const platform = opts.platform ?? process.platform;
101
+ const entryArgs = [...opts.args ?? []];
102
+ if (platform === "win32" && opts.entryPath.toLowerCase().endsWith(".cmd")) {
103
+ return {
104
+ command: "cmd.exe",
105
+ args: ["/c", opts.entryPath, ...entryArgs],
106
+ electronRunAsNode: false
107
+ };
108
+ }
109
+ if (!/\.(?:js|mjs|cjs|ts)$/i.test(opts.entryPath)) {
110
+ return { command: opts.entryPath, args: entryArgs, electronRunAsNode: false };
111
+ }
112
+ if (opts.hostKind === "pi-extension") {
113
+ return resolvePiExtensionLaunch(opts.entryPath, entryArgs, launchEnvOf(opts));
114
+ }
115
+ if (opts.hostKind === "runtime-sidecar") {
116
+ return resolveRuntimeSidecarLaunch(opts.entryPath, entryArgs, opts);
117
+ }
118
+ if (opts.hostKind === "standalone") {
119
+ return resolveStandaloneLaunch(opts.entryPath, entryArgs);
120
+ }
121
+ return { command: opts.entryPath, args: entryArgs, electronRunAsNode: false };
122
+ }
123
+ function hostKindOf(hostKind, env = process.env) {
124
+ if (hostKind.startsWith("runtime")) return "runtime-sidecar";
125
+ const engineNode = env[ENGINE_NODE_ENV]?.trim();
126
+ if (engineNode !== void 0 && engineNode !== "") return "pi-extension";
127
+ return "standalone";
128
+ }
129
+
130
+ export {
131
+ ENGINE_NODE_ENV,
132
+ probeNodeExecutor,
133
+ resetEngineNodeProbeCache,
134
+ resolveEngineNodeLaunch,
135
+ hostKindOf
136
+ };
@@ -0,0 +1,132 @@
1
+ import {
2
+ getLogger
3
+ } from "./chunk-75QEMUGV.js";
4
+
5
+ // src/env.ts
6
+ var logger = getLogger("engine-sdk/env");
7
+ var ENGINE_ENV_PREFIXES = [
8
+ "XYZ_",
9
+ "XYZ_AGENT_",
10
+ "XYZ_SUBAGENT_"
11
+ ];
12
+ var ENGINE_ENV_DENY_LIST = [
13
+ "XYZ_AGENT_PACKAGED",
14
+ "XYZ_RUNTIME_TOKEN",
15
+ "XYZ_AGENT_API_KEY",
16
+ "XYZ_SUBAGENT_RELAY_SESSION_ID",
17
+ "XYZ_SUBAGENT_RELAY_RECORD_ID",
18
+ "XYZ_SUBAGENT_RELAY_STDIN",
19
+ "XYZ_SUBAGENT_RELAY_STDOUT",
20
+ "XYZ_SUBAGENT_RELAY_STDERR"
21
+ ];
22
+ var ENGINE_ENV_L0_INFRA_KEYS = [
23
+ "XYZ_AGENT_DATA_DIR",
24
+ "XYZ_AGENT_ENGINE_NODE",
25
+ "ELECTRON_RUN_AS_NODE",
26
+ "XYZ_AGENT_SUBAGENT",
27
+ "XYZ_SUBAGENT_RELAY_SOCKET",
28
+ "XYZ_SUBAGENT_RELAY_NODE",
29
+ "XYZ_SUBAGENT_RELAY_SCRIPT"
30
+ ];
31
+ var ENV_PREFIX_SHAPE_RE = /^[A-Za-z0-9_]+$/;
32
+ function deleteEnvKeysCaseInsensitive(env, names) {
33
+ const lowered = new Set(names.map((n) => n.toLowerCase()));
34
+ for (const key of Object.keys(env)) {
35
+ if (lowered.has(key.toLowerCase())) delete env[key];
36
+ }
37
+ }
38
+ function compileManifestPrefixes(prefixes) {
39
+ const compiled = [];
40
+ for (const raw of prefixes) {
41
+ if (!ENV_PREFIX_SHAPE_RE.test(raw)) {
42
+ logger.warn(
43
+ `envPrefixes entry dropped (invalid shape, expected ^[A-Za-z0-9_]+$): ${JSON.stringify(raw)}`
44
+ );
45
+ continue;
46
+ }
47
+ const lowered = raw.toLowerCase();
48
+ if (ENGINE_ENV_PREFIXES.some((reserved) => lowered.startsWith(reserved.toLowerCase()))) {
49
+ logger.warn(
50
+ `envPrefixes entry dropped (reserved prefix, infra keys are L0-only): ${JSON.stringify(raw)}`
51
+ );
52
+ continue;
53
+ }
54
+ compiled.push(lowered);
55
+ }
56
+ return compiled.length > 0 ? compiled : null;
57
+ }
58
+ function applyManifestAllowlist(env, opts) {
59
+ if (opts.processEnv !== void 0 && opts.envPrefixes !== void 0) {
60
+ const compiled = compileManifestPrefixes(opts.envPrefixes);
61
+ if (compiled !== null) {
62
+ for (const [key, value] of Object.entries(opts.processEnv)) {
63
+ if (value === void 0) continue;
64
+ const loweredKey = key.toLowerCase();
65
+ if (compiled.some((prefix) => loweredKey.startsWith(prefix))) {
66
+ env[key] = value;
67
+ } else {
68
+ logger.warn(`processEnv key not allowed (no declared envPrefix matches): ${key}`);
69
+ }
70
+ }
71
+ }
72
+ } else if (opts.processEnv !== void 0) {
73
+ for (const key of Object.keys(opts.processEnv)) {
74
+ logger.warn(`processEnv key not allowed (manifest declares no envPrefixes): ${key}`);
75
+ }
76
+ }
77
+ }
78
+ function injectL0InfraKeys(env, opts) {
79
+ env.XYZ_AGENT_DATA_DIR = opts.dataDir;
80
+ if (opts.engineNode !== void 0) env.XYZ_AGENT_ENGINE_NODE = opts.engineNode;
81
+ if (opts.electronRunAsNode === true) env.ELECTRON_RUN_AS_NODE = "1";
82
+ env.XYZ_AGENT_SUBAGENT = "1";
83
+ if (opts.relay !== void 0) {
84
+ env.XYZ_SUBAGENT_RELAY_SOCKET = opts.relay.socket;
85
+ env.XYZ_SUBAGENT_RELAY_NODE = opts.relay.node;
86
+ env.XYZ_SUBAGENT_RELAY_SCRIPT = opts.relay.script;
87
+ }
88
+ if (opts.identityEnv !== void 0) {
89
+ for (const [key, value] of Object.entries(opts.identityEnv)) {
90
+ if (value !== void 0) env[key] = value;
91
+ }
92
+ }
93
+ }
94
+ function buildEngineChildEnv(baseEnv, opts) {
95
+ const env = {};
96
+ for (const [key, value] of Object.entries(baseEnv)) {
97
+ if (value !== void 0) env[key] = value;
98
+ }
99
+ deleteEnvKeysCaseInsensitive(env, ENGINE_ENV_DENY_LIST);
100
+ applyManifestAllowlist(env, opts);
101
+ deleteEnvKeysCaseInsensitive(env, ENGINE_ENV_DENY_LIST);
102
+ injectL0InfraKeys(env, opts);
103
+ return env;
104
+ }
105
+ function buildOutboundChildEnv(opts) {
106
+ const out = {};
107
+ const loweredPrefixes = opts.prefixes !== void 0 ? opts.prefixes.map((p) => p.toLowerCase()) : null;
108
+ for (const [key, value] of Object.entries(opts.parentEnv)) {
109
+ if (value === void 0) continue;
110
+ if (loweredPrefixes !== null) {
111
+ const loweredKey = key.toLowerCase();
112
+ if (!loweredPrefixes.some((prefix) => loweredKey.startsWith(prefix))) continue;
113
+ }
114
+ out[key] = value;
115
+ }
116
+ if (opts.extras !== void 0) {
117
+ for (const [key, value] of Object.entries(opts.extras)) {
118
+ if (value !== void 0) out[key] = value;
119
+ else delete out[key];
120
+ }
121
+ }
122
+ deleteEnvKeysCaseInsensitive(out, ENGINE_ENV_DENY_LIST);
123
+ return out;
124
+ }
125
+
126
+ export {
127
+ ENGINE_ENV_PREFIXES,
128
+ ENGINE_ENV_DENY_LIST,
129
+ ENGINE_ENV_L0_INFRA_KEYS,
130
+ buildEngineChildEnv,
131
+ buildOutboundChildEnv
132
+ };
@@ -0,0 +1,119 @@
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/cli-entry.ts
31
+ var cli_entry_exports = {};
32
+ __export(cli_entry_exports, {
33
+ runEngineCliEntry: () => runEngineCliEntry
34
+ });
35
+ module.exports = __toCommonJS(cli_entry_exports);
36
+ var readline = __toESM(require("readline"), 1);
37
+
38
+ // src/logger.ts
39
+ var SINK_SLOT_KEY = /* @__PURE__ */ Symbol.for("@zhushanwen/subagent-engine-sdk.logger-sink");
40
+ function getSinkSlot() {
41
+ let slot = Reflect.get(globalThis, SINK_SLOT_KEY);
42
+ if (!slot) {
43
+ slot = { current: void 0 };
44
+ Reflect.set(globalThis, SINK_SLOT_KEY, slot);
45
+ }
46
+ return slot;
47
+ }
48
+ var CONSOLE_SINK = {
49
+ log(level, component, message, data) {
50
+ const line = `[${component}] ${message}`;
51
+ if (level === "error") {
52
+ if (data === void 0) console.error(line);
53
+ else console.error(line, data);
54
+ return;
55
+ }
56
+ if (level === "warn") {
57
+ if (data === void 0) console.warn(line);
58
+ else console.warn(line, data);
59
+ return;
60
+ }
61
+ }
62
+ };
63
+ function currentSink() {
64
+ return getSinkSlot().current ?? CONSOLE_SINK;
65
+ }
66
+ function configureLoggerSink(sink) {
67
+ getSinkSlot().current = sink;
68
+ }
69
+ var facadeCache = /* @__PURE__ */ new Map();
70
+ function getLogger(component) {
71
+ const existing = facadeCache.get(component);
72
+ if (existing) return existing;
73
+ const facade = {
74
+ debug(msg, data) {
75
+ currentSink().log("debug", component, msg, data);
76
+ },
77
+ warn(msg, data) {
78
+ currentSink().log("warn", component, msg, data);
79
+ },
80
+ error(msg, data) {
81
+ currentSink().log("error", component, msg, data);
82
+ }
83
+ };
84
+ facadeCache.set(component, facade);
85
+ return facade;
86
+ }
87
+
88
+ // src/cli-entry.ts
89
+ var INBOUND_LOG_CHARS = 200;
90
+ function runEngineCliEntry(opts) {
91
+ const logger = getLogger(opts.component);
92
+ const server = opts.server;
93
+ configureLoggerSink({
94
+ log(level, component, message, data) {
95
+ process.stderr.write(`[${level}] [${component}] ${message}${data !== void 0 ? ` ${JSON.stringify(data)}` : ""}
96
+ `);
97
+ void server.reverseRequest("host/log", { level, component, message }).catch(() => void 0);
98
+ }
99
+ });
100
+ const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
101
+ rl.on("line", (line) => {
102
+ const text = line.trim();
103
+ if (text === "") return;
104
+ try {
105
+ server.handleFrame(JSON.parse(text));
106
+ } catch (err) {
107
+ logger.warn(`unparseable inbound protocol line (ignored): ${text.slice(0, INBOUND_LOG_CHARS)}`, {
108
+ reason: err instanceof Error ? err.message : String(err)
109
+ });
110
+ }
111
+ });
112
+ rl.on("close", () => {
113
+ logger.debug("stdin closed (host exit path)");
114
+ });
115
+ }
116
+ // Annotate the CommonJS export names for ESM import in node:
117
+ 0 && (module.exports = {
118
+ runEngineCliEntry
119
+ });
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 引擎协议服务器的结构化最小接口(调用方薄层注入本包 EngineProtocolServer 实例;
3
+ * 结构子集避免 SDK 反向依赖各包 server 类型)。
4
+ */
5
+ interface CliProtocolServerSink {
6
+ /** 入站协议帧处理(readline 已拆行 + JSON.parse 后的帧)。 */
7
+ handleFrame(frame: unknown): void;
8
+ /** 数据面反向请求(host/log 等;应答分类由各包 server 实现承载)。 */
9
+ reverseRequest(method: string, params: unknown): Promise<unknown>;
10
+ }
11
+ /** runEngineCliEntry 参数。 */
12
+ interface RunEngineCliEntryOptions {
13
+ /** logger component 标签(如 "pi-engine-cli" / "zcode-engine-cli")。 */
14
+ component: string;
15
+ /** 调用方构造的协议服务器实例(构造参数含 armEngineSelfDestruct 产出的 reverseClock)。 */
16
+ server: CliProtocolServerSink;
17
+ }
18
+ /**
19
+ * 引擎 CLI 进程入口样板(行为与收编前两包 main.ts 逐字节等价):
20
+ * configureLoggerSink → stdin 行解析(NDJSON)→ server.handleFrame → close 留痕。
21
+ */
22
+ declare function runEngineCliEntry(opts: RunEngineCliEntryOptions): void;
23
+
24
+ export { type CliProtocolServerSink, type RunEngineCliEntryOptions, runEngineCliEntry };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 引擎协议服务器的结构化最小接口(调用方薄层注入本包 EngineProtocolServer 实例;
3
+ * 结构子集避免 SDK 反向依赖各包 server 类型)。
4
+ */
5
+ interface CliProtocolServerSink {
6
+ /** 入站协议帧处理(readline 已拆行 + JSON.parse 后的帧)。 */
7
+ handleFrame(frame: unknown): void;
8
+ /** 数据面反向请求(host/log 等;应答分类由各包 server 实现承载)。 */
9
+ reverseRequest(method: string, params: unknown): Promise<unknown>;
10
+ }
11
+ /** runEngineCliEntry 参数。 */
12
+ interface RunEngineCliEntryOptions {
13
+ /** logger component 标签(如 "pi-engine-cli" / "zcode-engine-cli")。 */
14
+ component: string;
15
+ /** 调用方构造的协议服务器实例(构造参数含 armEngineSelfDestruct 产出的 reverseClock)。 */
16
+ server: CliProtocolServerSink;
17
+ }
18
+ /**
19
+ * 引擎 CLI 进程入口样板(行为与收编前两包 main.ts 逐字节等价):
20
+ * configureLoggerSink → stdin 行解析(NDJSON)→ server.handleFrame → close 留痕。
21
+ */
22
+ declare function runEngineCliEntry(opts: RunEngineCliEntryOptions): void;
23
+
24
+ export { type CliProtocolServerSink, type RunEngineCliEntryOptions, runEngineCliEntry };
@@ -0,0 +1,8 @@
1
+ import {
2
+ runEngineCliEntry
3
+ } from "./chunk-N3RL6OVM.js";
4
+ import "./chunk-75QEMUGV.js";
5
+ import "./chunk-JSBRDJBE.js";
6
+ export {
7
+ runEngineCliEntry
8
+ };