poe-code 3.0.265 → 3.0.267

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poe-code",
3
- "version": "3.0.265",
3
+ "version": "3.0.267",
4
4
  "description": "CLI tool to configure Poe API for developer workflows.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -3,6 +3,9 @@ const MAX_JSON_BYTES = 262_144;
3
3
  const BINARY_SCAN_BYTES = 1_024;
4
4
  const REDACTED_SECRET = "[redacted]";
5
5
  const BEARER_TOKEN_PATTERN = /\b(Bearer\s+)[A-Za-z0-9._~+/=-]+/gi;
6
+ const AUTH_HEADER_PATTERN = /\b((?:Proxy-)?Authorization\s*:\s*(?:Bearer|Basic|Token)\s+)[^\s"'\r\n]+/gi;
7
+ const COOKIE_HEADER_PATTERN = /\b((?:Set-)?Cookie\s*:\s*)[^\r\n"']+/gi;
8
+ const URL_USERINFO_PATTERN = /\b([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#\s@]+@)/g;
6
9
  const ASSIGNED_SECRET_NAME_PATTERN = String.raw `(?:(?:[A-Za-z0-9]+[-_])*api[-_ ]?key|(?:[A-Za-z0-9]+[-_])*(?:token|secret|password|private[-_ ]?key))`;
7
10
  const ASSIGNED_SECRET_PATTERN = new RegExp(String.raw `\b(${ASSIGNED_SECRET_NAME_PATTERN}\s*[:=]\s*)(?:"[^"\r\n]*"|'[^'\r\n]*'|[A-Za-z0-9._~+/=-]+)`, "gi");
8
11
  export function redact(value) {
@@ -51,7 +54,7 @@ function redactLeaf(value, ancestors, key) {
51
54
  configurable: true,
52
55
  enumerable: true,
53
56
  value: redactLeaf(item, ancestors, key),
54
- writable: true,
57
+ writable: true
55
58
  });
56
59
  }
57
60
  ancestors.delete(value);
@@ -65,6 +68,9 @@ function redactString(value) {
65
68
  return `[truncated:${bytes}]`;
66
69
  }
67
70
  return value
71
+ .replace(URL_USERINFO_PATTERN, `$1${REDACTED_SECRET}@`)
72
+ .replace(AUTH_HEADER_PATTERN, `$1${REDACTED_SECRET}`)
73
+ .replace(COOKIE_HEADER_PATTERN, `$1${REDACTED_SECRET}`)
68
74
  .replace(BEARER_TOKEN_PATTERN, `$1${REDACTED_SECRET}`)
69
75
  .replace(ASSIGNED_SECRET_PATTERN, redactAssignedSecretValue);
70
76
  }
@@ -8,17 +8,17 @@ export function acpToTrace(ctx) {
8
8
  input: redact({
9
9
  prompt: ctx.prompt,
10
10
  mode: ctx.mode,
11
- cwd: ctx.cwd,
11
+ cwd: ctx.cwd
12
12
  }),
13
13
  output: redact(accumulateAgentOutput(ctx.events)),
14
14
  metadata: redactRecord({
15
15
  ...spawnCtx.metadata,
16
16
  sessionId: ctx.sessionId,
17
- threadId: ctx.threadId,
17
+ threadId: ctx.threadId
18
18
  }),
19
19
  metrics: buildMetrics(ctx),
20
- children: logToolSpans(ctx.events),
21
- },
20
+ children: logToolSpans(ctx.events)
21
+ }
22
22
  };
23
23
  }
24
24
  function logToolSpans(events) {
@@ -37,14 +37,14 @@ function logToolSpans(events) {
37
37
  output: redact(assembleToolOutput(events, index, toolCallId)),
38
38
  ...(metadata ? { metadata } : {}),
39
39
  ...readSpanTimestamps(metadata),
40
- children: [],
40
+ children: []
41
41
  });
42
42
  }
43
43
  return spans;
44
44
  }
