@warlock.js/ai-cli 5.31.0 → 5.33.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/CHANGELOG.md +12 -0
- package/cjs/index.cjs +38 -46
- package/cjs/index.cjs.map +1 -1
- package/esm/adapters/aider.d.mts +4 -4
- package/esm/adapters/aider.d.mts.map +1 -1
- package/esm/adapters/amp.d.mts +2 -2
- package/esm/adapters/amp.d.mts.map +1 -1
- package/esm/adapters/antigravity.d.mts +3 -3
- package/esm/adapters/antigravity.d.mts.map +1 -1
- package/esm/adapters/claude-code.d.mts +2 -2
- package/esm/adapters/claude-code.d.mts.map +1 -1
- package/esm/adapters/claude-stream.d.mts +3 -3
- package/esm/adapters/claude-stream.d.mts.map +1 -1
- package/esm/adapters/codex.d.mts +3 -3
- package/esm/adapters/codex.d.mts.map +1 -1
- package/esm/adapters/codex.mjs +10 -8
- package/esm/adapters/codex.mjs.map +1 -1
- package/esm/adapters/copilot.d.mts +3 -3
- package/esm/adapters/copilot.d.mts.map +1 -1
- package/esm/adapters/copilot.mjs +5 -7
- package/esm/adapters/copilot.mjs.map +1 -1
- package/esm/adapters/cursor.d.mts +3 -3
- package/esm/adapters/cursor.d.mts.map +1 -1
- package/esm/adapters/droid.d.mts +3 -3
- package/esm/adapters/droid.d.mts.map +1 -1
- package/esm/adapters/grok.d.mts +3 -3
- package/esm/adapters/grok.d.mts.map +1 -1
- package/esm/adapters/grok.mjs +6 -8
- package/esm/adapters/grok.mjs.map +1 -1
- package/esm/adapters/index.d.mts +2 -1
- package/esm/adapters/index.mjs +1 -1
- package/esm/adapters/kimi.d.mts +3 -3
- package/esm/adapters/kimi.d.mts.map +1 -1
- package/esm/adapters/mistral-vibe.d.mts +3 -3
- package/esm/adapters/mistral-vibe.d.mts.map +1 -1
- package/esm/adapters/mistral-vibe.mjs +5 -7
- package/esm/adapters/mistral-vibe.mjs.map +1 -1
- package/esm/adapters/opencode.d.mts +3 -3
- package/esm/adapters/opencode.d.mts.map +1 -1
- package/esm/adapters/qwen-code.d.mts +2 -2
- package/esm/adapters/qwen-code.d.mts.map +1 -1
- package/esm/adapters/reasonix.d.mts +3 -3
- package/esm/adapters/reasonix.d.mts.map +1 -1
- package/esm/adapters/reasonix.mjs +6 -8
- package/esm/adapters/reasonix.mjs.map +1 -1
- package/esm/adapters/shared.d.mts +19 -16
- package/esm/adapters/shared.d.mts.map +1 -1
- package/esm/cli-agent.d.mts +9 -8
- package/esm/cli-agent.d.mts.map +1 -1
- package/esm/cli.d.mts +11 -8
- package/esm/cli.d.mts.map +1 -1
- package/esm/contracts/adapter.contract.d.mts +52 -31
- package/esm/contracts/adapter.contract.d.mts.map +1 -1
- package/esm/contracts/events.type.d.mts +36 -24
- package/esm/contracts/events.type.d.mts.map +1 -1
- package/esm/contracts/index.d.mts +2 -1
- package/esm/contracts/mcp.type.d.mts +4 -5
- package/esm/contracts/mcp.type.d.mts.map +1 -1
- package/esm/contracts/options.type.d.mts +56 -31
- package/esm/contracts/options.type.d.mts.map +1 -1
- package/esm/errors.d.mts +11 -9
- package/esm/errors.d.mts.map +1 -1
- package/esm/index.d.mts +2 -0
- package/esm/model/cli-model.d.mts +8 -7
- package/esm/model/cli-model.d.mts.map +1 -1
- package/esm/probe/probe.d.mts +4 -4
- package/esm/probe/probe.d.mts.map +1 -1
- package/esm/probe/probe.mjs +2 -2
- package/esm/probe/probe.mjs.map +1 -1
- package/esm/session/aggregate.mjs +2 -4
- package/esm/session/aggregate.mjs.map +1 -1
- package/esm/session/environment.mjs +1 -1
- package/esm/spawn/invocation.d.mts +6 -7
- package/esm/spawn/invocation.d.mts.map +1 -1
- package/esm/spawn/invocation.mjs +3 -3
- package/esm/spawn/invocation.mjs.map +1 -1
- package/esm/spawn/resolve-command.d.mts +12 -10
- package/esm/spawn/resolve-command.d.mts.map +1 -1
- package/esm/stream/json-lines.d.mts +10 -10
- package/esm/stream/json-lines.d.mts.map +1 -1
- package/esm/stream/line-splitter.mjs +2 -2
- package/esm/stream/line-splitter.mjs.map +1 -1
- package/esm/utils/toml.d.mts +3 -4
- package/esm/utils/toml.d.mts.map +1 -1
- package/package.json +2 -2
package/esm/probe/probe.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { spawn } from "node:child_process";
|
|
|
7
7
|
/** How long a single `--help`/`--version` call may take. */
|
|
8
8
|
const PROBE_TIMEOUT_MS = 3e4;
|
|
9
9
|
/** Output cap per probe call; help screens are a few KiB. */
|
|
10
|
-
const PROBE_OUTPUT_LIMIT =
|
|
10
|
+
const PROBE_OUTPUT_LIMIT = 1048576;
|
|
11
11
|
function escapeRegExp(text) {
|
|
12
12
|
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13
13
|
}
|
|
@@ -144,5 +144,5 @@ function assertCapabilities(adapter, probe, required) {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
//#endregion
|
|
147
|
-
export { assertCapabilities, helpLists, missingFlags, parseVersion, probeCli };
|
|
147
|
+
export { PROBE_TIMEOUT_MS, assertCapabilities, helpLists, missingFlags, parseVersion, probeCli };
|
|
148
148
|
//# sourceMappingURL=probe.mjs.map
|
package/esm/probe/probe.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/probe/probe.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport type { CliAdapter, CliProbeResult } from \"../contracts\";\nimport { CliError } from \"../errors\";\nimport { killProcessTree } from \"../spawn/process-tree\";\nimport { buildInvocation } from \"../spawn/invocation\";\nimport type { SpawnTarget } from \"../spawn/resolve-command\";\n\n/** How long a single `--help`/`--version` call may take. */\nexport const PROBE_TIMEOUT_MS = 30_000;\n\n/** Output cap per probe call; help screens are a few KiB. */\nconst PROBE_OUTPUT_LIMIT = 1024 * 1024;\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Whether a help screen lists a flag or subcommand. Flags (`--json`, `-p`)\n * must appear as a whole token — `--json` does not match `--json-schema`;\n * a bare word (`exec`) is matched as a whole word.\n *\n * @example\n * helpLists(\" -p, --print Print response\", \"--print\"); // true\n * helpLists(\" --output-format <format>\", \"--output\"); // false\n */\nexport function helpLists(help: string, flag: string): boolean {\n const escaped = escapeRegExp(flag);\n\n if (flag.startsWith(\"-\")) {\n return new RegExp(`(^|[\\\\s,\\\\[(|/\"'\\`])${escaped}(?=$|[\\\\s,=\\\\])|<\\\\[.:;\"'\\`])`, \"m\").test(\n help,\n );\n }\n\n return new RegExp(`(^|[^\\\\w-])${escaped}(?=$|[^\\\\w-])`, \"m\").test(help);\n}\n\n/** The first version-looking token of `--version` output, else its first line. */\nexport function parseVersion(output: string): string {\n const match = /\\d+\\.\\d+(?:\\.\\d+)?(?:[-+][0-9A-Za-z.-]+)?/.exec(output);\n\n if (match) {\n return match[0];\n }\n\n const firstLine = output.trim().split(/\\r?\\n/)[0]?.trim();\n\n return firstLine && firstLine.length > 0 ? firstLine : \"unknown\";\n}\n\n/** Flags a plan requires that the help screen does not list. */\nexport function missingFlags(help: string, required: readonly string[]): string[] {\n return required.filter((flag) => !helpLists(help, flag));\n}\n\ntype CaptureInput = {\n target: SpawnTarget;\n args: string[];\n env: Record<string, string>;\n cwd: string;\n comspec: string;\n platform: NodeJS.Platform;\n};\n\n/** Run a probe invocation and capture stdout + stderr (help is printed to either). */\nfunction capture(\n input: CaptureInput,\n): Promise<{ output: string; exitCode: number | null; error?: Error }> {\n return new Promise((resolve) => {\n const invocation = buildInvocation(input.target, input.args, input.comspec);\n\n if (\"refused\" in invocation) {\n resolve({ output: \"\", exitCode: null, error: new Error(invocation.refused) });\n\n return;\n }\n\n const child = spawn(invocation.file, invocation.args, {\n cwd: input.cwd,\n env: input.env,\n shell: false,\n windowsHide: true,\n windowsVerbatimArguments: invocation.windowsVerbatimArguments,\n detached: input.platform !== \"win32\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n const chunks: Buffer[] = [];\n let size = 0;\n let settled = false;\n\n const collect = (chunk: Buffer): void => {\n if (size < PROBE_OUTPUT_LIMIT) {\n chunks.push(chunk);\n size += chunk.length;\n }\n };\n\n const timer = setTimeout(() => {\n killProcessTree(child, input.platform, 0);\n }, PROBE_TIMEOUT_MS);\n\n const finish = (exitCode: number | null, error?: Error): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n clearTimeout(timer);\n resolve({ output: Buffer.concat(chunks).toString(\"utf8\"), exitCode, error });\n };\n\n child.stdout?.on(\"data\", collect);\n child.stderr?.on(\"data\", collect);\n child.on(\"error\", (error) => finish(null, error));\n child.on(\"close\", (code) => finish(code));\n });\n}\n\nexport type ProbeInput = Omit<CaptureInput, \"args\"> & { adapter: CliAdapter };\n\n/**\n * Read the CLI's version and help screens. A help invocation that cannot\n * run at all (spawn error, no output) fails the probe; a non-zero exit with\n * output is accepted, because several CLIs exit 1 after printing help.\n */\nexport async function probeCli(input: ProbeInput): Promise<CliProbeResult> {\n const { adapter } = input;\n const versionRun = await capture({ ...input, args: adapter.probe.version });\n\n if (versionRun.error !== undefined) {\n throw new CliError(\n `${adapter.title}: could not run \"${input.target.executable} ${adapter.probe.version.join(\" \")}\": ${versionRun.error.message}`,\n {\n type: \"probe-failed\",\n adapter: adapter.name,\n executable: input.target.executable,\n cause: versionRun.error,\n },\n );\n }\n\n const version = parseVersion(versionRun.output);\n const helps: string[] = [];\n\n for (const args of adapter.probe.help) {\n const helpRun = await capture({ ...input, args });\n\n if (helpRun.error !== undefined || helpRun.output.trim().length === 0) {\n throw new CliError(\n `${adapter.title} ${version}: \"${input.target.executable} ${args.join(\" \")}\" printed no help` +\n (helpRun.error ? ` (${helpRun.error.message})` : \"\") +\n \"; the capability probe cannot verify the flags this adapter needs.\",\n {\n type: \"probe-failed\",\n adapter: adapter.name,\n version,\n executable: input.target.executable,\n cause: helpRun.error,\n },\n );\n }\n\n helps.push(helpRun.output);\n }\n\n return { executable: input.target.executable, version, help: helps.join(\"\\n\") };\n}\n\n/** Throw a `capability` error naming the first required flag the help does not list. */\nexport function assertCapabilities(\n adapter: CliAdapter,\n probe: CliProbeResult,\n required: readonly string[],\n): void {\n const missing = missingFlags(probe.help, required);\n const flag = missing[0];\n\n if (flag === undefined) {\n return;\n }\n\n const helpCommands = adapter.probe.help\n .map((args) => `${adapter.command} ${args.join(\" \")}`)\n .join(\", \");\n\n throw new CliError(\n `${adapter.title} ${probe.version} (${probe.executable}) does not support ${missing.join(\", \")}: ` +\n `not listed in \"${helpCommands}\". This adapter was verified against ${adapter.title} ` +\n `${adapter.verification.version}; install a compatible version or drop the option that needs ${flag}.`,\n {\n type: \"capability\",\n adapter: adapter.name,\n flag,\n version: probe.version,\n executable: probe.executable,\n },\n );\n}\n"],"mappings":";;;;;;;AAQA,MAAa,mBAAmB;;AAGhC,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"probe.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/probe/probe.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport type { CliAdapter, CliProbeResult } from \"../contracts\";\nimport { CliError } from \"../errors\";\nimport { killProcessTree } from \"../spawn/process-tree\";\nimport { buildInvocation } from \"../spawn/invocation\";\nimport type { SpawnTarget } from \"../spawn/resolve-command\";\n\n/** How long a single `--help`/`--version` call may take. */\nexport const PROBE_TIMEOUT_MS = 30_000;\n\n/** Output cap per probe call; help screens are a few KiB. */\nconst PROBE_OUTPUT_LIMIT = 1024 * 1024;\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Whether a help screen lists a flag or subcommand. Flags (`--json`, `-p`)\n * must appear as a whole token — `--json` does not match `--json-schema`;\n * a bare word (`exec`) is matched as a whole word.\n *\n * @example\n * helpLists(\" -p, --print Print response\", \"--print\"); // true\n * helpLists(\" --output-format <format>\", \"--output\"); // false\n */\nexport function helpLists(help: string, flag: string): boolean {\n const escaped = escapeRegExp(flag);\n\n if (flag.startsWith(\"-\")) {\n return new RegExp(`(^|[\\\\s,\\\\[(|/\"'\\`])${escaped}(?=$|[\\\\s,=\\\\])|<\\\\[.:;\"'\\`])`, \"m\").test(\n help,\n );\n }\n\n return new RegExp(`(^|[^\\\\w-])${escaped}(?=$|[^\\\\w-])`, \"m\").test(help);\n}\n\n/** The first version-looking token of `--version` output, else its first line. */\nexport function parseVersion(output: string): string {\n const match = /\\d+\\.\\d+(?:\\.\\d+)?(?:[-+][0-9A-Za-z.-]+)?/.exec(output);\n\n if (match) {\n return match[0];\n }\n\n const firstLine = output.trim().split(/\\r?\\n/)[0]?.trim();\n\n return firstLine && firstLine.length > 0 ? firstLine : \"unknown\";\n}\n\n/** Flags a plan requires that the help screen does not list. */\nexport function missingFlags(help: string, required: readonly string[]): string[] {\n return required.filter((flag) => !helpLists(help, flag));\n}\n\ntype CaptureInput = {\n target: SpawnTarget;\n args: string[];\n env: Record<string, string>;\n cwd: string;\n comspec: string;\n platform: NodeJS.Platform;\n};\n\n/** Run a probe invocation and capture stdout + stderr (help is printed to either). */\nfunction capture(\n input: CaptureInput,\n): Promise<{ output: string; exitCode: number | null; error?: Error }> {\n return new Promise((resolve) => {\n const invocation = buildInvocation(input.target, input.args, input.comspec);\n\n if (\"refused\" in invocation) {\n resolve({ output: \"\", exitCode: null, error: new Error(invocation.refused) });\n\n return;\n }\n\n const child = spawn(invocation.file, invocation.args, {\n cwd: input.cwd,\n env: input.env,\n shell: false,\n windowsHide: true,\n windowsVerbatimArguments: invocation.windowsVerbatimArguments,\n detached: input.platform !== \"win32\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n const chunks: Buffer[] = [];\n let size = 0;\n let settled = false;\n\n const collect = (chunk: Buffer): void => {\n if (size < PROBE_OUTPUT_LIMIT) {\n chunks.push(chunk);\n size += chunk.length;\n }\n };\n\n const timer = setTimeout(() => {\n killProcessTree(child, input.platform, 0);\n }, PROBE_TIMEOUT_MS);\n\n const finish = (exitCode: number | null, error?: Error): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n clearTimeout(timer);\n resolve({ output: Buffer.concat(chunks).toString(\"utf8\"), exitCode, error });\n };\n\n child.stdout?.on(\"data\", collect);\n child.stderr?.on(\"data\", collect);\n child.on(\"error\", (error) => finish(null, error));\n child.on(\"close\", (code) => finish(code));\n });\n}\n\nexport type ProbeInput = Omit<CaptureInput, \"args\"> & { adapter: CliAdapter };\n\n/**\n * Read the CLI's version and help screens. A help invocation that cannot\n * run at all (spawn error, no output) fails the probe; a non-zero exit with\n * output is accepted, because several CLIs exit 1 after printing help.\n */\nexport async function probeCli(input: ProbeInput): Promise<CliProbeResult> {\n const { adapter } = input;\n const versionRun = await capture({ ...input, args: adapter.probe.version });\n\n if (versionRun.error !== undefined) {\n throw new CliError(\n `${adapter.title}: could not run \"${input.target.executable} ${adapter.probe.version.join(\" \")}\": ${versionRun.error.message}`,\n {\n type: \"probe-failed\",\n adapter: adapter.name,\n executable: input.target.executable,\n cause: versionRun.error,\n },\n );\n }\n\n const version = parseVersion(versionRun.output);\n const helps: string[] = [];\n\n for (const args of adapter.probe.help) {\n const helpRun = await capture({ ...input, args });\n\n if (helpRun.error !== undefined || helpRun.output.trim().length === 0) {\n throw new CliError(\n `${adapter.title} ${version}: \"${input.target.executable} ${args.join(\" \")}\" printed no help` +\n (helpRun.error ? ` (${helpRun.error.message})` : \"\") +\n \"; the capability probe cannot verify the flags this adapter needs.\",\n {\n type: \"probe-failed\",\n adapter: adapter.name,\n version,\n executable: input.target.executable,\n cause: helpRun.error,\n },\n );\n }\n\n helps.push(helpRun.output);\n }\n\n return { executable: input.target.executable, version, help: helps.join(\"\\n\") };\n}\n\n/** Throw a `capability` error naming the first required flag the help does not list. */\nexport function assertCapabilities(\n adapter: CliAdapter,\n probe: CliProbeResult,\n required: readonly string[],\n): void {\n const missing = missingFlags(probe.help, required);\n const flag = missing[0];\n\n if (flag === undefined) {\n return;\n }\n\n const helpCommands = adapter.probe.help\n .map((args) => `${adapter.command} ${args.join(\" \")}`)\n .join(\", \");\n\n throw new CliError(\n `${adapter.title} ${probe.version} (${probe.executable}) does not support ${missing.join(\", \")}: ` +\n `not listed in \"${helpCommands}\". This adapter was verified against ${adapter.title} ` +\n `${adapter.verification.version}; install a compatible version or drop the option that needs ${flag}.`,\n {\n type: \"capability\",\n adapter: adapter.name,\n flag,\n version: probe.version,\n executable: probe.executable,\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -59,9 +59,7 @@ var ResultAggregator = class {
|
|
|
59
59
|
case "usage":
|
|
60
60
|
this.usage = event.cumulative ? { ...event.usage } : addUsage(this.usage, event.usage);
|
|
61
61
|
break;
|
|
62
|
-
case "error":
|
|
63
|
-
if (event.fatal && this.fatalError === void 0) this.fatalError = event.message;
|
|
64
|
-
break;
|
|
62
|
+
case "error": if (event.fatal && this.fatalError === void 0) this.fatalError = event.message;
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
/** Close the stream: deltas never followed by a complete message count as one. */
|
|
@@ -82,5 +80,5 @@ var ResultAggregator = class {
|
|
|
82
80
|
};
|
|
83
81
|
|
|
84
82
|
//#endregion
|
|
85
|
-
export { ResultAggregator };
|
|
83
|
+
export { ResultAggregator, addUsage };
|
|
86
84
|
//# sourceMappingURL=aggregate.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/session/aggregate.ts"],"sourcesContent":["import type { CliParsedEvent, CliUsage } from \"../contracts\";\n\nfunction sum(a: number | undefined, b: number | undefined): number | undefined {\n return a === undefined && b === undefined ? undefined : (a ?? 0) + (b ?? 0);\n}\n\n/** Add two usages field by field; optional fields stay absent unless either side has them. */\nexport function addUsage(left: CliUsage | undefined, right: CliUsage): CliUsage {\n if (left === undefined) {\n return { ...right };\n }\n\n const merged: CliUsage = {\n input: left.input + right.input,\n output: left.output + right.output,\n total: left.total + right.total,\n };\n\n const cachedTokens = sum(left.cachedTokens, right.cachedTokens);\n const cacheWriteTokens = sum(left.cacheWriteTokens, right.cacheWriteTokens);\n const reasoningTokens = sum(left.reasoningTokens, right.reasoningTokens);\n const costUSD = sum(left.costUSD, right.costUSD);\n\n if (cachedTokens !== undefined) merged.cachedTokens = cachedTokens;\n if (cacheWriteTokens !== undefined) merged.cacheWriteTokens = cacheWriteTokens;\n if (reasoningTokens !== undefined) merged.reasoningTokens = reasoningTokens;\n if (costUSD !== undefined) merged.costUSD = costUSD;\n\n return merged;\n}\n\n/**\n * Folds parsed events into the pieces of a `CliResult`: the session ref,\n * usage, every complete message, and the final answer.\n *\n * Final-answer rule: the last `final: true` message (the vendor's own\n * result record) wins; otherwise the newest assistant text — a complete\n * message, or the deltas streamed since the last message or tool activity.\n */\nexport class ResultAggregator {\n public sessionRef?: string;\n public usage?: CliUsage;\n public readonly messages: string[] = [];\n public fatalError?: string;\n private finalText?: string;\n private deltaBuffer = \"\";\n private lastCompleteText?: string;\n\n public constructor(resume?: string) {\n this.sessionRef = resume;\n }\n\n public add(event: CliParsedEvent): void {\n switch (event.type) {\n case \"session.started\":\n if (event.sessionRef) {\n this.sessionRef = event.sessionRef;\n }\n break;\n case \"message\":\n if (event.delta) {\n this.deltaBuffer += event.text;\n break;\n }\n\n if (event.final) {\n this.finalText = event.text;\n break;\n }\n\n this.messages.push(event.text);\n this.lastCompleteText = event.text;\n this.deltaBuffer = \"\";\n break;\n case \"tool.call\":\n case \"tool.result\":\n this.flushDeltas();\n break;\n case \"usage\":\n this.usage = event.cumulative ? { ...event.usage } : addUsage(this.usage, event.usage);\n break;\n case \"error\":\n if (event.fatal && this.fatalError === undefined) {\n this.fatalError = event.message;\n }\n break;\n }\n }\n\n /** Close the stream: deltas never followed by a complete message count as one. */\n public finish(): void {\n this.flushDeltas();\n }\n\n public get text(): string {\n if (this.finalText !== undefined) {\n return this.finalText;\n }\n\n return this.deltaBuffer.length > 0 ? this.deltaBuffer : (this.lastCompleteText ?? \"\");\n }\n\n private flushDeltas(): void {\n if (this.deltaBuffer.trim().length > 0) {\n this.messages.push(this.deltaBuffer);\n this.lastCompleteText = this.deltaBuffer;\n }\n\n this.deltaBuffer = \"\";\n }\n}\n"],"mappings":";AAEA,SAAS,IAAI,GAAuB,GAA2C;CAC7E,OAAO,MAAM,UAAa,MAAM,SAAY,UAAa,KAAK,MAAM,KAAK;AAC3E;;AAGA,SAAgB,SAAS,MAA4B,OAA2B;CAC9E,IAAI,SAAS,QACX,OAAO,EAAE,GAAG,MAAM;CAGpB,MAAM,SAAmB;EACvB,OAAO,KAAK,QAAQ,MAAM;EAC1B,QAAQ,KAAK,SAAS,MAAM;EAC5B,OAAO,KAAK,QAAQ,MAAM;CAC5B;CAEA,MAAM,eAAe,IAAI,KAAK,cAAc,MAAM,YAAY;CAC9D,MAAM,mBAAmB,IAAI,KAAK,kBAAkB,MAAM,gBAAgB;CAC1E,MAAM,kBAAkB,IAAI,KAAK,iBAAiB,MAAM,eAAe;CACvE,MAAM,UAAU,IAAI,KAAK,SAAS,MAAM,OAAO;CAE/C,IAAI,iBAAiB,QAAW,OAAO,eAAe;CACtD,IAAI,qBAAqB,QAAW,OAAO,mBAAmB;CAC9D,IAAI,oBAAoB,QAAW,OAAO,kBAAkB;CAC5D,IAAI,YAAY,QAAW,OAAO,UAAU;CAE5C,OAAO;AACT;;;;;;;;;AAUA,IAAa,mBAAb,MAA8B;CAS5B,AAAO,YAAY,QAAiB;kBANC,CAAC;qBAGhB;EAIpB,KAAK,aAAa;CACpB;CAEA,AAAO,IAAI,OAA6B;EACtC,QAAQ,MAAM,MAAd;GACE,KAAK;IACH,IAAI,MAAM,YACR,KAAK,aAAa,MAAM;IAE1B;GACF,KAAK;IACH,IAAI,MAAM,OAAO;KACf,KAAK,eAAe,MAAM;KAC1B;IACF;IAEA,IAAI,MAAM,OAAO;KACf,KAAK,YAAY,MAAM;KACvB;IACF;IAEA,KAAK,SAAS,KAAK,MAAM,IAAI;IAC7B,KAAK,mBAAmB,MAAM;IAC9B,KAAK,cAAc;IACnB;GACF,KAAK;GACL,KAAK;IACH,KAAK,YAAY;IACjB;GACF,KAAK;IACH,KAAK,QAAQ,MAAM,aAAa,EAAE,GAAG,MAAM,MAAM,IAAI,SAAS,KAAK,OAAO,MAAM,KAAK;IACrF;GACF,KAAK
|
|
1
|
+
{"version":3,"file":"aggregate.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/session/aggregate.ts"],"sourcesContent":["import type { CliParsedEvent, CliUsage } from \"../contracts\";\n\nfunction sum(a: number | undefined, b: number | undefined): number | undefined {\n return a === undefined && b === undefined ? undefined : (a ?? 0) + (b ?? 0);\n}\n\n/** Add two usages field by field; optional fields stay absent unless either side has them. */\nexport function addUsage(left: CliUsage | undefined, right: CliUsage): CliUsage {\n if (left === undefined) {\n return { ...right };\n }\n\n const merged: CliUsage = {\n input: left.input + right.input,\n output: left.output + right.output,\n total: left.total + right.total,\n };\n\n const cachedTokens = sum(left.cachedTokens, right.cachedTokens);\n const cacheWriteTokens = sum(left.cacheWriteTokens, right.cacheWriteTokens);\n const reasoningTokens = sum(left.reasoningTokens, right.reasoningTokens);\n const costUSD = sum(left.costUSD, right.costUSD);\n\n if (cachedTokens !== undefined) merged.cachedTokens = cachedTokens;\n if (cacheWriteTokens !== undefined) merged.cacheWriteTokens = cacheWriteTokens;\n if (reasoningTokens !== undefined) merged.reasoningTokens = reasoningTokens;\n if (costUSD !== undefined) merged.costUSD = costUSD;\n\n return merged;\n}\n\n/**\n * Folds parsed events into the pieces of a `CliResult`: the session ref,\n * usage, every complete message, and the final answer.\n *\n * Final-answer rule: the last `final: true` message (the vendor's own\n * result record) wins; otherwise the newest assistant text — a complete\n * message, or the deltas streamed since the last message or tool activity.\n */\nexport class ResultAggregator {\n public sessionRef?: string;\n public usage?: CliUsage;\n public readonly messages: string[] = [];\n public fatalError?: string;\n private finalText?: string;\n private deltaBuffer = \"\";\n private lastCompleteText?: string;\n\n public constructor(resume?: string) {\n this.sessionRef = resume;\n }\n\n public add(event: CliParsedEvent): void {\n switch (event.type) {\n case \"session.started\":\n if (event.sessionRef) {\n this.sessionRef = event.sessionRef;\n }\n break;\n case \"message\":\n if (event.delta) {\n this.deltaBuffer += event.text;\n break;\n }\n\n if (event.final) {\n this.finalText = event.text;\n break;\n }\n\n this.messages.push(event.text);\n this.lastCompleteText = event.text;\n this.deltaBuffer = \"\";\n break;\n case \"tool.call\":\n case \"tool.result\":\n this.flushDeltas();\n break;\n case \"usage\":\n this.usage = event.cumulative ? { ...event.usage } : addUsage(this.usage, event.usage);\n break;\n case \"error\":\n if (event.fatal && this.fatalError === undefined) {\n this.fatalError = event.message;\n }\n break;\n }\n }\n\n /** Close the stream: deltas never followed by a complete message count as one. */\n public finish(): void {\n this.flushDeltas();\n }\n\n public get text(): string {\n if (this.finalText !== undefined) {\n return this.finalText;\n }\n\n return this.deltaBuffer.length > 0 ? this.deltaBuffer : (this.lastCompleteText ?? \"\");\n }\n\n private flushDeltas(): void {\n if (this.deltaBuffer.trim().length > 0) {\n this.messages.push(this.deltaBuffer);\n this.lastCompleteText = this.deltaBuffer;\n }\n\n this.deltaBuffer = \"\";\n }\n}\n"],"mappings":";AAEA,SAAS,IAAI,GAAuB,GAA2C;CAC7E,OAAO,MAAM,UAAa,MAAM,SAAY,UAAa,KAAK,MAAM,KAAK;AAC3E;;AAGA,SAAgB,SAAS,MAA4B,OAA2B;CAC9E,IAAI,SAAS,QACX,OAAO,EAAE,GAAG,MAAM;CAGpB,MAAM,SAAmB;EACvB,OAAO,KAAK,QAAQ,MAAM;EAC1B,QAAQ,KAAK,SAAS,MAAM;EAC5B,OAAO,KAAK,QAAQ,MAAM;CAC5B;CAEA,MAAM,eAAe,IAAI,KAAK,cAAc,MAAM,YAAY;CAC9D,MAAM,mBAAmB,IAAI,KAAK,kBAAkB,MAAM,gBAAgB;CAC1E,MAAM,kBAAkB,IAAI,KAAK,iBAAiB,MAAM,eAAe;CACvE,MAAM,UAAU,IAAI,KAAK,SAAS,MAAM,OAAO;CAE/C,IAAI,iBAAiB,QAAW,OAAO,eAAe;CACtD,IAAI,qBAAqB,QAAW,OAAO,mBAAmB;CAC9D,IAAI,oBAAoB,QAAW,OAAO,kBAAkB;CAC5D,IAAI,YAAY,QAAW,OAAO,UAAU;CAE5C,OAAO;AACT;;;;;;;;;AAUA,IAAa,mBAAb,MAA8B;CAS5B,AAAO,YAAY,QAAiB;kBANC,CAAC;qBAGhB;EAIpB,KAAK,aAAa;CACpB;CAEA,AAAO,IAAI,OAA6B;EACtC,QAAQ,MAAM,MAAd;GACE,KAAK;IACH,IAAI,MAAM,YACR,KAAK,aAAa,MAAM;IAE1B;GACF,KAAK;IACH,IAAI,MAAM,OAAO;KACf,KAAK,eAAe,MAAM;KAC1B;IACF;IAEA,IAAI,MAAM,OAAO;KACf,KAAK,YAAY,MAAM;KACvB;IACF;IAEA,KAAK,SAAS,KAAK,MAAM,IAAI;IAC7B,KAAK,mBAAmB,MAAM;IAC9B,KAAK,cAAc;IACnB;GACF,KAAK;GACL,KAAK;IACH,KAAK,YAAY;IACjB;GACF,KAAK;IACH,KAAK,QAAQ,MAAM,aAAa,EAAE,GAAG,MAAM,MAAM,IAAI,SAAS,KAAK,OAAO,MAAM,KAAK;IACrF;GACF,KAAK,SACH,IAAI,MAAM,SAAS,KAAK,eAAe,QACrC,KAAK,aAAa,MAAM;EAG9B;CACF;;CAGA,AAAO,SAAe;EACpB,KAAK,YAAY;CACnB;CAEA,IAAW,OAAe;EACxB,IAAI,KAAK,cAAc,QACrB,OAAO,KAAK;EAGd,OAAO,KAAK,YAAY,SAAS,IAAI,KAAK,cAAe,KAAK,oBAAoB;CACpF;CAEA,AAAQ,cAAoB;EAC1B,IAAI,KAAK,YAAY,KAAK,CAAC,CAAC,SAAS,GAAG;GACtC,KAAK,SAAS,KAAK,KAAK,WAAW;GACnC,KAAK,mBAAmB,KAAK;EAC/B;EAEA,KAAK,cAAc;CACrB;AACF"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { SpawnTarget } from "./resolve-command.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/ai-cli/src/spawn/invocation.d.ts
|
|
4
3
|
/** A ready-to-spawn invocation. */
|
|
5
|
-
type Invocation = {
|
|
4
|
+
export type Invocation = {
|
|
6
5
|
file: string;
|
|
7
|
-
args: string[];
|
|
6
|
+
args: string[];
|
|
7
|
+
/** Set for `cmd.exe` so Node does not re-quote the already-quoted command line. */
|
|
8
8
|
windowsVerbatimArguments: boolean;
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
@@ -13,14 +13,14 @@ type Invocation = {
|
|
|
13
13
|
* are literal; trailing backslashes are doubled so the target program's
|
|
14
14
|
* argv parser does not read the closing quote as escaped.
|
|
15
15
|
*/
|
|
16
|
-
declare function quoteForCmd(argument: string): string | null;
|
|
16
|
+
export declare function quoteForCmd(argument: string): string | null;
|
|
17
17
|
/**
|
|
18
18
|
* Build the invocation for a target and argv. A `cmd` target becomes
|
|
19
19
|
* `cmd.exe /d /v:off /s /c ""batch" "arg" …"` — AutoRun disabled, delayed
|
|
20
20
|
* expansion off (so `!` stays literal), each element quoted. Returns a
|
|
21
21
|
* `refused` reason when an argument cannot be quoted safely.
|
|
22
22
|
*/
|
|
23
|
-
declare function buildInvocation(target: SpawnTarget, args: string[], comspec: string): Invocation | {
|
|
23
|
+
export declare function buildInvocation(target: SpawnTarget, args: string[], comspec: string): Invocation | {
|
|
24
24
|
refused: string;
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
@@ -29,7 +29,6 @@ declare function buildInvocation(target: SpawnTarget, args: string[], comspec: s
|
|
|
29
29
|
* each argument quoted); POSIX limits a single argument to 128 KiB on Linux
|
|
30
30
|
* and shares `ARG_MAX` with the environment.
|
|
31
31
|
*/
|
|
32
|
-
declare function fitsCommandLine(invocation: Invocation, platform: NodeJS.Platform): boolean;
|
|
32
|
+
export declare function fitsCommandLine(invocation: Invocation, platform: NodeJS.Platform): boolean;
|
|
33
33
|
//#endregion
|
|
34
|
-
export { Invocation, buildInvocation, fitsCommandLine, quoteForCmd };
|
|
35
34
|
//# sourceMappingURL=invocation.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invocation.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/spawn/invocation.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"invocation.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/spawn/invocation.ts"],"mappings":";;;YAGY;EACV;EACA;;EAEA;;;;;;;;wBA6Bc,YAAY;;;;;;;wBAgBZ,gBACd,QAAQ,aACR,gBACA,kBACC;EAAe;;;;;;;;wBAqCF,gBAAgB,YAAY,YAAY,UAAU,OAAO"}
|
package/esm/spawn/invocation.mjs
CHANGED
|
@@ -11,9 +11,9 @@ const CMD_LINE_LIMIT = 8e3;
|
|
|
11
11
|
/** `CreateProcess` command-line limit (32767 characters), with headroom. */
|
|
12
12
|
const WINDOWS_LINE_LIMIT = 32e3;
|
|
13
13
|
/** Linux `MAX_ARG_STRLEN` (128 KiB per argument), with headroom. */
|
|
14
|
-
const POSIX_ARGUMENT_LIMIT =
|
|
14
|
+
const POSIX_ARGUMENT_LIMIT = 122880;
|
|
15
15
|
/** Conservative total argv budget on POSIX (ARG_MAX is shared with the environment). */
|
|
16
|
-
const POSIX_TOTAL_LIMIT =
|
|
16
|
+
const POSIX_TOTAL_LIMIT = 524288;
|
|
17
17
|
/**
|
|
18
18
|
* Quote one argument for a `cmd.exe /s /c "..."` line, or return `null` when
|
|
19
19
|
* it holds a byte cmd cannot quote safely. Inside double quotes `& | < > ^`
|
|
@@ -72,5 +72,5 @@ function fitsCommandLine(invocation, platform) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
//#endregion
|
|
75
|
-
export { buildInvocation, fitsCommandLine, quoteForCmd };
|
|
75
|
+
export { CMD_LINE_LIMIT, POSIX_ARGUMENT_LIMIT, POSIX_TOTAL_LIMIT, WINDOWS_LINE_LIMIT, buildInvocation, fitsCommandLine, quoteForCmd };
|
|
76
76
|
//# sourceMappingURL=invocation.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invocation.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/spawn/invocation.ts"],"sourcesContent":["import type { SpawnTarget } from \"./resolve-command\";\n\n/** A ready-to-spawn invocation. */\nexport type Invocation = {\n file: string;\n args: string[];\n /** Set for `cmd.exe` so Node does not re-quote the already-quoted command line. */\n windowsVerbatimArguments: boolean;\n};\n\n/**\n * Bytes `cmd.exe` cannot carry inside a double-quoted argument: a quote ends\n * the quoted span, `%` expands variables even inside quotes, and a newline\n * ends the command (the BatBadBut / CVE-2024-24576 class). An argument\n * holding one of them is refused rather than escaped.\n */\nconst CMD_UNSAFE = /[\"%\\r\\n\\0]/;\n\n/** `cmd.exe` command-line limit (8191 characters), with headroom for the wrapper. */\nexport const CMD_LINE_LIMIT = 8000;\n\n/** `CreateProcess` command-line limit (32767 characters), with headroom. */\nexport const WINDOWS_LINE_LIMIT = 32000;\n\n/** Linux `MAX_ARG_STRLEN` (128 KiB per argument), with headroom. */\nexport const POSIX_ARGUMENT_LIMIT = 120 * 1024;\n\n/** Conservative total argv budget on POSIX (ARG_MAX is shared with the environment). */\nexport const POSIX_TOTAL_LIMIT = 512 * 1024;\n\n/**\n * Quote one argument for a `cmd.exe /s /c \"...\"` line, or return `null` when\n * it holds a byte cmd cannot quote safely. Inside double quotes `& | < > ^`\n * are literal; trailing backslashes are doubled so the target program's\n * argv parser does not read the closing quote as escaped.\n */\nexport function quoteForCmd(argument: string): string | null {\n if (CMD_UNSAFE.test(argument)) {\n return null;\n }\n\n const trailing = /\\\\+$/.exec(argument)?.[0] ?? \"\";\n\n return `\"${argument}${trailing}\"`;\n}\n\n/**\n * Build the invocation for a target and argv. A `cmd` target becomes\n * `cmd.exe /d /v:off /s /c \"\"batch\" \"arg\" …\"` — AutoRun disabled, delayed\n * expansion off (so `!` stays literal), each element quoted. Returns a\n * `refused` reason when an argument cannot be quoted safely.\n */\nexport function buildInvocation(\n target: SpawnTarget,\n args: string[],\n comspec: string,\n): Invocation | { refused: string } {\n if (target.type === \"direct\") {\n return {\n file: target.file,\n args: [...target.prefixArgs, ...args],\n windowsVerbatimArguments: false,\n };\n }\n\n const quoted: string[] = [];\n\n for (const element of [target.file, ...args]) {\n const safe = quoteForCmd(element);\n\n if (safe === null) {\n return {\n refused:\n 'an argument contains \", %, a newline or a NUL byte, which cmd.exe cannot carry safely',\n };\n }\n\n quoted.push(safe);\n }\n\n return {\n file: comspec,\n args: [\"/d\", \"/v:off\", \"/s\", \"/c\", `\"${quoted.join(\" \")}\"`],\n windowsVerbatimArguments: true,\n };\n}\n\n/**\n * Whether an invocation's argv fits the platform's limits. Windows counts\n * the whole command line (8191 for `cmd.exe`, 32767 for `CreateProcess`,\n * each argument quoted); POSIX limits a single argument to 128 KiB on Linux\n * and shares `ARG_MAX` with the environment.\n */\nexport function fitsCommandLine(invocation: Invocation, platform: NodeJS.Platform): boolean {\n if (platform === \"win32\") {\n const length = [invocation.file, ...invocation.args].reduce(\n (total, element) => total + element.length + 3,\n 0,\n );\n\n return length <= (invocation.windowsVerbatimArguments ? CMD_LINE_LIMIT : WINDOWS_LINE_LIMIT);\n }\n\n let total = 0;\n\n for (const element of [invocation.file, ...invocation.args]) {\n const bytes = Buffer.byteLength(element, \"utf8\") + 1;\n\n if (bytes > POSIX_ARGUMENT_LIMIT) {\n return false;\n }\n\n total += bytes;\n }\n\n return total <= POSIX_TOTAL_LIMIT;\n}\n"],"mappings":";;;;;;;AAgBA,MAAM,aAAa;;AAGnB,MAAa,iBAAiB;;AAG9B,MAAa,qBAAqB;;AAGlC,MAAa,uBAAuB
|
|
1
|
+
{"version":3,"file":"invocation.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/spawn/invocation.ts"],"sourcesContent":["import type { SpawnTarget } from \"./resolve-command\";\n\n/** A ready-to-spawn invocation. */\nexport type Invocation = {\n file: string;\n args: string[];\n /** Set for `cmd.exe` so Node does not re-quote the already-quoted command line. */\n windowsVerbatimArguments: boolean;\n};\n\n/**\n * Bytes `cmd.exe` cannot carry inside a double-quoted argument: a quote ends\n * the quoted span, `%` expands variables even inside quotes, and a newline\n * ends the command (the BatBadBut / CVE-2024-24576 class). An argument\n * holding one of them is refused rather than escaped.\n */\nconst CMD_UNSAFE = /[\"%\\r\\n\\0]/;\n\n/** `cmd.exe` command-line limit (8191 characters), with headroom for the wrapper. */\nexport const CMD_LINE_LIMIT = 8000;\n\n/** `CreateProcess` command-line limit (32767 characters), with headroom. */\nexport const WINDOWS_LINE_LIMIT = 32000;\n\n/** Linux `MAX_ARG_STRLEN` (128 KiB per argument), with headroom. */\nexport const POSIX_ARGUMENT_LIMIT = 120 * 1024;\n\n/** Conservative total argv budget on POSIX (ARG_MAX is shared with the environment). */\nexport const POSIX_TOTAL_LIMIT = 512 * 1024;\n\n/**\n * Quote one argument for a `cmd.exe /s /c \"...\"` line, or return `null` when\n * it holds a byte cmd cannot quote safely. Inside double quotes `& | < > ^`\n * are literal; trailing backslashes are doubled so the target program's\n * argv parser does not read the closing quote as escaped.\n */\nexport function quoteForCmd(argument: string): string | null {\n if (CMD_UNSAFE.test(argument)) {\n return null;\n }\n\n const trailing = /\\\\+$/.exec(argument)?.[0] ?? \"\";\n\n return `\"${argument}${trailing}\"`;\n}\n\n/**\n * Build the invocation for a target and argv. A `cmd` target becomes\n * `cmd.exe /d /v:off /s /c \"\"batch\" \"arg\" …\"` — AutoRun disabled, delayed\n * expansion off (so `!` stays literal), each element quoted. Returns a\n * `refused` reason when an argument cannot be quoted safely.\n */\nexport function buildInvocation(\n target: SpawnTarget,\n args: string[],\n comspec: string,\n): Invocation | { refused: string } {\n if (target.type === \"direct\") {\n return {\n file: target.file,\n args: [...target.prefixArgs, ...args],\n windowsVerbatimArguments: false,\n };\n }\n\n const quoted: string[] = [];\n\n for (const element of [target.file, ...args]) {\n const safe = quoteForCmd(element);\n\n if (safe === null) {\n return {\n refused:\n 'an argument contains \", %, a newline or a NUL byte, which cmd.exe cannot carry safely',\n };\n }\n\n quoted.push(safe);\n }\n\n return {\n file: comspec,\n args: [\"/d\", \"/v:off\", \"/s\", \"/c\", `\"${quoted.join(\" \")}\"`],\n windowsVerbatimArguments: true,\n };\n}\n\n/**\n * Whether an invocation's argv fits the platform's limits. Windows counts\n * the whole command line (8191 for `cmd.exe`, 32767 for `CreateProcess`,\n * each argument quoted); POSIX limits a single argument to 128 KiB on Linux\n * and shares `ARG_MAX` with the environment.\n */\nexport function fitsCommandLine(invocation: Invocation, platform: NodeJS.Platform): boolean {\n if (platform === \"win32\") {\n const length = [invocation.file, ...invocation.args].reduce(\n (total, element) => total + element.length + 3,\n 0,\n );\n\n return length <= (invocation.windowsVerbatimArguments ? CMD_LINE_LIMIT : WINDOWS_LINE_LIMIT);\n }\n\n let total = 0;\n\n for (const element of [invocation.file, ...invocation.args]) {\n const bytes = Buffer.byteLength(element, \"utf8\") + 1;\n\n if (bytes > POSIX_ARGUMENT_LIMIT) {\n return false;\n }\n\n total += bytes;\n }\n\n return total <= POSIX_TOTAL_LIMIT;\n}\n"],"mappings":";;;;;;;AAgBA,MAAM,aAAa;;AAGnB,MAAa,iBAAiB;;AAG9B,MAAa,qBAAqB;;AAGlC,MAAa,uBAAuB;;AAGpC,MAAa,oBAAoB;;;;;;;AAQjC,SAAgB,YAAY,UAAiC;CAC3D,IAAI,WAAW,KAAK,QAAQ,GAC1B,OAAO;CAKT,OAAO,IAAI,WAFM,OAAO,KAAK,QAAQ,CAAC,GAAG,MAAM,GAEhB;AACjC;;;;;;;AAQA,SAAgB,gBACd,QACA,MACA,SACkC;CAClC,IAAI,OAAO,SAAS,UAClB,OAAO;EACL,MAAM,OAAO;EACb,MAAM,CAAC,GAAG,OAAO,YAAY,GAAG,IAAI;EACpC,0BAA0B;CAC5B;CAGF,MAAM,SAAmB,CAAC;CAE1B,KAAK,MAAM,WAAW,CAAC,OAAO,MAAM,GAAG,IAAI,GAAG;EAC5C,MAAM,OAAO,YAAY,OAAO;EAEhC,IAAI,SAAS,MACX,OAAO,EACL,SACE,yFACJ;EAGF,OAAO,KAAK,IAAI;CAClB;CAEA,OAAO;EACL,MAAM;EACN,MAAM;GAAC;GAAM;GAAU;GAAM;GAAM,IAAI,OAAO,KAAK,GAAG,EAAE;EAAE;EAC1D,0BAA0B;CAC5B;AACF;;;;;;;AAQA,SAAgB,gBAAgB,YAAwB,UAAoC;CAC1F,IAAI,aAAa,SAMf,OALe,CAAC,WAAW,MAAM,GAAG,WAAW,IAAI,CAAC,CAAC,QAClD,OAAO,YAAY,QAAQ,QAAQ,SAAS,GAC7C,CAGU,MAAM,WAAW,2BAA2B,iBAAiB;CAG3E,IAAI,QAAQ;CAEZ,KAAK,MAAM,WAAW,CAAC,WAAW,MAAM,GAAG,WAAW,IAAI,GAAG;EAC3D,MAAM,QAAQ,OAAO,WAAW,SAAS,MAAM,IAAI;EAEnD,IAAI,gBACF,OAAO;EAGT,SAAS;CACX;CAEA,OAAO,SAAS;AAClB"}
|
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
* Host facts the resolver needs, injected so every rule is a pure function
|
|
4
4
|
* that tests can drive for Windows on any OS.
|
|
5
5
|
*/
|
|
6
|
-
type CommandLookup = {
|
|
6
|
+
export type CommandLookup = {
|
|
7
7
|
platform: NodeJS.Platform;
|
|
8
|
-
env: Record<string, string | undefined>;
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
env: Record<string, string | undefined>;
|
|
9
|
+
/** Whether a regular, runnable file exists at this absolute path. */
|
|
10
|
+
isFile(filePath: string): boolean;
|
|
11
|
+
/** Read a small text file (used only for npm `.cmd` shims). */
|
|
12
|
+
readFile(filePath: string): string | undefined;
|
|
13
|
+
/** Node binary used to run a JavaScript entry behind an npm shim. */
|
|
11
14
|
execPath: string;
|
|
12
15
|
};
|
|
13
16
|
/**
|
|
@@ -18,7 +21,7 @@ type CommandLookup = {
|
|
|
18
21
|
* `.cmd`/`.bat` since CVE-2024-27980); it runs through `cmd.exe` with
|
|
19
22
|
* every argument quoted (see {@link buildInvocation}).
|
|
20
23
|
*/
|
|
21
|
-
type SpawnTarget = {
|
|
24
|
+
export type SpawnTarget = {
|
|
22
25
|
type: "direct";
|
|
23
26
|
file: string;
|
|
24
27
|
prefixArgs: string[];
|
|
@@ -40,9 +43,9 @@ type SpawnTarget = {
|
|
|
40
43
|
* findExecutable("claude", { platform: "win32", env: { PATH: "C:\\npm", PATHEXT: ".EXE;.CMD" }, ... });
|
|
41
44
|
* // → "C:\\npm\\claude.cmd"
|
|
42
45
|
*/
|
|
43
|
-
declare function findExecutable(command: string, lookup: CommandLookup): string | undefined;
|
|
46
|
+
export declare function findExecutable(command: string, lookup: CommandLookup): string | undefined;
|
|
44
47
|
/** What an npm/pnpm `.cmd` shim launches. */
|
|
45
|
-
type CmdShimTarget = {
|
|
48
|
+
export type CmdShimTarget = {
|
|
46
49
|
type: "node";
|
|
47
50
|
script: string;
|
|
48
51
|
} | {
|
|
@@ -59,7 +62,7 @@ type CmdShimTarget = {
|
|
|
59
62
|
* directly. Anything else returns `undefined` and the caller falls back to
|
|
60
63
|
* `cmd.exe`.
|
|
61
64
|
*/
|
|
62
|
-
declare function parseCmdShim(content: string, shimPath: string): CmdShimTarget | undefined;
|
|
65
|
+
export declare function parseCmdShim(content: string, shimPath: string): CmdShimTarget | undefined;
|
|
63
66
|
/**
|
|
64
67
|
* Resolve a command to something `child_process.spawn` can start without a
|
|
65
68
|
* shell. On Windows a `.cmd`/`.bat` npm shim is unwrapped to
|
|
@@ -67,7 +70,6 @@ declare function parseCmdShim(content: string, shimPath: string): CmdShimTarget
|
|
|
67
70
|
* with no `cmd.exe` parsing in between; any other batch file falls back
|
|
68
71
|
* to `cmd.exe`.
|
|
69
72
|
*/
|
|
70
|
-
declare function resolveSpawnTarget(command: string, lookup: CommandLookup): SpawnTarget | undefined;
|
|
73
|
+
export declare function resolveSpawnTarget(command: string, lookup: CommandLookup): SpawnTarget | undefined;
|
|
71
74
|
//#endregion
|
|
72
|
-
export { CmdShimTarget, CommandLookup, SpawnTarget, findExecutable, parseCmdShim, resolveSpawnTarget };
|
|
73
75
|
//# sourceMappingURL=resolve-command.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-command.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/spawn/resolve-command.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-command.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/spawn/resolve-command.ts"],"mappings":";;;;;YAMY;EACV,UAAU,OAAO;EACjB,KAAK;;EAEL,OAAO;;EAEP,SAAS;;EAET;;;;;;;;;;YAWU;EACN;EAAgB;EAAc;EAAsB;;EACpD;EAAa;EAAc;;;;;;;;;;;;;;wBA0CjB,eAAe,iBAAiB,QAAQ;;YA+C5C;EAAkB;EAAc;;EAAqB;EAAgB;;;;;;;;;;;;wBAYjE,aAAa,iBAAiB,mBAAmB;;;;;;;;wBAuCjD,mBACd,iBACA,QAAQ,gBACP"}
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { CliParsedEvent } from "../contracts/events.type.mjs";
|
|
2
2
|
import { CliStreamParser } from "../contracts/adapter.contract.mjs";
|
|
3
|
+
import "../contracts/index.mjs";
|
|
3
4
|
//#region ../../packages/ai-cli/src/stream/json-lines.d.ts
|
|
4
5
|
/** A plain JSON object. */
|
|
5
|
-
type JsonRecord = Record<string, unknown>;
|
|
6
|
+
export type JsonRecord = Record<string, unknown>;
|
|
6
7
|
/** `value` as a JSON object, or `undefined`. */
|
|
7
|
-
declare function asRecord(value: unknown): JsonRecord | undefined;
|
|
8
|
+
export declare function asRecord(value: unknown): JsonRecord | undefined;
|
|
8
9
|
/** `value` as an array, or an empty array. */
|
|
9
|
-
declare function asArray(value: unknown): unknown[];
|
|
10
|
+
export declare function asArray(value: unknown): unknown[];
|
|
10
11
|
/** A string field, or `undefined`. */
|
|
11
|
-
declare function stringField(record: JsonRecord | undefined, key: string): string | undefined;
|
|
12
|
+
export declare function stringField(record: JsonRecord | undefined, key: string): string | undefined;
|
|
12
13
|
/** A finite number field, or `undefined`. */
|
|
13
|
-
declare function numberField(record: JsonRecord | undefined, key: string): number | undefined;
|
|
14
|
+
export declare function numberField(record: JsonRecord | undefined, key: string): number | undefined;
|
|
14
15
|
/** A nested object field, or `undefined`. */
|
|
15
|
-
declare function recordField(record: JsonRecord | undefined, key: string): JsonRecord | undefined;
|
|
16
|
+
export declare function recordField(record: JsonRecord | undefined, key: string): JsonRecord | undefined;
|
|
16
17
|
/** Tool output as text: strings verbatim, text-block arrays joined, anything else as JSON. */
|
|
17
|
-
declare function outputText(value: unknown): string;
|
|
18
|
+
export declare function outputText(value: unknown): string;
|
|
18
19
|
/** Parse one line as a JSON object; anything else (banners, blank lines) is `undefined`. */
|
|
19
|
-
declare function parseJsonLine(line: string): JsonRecord | undefined;
|
|
20
|
+
export declare function parseJsonLine(line: string): JsonRecord | undefined;
|
|
20
21
|
/**
|
|
21
22
|
* Build a parser for a JSONL/NDJSON stream. Non-JSON lines (progress
|
|
22
23
|
* banners, warnings) are skipped; each JSON object goes to `onRecord`.
|
|
@@ -27,7 +28,6 @@ declare function parseJsonLine(line: string): JsonRecord | undefined;
|
|
|
27
28
|
* record.type === "text" ? [{ type: "message", text: String(record.text), delta: false }] : [],
|
|
28
29
|
* );
|
|
29
30
|
*/
|
|
30
|
-
declare function jsonLinesParser(onRecord: (record: JsonRecord) => CliParsedEvent[], onEnd?: () => CliParsedEvent[]): CliStreamParser;
|
|
31
|
+
export declare function jsonLinesParser(onRecord: (record: JsonRecord) => CliParsedEvent[], onEnd?: () => CliParsedEvent[]): CliStreamParser;
|
|
31
32
|
//#endregion
|
|
32
|
-
export { JsonRecord, asArray, asRecord, jsonLinesParser, numberField, outputText, parseJsonLine, recordField, stringField };
|
|
33
33
|
//# sourceMappingURL=json-lines.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-lines.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/json-lines.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"json-lines.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/json-lines.ts"],"mappings":";;;;;YAGY,aAAa;;wBAGT,SAAS,iBAAiB;;wBAO1B,QAAQ;;wBAKR,YAAY,QAAQ,wBAAwB;;wBAO5C,YAAY,QAAQ,wBAAwB;;wBAO5C,YAAY,QAAQ,wBAAwB,cAAc;;wBAK1D,WAAW;;wBAwBX,cAAc,eAAe;;;;;;;;;;;wBAwB7B,gBACd,WAAW,QAAQ,eAAe,kBAClC,cAAa,mBACZ"}
|
|
@@ -2,7 +2,7 @@ import { StringDecoder } from "node:string_decoder";
|
|
|
2
2
|
|
|
3
3
|
//#region ../../packages/ai-cli/src/stream/line-splitter.ts
|
|
4
4
|
/** Longest line kept in memory; a longer one is dropped (reported via `onOverflow`). */
|
|
5
|
-
const MAX_LINE_BYTES =
|
|
5
|
+
const MAX_LINE_BYTES = 33554432;
|
|
6
6
|
/**
|
|
7
7
|
* Split a byte stream into lines. Multi-byte UTF-8 characters split across
|
|
8
8
|
* chunks are decoded correctly, `\r\n` and `\n` both end a line, and a final
|
|
@@ -49,5 +49,5 @@ function createLineSplitter(onLine, onOverflow = () => void 0) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
//#endregion
|
|
52
|
-
export { createLineSplitter };
|
|
52
|
+
export { MAX_LINE_BYTES, createLineSplitter };
|
|
53
53
|
//# sourceMappingURL=line-splitter.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"line-splitter.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/line-splitter.ts"],"sourcesContent":["import { StringDecoder } from \"node:string_decoder\";\n\n/** Longest line kept in memory; a longer one is dropped (reported via `onOverflow`). */\nexport const MAX_LINE_BYTES = 32 * 1024 * 1024;\n\n/**\n * Split a byte stream into lines. Multi-byte UTF-8 characters split across\n * chunks are decoded correctly, `\\r\\n` and `\\n` both end a line, and a final\n * line without a newline is flushed by `end()`.\n *\n * @example\n * const splitter = createLineSplitter((line) => console.log(line));\n * splitter.write(Buffer.from('{\"a\":1}\\n{\"b\"'));\n * splitter.write(Buffer.from(\":2}\\n\"));\n * splitter.end();\n */\nexport function createLineSplitter(\n onLine: (line: string) => void,\n onOverflow: () => void = () => undefined,\n): { write(chunk: Buffer): void; end(): void } {\n const decoder = new StringDecoder(\"utf8\");\n let pending = \"\";\n let overflowed = false;\n\n const consume = (text: string): void => {\n pending += text;\n\n let newline = pending.indexOf(\"\\n\");\n\n while (newline !== -1) {\n const line = pending.slice(0, newline).replace(/\\r$/, \"\");\n\n pending = pending.slice(newline + 1);\n\n if (overflowed) {\n overflowed = false;\n } else {\n onLine(line);\n }\n\n newline = pending.indexOf(\"\\n\");\n }\n\n if (pending.length > MAX_LINE_BYTES) {\n pending = \"\";\n\n if (!overflowed) {\n overflowed = true;\n onOverflow();\n }\n }\n };\n\n return {\n write(chunk: Buffer): void {\n consume(decoder.write(chunk));\n },\n end(): void {\n consume(decoder.end());\n\n if (pending.length > 0 && !overflowed) {\n onLine(pending.replace(/\\r$/, \"\"));\n }\n\n pending = \"\";\n },\n };\n}\n"],"mappings":";;;;AAGA,MAAa,iBAAiB
|
|
1
|
+
{"version":3,"file":"line-splitter.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/line-splitter.ts"],"sourcesContent":["import { StringDecoder } from \"node:string_decoder\";\n\n/** Longest line kept in memory; a longer one is dropped (reported via `onOverflow`). */\nexport const MAX_LINE_BYTES = 32 * 1024 * 1024;\n\n/**\n * Split a byte stream into lines. Multi-byte UTF-8 characters split across\n * chunks are decoded correctly, `\\r\\n` and `\\n` both end a line, and a final\n * line without a newline is flushed by `end()`.\n *\n * @example\n * const splitter = createLineSplitter((line) => console.log(line));\n * splitter.write(Buffer.from('{\"a\":1}\\n{\"b\"'));\n * splitter.write(Buffer.from(\":2}\\n\"));\n * splitter.end();\n */\nexport function createLineSplitter(\n onLine: (line: string) => void,\n onOverflow: () => void = () => undefined,\n): { write(chunk: Buffer): void; end(): void } {\n const decoder = new StringDecoder(\"utf8\");\n let pending = \"\";\n let overflowed = false;\n\n const consume = (text: string): void => {\n pending += text;\n\n let newline = pending.indexOf(\"\\n\");\n\n while (newline !== -1) {\n const line = pending.slice(0, newline).replace(/\\r$/, \"\");\n\n pending = pending.slice(newline + 1);\n\n if (overflowed) {\n overflowed = false;\n } else {\n onLine(line);\n }\n\n newline = pending.indexOf(\"\\n\");\n }\n\n if (pending.length > MAX_LINE_BYTES) {\n pending = \"\";\n\n if (!overflowed) {\n overflowed = true;\n onOverflow();\n }\n }\n };\n\n return {\n write(chunk: Buffer): void {\n consume(decoder.write(chunk));\n },\n end(): void {\n consume(decoder.end());\n\n if (pending.length > 0 && !overflowed) {\n onLine(pending.replace(/\\r$/, \"\"));\n }\n\n pending = \"\";\n },\n };\n}\n"],"mappings":";;;;AAGA,MAAa,iBAAiB;;;;;;;;;;;;AAa9B,SAAgB,mBACd,QACA,mBAA+B,QACc;CAC7C,MAAM,UAAU,IAAI,cAAc,MAAM;CACxC,IAAI,UAAU;CACd,IAAI,aAAa;CAEjB,MAAM,WAAW,SAAuB;EACtC,WAAW;EAEX,IAAI,UAAU,QAAQ,QAAQ,IAAI;EAElC,OAAO,YAAY,IAAI;GACrB,MAAM,OAAO,QAAQ,MAAM,GAAG,OAAO,CAAC,CAAC,QAAQ,OAAO,EAAE;GAExD,UAAU,QAAQ,MAAM,UAAU,CAAC;GAEnC,IAAI,YACF,aAAa;QAEb,OAAO,IAAI;GAGb,UAAU,QAAQ,QAAQ,IAAI;EAChC;EAEA,IAAI,QAAQ,mBAAyB;GACnC,UAAU;GAEV,IAAI,CAAC,YAAY;IACf,aAAa;IACb,WAAW;GACb;EACF;CACF;CAEA,OAAO;EACL,MAAM,OAAqB;GACzB,QAAQ,QAAQ,MAAM,KAAK,CAAC;EAC9B;EACA,MAAY;GACV,QAAQ,QAAQ,IAAI,CAAC;GAErB,IAAI,QAAQ,SAAS,KAAK,CAAC,YACzB,OAAO,QAAQ,QAAQ,OAAO,EAAE,CAAC;GAGnC,UAAU;EACZ;CACF;AACF"}
|
package/esm/utils/toml.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region ../../packages/ai-cli/src/utils/toml.d.ts
|
|
2
2
|
/** A TOML value this writer supports. */
|
|
3
|
-
type TomlValue = string | number | boolean | TomlValue[] | TomlTable;
|
|
3
|
+
export type TomlValue = string | number | boolean | TomlValue[] | TomlTable;
|
|
4
4
|
/** A TOML table. */
|
|
5
|
-
type TomlTable = {
|
|
5
|
+
export type TomlTable = {
|
|
6
6
|
[key: string]: TomlValue | undefined;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
@@ -16,7 +16,6 @@ type TomlTable = {
|
|
|
16
16
|
* // command = "npx"
|
|
17
17
|
* // args = ["-y", "docs-mcp"]
|
|
18
18
|
*/
|
|
19
|
-
declare function toToml(table: TomlTable, prefix?: string[]): string;
|
|
19
|
+
export declare function toToml(table: TomlTable, prefix?: string[]): string;
|
|
20
20
|
//#endregion
|
|
21
|
-
export { TomlTable, TomlValue, toToml };
|
|
22
21
|
//# sourceMappingURL=toml.d.mts.map
|
package/esm/utils/toml.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toml.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/utils/toml.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"toml.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/utils/toml.ts"],"mappings":";;YACY,wCAAwC,cAAc;;YAGtD;GAAe,cAAc;;;;;;;;;;;;;wBAmDzB,OAAO,OAAO,WAAW"}
|
package/package.json
CHANGED
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"directory": "packages/ai-cli"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@warlock.js/ai": "5.
|
|
23
|
+
"@warlock.js/ai": "5.33.0"
|
|
24
24
|
},
|
|
25
|
-
"version": "5.
|
|
25
|
+
"version": "5.33.0",
|
|
26
26
|
"main": "./cjs/index.cjs",
|
|
27
27
|
"module": "./esm/index.mjs",
|
|
28
28
|
"types": "./esm/index.d.mts",
|