apex-code 0.4.0 → 0.5.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 +23 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -7
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +8 -30
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +2 -2
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +4 -4
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -4
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +4 -4
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +11 -8
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +4 -5
- package/dist/core/tools/write.js.map +1 -1
- package/dist/extensions/llama/ui.d.ts.map +1 -1
- package/dist/extensions/llama/ui.js +3 -2
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +0 -10
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/autocomplete-source.d.ts +8 -0
- package/dist/modes/interactive/components/autocomplete-source.d.ts.map +1 -0
- package/dist/modes/interactive/components/autocomplete-source.js +23 -0
- package/dist/modes/interactive/components/autocomplete-source.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +6 -4
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/composer-dock.d.ts +12 -0
- package/dist/modes/interactive/components/composer-dock.d.ts.map +1 -0
- package/dist/modes/interactive/components/composer-dock.js +24 -0
- package/dist/modes/interactive/components/composer-dock.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +11 -9
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +9 -9
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +9 -5
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +11 -10
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +6 -6
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +21 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +34 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +27 -23
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +14 -18
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +7 -6
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/permission-preview.d.ts.map +1 -1
- package/dist/modes/interactive/components/permission-preview.js +3 -3
- package/dist/modes/interactive/components/permission-preview.js.map +1 -1
- package/dist/modes/interactive/components/prompt-input.d.ts +12 -0
- package/dist/modes/interactive/components/prompt-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/prompt-input.js +18 -0
- package/dist/modes/interactive/components/prompt-input.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +4 -3
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +26 -19
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +39 -6
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js +8 -6
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +10 -5
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -11
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +9 -38
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-panel.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-panel.js +7 -2
- package/dist/modes/interactive/components/tool-panel.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +9 -5
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +11 -11
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +2 -2
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +6 -3
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +7 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +64 -64
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +49 -23
- package/dist/modes/print-mode.js.map +1 -1
- package/docs/json.md +36 -0
- package/docs/settings.md +1 -1
- package/npm-shrinkwrap.json +5 -5
- package/package.json +2 -2
- package/dist/modes/interactive/components/message-spine.d.ts +0 -14
- package/dist/modes/interactive/components/message-spine.d.ts.map +0 -1
- package/dist/modes/interactive/components/message-spine.js +0 -19
- package/dist/modes/interactive/components/message-spine.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-mode.d.ts","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAK5E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"print-mode.d.ts","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAK5E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;CAC/B;AAoDD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmJ/G","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `pi -p \"prompt\"` - text output\n * - `pi --mode json \"prompt\"` - JSON event stream\n */\n\nimport type { AssistantMessage, ImageContent } from \"@earendil-works/pi-ai\";\nimport type { AgentStopReason } from \"apex-code-agent-core\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport { flushRawStdout, waitForRawStdoutBackpressure, writeRawStdout } from \"../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\nimport { toJsonEvent } from \"./json-event.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Terminal status of a non-interactive run, written as the `result` envelope in\n * JSON mode. The vocabulary is `AgentStopReason`'s own, rather than a second one\n * defined here, so the two cannot drift.\n */\ntype PrintRunStatus = AgentStopReason[\"kind\"];\n\ninterface PrintRunOutcome {\n\tstatus: PrintRunStatus;\n\t/** What text mode prints to stderr. Empty when the run completed. */\n\tmessage: string;\n}\n\n/**\n * Resolve the run's terminal outcome.\n *\n * `agent_end`'s structured stop reason wins because the loop already applied its\n * documented precedence (aborted > error > budget > completed) to produce it. The\n * settled assistant message is only a fallback, for the runs that end without an\n * `agent_end` reaching this mode at all.\n */\nfunction resolveRunOutcome(\n\tstopReason: AgentStopReason | undefined,\n\tsettled: AssistantMessage | undefined,\n): PrintRunOutcome {\n\tif (stopReason?.kind === \"budget-exhausted\") {\n\t\tconst limit = stopReason.limit.replace(/-/g, \" \");\n\t\treturn {\n\t\t\tstatus: \"budget-exhausted\",\n\t\t\tmessage: `Run stopped: the ${limit} budget was exhausted (runBudget settings).`,\n\t\t};\n\t}\n\tconst failed = (reason: \"aborted\" | \"error\"): PrintRunOutcome => ({\n\t\tstatus: reason,\n\t\tmessage: settled?.errorMessage || `Request ${reason}`,\n\t});\n\tconst completed: PrintRunOutcome = { status: \"completed\", message: \"\" };\n\n\t// A stop reason answers the question by itself, including when it says the run\n\t// completed. Reading the settled message in that case would let one left over\n\t// from an earlier failed turn outrank what the loop concluded.\n\tif (stopReason !== undefined) {\n\t\treturn stopReason.kind === \"aborted\" || stopReason.kind === \"error\" ? failed(stopReason.kind) : completed;\n\t}\n\tif (settled?.stopReason === \"aborted\" || settled?.stopReason === \"error\") {\n\t\treturn failed(settled.stopReason);\n\t}\n\treturn completed;\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet unsubscribeBackpressure: (() => void) | undefined;\n\tlet disposed = false;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\t// Structured terminal outcome of the last run (spec 2026-09-01-tool-reliability-\n\t// and-execution-budgets.md); surfaced in this mode's native form below.\n\tlet lastStopReason: AgentStopReason | undefined;\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeHost.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tawait session.bindExtensions({\n\t\t\tmode: mode === \"json\" ? \"json\" : \"print\",\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.waitForIdle(),\n\t\t\t\tnewSession: async (newSessionOptions) => runtimeHost.newSession(newSessionOptions),\n\t\t\t\tfork: async (entryId, forkOptions) => {\n\t\t\t\t\tconst result = await runtimeHost.fork(entryId, forkOptions);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, navigateOptions) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, {\n\t\t\t\t\t\tsummarize: navigateOptions?.summarize,\n\t\t\t\t\t\tcustomInstructions: navigateOptions?.customInstructions,\n\t\t\t\t\t\treplaceInstructions: navigateOptions?.replaceInstructions,\n\t\t\t\t\t\tlabel: navigateOptions?.label,\n\t\t\t\t\t});\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: async (sessionPath, switchOptions) => {\n\t\t\t\t\treturn runtimeHost.switchSession(sessionPath, switchOptions);\n\t\t\t\t},\n\t\t\t\treload: async () => {\n\t\t\t\t\tawait session.reload();\n\t\t\t\t},\n\t\t\t},\n\t\t\tonError: (err) => {\n\t\t\t\tconsole.error(`Extension error (${err.extensionPath}): ${err.error}`);\n\t\t\t},\n\t\t});\n\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tunsubscribe = session.subscribe((event) => {\n\t\t\tif (event.type === \"agent_end\") {\n\t\t\t\tlastStopReason = event.stopReason;\n\t\t\t}\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(toJsonEvent(event))}\\n`);\n\t\t\t}\n\t\t});\n\t\tunsubscribeBackpressure =\n\t\t\tmode === \"json\"\n\t\t\t\t? session.agent.subscribe(async () => {\n\t\t\t\t\t\tawait waitForRawStdoutBackpressure();\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = session.sessionManager.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\tif (initialMessage) {\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tawait session.prompt(message);\n\t\t}\n\n\t\t// The outcome is resolved once, for every mode. Deciding it inside the text\n\t\t// branch is what let a failed `--mode json` run exit 0: the stream carried the\n\t\t// error and the exit code reported success.\n\t\tconst lastMessage = session.state.messages[session.state.messages.length - 1];\n\t\tconst outcome = resolveRunOutcome(\n\t\t\tlastStopReason,\n\t\t\tlastMessage?.role === \"assistant\" ? (lastMessage as AssistantMessage) : undefined,\n\t\t);\n\t\texitCode = outcome.status === \"completed\" ? 0 : 1;\n\n\t\tif (mode === \"json\") {\n\t\t\twriteRawStdout(`${JSON.stringify({ type: \"result\", status: outcome.status })}\\n`);\n\t\t} else if (outcome.status === \"completed\") {\n\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\tfor (const content of (lastMessage as AssistantMessage).content) {\n\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.error(outcome.message);\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
|
package/dist/modes/print-mode.js
CHANGED
|
@@ -8,6 +8,38 @@
|
|
|
8
8
|
import { flushRawStdout, waitForRawStdoutBackpressure, writeRawStdout } from "../core/output-guard.js";
|
|
9
9
|
import { killTrackedDetachedChildren } from "../utils/shell.js";
|
|
10
10
|
import { toJsonEvent } from "./json-event.js";
|
|
11
|
+
/**
|
|
12
|
+
* Resolve the run's terminal outcome.
|
|
13
|
+
*
|
|
14
|
+
* `agent_end`'s structured stop reason wins because the loop already applied its
|
|
15
|
+
* documented precedence (aborted > error > budget > completed) to produce it. The
|
|
16
|
+
* settled assistant message is only a fallback, for the runs that end without an
|
|
17
|
+
* `agent_end` reaching this mode at all.
|
|
18
|
+
*/
|
|
19
|
+
function resolveRunOutcome(stopReason, settled) {
|
|
20
|
+
if (stopReason?.kind === "budget-exhausted") {
|
|
21
|
+
const limit = stopReason.limit.replace(/-/g, " ");
|
|
22
|
+
return {
|
|
23
|
+
status: "budget-exhausted",
|
|
24
|
+
message: `Run stopped: the ${limit} budget was exhausted (runBudget settings).`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const failed = (reason) => ({
|
|
28
|
+
status: reason,
|
|
29
|
+
message: settled?.errorMessage || `Request ${reason}`,
|
|
30
|
+
});
|
|
31
|
+
const completed = { status: "completed", message: "" };
|
|
32
|
+
// A stop reason answers the question by itself, including when it says the run
|
|
33
|
+
// completed. Reading the settled message in that case would let one left over
|
|
34
|
+
// from an earlier failed turn outrank what the loop concluded.
|
|
35
|
+
if (stopReason !== undefined) {
|
|
36
|
+
return stopReason.kind === "aborted" || stopReason.kind === "error" ? failed(stopReason.kind) : completed;
|
|
37
|
+
}
|
|
38
|
+
if (settled?.stopReason === "aborted" || settled?.stopReason === "error") {
|
|
39
|
+
return failed(settled.stopReason);
|
|
40
|
+
}
|
|
41
|
+
return completed;
|
|
42
|
+
}
|
|
11
43
|
/**
|
|
12
44
|
* Run in print (single-shot) mode.
|
|
13
45
|
* Sends prompts to the agent and outputs the result.
|
|
@@ -113,33 +145,27 @@ export async function runPrintMode(runtimeHost, options) {
|
|
|
113
145
|
for (const message of messages) {
|
|
114
146
|
await session.prompt(message);
|
|
115
147
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
console.error(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);
|
|
131
|
-
exitCode = 1;
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
for (const content of assistantMsg.content) {
|
|
135
|
-
if (content.type === "text") {
|
|
136
|
-
writeRawStdout(`${content.text}\n`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
148
|
+
// The outcome is resolved once, for every mode. Deciding it inside the text
|
|
149
|
+
// branch is what let a failed `--mode json` run exit 0: the stream carried the
|
|
150
|
+
// error and the exit code reported success.
|
|
151
|
+
const lastMessage = session.state.messages[session.state.messages.length - 1];
|
|
152
|
+
const outcome = resolveRunOutcome(lastStopReason, lastMessage?.role === "assistant" ? lastMessage : undefined);
|
|
153
|
+
exitCode = outcome.status === "completed" ? 0 : 1;
|
|
154
|
+
if (mode === "json") {
|
|
155
|
+
writeRawStdout(`${JSON.stringify({ type: "result", status: outcome.status })}\n`);
|
|
156
|
+
}
|
|
157
|
+
else if (outcome.status === "completed") {
|
|
158
|
+
if (lastMessage?.role === "assistant") {
|
|
159
|
+
for (const content of lastMessage.content) {
|
|
160
|
+
if (content.type === "text") {
|
|
161
|
+
writeRawStdout(`${content.text}\n`);
|
|
139
162
|
}
|
|
140
163
|
}
|
|
141
164
|
}
|
|
142
165
|
}
|
|
166
|
+
else {
|
|
167
|
+
console.error(outcome.message);
|
|
168
|
+
}
|
|
143
169
|
return exitCode;
|
|
144
170
|
}
|
|
145
171
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-mode.js","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `pi -p \"prompt\"` - text output\n * - `pi --mode json \"prompt\"` - JSON event stream\n */\n\nimport type { AssistantMessage, ImageContent } from \"@earendil-works/pi-ai\";\nimport type { AgentStopReason } from \"apex-code-agent-core\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport { flushRawStdout, waitForRawStdoutBackpressure, writeRawStdout } from \"../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\nimport { toJsonEvent } from \"./json-event.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet unsubscribeBackpressure: (() => void) | undefined;\n\tlet disposed = false;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\t// Structured terminal outcome of the last run (spec 2026-09-01-tool-reliability-\n\t// and-execution-budgets.md); surfaced in this mode's native form below.\n\tlet lastStopReason: AgentStopReason | undefined;\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeHost.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tawait session.bindExtensions({\n\t\t\tmode: mode === \"json\" ? \"json\" : \"print\",\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.waitForIdle(),\n\t\t\t\tnewSession: async (newSessionOptions) => runtimeHost.newSession(newSessionOptions),\n\t\t\t\tfork: async (entryId, forkOptions) => {\n\t\t\t\t\tconst result = await runtimeHost.fork(entryId, forkOptions);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, navigateOptions) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, {\n\t\t\t\t\t\tsummarize: navigateOptions?.summarize,\n\t\t\t\t\t\tcustomInstructions: navigateOptions?.customInstructions,\n\t\t\t\t\t\treplaceInstructions: navigateOptions?.replaceInstructions,\n\t\t\t\t\t\tlabel: navigateOptions?.label,\n\t\t\t\t\t});\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: async (sessionPath, switchOptions) => {\n\t\t\t\t\treturn runtimeHost.switchSession(sessionPath, switchOptions);\n\t\t\t\t},\n\t\t\t\treload: async () => {\n\t\t\t\t\tawait session.reload();\n\t\t\t\t},\n\t\t\t},\n\t\t\tonError: (err) => {\n\t\t\t\tconsole.error(`Extension error (${err.extensionPath}): ${err.error}`);\n\t\t\t},\n\t\t});\n\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tunsubscribe = session.subscribe((event) => {\n\t\t\tif (event.type === \"agent_end\") {\n\t\t\t\tlastStopReason = event.stopReason;\n\t\t\t}\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(toJsonEvent(event))}\\n`);\n\t\t\t}\n\t\t});\n\t\tunsubscribeBackpressure =\n\t\t\tmode === \"json\"\n\t\t\t\t? session.agent.subscribe(async () => {\n\t\t\t\t\t\tawait waitForRawStdoutBackpressure();\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = session.sessionManager.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\tif (initialMessage) {\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tawait session.prompt(message);\n\t\t}\n\n\t\tif (mode === \"text\") {\n\t\t\t// A budget stop can settle after a tool result with no assistant message,\n\t\t\t// so it is reported from the structured stop reason rather than inferred\n\t\t\t// from the last message.\n\t\t\tif (lastStopReason?.kind === \"budget-exhausted\") {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Run stopped: the ${lastStopReason.limit.replace(/-/g, \" \")} budget was exhausted (runBudget settings).`,\n\t\t\t\t);\n\t\t\t\texitCode = 1;\n\t\t\t} else {\n\t\t\t\tconst state = session.state;\n\t\t\t\tconst lastMessage = state.messages[state.messages.length - 1];\n\n\t\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\t\tconst assistantMsg = lastMessage as AssistantMessage;\n\t\t\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\t\t\tconsole.error(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);\n\t\t\t\t\t\texitCode = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const content of assistantMsg.content) {\n\t\t\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"print-mode.js","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `pi -p \"prompt\"` - text output\n * - `pi --mode json \"prompt\"` - JSON event stream\n */\n\nimport type { AssistantMessage, ImageContent } from \"@earendil-works/pi-ai\";\nimport type { AgentStopReason } from \"apex-code-agent-core\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport { flushRawStdout, waitForRawStdoutBackpressure, writeRawStdout } from \"../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\nimport { toJsonEvent } from \"./json-event.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Terminal status of a non-interactive run, written as the `result` envelope in\n * JSON mode. The vocabulary is `AgentStopReason`'s own, rather than a second one\n * defined here, so the two cannot drift.\n */\ntype PrintRunStatus = AgentStopReason[\"kind\"];\n\ninterface PrintRunOutcome {\n\tstatus: PrintRunStatus;\n\t/** What text mode prints to stderr. Empty when the run completed. */\n\tmessage: string;\n}\n\n/**\n * Resolve the run's terminal outcome.\n *\n * `agent_end`'s structured stop reason wins because the loop already applied its\n * documented precedence (aborted > error > budget > completed) to produce it. The\n * settled assistant message is only a fallback, for the runs that end without an\n * `agent_end` reaching this mode at all.\n */\nfunction resolveRunOutcome(\n\tstopReason: AgentStopReason | undefined,\n\tsettled: AssistantMessage | undefined,\n): PrintRunOutcome {\n\tif (stopReason?.kind === \"budget-exhausted\") {\n\t\tconst limit = stopReason.limit.replace(/-/g, \" \");\n\t\treturn {\n\t\t\tstatus: \"budget-exhausted\",\n\t\t\tmessage: `Run stopped: the ${limit} budget was exhausted (runBudget settings).`,\n\t\t};\n\t}\n\tconst failed = (reason: \"aborted\" | \"error\"): PrintRunOutcome => ({\n\t\tstatus: reason,\n\t\tmessage: settled?.errorMessage || `Request ${reason}`,\n\t});\n\tconst completed: PrintRunOutcome = { status: \"completed\", message: \"\" };\n\n\t// A stop reason answers the question by itself, including when it says the run\n\t// completed. Reading the settled message in that case would let one left over\n\t// from an earlier failed turn outrank what the loop concluded.\n\tif (stopReason !== undefined) {\n\t\treturn stopReason.kind === \"aborted\" || stopReason.kind === \"error\" ? failed(stopReason.kind) : completed;\n\t}\n\tif (settled?.stopReason === \"aborted\" || settled?.stopReason === \"error\") {\n\t\treturn failed(settled.stopReason);\n\t}\n\treturn completed;\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet unsubscribeBackpressure: (() => void) | undefined;\n\tlet disposed = false;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\t// Structured terminal outcome of the last run (spec 2026-09-01-tool-reliability-\n\t// and-execution-budgets.md); surfaced in this mode's native form below.\n\tlet lastStopReason: AgentStopReason | undefined;\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeHost.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tawait session.bindExtensions({\n\t\t\tmode: mode === \"json\" ? \"json\" : \"print\",\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.waitForIdle(),\n\t\t\t\tnewSession: async (newSessionOptions) => runtimeHost.newSession(newSessionOptions),\n\t\t\t\tfork: async (entryId, forkOptions) => {\n\t\t\t\t\tconst result = await runtimeHost.fork(entryId, forkOptions);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, navigateOptions) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, {\n\t\t\t\t\t\tsummarize: navigateOptions?.summarize,\n\t\t\t\t\t\tcustomInstructions: navigateOptions?.customInstructions,\n\t\t\t\t\t\treplaceInstructions: navigateOptions?.replaceInstructions,\n\t\t\t\t\t\tlabel: navigateOptions?.label,\n\t\t\t\t\t});\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: async (sessionPath, switchOptions) => {\n\t\t\t\t\treturn runtimeHost.switchSession(sessionPath, switchOptions);\n\t\t\t\t},\n\t\t\t\treload: async () => {\n\t\t\t\t\tawait session.reload();\n\t\t\t\t},\n\t\t\t},\n\t\t\tonError: (err) => {\n\t\t\t\tconsole.error(`Extension error (${err.extensionPath}): ${err.error}`);\n\t\t\t},\n\t\t});\n\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tunsubscribe = session.subscribe((event) => {\n\t\t\tif (event.type === \"agent_end\") {\n\t\t\t\tlastStopReason = event.stopReason;\n\t\t\t}\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(toJsonEvent(event))}\\n`);\n\t\t\t}\n\t\t});\n\t\tunsubscribeBackpressure =\n\t\t\tmode === \"json\"\n\t\t\t\t? session.agent.subscribe(async () => {\n\t\t\t\t\t\tawait waitForRawStdoutBackpressure();\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = session.sessionManager.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\tif (initialMessage) {\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tawait session.prompt(message);\n\t\t}\n\n\t\t// The outcome is resolved once, for every mode. Deciding it inside the text\n\t\t// branch is what let a failed `--mode json` run exit 0: the stream carried the\n\t\t// error and the exit code reported success.\n\t\tconst lastMessage = session.state.messages[session.state.messages.length - 1];\n\t\tconst outcome = resolveRunOutcome(\n\t\t\tlastStopReason,\n\t\t\tlastMessage?.role === \"assistant\" ? (lastMessage as AssistantMessage) : undefined,\n\t\t);\n\t\texitCode = outcome.status === \"completed\" ? 0 : 1;\n\n\t\tif (mode === \"json\") {\n\t\t\twriteRawStdout(`${JSON.stringify({ type: \"result\", status: outcome.status })}\\n`);\n\t\t} else if (outcome.status === \"completed\") {\n\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\tfor (const content of (lastMessage as AssistantMessage).content) {\n\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.error(outcome.message);\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
|
package/docs/json.md
CHANGED
|
@@ -96,3 +96,39 @@ fields. `message_end` contains the final authoritative message.
|
|
|
96
96
|
```bash
|
|
97
97
|
apex-code --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
|
|
98
98
|
```
|
|
99
|
+
|
|
100
|
+
## Result envelope and exit codes
|
|
101
|
+
|
|
102
|
+
A `--mode json` run that reaches a normal terminal outcome ends with a `result` envelope.
|
|
103
|
+
It is written by print mode rather than emitted by the session, so it is not an
|
|
104
|
+
`AgentSessionEvent` and does not appear in `--mode text`. A run killed by `SIGTERM` or
|
|
105
|
+
`SIGHUP` exits from the signal handler before the envelope is written, so a consumer
|
|
106
|
+
treats a missing envelope as an incomplete run rather than as a success.
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{"type":"result","status":"completed"}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`status` is the run's terminal outcome, using the same vocabulary as the agent loop's
|
|
113
|
+
`AgentStopReason`:
|
|
114
|
+
|
|
115
|
+
| `status` | Meaning | Exit code |
|
|
116
|
+
| --- | --- | --- |
|
|
117
|
+
| `completed` | The run finished normally. | `0` |
|
|
118
|
+
| `error` | The run failed, for example a provider error. | `1` |
|
|
119
|
+
| `aborted` | The run was cancelled. | `1` |
|
|
120
|
+
| `budget-exhausted` | A `runBudget` limit stopped the run. | `1` |
|
|
121
|
+
|
|
122
|
+
Exit codes are `0` for `completed` and `1` for every other status. A caller that needs to
|
|
123
|
+
distinguish the causes reads `status` rather than the exit code, so new statuses can be
|
|
124
|
+
added without changing what an existing script sees. Signals are unchanged: `SIGTERM` exits
|
|
125
|
+
`143` and `SIGHUP` exits `129`.
|
|
126
|
+
|
|
127
|
+
Before this envelope existed, a failed `--mode json` run exited `0`, because the exit-code
|
|
128
|
+
decision was reachable only from `--mode text`. Scripts written against that behavior treated
|
|
129
|
+
every run as a success.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
apex-code --mode json --permission-mode plan --print "Summarize the repository" \
|
|
133
|
+
| jq -r 'select(.type == "result") | .status'
|
|
134
|
+
```
|
package/docs/settings.md
CHANGED
|
@@ -56,7 +56,7 @@ Use `/trust` in interactive mode to save a project trust decision for future ses
|
|
|
56
56
|
| `externalEditor` | string | `$VISUAL`, then `$EDITOR`, then Notepad on Windows or `nano` elsewhere | Command for Ctrl+G external editor; takes precedence over environment variables |
|
|
57
57
|
| `quietStartup` | boolean | `false` | Hide startup header |
|
|
58
58
|
| `defaultProjectTrust` | string | `"ask"` | Fallback project trust behavior: `"ask"`, `"always"`, or `"never"`. Global setting only |
|
|
59
|
-
| `collapseChangelog` | boolean | `
|
|
59
|
+
| `collapseChangelog` | boolean | `true` | Show one line after an update instead of the full release notes; `/changelog` shows them |
|
|
60
60
|
| `doubleEscapeAction` | string | `"tree"` | Action for double-escape: `"tree"`, `"fork"`, or `"none"` |
|
|
61
61
|
| `treeFilterMode` | string | `"default"` | Default filter for `/tree`: `"default"`, `"no-tools"`, `"user-only"`, `"labeled-only"`, `"all"` |
|
|
62
62
|
| `editorPaddingX` | number | `0` | Horizontal padding for input editor (0-3) |
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apex-code",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "apex-code",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.5.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@earendil-works/pi-ai": "^0.84.4",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@modelcontextprotocol/client": "2.0.0",
|
|
17
17
|
"@modelcontextprotocol/core": "2.0.0",
|
|
18
18
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
19
|
-
"apex-code-agent-core": "0.
|
|
19
|
+
"apex-code-agent-core": "0.5.0",
|
|
20
20
|
"chalk": "5.6.2",
|
|
21
21
|
"cross-spawn": "7.0.6",
|
|
22
22
|
"diff": "9.0.0",
|
|
@@ -1085,8 +1085,8 @@
|
|
|
1085
1085
|
}
|
|
1086
1086
|
},
|
|
1087
1087
|
"node_modules/apex-code-agent-core": {
|
|
1088
|
-
"version": "0.
|
|
1089
|
-
"resolved": "https://registry.npmjs.org/apex-code-agent-core/-/apex-code-agent-core-0.
|
|
1088
|
+
"version": "0.5.0",
|
|
1089
|
+
"resolved": "https://registry.npmjs.org/apex-code-agent-core/-/apex-code-agent-core-0.5.0.tgz",
|
|
1090
1090
|
"license": "MIT",
|
|
1091
1091
|
"dependencies": {
|
|
1092
1092
|
"@earendil-works/pi-ai": "^0.84.4",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apex-code",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@modelcontextprotocol/client": "2.0.0",
|
|
51
51
|
"@modelcontextprotocol/core": "2.0.0",
|
|
52
52
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
53
|
-
"apex-code-agent-core": "0.
|
|
53
|
+
"apex-code-agent-core": "0.5.0",
|
|
54
54
|
"chalk": "5.6.2",
|
|
55
55
|
"cross-spawn": "7.0.6",
|
|
56
56
|
"diff": "9.0.0",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Put the accent spine in the first padding column of an already-rendered line.
|
|
3
|
-
*
|
|
4
|
-
* Both message components render their children with `outputPad` leading spaces, so the
|
|
5
|
-
* first column is padding and is free to take. Prefixing the spine instead makes the line
|
|
6
|
-
* one column wider than the width it was rendered for, and nothing downstream re-flows it:
|
|
7
|
-
* the user-message line then overflows the terminal by one column, and the assistant path
|
|
8
|
-
* hands it to `truncateToWidth`, which clips real content and appends an ellipsis.
|
|
9
|
-
*
|
|
10
|
-
* A line that does not start with a padding column is returned unchanged, because there is
|
|
11
|
-
* no free column to take and widening it is the defect this exists to avoid.
|
|
12
|
-
*/
|
|
13
|
-
export declare function withAccentSpine(line: string): string;
|
|
14
|
-
//# sourceMappingURL=message-spine.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message-spine.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/message-spine.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpD","sourcesContent":["import { theme } from \"../theme/theme.ts\";\n\n/**\n * Put the accent spine in the first padding column of an already-rendered line.\n *\n * Both message components render their children with `outputPad` leading spaces, so the\n * first column is padding and is free to take. Prefixing the spine instead makes the line\n * one column wider than the width it was rendered for, and nothing downstream re-flows it:\n * the user-message line then overflows the terminal by one column, and the assistant path\n * hands it to `truncateToWidth`, which clips real content and appends an ellipsis.\n *\n * A line that does not start with a padding column is returned unchanged, because there is\n * no free column to take and widening it is the defect this exists to avoid.\n */\nexport function withAccentSpine(line: string): string {\n\tif (!line.startsWith(\" \")) return line;\n\treturn theme.fg(\"accent\", \"│\") + line.slice(1);\n}\n"]}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { theme } from "../theme/theme.js";
|
|
2
|
-
/**
|
|
3
|
-
* Put the accent spine in the first padding column of an already-rendered line.
|
|
4
|
-
*
|
|
5
|
-
* Both message components render their children with `outputPad` leading spaces, so the
|
|
6
|
-
* first column is padding and is free to take. Prefixing the spine instead makes the line
|
|
7
|
-
* one column wider than the width it was rendered for, and nothing downstream re-flows it:
|
|
8
|
-
* the user-message line then overflows the terminal by one column, and the assistant path
|
|
9
|
-
* hands it to `truncateToWidth`, which clips real content and appends an ellipsis.
|
|
10
|
-
*
|
|
11
|
-
* A line that does not start with a padding column is returned unchanged, because there is
|
|
12
|
-
* no free column to take and widening it is the defect this exists to avoid.
|
|
13
|
-
*/
|
|
14
|
-
export function withAccentSpine(line) {
|
|
15
|
-
if (!line.startsWith(" "))
|
|
16
|
-
return line;
|
|
17
|
-
return theme.fg("accent", "│") + line.slice(1);
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=message-spine.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message-spine.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/message-spine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAU;IACrD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAAA,CAC/C","sourcesContent":["import { theme } from \"../theme/theme.ts\";\n\n/**\n * Put the accent spine in the first padding column of an already-rendered line.\n *\n * Both message components render their children with `outputPad` leading spaces, so the\n * first column is padding and is free to take. Prefixing the spine instead makes the line\n * one column wider than the width it was rendered for, and nothing downstream re-flows it:\n * the user-message line then overflows the terminal by one column, and the assistant path\n * hands it to `truncateToWidth`, which clips real content and appends an ellipsis.\n *\n * A line that does not start with a padding column is returned unchanged, because there is\n * no free column to take and widening it is the defect this exists to avoid.\n */\nexport function withAccentSpine(line: string): string {\n\tif (!line.startsWith(\" \")) return line;\n\treturn theme.fg(\"accent\", \"│\") + line.slice(1);\n}\n"]}
|