45
45
  function collectToolMeta(events, toolCallIndex, toolCallId) {
46
46
  const merged = {
47
- ...(toolCallId !== undefined ? { toolCallId } : {}),
47
+ ...(toolCallId !== undefined ? { toolCallId } : {})
48
48
  };
49
49
  const startMeta = asRecord(asRecord(events[toolCallIndex])?._meta);
50
50
  if (startMeta) {
@@ -53,6 +53,9 @@ function collectToolMeta(events, toolCallIndex, toolCallId) {
53
53
  }
54
54
  }
55
55
  for (const event of events.slice(toolCallIndex + 1)) {
56
+ if (toolCallId === undefined && asToolCall(event) !== undefined) {
57
+ break;
58
+ }
56
59
  const update = asToolCallUpdate(event);
57
60
  if (update === undefined)
58
61
  continue;
@@ -91,6 +94,9 @@ function assembleToolOutput(events, toolCallIndex, toolCallId) {
91
94
  const outputs = [];
92
95
  let text = "";
93
96
  for (const event of events.slice(toolCallIndex + 1)) {
97
+ if (toolCallId === undefined && asToolCall(event) !== undefined) {
98
+ break;
99
+ }
94
100
  const update = asToolCallUpdate(event);
95
101
  if (update === undefined) {
96
102
  continue;
@@ -169,7 +175,7 @@ function readSpanTimestamps(metadata) {
169
175
  const endTs = readNumber(metadata.endTs);
170
176
  return {
171
177
  ...(startTs !== undefined ? { startTs } : {}),
172
- ...(endTs !== undefined ? { endTs } : {}),
178
+ ...(endTs !== undefined ? { endTs } : {})
173
179
  };
174
180
  }
175
181
  function redactRecord(record) {
@@ -177,25 +183,21 @@ function redactRecord(record) {
177
183
  return asRecord(redacted) ?? { redacted };
178
184
  }
179
185
  function asRecord(value) {
180
- return typeof value === "object" && value !== null
181
- ? value
182
- : undefined;
186
+ return typeof value === "object" && value !== null ? value : undefined;
183
187
  }
184
188
  function readString(value) {
185
189
  return typeof value === "string" ? value : undefined;
186
190
  }
187
191
  function readNumber(value) {
188
- return typeof value === "number" && Number.isFinite(value)
189
- ? value
190
- : undefined;
192
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
191
193
  }
192
194
  function addMetric(metrics, key, value) {
193
- if (value !== undefined) {
195
+ if (value !== undefined && value >= 0) {
194
196
  metrics[key] = value;
195
197
  }
196
198
  }
197
199
  function sumIfPresent(left, right) {
198
- if (left === undefined || right === undefined) {
200
+ if (left === undefined || right === undefined || left < 0 || right < 0) {
199
201
  return undefined;
200
202
  }
201
203
  return readNumber(left + right);
@@ -205,6 +207,6 @@ function setOwnProperty(target, key, value) {
205
207
  configurable: true,
206
208
  enumerable: true,
207
209
  value,
208
- writable: true,
210
+ writable: true
209
211
  });
210
212
  }
@@ -1,4 +1,4 @@
1
- import type { Readable, Writable } from "node:stream";
1
+ import { type Readable, type Writable } from "node:stream";
2
2
  import type { SpawnResult, SpawnUsage } from "../../agent-spawn/dist/index.js";
3
3
  export type SpawnProcess = typeof import("node:child_process").spawn;
4
4
  export type AgentChildProcessKind = "exec" | "execFile" | "spawn";
@@ -1,4 +1,5 @@
1
1
  import { spawn as defaultSpawn } from "node:child_process";
2
+ import { PassThrough } from "node:stream";
2
3
  import { StringDecoder } from "node:string_decoder";
3
4
  export class AgentChildProcessError extends Error {
4
5
  result;
@@ -9,7 +10,10 @@ export class AgentChildProcessError extends Error {
9
10
  }
10
11
  }
11
12
  export async function exec(command, options) {
12
- const shell = process.platform === "win32" ? process.env.ComSpec ?? "cmd.exe" : process.env.SHELL ?? "sh";
13
+ assertNonBlank(command, "command");
14
+ const shell = process.platform === "win32"
15
+ ? (options?.env?.ComSpec ?? process.env.ComSpec ?? "cmd.exe")
16
+ : (options?.env?.SHELL ?? process.env.SHELL ?? "sh");
13
17
  const shellArgs = process.platform === "win32" ? ["/d", "/s", "/c", command] : ["-c", command];
14
18
  return runExecution({
15
19
  kind: "exec",
@@ -21,6 +25,7 @@ export async function exec(command, options) {
21
25
  });
22
26
  }
23
27
  export async function execFile(file, argsOrOptions = [], maybeOptions) {
28
+ assertNonBlank(file, "file");
24
29
  const args = Array.isArray(argsOrOptions) ? argsOrOptions : [];
25
30
  const options = Array.isArray(argsOrOptions) ? maybeOptions : argsOrOptions;
26
31
  return runExecution({
@@ -33,10 +38,11 @@ export async function execFile(file, argsOrOptions = [], maybeOptions) {
33
38
  });
34
39
  }
35
40
  export function spawn(file, argsOrOptions = [], maybeOptions) {
36
- const args = Array.isArray(argsOrOptions) ? argsOrOptions : [];
37
- const options = Array.isArray(argsOrOptions) ? maybeOptions : argsOrOptions;
38
41
  let child;
39
42
  try {
43
+ assertNonBlank(file, "file");
44
+ const args = Array.isArray(argsOrOptions) ? argsOrOptions : [];
45
+ const options = Array.isArray(argsOrOptions) ? maybeOptions : argsOrOptions;
40
46
  child = startChildProcess({
41
47
  kind: "spawn",
42
48
  file,
@@ -59,8 +65,8 @@ export function spawn(file, argsOrOptions = [], maybeOptions) {
59
65
  return {
60
66
  pid: child.process.pid,
61
67
  stdin: child.process.stdin,
62
- stdout: child.process.stdout,
63
- stderr: child.process.stderr,
68
+ stdout: child.stdout,
69
+ stderr: child.stderr,
64
70
  kill(signal) {
65
71
  return child.process.kill(signal);
66
72
  },
@@ -72,8 +78,13 @@ async function runExecution(spec) {
72
78
  }
73
79
  function startChildProcess(spec) {
74
80
  const child = spawnChild(spec);
75
- const result = collectResult(child, spec).then((commandResult) => applyExitPolicy(commandResult, spec.options));
76
- return { process: child, result };
81
+ const stdout = createOutputPipes(child.stdout, spec.kind === "spawn");
82
+ const stderr = createOutputPipes(child.stderr, spec.kind === "spawn");
83
+ const result = collectResult(child, spec, {
84
+ stdout: stdout.result,
85
+ stderr: stderr.result
86
+ }).then((commandResult) => applyExitPolicy(commandResult, spec.options));
87
+ return { process: child, stdout: stdout.user, stderr: stderr.user, result };
77
88
  }
78
89
  function spawnChild(spec) {
79
90
  const options = spec.options;
@@ -89,22 +100,22 @@ function spawnChild(spec) {
89
100
  function getStdio(kind) {
90
101
  return kind === "spawn" ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"];
91
102
  }
92
- function collectResult(child, spec) {
103
+ function collectResult(child, spec, streams) {
93
104
  const stdoutDecoder = new StringDecoder("utf8");
94
105
  const stderrDecoder = new StringDecoder("utf8");
95
106
  let stdout = "";
96
107
  let stderr = "";
97
108
  let childClosed = false;
98
- let stdoutFinished = child.stdout === null;
99
- let stderrFinished = child.stderr === null;
109
+ let stdoutFinished = streams.stdout === null;
110
+ let stderrFinished = streams.stderr === null;
100
111
  let exitCode = 1;
101
112
  let exitSignal = null;
102
113
  let processError;
103
114
  let outputError;
104
- child.stdout?.on("data", (chunk) => {
115
+ streams.stdout?.on("data", (chunk) => {
105
116
  stdout += typeof chunk === "string" ? chunk : stdoutDecoder.write(chunk);
106
117
  });
107
- child.stderr?.on("data", (chunk) => {
118
+ streams.stderr?.on("data", (chunk) => {
108
119
  stderr += typeof chunk === "string" ? chunk : stderrDecoder.write(chunk);
109
120
  });
110
121
  return new Promise((resolve) => {
@@ -127,20 +138,20 @@ function collectResult(child, spec) {
127
138
  });
128
139
  resolve({ ...attempt, attempts: [attempt] });
129
140
  };
130
- child.stdout?.once("end", () => {
141
+ streams.stdout?.once("end", () => {
131
142
  stdoutFinished = true;
132
143
  finish();
133
144
  });
134
- child.stderr?.once("end", () => {
145
+ streams.stderr?.once("end", () => {
135
146
  stderrFinished = true;
136
147
  finish();
137
148
  });
138
- child.stdout?.once("error", (error) => {
149
+ streams.stdout?.once("error", (error) => {
139
150
  outputError = error;
140
151
  stdoutFinished = true;
141
152
  finish();
142
153
  });
143
- child.stderr?.once("error", (error) => {
154
+ streams.stderr?.once("error", (error) => {
144
155
  outputError = error;
145
156
  stderrFinished = true;
146
157
  finish();
@@ -161,6 +172,22 @@ function collectResult(child, spec) {
161
172
  });
162
173
  });
163
174
  }
175
+ function createOutputPipes(source, exposeUserStream) {
176
+ if (source === null) {
177
+ return { result: null, user: null };
178
+ }
179
+ const result = new PassThrough();
180
+ const user = exposeUserStream ? new PassThrough() : null;
181
+ source.once("error", (error) => {
182
+ result.destroy(error);
183
+ user?.destroy();
184
+ });
185
+ source.pipe(result);
186
+ if (user !== null) {
187
+ source.pipe(user);
188
+ }
189
+ return { result, user };
190
+ }
164
191
  function createAttempt(spec, output) {
165
192
  return {
166
193
  kind: spec.kind,
@@ -195,6 +222,14 @@ async function maybeRunAgent(result, options) {
195
222
  cause: error
196
223
  });
197
224
  }
225
+ try {
226
+ validateExitPolicy(policy);
227
+ }
228
+ catch (error) {
229
+ throw new AgentChildProcessError("Agent exit policy is invalid", result, {
230
+ cause: error
231
+ });
232
+ }
198
233
  const runAgent = options.runAgent ?? defaultRunAgent;
199
234
  let agentResult;
200
235
  try {
@@ -225,6 +260,15 @@ async function maybeRunAgent(result, options) {
225
260
  }
226
261
  };
227
262
  }
263
+ function validateExitPolicy(policy) {
264
+ assertNonBlank(policy.agent, "onExit.agent");
265
+ assertNonBlank(policy.prompt, "onExit.prompt");
266
+ }
267
+ function assertNonBlank(value, field) {
268
+ if (value.trim().length === 0) {
269
+ throw new TypeError(`${field} must not be empty`);
270
+ }
271
+ }
228
272
  async function defaultRunAgent(input) {
229
273
  const { spawn: spawnAgent } = await import("@poe-code/agent-spawn");
230
274
  return spawnAgent(input.agent, {
@@ -41850,6 +41850,9 @@ var MAX_JSON_BYTES = 262144;
41850
41850
  var BINARY_SCAN_BYTES = 1024;
41851
41851
  var REDACTED_SECRET = "[redacted]";
41852
41852
  var BEARER_TOKEN_PATTERN = /\b(Bearer\s+)[A-Za-z0-9._~+/=-]+/gi;
41853
+ var AUTH_HEADER_PATTERN = /\b((?:Proxy-)?Authorization\s*:\s*(?:Bearer|Basic|Token)\s+)[^\s"'\r\n]+/gi;
41854
+ var COOKIE_HEADER_PATTERN = /\b((?:Set-)?Cookie\s*:\s*)[^\r\n"']+/gi;
41855
+ var URL_USERINFO_PATTERN = /\b([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#\s@]+@)/g;
41853
41856
  var ASSIGNED_SECRET_NAME_PATTERN = String.raw`(?:(?:[A-Za-z0-9]+[-_])*api[-_ ]?key|(?:[A-Za-z0-9]+[-_])*(?:token|secret|password|private[-_ ]?key))`;
41854
41857
  var ASSIGNED_SECRET_PATTERN = new RegExp(
41855
41858
  String.raw`\b(${ASSIGNED_SECRET_NAME_PATTERN}\s*[:=]\s*)(?:"[^"\r\n]*"|'[^'\r\n]*'|[A-Za-z0-9._~+/=-]+)`,
@@ -41914,7 +41917,7 @@ function redactString(value) {
41914
41917
  if (bytes > MAX_STRING_BYTES) {
41915
41918
  return `[truncated:${bytes}]`;
41916
41919
  }
41917
- return value.replace(BEARER_TOKEN_PATTERN, `$1${REDACTED_SECRET}`).replace(ASSIGNED_SECRET_PATTERN, redactAssignedSecretValue);
41920
+ return value.replace(URL_USERINFO_PATTERN, `$1${REDACTED_SECRET}@`).replace(AUTH_HEADER_PATTERN, `$1${REDACTED_SECRET}`).replace(COOKIE_HEADER_PATTERN, `$1${REDACTED_SECRET}`).replace(BEARER_TOKEN_PATTERN, `$1${REDACTED_SECRET}`).replace(ASSIGNED_SECRET_PATTERN, redactAssignedSecretValue);
41918
41921
  }
41919
41922
  function redactAssignedSecretValue(match, prefix) {
41920
41923
  const secret = match.slice(prefix.length);
@@ -42000,6 +42003,9 @@ function collectToolMeta(events, toolCallIndex, toolCallId) {
42000
42003
  }
42001
42004
  }
42002
42005
  for (const event of events.slice(toolCallIndex + 1)) {
42006
+ if (toolCallId === void 0 && asToolCall(event) !== void 0) {
42007
+ break;
42008
+ }
42003
42009
  const update = asToolCallUpdate(event);
42004
42010
  if (update === void 0) continue;
42005
42011
  if (readToolCallId(update) !== toolCallId) continue;
@@ -42035,6 +42041,9 @@ function assembleToolOutput(events, toolCallIndex, toolCallId) {
42035
42041
  const outputs = [];
42036
42042
  let text4 = "";
42037
42043
  for (const event of events.slice(toolCallIndex + 1)) {
42044
+ if (toolCallId === void 0 && asToolCall(event) !== void 0) {
42045
+ break;
42046
+ }
42038
42047
  const update = asToolCallUpdate(event);
42039
42048
  if (update === void 0) {
42040
42049
  continue;
@@ -42138,12 +42147,12 @@ function readNumber(value) {
42138
42147
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
42139
42148
  }
42140
42149
  function addMetric(metrics, key2, value) {
42141
- if (value !== void 0) {
42150
+ if (value !== void 0 && value >= 0) {
42142
42151
  metrics[key2] = value;
42143
42152
  }
42144
42153
  }
42145
42154
  function sumIfPresent(left, right) {
42146
- if (left === void 0 || right === void 0) {
42155
+ if (left === void 0 || right === void 0 || left < 0 || right < 0) {
42147
42156
  return void 0;
42148
42157
  }
42149
42158
  return readNumber(left + right);