@bastani/atomic 0.8.24-alpha.2 → 0.8.24-alpha.4
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/README.md +2 -1
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +12 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +16 -0
- package/dist/builtin/subagents/README.md +132 -21
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/prompts/parallel-context-build.md +4 -2
- package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +3 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +49 -11
- package/dist/builtin/subagents/src/agents/agent-management.ts +79 -16
- package/dist/builtin/subagents/src/agents/agents.ts +47 -16
- package/dist/builtin/subagents/src/agents/chain-serializer.ts +114 -0
- package/dist/builtin/subagents/src/extension/schemas.ts +139 -3
- package/dist/builtin/subagents/src/runs/background/async-execution.ts +92 -6
- package/dist/builtin/subagents/src/runs/background/async-status.ts +11 -1
- package/dist/builtin/subagents/src/runs/background/run-status.ts +4 -1
- package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +529 -32
- package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +361 -118
- package/dist/builtin/subagents/src/runs/foreground/execution.ts +75 -7
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +33 -0
- package/dist/builtin/subagents/src/runs/shared/acceptance.ts +611 -0
- package/dist/builtin/subagents/src/runs/shared/chain-outputs.ts +101 -0
- package/dist/builtin/subagents/src/runs/shared/dynamic-fanout.ts +293 -0
- package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +29 -1
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +11 -0
- package/dist/builtin/subagents/src/runs/shared/structured-output.ts +79 -0
- package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +52 -2
- package/dist/builtin/subagents/src/runs/shared/workflow-graph.ts +206 -0
- package/dist/builtin/subagents/src/shared/formatters.ts +2 -2
- package/dist/builtin/subagents/src/shared/settings.ts +53 -4
- package/dist/builtin/subagents/src/shared/types.ts +226 -0
- package/dist/builtin/subagents/src/shared/utils.ts +2 -1
- package/dist/builtin/subagents/src/slash/slash-commands.ts +41 -3
- package/dist/builtin/subagents/src/tui/render.ts +152 -34
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/create-spec/SKILL.md +1 -1
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +0 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +4 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/usage.md +1 -0
- package/docs/workflows.md +173 -0
- package/node_modules/@earendil-works/pi-tui/README.md +779 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +54 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +632 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts +22 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.js +104 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts +22 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js +35 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +249 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +1857 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts +28 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.js +89 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts +37 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js +378 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts +31 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.js +69 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +96 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +644 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +50 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +159 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts +50 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js +185 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts +12 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js +23 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts +19 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.js +89 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts +13 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js +51 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts +39 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.js +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +16 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +110 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +23 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.js +32 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +193 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +174 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts +184 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.js +1173 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts +28 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js +44 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts +3 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js +53 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +50 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +361 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +90 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +366 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +113 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +472 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +227 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +1106 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts +17 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js +25 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +84 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +1029 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +25 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +96 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/pi-tui/package.json +47 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +21 -0
- package/node_modules/get-east-asian-width/lookup.js +138 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/marked/LICENSE.md +44 -0
- package/node_modules/marked/README.md +106 -0
- package/node_modules/marked/bin/main.js +282 -0
- package/node_modules/marked/bin/marked.js +15 -0
- package/node_modules/marked/lib/marked.cjs +2211 -0
- package/node_modules/marked/lib/marked.cjs.map +7 -0
- package/node_modules/marked/lib/marked.d.cts +728 -0
- package/node_modules/marked/lib/marked.d.ts +728 -0
- package/node_modules/marked/lib/marked.esm.js +2189 -0
- package/node_modules/marked/lib/marked.esm.js.map +7 -0
- package/node_modules/marked/lib/marked.umd.js +2213 -0
- package/node_modules/marked/lib/marked.umd.js.map +7 -0
- package/node_modules/marked/man/marked.1 +111 -0
- package/node_modules/marked/man/marked.1.md +92 -0
- package/node_modules/marked/marked.min.js +69 -0
- package/node_modules/marked/package.json +111 -0
- package/package.json +9 -1
|
@@ -5,7 +5,8 @@ import type { ExtensionAPI, ExtensionContext } from "@bastani/atomic";
|
|
|
5
5
|
import { Key, matchesKey } from "@earendil-works/pi-tui";
|
|
6
6
|
import { discoverAgents, discoverAgentsAll, type ChainConfig } from "../agents/agents.ts";
|
|
7
7
|
import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
|
|
8
|
-
import { isParallelStep, type ChainStep } from "../shared/settings.ts";
|
|
8
|
+
import { isDynamicParallelStep, isParallelStep, type ChainStep } from "../shared/settings.ts";
|
|
9
|
+
import { assertJsonSchemaObject } from "../runs/shared/structured-output.ts";
|
|
9
10
|
import type { SlashSubagentResponse, SlashSubagentUpdate } from "./slash-bridge.ts";
|
|
10
11
|
import {
|
|
11
12
|
applySlashUpdate,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
SLASH_SUBAGENT_RESPONSE_EVENT,
|
|
21
22
|
SLASH_SUBAGENT_STARTED_EVENT,
|
|
22
23
|
SLASH_SUBAGENT_UPDATE_EVENT,
|
|
24
|
+
type JsonSchemaObject,
|
|
23
25
|
type SingleResult,
|
|
24
26
|
type SubagentState,
|
|
25
27
|
} from "../shared/types.ts";
|
|
@@ -123,12 +125,48 @@ const makeChainCompletions = (state: SubagentState) => (prefix: string) => {
|
|
|
123
125
|
.map((chain) => ({ value: chain.name, label: chain.name }));
|
|
124
126
|
};
|
|
125
127
|
|
|
128
|
+
function loadSavedOutputSchema(chain: ChainConfig, stepAgent: string, outputSchema: unknown): JsonSchemaObject | undefined {
|
|
129
|
+
if (outputSchema === undefined) return undefined;
|
|
130
|
+
if (typeof outputSchema === "string") {
|
|
131
|
+
const schemaPath = path.isAbsolute(outputSchema)
|
|
132
|
+
? outputSchema
|
|
133
|
+
: path.join(path.dirname(chain.filePath), outputSchema);
|
|
134
|
+
const parsed = JSON.parse(fs.readFileSync(schemaPath, "utf-8")) as unknown;
|
|
135
|
+
assertJsonSchemaObject(parsed, `outputSchema for chain '${chain.name}' step '${stepAgent}' (${schemaPath})`);
|
|
136
|
+
return parsed;
|
|
137
|
+
}
|
|
138
|
+
assertJsonSchemaObject(outputSchema, `outputSchema for chain '${chain.name}' step '${stepAgent}'`);
|
|
139
|
+
return outputSchema;
|
|
140
|
+
}
|
|
141
|
+
|
|
126
142
|
const mapSavedChainSteps = (chain: ChainConfig, worktree = false): ChainStep[] => {
|
|
127
|
-
return (chain.steps as Array<ChainStep & { skills?: string[] | false }>).map((step) => {
|
|
128
|
-
if (isParallelStep(step))
|
|
143
|
+
return (chain.steps as unknown as Array<ChainStep & { skills?: string[] | false }>).map((step) => {
|
|
144
|
+
if (isParallelStep(step)) {
|
|
145
|
+
const parallel = step.parallel.map((task) => {
|
|
146
|
+
const { outputSchema: rawOutputSchema, ...rest } = task as typeof task & { outputSchema?: unknown };
|
|
147
|
+
const outputSchema = loadSavedOutputSchema(chain, task.agent, rawOutputSchema);
|
|
148
|
+
return { ...rest, ...(outputSchema ? { outputSchema } : {}) };
|
|
149
|
+
});
|
|
150
|
+
return { ...step, parallel, ...(worktree ? { worktree: true } : {}) };
|
|
151
|
+
}
|
|
152
|
+
if (isDynamicParallelStep(step)) {
|
|
153
|
+
const { outputSchema: rawOutputSchema, ...parallelRest } = step.parallel as typeof step.parallel & { outputSchema?: unknown };
|
|
154
|
+
const outputSchema = loadSavedOutputSchema(chain, step.parallel.agent, rawOutputSchema);
|
|
155
|
+
const collectSchema = loadSavedOutputSchema(chain, `${step.collect.as} collection`, step.collect.outputSchema);
|
|
156
|
+
return {
|
|
157
|
+
...step,
|
|
158
|
+
parallel: { ...parallelRest, ...(outputSchema ? { outputSchema } : {}) },
|
|
159
|
+
collect: { ...step.collect, ...(collectSchema ? { outputSchema: collectSchema } : {}) },
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const outputSchema = loadSavedOutputSchema(chain, step.agent, (step as { outputSchema?: unknown }).outputSchema);
|
|
129
163
|
return {
|
|
130
164
|
agent: step.agent,
|
|
131
165
|
task: step.task || undefined,
|
|
166
|
+
...(step.phase ? { phase: step.phase } : {}),
|
|
167
|
+
...(step.label ? { label: step.label } : {}),
|
|
168
|
+
...(step.as ? { as: step.as } : {}),
|
|
169
|
+
...(outputSchema ? { outputSchema } : {}),
|
|
132
170
|
output: step.output,
|
|
133
171
|
outputMode: step.outputMode,
|
|
134
172
|
reads: step.reads,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
type Details,
|
|
15
15
|
type NestedRunSummary,
|
|
16
16
|
type NestedStepSummary,
|
|
17
|
+
type WorkflowNodeStatus,
|
|
17
18
|
MAX_WIDGET_JOBS,
|
|
18
19
|
WIDGET_KEY,
|
|
19
20
|
} from "../shared/types.ts";
|
|
@@ -305,6 +306,7 @@ function resultStatusLine(result: Details["results"][number], output: string): s
|
|
|
305
306
|
if (result.detached) return result.detachedReason ? `Detached: ${result.detachedReason}` : "Detached";
|
|
306
307
|
if (result.interrupted) return "Paused";
|
|
307
308
|
if (result.exitCode !== 0) return `Error: ${result.error ?? (firstOutputLine(output) || `exit ${result.exitCode}`)}`;
|
|
309
|
+
if (result.acceptance?.status && result.acceptance.status !== "not-required") return `Done · acceptance: ${result.acceptance.status}`;
|
|
308
310
|
if (hasEmptyTextOutputWithoutOutputTarget(result.task, output)) return "Done (no text output)";
|
|
309
311
|
return "Done";
|
|
310
312
|
}
|
|
@@ -507,26 +509,44 @@ function parseParallelGroupAgentCount(label: string | undefined): number | undef
|
|
|
507
509
|
return inner.split("+").map((part) => part.trim()).filter(Boolean).length;
|
|
508
510
|
}
|
|
509
511
|
|
|
510
|
-
function isChainParallelGroupActive(details: Pick<Details, "mode" | "chainAgents" | "currentStepIndex">): boolean {
|
|
511
|
-
if (details.mode !== "chain") return false;
|
|
512
|
-
if (details.currentStepIndex === undefined) return false;
|
|
513
|
-
const currentLabel = details.chainAgents?.[details.currentStepIndex];
|
|
514
|
-
return parseParallelGroupAgentCount(currentLabel) !== undefined;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
512
|
interface ChainStepSpan {
|
|
518
513
|
stepIndex: number;
|
|
519
514
|
start: number;
|
|
520
515
|
count: number;
|
|
521
516
|
isParallel: boolean;
|
|
522
|
-
|
|
517
|
+
status?: WorkflowNodeStatus;
|
|
518
|
+
label?: string;
|
|
519
|
+
error?: string;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function buildChainStepSpans(details: Pick<Details, "chainAgents" | "workflowGraph">): ChainStepSpan[] {
|
|
523
|
+
if (details.workflowGraph?.nodes?.length) {
|
|
524
|
+
const spans: ChainStepSpan[] = [];
|
|
525
|
+
let flatCursor = 0;
|
|
526
|
+
for (const node of details.workflowGraph.nodes) {
|
|
527
|
+
if (node.stepIndex === undefined) continue;
|
|
528
|
+
if (node.kind === "parallel-group" || node.kind === "dynamic-parallel-group") {
|
|
529
|
+
const childFlatIndexes = (node.children ?? [])
|
|
530
|
+
.map((child) => child.flatIndex)
|
|
531
|
+
.filter((value): value is number => typeof value === "number");
|
|
532
|
+
const start = childFlatIndexes.length ? Math.min(...childFlatIndexes) : flatCursor;
|
|
533
|
+
const count = node.children?.length ?? 0;
|
|
534
|
+
spans.push({ stepIndex: node.stepIndex, start, count, isParallel: true, status: node.status, label: node.label, error: node.error });
|
|
535
|
+
flatCursor = Math.max(flatCursor, start + count);
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
const start = node.flatIndex ?? flatCursor;
|
|
539
|
+
spans.push({ stepIndex: node.stepIndex, start, count: 1, isParallel: false, status: node.status, label: node.label, error: node.error });
|
|
540
|
+
flatCursor = Math.max(flatCursor, start + 1);
|
|
541
|
+
}
|
|
542
|
+
if (spans.length) return spans.sort((left, right) => left.stepIndex - right.stepIndex);
|
|
543
|
+
}
|
|
523
544
|
|
|
524
|
-
|
|
525
|
-
if (!chainAgents?.length) return [];
|
|
545
|
+
if (!details.chainAgents?.length) return [];
|
|
526
546
|
const spans: ChainStepSpan[] = [];
|
|
527
547
|
let start = 0;
|
|
528
|
-
for (let stepIndex = 0; stepIndex < chainAgents.length; stepIndex++) {
|
|
529
|
-
const label = chainAgents[stepIndex]!;
|
|
548
|
+
for (let stepIndex = 0; stepIndex < details.chainAgents.length; stepIndex++) {
|
|
549
|
+
const label = details.chainAgents[stepIndex]!;
|
|
530
550
|
const parsedCount = parseParallelGroupAgentCount(label);
|
|
531
551
|
const count = parsedCount ?? 1;
|
|
532
552
|
spans.push({ stepIndex, start, count, isParallel: parsedCount !== undefined });
|
|
@@ -535,6 +555,12 @@ function buildChainStepSpans(chainAgents: string[] | undefined): ChainStepSpan[]
|
|
|
535
555
|
return spans;
|
|
536
556
|
}
|
|
537
557
|
|
|
558
|
+
function isChainParallelGroupActive(details: Pick<Details, "mode" | "chainAgents" | "currentStepIndex" | "workflowGraph">): boolean {
|
|
559
|
+
if (details.mode !== "chain") return false;
|
|
560
|
+
if (details.currentStepIndex === undefined) return false;
|
|
561
|
+
return buildChainStepSpans(details).some((span) => span.stepIndex === details.currentStepIndex && span.isParallel);
|
|
562
|
+
}
|
|
563
|
+
|
|
538
564
|
function buildAsyncChainStepSpans(total: number, stepCount: number, parallelGroups: AsyncParallelGroupStatus[] = []): ChainStepSpan[] {
|
|
539
565
|
const spans: ChainStepSpan[] = [];
|
|
540
566
|
let flatIndex = 0;
|
|
@@ -559,6 +585,55 @@ function isDoneResult(result: Details["results"][number]): boolean {
|
|
|
559
585
|
return result.exitCode === 0;
|
|
560
586
|
}
|
|
561
587
|
|
|
588
|
+
function workflowGraphHasStatus(details: Pick<Details, "workflowGraph">, statuses: WorkflowNodeStatus[]): boolean {
|
|
589
|
+
return details.workflowGraph?.nodes.some((node) => statuses.includes(node.status)) ?? false;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
interface ChainRenderResultEntry {
|
|
593
|
+
kind: "result";
|
|
594
|
+
resultIndex: number;
|
|
595
|
+
rowNumber: number;
|
|
596
|
+
agentName: string;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
interface ChainRenderPlaceholderEntry {
|
|
600
|
+
kind: "placeholder";
|
|
601
|
+
rowNumber: number;
|
|
602
|
+
stepLabel: string;
|
|
603
|
+
agentName: string;
|
|
604
|
+
status: WorkflowNodeStatus;
|
|
605
|
+
error?: string;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
type ChainRenderEntry = ChainRenderResultEntry | ChainRenderPlaceholderEntry;
|
|
609
|
+
|
|
610
|
+
function buildChainRenderEntries(details: Details, label: MultiProgressLabel): ChainRenderEntry[] | undefined {
|
|
611
|
+
if (details.mode !== "chain" || !label.hasParallelInChain || label.showActiveGroupOnly) return undefined;
|
|
612
|
+
const entries: ChainRenderEntry[] = [];
|
|
613
|
+
for (const span of buildChainStepSpans(details)) {
|
|
614
|
+
if (span.isParallel && span.count === 0) {
|
|
615
|
+
entries.push({
|
|
616
|
+
kind: "placeholder",
|
|
617
|
+
rowNumber: span.stepIndex + 1,
|
|
618
|
+
stepLabel: `Step ${span.stepIndex + 1}`,
|
|
619
|
+
agentName: span.label ?? details.chainAgents?.[span.stepIndex] ?? `step-${span.stepIndex + 1}`,
|
|
620
|
+
status: span.status ?? "pending",
|
|
621
|
+
error: span.error,
|
|
622
|
+
});
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
for (let index = span.start; index < span.start + span.count; index++) {
|
|
626
|
+
entries.push({
|
|
627
|
+
kind: "result",
|
|
628
|
+
resultIndex: index,
|
|
629
|
+
rowNumber: index + 1,
|
|
630
|
+
agentName: details.results[index]?.agent ?? details.chainAgents?.[span.stepIndex] ?? `step-${span.stepIndex + 1}`,
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return entries;
|
|
635
|
+
}
|
|
636
|
+
|
|
562
637
|
interface MultiProgressLabel {
|
|
563
638
|
headerLabel: string;
|
|
564
639
|
itemTitle: "Step" | "Agent";
|
|
@@ -570,8 +645,8 @@ interface MultiProgressLabel {
|
|
|
570
645
|
showActiveGroupOnly: boolean;
|
|
571
646
|
}
|
|
572
647
|
|
|
573
|
-
function buildMultiProgressLabel(details: Pick<Details, "mode" | "results" | "progress" | "totalSteps" | "currentStepIndex" | "chainAgents">, hasRunning: boolean): MultiProgressLabel {
|
|
574
|
-
const stepSpans = buildChainStepSpans(details
|
|
648
|
+
function buildMultiProgressLabel(details: Pick<Details, "mode" | "results" | "progress" | "totalSteps" | "currentStepIndex" | "chainAgents" | "workflowGraph">, hasRunning: boolean): MultiProgressLabel {
|
|
649
|
+
const stepSpans = buildChainStepSpans(details);
|
|
575
650
|
const hasParallelInChain = details.mode === "chain" && stepSpans.some((span) => span.isParallel);
|
|
576
651
|
const activeParallelGroup = isChainParallelGroupActive(details);
|
|
577
652
|
const itemTitle: "Step" | "Agent" = details.mode === "parallel" || activeParallelGroup ? "Agent" : "Step";
|
|
@@ -635,11 +710,13 @@ function buildMultiProgressLabel(details: Pick<Details, "mode" | "results" | "pr
|
|
|
635
710
|
if (details.mode === "chain" && details.chainAgents?.length) {
|
|
636
711
|
const totalCount = details.totalSteps ?? details.chainAgents.length;
|
|
637
712
|
const doneLogical = stepSpans.filter((span) => {
|
|
713
|
+
if (span.status && span.status !== "completed") return false;
|
|
714
|
+
if (span.count === 0) return span.status === "completed";
|
|
638
715
|
for (let index = span.start; index < span.start + span.count; index++) {
|
|
639
716
|
const progressEntry = details.progress?.find((progress) => progress.index === index);
|
|
640
717
|
const resultEntry = details.results.find((result) => result.progress?.index === index) ?? details.results[index];
|
|
641
|
-
if (progressEntry?.status === "running" || progressEntry?.status === "pending") return false;
|
|
642
|
-
if (resultEntry
|
|
718
|
+
if (progressEntry?.status === "running" || progressEntry?.status === "pending" || progressEntry?.status === "failed") return false;
|
|
719
|
+
if (!resultEntry || !isDoneResult(resultEntry)) return false;
|
|
643
720
|
}
|
|
644
721
|
return true;
|
|
645
722
|
}).length;
|
|
@@ -655,9 +732,9 @@ function buildMultiProgressLabel(details: Pick<Details, "mode" | "results" | "pr
|
|
|
655
732
|
return { headerLabel, itemTitle, totalCount, hasParallelInChain, activeParallelGroup, groupStartIndex: 0, groupEndIndex: details.results.length, showActiveGroupOnly: false };
|
|
656
733
|
}
|
|
657
734
|
|
|
658
|
-
function resultRowLabel(details: Pick<Details, "mode" | "chainAgents">, label: MultiProgressLabel, resultIndex: number, stepNumber: number): string {
|
|
735
|
+
function resultRowLabel(details: Pick<Details, "mode" | "chainAgents" | "workflowGraph">, label: MultiProgressLabel, resultIndex: number, stepNumber: number): string {
|
|
659
736
|
if (details.mode === "chain" && label.hasParallelInChain) {
|
|
660
|
-
const span = buildChainStepSpans(details
|
|
737
|
+
const span = buildChainStepSpans(details).find((candidate) => resultIndex >= candidate.start && resultIndex < candidate.start + candidate.count);
|
|
661
738
|
if (span?.isParallel) return `Agent ${resultIndex - span.start + 1}/${span.count}`;
|
|
662
739
|
if (span) return `Step ${span.stepIndex + 1}`;
|
|
663
740
|
}
|
|
@@ -1216,9 +1293,12 @@ function renderSingleCompact(d: Details, r: Details["results"][number], theme: T
|
|
|
1216
1293
|
|
|
1217
1294
|
function renderMultiCompact(d: Details, theme: Theme, now?: number, spinnerNow?: number): Component {
|
|
1218
1295
|
const hasRunning = d.progress?.some((p) => p.status === "running")
|
|
1219
|
-
|| d.results.some((r) => r.progress?.status === "running")
|
|
1220
|
-
|
|
1221
|
-
const
|
|
1296
|
+
|| d.results.some((r) => r.progress?.status === "running")
|
|
1297
|
+
|| workflowGraphHasStatus(d, ["running"]);
|
|
1298
|
+
const failed = d.results.some((r) => r.exitCode !== 0 && r.progress?.status !== "running")
|
|
1299
|
+
|| workflowGraphHasStatus(d, ["failed"]);
|
|
1300
|
+
const paused = d.results.some((r) => (r.interrupted || r.detached) && r.progress?.status !== "running")
|
|
1301
|
+
|| workflowGraphHasStatus(d, ["paused", "detached"]);
|
|
1222
1302
|
let totalSummary = d.progressSummary;
|
|
1223
1303
|
if (!totalSummary) {
|
|
1224
1304
|
let sawProgress = false;
|
|
@@ -1251,13 +1331,29 @@ function renderMultiCompact(d: Details, theme: Theme, now?: number, spinnerNow?:
|
|
|
1251
1331
|
const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
|
|
1252
1332
|
const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
|
|
1253
1333
|
const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents!.length);
|
|
1254
|
-
|
|
1334
|
+
const chainEntries = buildChainRenderEntries(d, multiLabel);
|
|
1335
|
+
const renderEntries = chainEntries ?? Array.from({ length: displayEnd - displayStart }, (_, offset): ChainRenderEntry => {
|
|
1336
|
+
const i = displayStart + offset;
|
|
1255
1337
|
const r = d.results[i];
|
|
1256
1338
|
const fallbackLabel = itemTitle.toLowerCase();
|
|
1257
1339
|
const rowNumber = multiLabel.showActiveGroupOnly ? (i - multiLabel.groupStartIndex + 1) : (i + 1);
|
|
1258
|
-
|
|
1340
|
+
return { kind: "result", resultIndex: i, rowNumber, agentName: useResultsDirectly ? (r?.agent || `${fallbackLabel}-${rowNumber}`) : (d.chainAgents![i] || r?.agent || `${fallbackLabel}-${rowNumber}`) };
|
|
1341
|
+
});
|
|
1342
|
+
for (const entry of renderEntries) {
|
|
1343
|
+
if (entry.kind === "placeholder") {
|
|
1344
|
+
const glyph = widgetStepGlyph(entry.status as AsyncJobStep["status"], theme);
|
|
1345
|
+
const statusLabel = widgetStepStatus(entry.status as AsyncJobStep["status"], theme);
|
|
1346
|
+
c.addChild(new Text(truncLine(` ${glyph} ${entry.stepLabel}: ${themeBold(theme, entry.agentName)} ${theme.fg("dim", "·")} ${statusLabel}`, width), 0, 0));
|
|
1347
|
+
if (entry.error) c.addChild(new Text(truncLine(theme.fg("error", ` ⎿ Error: ${entry.error}`), width), 0, 0));
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
const i = entry.resultIndex;
|
|
1351
|
+
const r = d.results[i];
|
|
1352
|
+
const rowNumber = entry.rowNumber;
|
|
1353
|
+
const agentName = entry.agentName;
|
|
1259
1354
|
if (!r) {
|
|
1260
|
-
|
|
1355
|
+
const pendingLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
|
|
1356
|
+
c.addChild(new Text(truncLine(theme.fg("dim", ` ◦ ${pendingLabel}: ${agentName} · pending`), width), 0, 0));
|
|
1261
1357
|
continue;
|
|
1262
1358
|
}
|
|
1263
1359
|
const output = getSingleResultOutput(r);
|
|
@@ -1489,20 +1585,27 @@ export function renderSubagentResult(
|
|
|
1489
1585
|
if (!expanded) return renderMultiCompact(d, theme, options.now, options.spinnerNow);
|
|
1490
1586
|
|
|
1491
1587
|
const hasRunning = d.progress?.some((p) => p.status === "running")
|
|
1492
|
-
|| d.results.some((r) => r.progress?.status === "running")
|
|
1588
|
+
|| d.results.some((r) => r.progress?.status === "running")
|
|
1589
|
+
|| workflowGraphHasStatus(d, ["running"]);
|
|
1493
1590
|
const ok = d.results.filter((r) => r.progress?.status === "completed" || (r.exitCode === 0 && r.progress?.status !== "running")).length;
|
|
1494
1591
|
const hasEmptyWithoutTarget = d.results.some((r) =>
|
|
1495
1592
|
r.exitCode === 0
|
|
1496
1593
|
&& r.progress?.status !== "running"
|
|
1497
1594
|
&& hasEmptyTextOutputWithoutOutputTarget(r.task, getSingleResultOutput(r)),
|
|
1498
1595
|
);
|
|
1596
|
+
const hasWorkflowFailure = workflowGraphHasStatus(d, ["failed"]);
|
|
1597
|
+
const hasWorkflowPause = workflowGraphHasStatus(d, ["paused", "detached"]);
|
|
1499
1598
|
const icon = hasRunning
|
|
1500
1599
|
? theme.fg("warning", "running")
|
|
1501
1600
|
: hasEmptyWithoutTarget
|
|
1502
1601
|
? theme.fg("warning", "warning")
|
|
1503
|
-
:
|
|
1504
|
-
? theme.fg("
|
|
1505
|
-
:
|
|
1602
|
+
: hasWorkflowFailure
|
|
1603
|
+
? theme.fg("error", "failed")
|
|
1604
|
+
: hasWorkflowPause
|
|
1605
|
+
? theme.fg("warning", "paused")
|
|
1606
|
+
: ok === d.results.length
|
|
1607
|
+
? theme.fg("success", "ok")
|
|
1608
|
+
: theme.fg("error", "failed");
|
|
1506
1609
|
|
|
1507
1610
|
const totalSummary =
|
|
1508
1611
|
d.progressSummary ||
|
|
@@ -1573,18 +1676,33 @@ export function renderSubagentResult(
|
|
|
1573
1676
|
const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
|
|
1574
1677
|
const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
|
|
1575
1678
|
const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents!.length);
|
|
1679
|
+
const chainEntries = buildChainRenderEntries(d, multiLabel);
|
|
1680
|
+
const renderEntries = chainEntries ?? Array.from({ length: displayEnd - displayStart }, (_, offset): ChainRenderEntry => {
|
|
1681
|
+
const i = displayStart + offset;
|
|
1682
|
+
const r = d.results[i];
|
|
1683
|
+
const rowNumber = multiLabel.showActiveGroupOnly ? (i - multiLabel.groupStartIndex + 1) : (i + 1);
|
|
1684
|
+
return { kind: "result", resultIndex: i, rowNumber, agentName: useResultsDirectly ? (r?.agent || `step-${rowNumber}`) : (d.chainAgents![i] || r?.agent || `step-${rowNumber}`) };
|
|
1685
|
+
});
|
|
1576
1686
|
|
|
1577
1687
|
c.addChild(new Spacer(1));
|
|
1578
1688
|
|
|
1579
|
-
for (
|
|
1689
|
+
for (const entry of renderEntries) {
|
|
1690
|
+
if (entry.kind === "placeholder") {
|
|
1691
|
+
const statusLabel = widgetStepStatus(entry.status as AsyncJobStep["status"], theme);
|
|
1692
|
+
c.addChild(new Text(fit(` ${statusLabel} ${entry.stepLabel}: ${theme.bold(entry.agentName)}`), 0, 0));
|
|
1693
|
+
c.addChild(new Text(theme.fg(entry.status === "failed" ? "error" : "dim", ` status: ${entry.status}`), 0, 0));
|
|
1694
|
+
if (entry.error) c.addChild(new Text(theme.fg("error", ` error: ${entry.error}`), 0, 0));
|
|
1695
|
+
c.addChild(new Spacer(1));
|
|
1696
|
+
continue;
|
|
1697
|
+
}
|
|
1698
|
+
const i = entry.resultIndex;
|
|
1580
1699
|
const r = d.results[i];
|
|
1581
|
-
const rowNumber =
|
|
1582
|
-
const agentName =
|
|
1583
|
-
? (r?.agent || `step-${rowNumber}`)
|
|
1584
|
-
: (d.chainAgents![i] || r?.agent || `step-${rowNumber}`);
|
|
1700
|
+
const rowNumber = entry.rowNumber;
|
|
1701
|
+
const agentName = entry.agentName;
|
|
1585
1702
|
|
|
1586
1703
|
if (!r) {
|
|
1587
|
-
|
|
1704
|
+
const pendingLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
|
|
1705
|
+
c.addChild(new Text(fit(theme.fg("dim", ` ${pendingLabel}: ${agentName}`)), 0, 0));
|
|
1588
1706
|
c.addChild(new Text(theme.fg("dim", ` status: pending`), 0, 0));
|
|
1589
1707
|
c.addChild(new Spacer(1));
|
|
1590
1708
|
continue;
|
|
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.8.24-alpha.4] - 2026-06-04
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Bumped package version for the Atomic 0.8.24-alpha.4 prerelease.
|
|
12
|
+
|
|
13
|
+
## [0.8.24-alpha.3] - 2026-06-03
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Bumped package version for the Atomic 0.8.24-alpha.3 prerelease.
|
|
18
|
+
|
|
7
19
|
## [0.8.24-alpha.2] - 2026-06-03
|
|
8
20
|
|
|
9
21
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.8.24-alpha.
|
|
3
|
+
"version": "0.8.24-alpha.4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
|
|
6
6
|
"contributors": [
|
|
@@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.8.24-alpha.4] - 2026-06-04
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Bumped package version for the Atomic 0.8.24-alpha.4 prerelease.
|
|
14
|
+
|
|
15
|
+
## [0.8.24-alpha.3] - 2026-06-03
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Bumped package version for the Atomic 0.8.24-alpha.3 prerelease.
|
|
20
|
+
|
|
9
21
|
## [0.8.24-alpha.2] - 2026-06-03
|
|
10
22
|
|
|
11
23
|
### Added
|
|
@@ -288,4 +288,4 @@ _Instruction: List known unknowns. These must be resolved before the doc is mark
|
|
|
288
288
|
- [ ] Is `publish_draft` the only door that moves a draft to live, or can the admin panel also publish? (If the latter, the effect is not yet funneled — rubric #8.)
|
|
289
289
|
- [ ] What exactly does `authorize_charge` promise on a partial provider outage — is the guarantee defined? (rubric #2.)
|
|
290
290
|
- [ ] Will the Legal team approve the 3rd-party library for PDF generation?
|
|
291
|
-
- [ ] Does the current VPC peering allow connection to the legacy mainframe?
|
|
291
|
+
- [ ] Does the current VPC peering allow connection to the legacy mainframe?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAO/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElE,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,CAAC,EAAE,CACxB,cAAc,EAAE,MAAM,KAClB,gBAAgB,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;CACpE;AAED,eAAO,MAAM,sBAAsB,EAAE,aAAa,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAO/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElE,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,CAAC,EAAE,CACxB,cAAc,EAAE,MAAM,KAClB,gBAAgB,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;CACpE;AAED,eAAO,MAAM,sBAAsB,EAAE,aAAa,CAAC,mBAAmB,CA6BrE,CAAC","sourcesContent":["import type { AutocompleteItem } from \"@earendil-works/pi-tui\";\nimport { APP_NAME } from \"../config.ts\";\nimport {\n\tATOMIC_GUIDE_COMMAND_DESCRIPTION,\n\tATOMIC_GUIDE_COMMAND_NAME,\n\tgetAtomicGuideArgumentCompletions,\n} from \"./atomic-guide-command.ts\";\nimport type { SourceInfo } from \"./source-info.ts\";\n\nexport type SlashCommandSource = \"extension\" | \"prompt\" | \"skill\";\n\nexport interface SlashCommandInfo {\n\tname: string;\n\tdescription?: string;\n\tsource: SlashCommandSource;\n\tsourceInfo: SourceInfo;\n}\n\nexport interface BuiltinSlashCommand {\n\tname: string;\n\tdescription: string;\n\tgetArgumentCompletions?: (\n\t\targumentPrefix: string,\n\t) => AutocompleteItem[] | null | Promise<AutocompleteItem[] | null>;\n}\n\nexport const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [\n\t{ name: \"settings\", description: \"Open settings menu\" },\n\t{ name: \"model\", description: \"Select model (opens selector UI)\" },\n\t{ name: \"scoped-models\", description: \"Enable/disable models for ctrl+p cycling\" },\n\t{ name: \"fast\", description: \"Configure Codex fast mode for chat and workflows\" },\n\t{ name: \"export\", description: \"Export session (HTML default, or specify path: .html/.jsonl)\" },\n\t{ name: \"import\", description: \"Import and resume a session from a JSONL file\" },\n\t{ name: \"share\", description: \"Share session as a secret GitHub gist\" },\n\t{ name: \"copy\", description: \"Copy last agent message to clipboard\" },\n\t{ name: \"name\", description: \"Set session display name\" },\n\t{ name: \"session\", description: \"Show session info and stats\" },\n\t{ name: \"changelog\", description: \"Show changelog entries\" },\n\t{\n\t\tname: ATOMIC_GUIDE_COMMAND_NAME,\n\t\tdescription: ATOMIC_GUIDE_COMMAND_DESCRIPTION,\n\t\tgetArgumentCompletions: getAtomicGuideArgumentCompletions,\n\t},\n\t{ name: \"hotkeys\", description: \"Show all keyboard shortcuts\" },\n\t{ name: \"fork\", description: \"Create a new fork from a previous user message\" },\n\t{ name: \"clone\", description: \"Duplicate the current session at the current position\" },\n\t{ name: \"tree\", description: \"Navigate session tree (switch branches)\" },\n\t{ name: \"login\", description: \"Configure provider authentication\" },\n\t{ name: \"logout\", description: \"Remove provider authentication\" },\n\t{ name: \"new\", description: \"Start a new session\" },\n\t{ name: \"compact\", description: \"Manually compact the session context\" },\n\t{ name: \"resume\", description: \"Resume a different session\" },\n\t{ name: \"reload\", description: \"Reload keybindings, extensions, skills, prompts, and themes\" },\n\t{ name: \"exit\", description: `Exit ${APP_NAME}` },\n\t{ name: \"quit\", description: `Quit ${APP_NAME}` },\n];\n"]}
|
|
@@ -27,6 +27,7 @@ export const BUILTIN_SLASH_COMMANDS = [
|
|
|
27
27
|
{ name: "compact", description: "Manually compact the session context" },
|
|
28
28
|
{ name: "resume", description: "Resume a different session" },
|
|
29
29
|
{ name: "reload", description: "Reload keybindings, extensions, skills, prompts, and themes" },
|
|
30
|
+
{ name: "exit", description: `Exit ${APP_NAME}` },
|
|
30
31
|
{ name: "quit", description: `Quit ${APP_NAME}` },
|
|
31
32
|
];
|
|
32
33
|
//# sourceMappingURL=slash-commands.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EACN,gCAAgC,EAChC,yBAAyB,EACzB,iCAAiC,GACjC,MAAM,2BAA2B,CAAC;AAoBnC,MAAM,CAAC,MAAM,sBAAsB,GAAuC;IACzE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACvD,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,kCAAkC,EAAE;IAClE,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,0CAA0C,EAAE;IAClF,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,kDAAkD,EAAE;IACjF,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8DAA8D,EAAE;IAC/F,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;IAChF,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,uCAAuC,EAAE;IACvE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,sCAAsC,EAAE;IACrE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,0BAA0B,EAAE;IACzD,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,6BAA6B,EAAE;IAC/D,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,wBAAwB,EAAE;IAC5D;QACC,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,gCAAgC;QAC7C,sBAAsB,EAAE,iCAAiC;KACzD;IACD,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,6BAA6B,EAAE;IAC/D,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,gDAAgD,EAAE;IAC/E,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,uDAAuD,EAAE;IACvF,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,yCAAyC,EAAE;IACxE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,mCAAmC,EAAE;IACnE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACjE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE;IACnD,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,sCAAsC,EAAE;IACxE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,4BAA4B,EAAE;IAC7D,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6DAA6D,EAAE;IAC9F,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,QAAQ,EAAE,EAAE;CACjD,CAAC","sourcesContent":["import type { AutocompleteItem } from \"@earendil-works/pi-tui\";\nimport { APP_NAME } from \"../config.ts\";\nimport {\n\tATOMIC_GUIDE_COMMAND_DESCRIPTION,\n\tATOMIC_GUIDE_COMMAND_NAME,\n\tgetAtomicGuideArgumentCompletions,\n} from \"./atomic-guide-command.ts\";\nimport type { SourceInfo } from \"./source-info.ts\";\n\nexport type SlashCommandSource = \"extension\" | \"prompt\" | \"skill\";\n\nexport interface SlashCommandInfo {\n\tname: string;\n\tdescription?: string;\n\tsource: SlashCommandSource;\n\tsourceInfo: SourceInfo;\n}\n\nexport interface BuiltinSlashCommand {\n\tname: string;\n\tdescription: string;\n\tgetArgumentCompletions?: (\n\t\targumentPrefix: string,\n\t) => AutocompleteItem[] | null | Promise<AutocompleteItem[] | null>;\n}\n\nexport const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [\n\t{ name: \"settings\", description: \"Open settings menu\" },\n\t{ name: \"model\", description: \"Select model (opens selector UI)\" },\n\t{ name: \"scoped-models\", description: \"Enable/disable models for ctrl+p cycling\" },\n\t{ name: \"fast\", description: \"Configure Codex fast mode for chat and workflows\" },\n\t{ name: \"export\", description: \"Export session (HTML default, or specify path: .html/.jsonl)\" },\n\t{ name: \"import\", description: \"Import and resume a session from a JSONL file\" },\n\t{ name: \"share\", description: \"Share session as a secret GitHub gist\" },\n\t{ name: \"copy\", description: \"Copy last agent message to clipboard\" },\n\t{ name: \"name\", description: \"Set session display name\" },\n\t{ name: \"session\", description: \"Show session info and stats\" },\n\t{ name: \"changelog\", description: \"Show changelog entries\" },\n\t{\n\t\tname: ATOMIC_GUIDE_COMMAND_NAME,\n\t\tdescription: ATOMIC_GUIDE_COMMAND_DESCRIPTION,\n\t\tgetArgumentCompletions: getAtomicGuideArgumentCompletions,\n\t},\n\t{ name: \"hotkeys\", description: \"Show all keyboard shortcuts\" },\n\t{ name: \"fork\", description: \"Create a new fork from a previous user message\" },\n\t{ name: \"clone\", description: \"Duplicate the current session at the current position\" },\n\t{ name: \"tree\", description: \"Navigate session tree (switch branches)\" },\n\t{ name: \"login\", description: \"Configure provider authentication\" },\n\t{ name: \"logout\", description: \"Remove provider authentication\" },\n\t{ name: \"new\", description: \"Start a new session\" },\n\t{ name: \"compact\", description: \"Manually compact the session context\" },\n\t{ name: \"resume\", description: \"Resume a different session\" },\n\t{ name: \"reload\", description: \"Reload keybindings, extensions, skills, prompts, and themes\" },\n\t{ name: \"quit\", description: `Quit ${APP_NAME}` },\n];\n"]}
|
|
1
|
+
{"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EACN,gCAAgC,EAChC,yBAAyB,EACzB,iCAAiC,GACjC,MAAM,2BAA2B,CAAC;AAoBnC,MAAM,CAAC,MAAM,sBAAsB,GAAuC;IACzE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACvD,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,kCAAkC,EAAE;IAClE,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,0CAA0C,EAAE;IAClF,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,kDAAkD,EAAE;IACjF,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8DAA8D,EAAE;IAC/F,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;IAChF,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,uCAAuC,EAAE;IACvE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,sCAAsC,EAAE;IACrE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,0BAA0B,EAAE;IACzD,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,6BAA6B,EAAE;IAC/D,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,wBAAwB,EAAE;IAC5D;QACC,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,gCAAgC;QAC7C,sBAAsB,EAAE,iCAAiC;KACzD;IACD,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,6BAA6B,EAAE;IAC/D,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,gDAAgD,EAAE;IAC/E,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,uDAAuD,EAAE;IACvF,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,yCAAyC,EAAE;IACxE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,mCAAmC,EAAE;IACnE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACjE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE;IACnD,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,sCAAsC,EAAE;IACxE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,4BAA4B,EAAE;IAC7D,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6DAA6D,EAAE;IAC9F,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,QAAQ,EAAE,EAAE;IACjD,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,QAAQ,EAAE,EAAE;CACjD,CAAC","sourcesContent":["import type { AutocompleteItem } from \"@earendil-works/pi-tui\";\nimport { APP_NAME } from \"../config.ts\";\nimport {\n\tATOMIC_GUIDE_COMMAND_DESCRIPTION,\n\tATOMIC_GUIDE_COMMAND_NAME,\n\tgetAtomicGuideArgumentCompletions,\n} from \"./atomic-guide-command.ts\";\nimport type { SourceInfo } from \"./source-info.ts\";\n\nexport type SlashCommandSource = \"extension\" | \"prompt\" | \"skill\";\n\nexport interface SlashCommandInfo {\n\tname: string;\n\tdescription?: string;\n\tsource: SlashCommandSource;\n\tsourceInfo: SourceInfo;\n}\n\nexport interface BuiltinSlashCommand {\n\tname: string;\n\tdescription: string;\n\tgetArgumentCompletions?: (\n\t\targumentPrefix: string,\n\t) => AutocompleteItem[] | null | Promise<AutocompleteItem[] | null>;\n}\n\nexport const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [\n\t{ name: \"settings\", description: \"Open settings menu\" },\n\t{ name: \"model\", description: \"Select model (opens selector UI)\" },\n\t{ name: \"scoped-models\", description: \"Enable/disable models for ctrl+p cycling\" },\n\t{ name: \"fast\", description: \"Configure Codex fast mode for chat and workflows\" },\n\t{ name: \"export\", description: \"Export session (HTML default, or specify path: .html/.jsonl)\" },\n\t{ name: \"import\", description: \"Import and resume a session from a JSONL file\" },\n\t{ name: \"share\", description: \"Share session as a secret GitHub gist\" },\n\t{ name: \"copy\", description: \"Copy last agent message to clipboard\" },\n\t{ name: \"name\", description: \"Set session display name\" },\n\t{ name: \"session\", description: \"Show session info and stats\" },\n\t{ name: \"changelog\", description: \"Show changelog entries\" },\n\t{\n\t\tname: ATOMIC_GUIDE_COMMAND_NAME,\n\t\tdescription: ATOMIC_GUIDE_COMMAND_DESCRIPTION,\n\t\tgetArgumentCompletions: getAtomicGuideArgumentCompletions,\n\t},\n\t{ name: \"hotkeys\", description: \"Show all keyboard shortcuts\" },\n\t{ name: \"fork\", description: \"Create a new fork from a previous user message\" },\n\t{ name: \"clone\", description: \"Duplicate the current session at the current position\" },\n\t{ name: \"tree\", description: \"Navigate session tree (switch branches)\" },\n\t{ name: \"login\", description: \"Configure provider authentication\" },\n\t{ name: \"logout\", description: \"Remove provider authentication\" },\n\t{ name: \"new\", description: \"Start a new session\" },\n\t{ name: \"compact\", description: \"Manually compact the session context\" },\n\t{ name: \"resume\", description: \"Resume a different session\" },\n\t{ name: \"reload\", description: \"Reload keybindings, extensions, skills, prompts, and themes\" },\n\t{ name: \"exit\", description: `Exit ${APP_NAME}` },\n\t{ name: \"quit\", description: `Quit ${APP_NAME}` },\n];\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAWhE,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,+DAA+D;IAC/D,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CA8M3E","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.ts\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.ts\";\n\nconst DEFAULT_PROMPT_TOOLS = [\n \"read\",\n \"bash\",\n \"edit\",\n \"write\",\n \"ask_user_question\",\n \"todo\",\n] as const;\n\nexport interface SystemPromptModel {\n /** Provider identifier for the selected model. */\n provider: string;\n /** Stable provider-specific model identifier. */\n id: string;\n /** Human-readable model name, when available. */\n name?: string;\n}\n\nexport interface BuildSystemPromptOptions {\n /** Custom system prompt (replaces default). */\n customPrompt?: string;\n /** Tools to include in prompt. Default: [read, bash, edit, write, ask_user_question, todo] */\n selectedTools?: string[];\n /** Tool names explicitly excluded by the caller and omitted from generated guidance. */\n excludedTools?: string[];\n /** Optional one-line tool snippets keyed by tool name. */\n toolSnippets?: Record<string, string>;\n /** Additional guideline bullets appended to the default system prompt guidelines. */\n promptGuidelines?: string[];\n /** Text to append to system prompt. */\n appendSystemPrompt?: string;\n /** Working directory. */\n cwd: string;\n /** Currently selected model, used for model-aware prompt metadata. */\n selectedModel?: SystemPromptModel;\n /** Current reasoning/thinking level for the selected model. */\n selectedThinkingLevel?: string;\n /** Pre-loaded context files. */\n contextFiles?: Array<{ path: string; content: string }>;\n /** Pre-loaded skills. */\n skills?: Skill[];\n}\n\n/** Build the system prompt with tools, guidelines, and context */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n const {\n customPrompt,\n selectedTools,\n excludedTools,\n toolSnippets,\n promptGuidelines,\n appendSystemPrompt,\n cwd,\n selectedModel,\n selectedThinkingLevel,\n contextFiles: providedContextFiles,\n skills: providedSkills,\n } = options;\n const resolvedCwd = cwd;\n const promptCwd = resolvedCwd.replace(/\\\\/g, \"/\");\n\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, \"0\");\n const day = String(now.getDate()).padStart(2, \"0\");\n const date = `${year}-${month}-${day}`;\n\n const appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n const modelName =\n selectedModel?.name?.trim() || selectedModel?.id || \"unknown\";\n const modelReasoningLevel = selectedThinkingLevel?.trim() || \"off\";\n\n const contextFiles = providedContextFiles ?? [];\n const skills = providedSkills ?? [];\n const explicitlyExcludedTools = new Set(excludedTools ?? []);\n const isPromptToolAvailable = (name: string): boolean =>\n (!selectedTools || selectedTools.includes(name)) &&\n !explicitlyExcludedTools.has(name);\n\n if (customPrompt) {\n let prompt = customPrompt;\n\n if (appendSection) {\n prompt += appendSection;\n }\n\n // Append project context files\n if (contextFiles.length > 0) {\n prompt += \"\\n\\n# Project Context\\n\\n\";\n prompt += \"Project-specific instructions and guidelines:\\n\\n\";\n for (const { path: filePath, content } of contextFiles) {\n prompt += `<context_file path=\\\"${filePath}\\\">\\n${content}\\n</context_file>\\n\\n`;\n }\n }\n\n // Append skills section (only if read tool is available)\n if (isPromptToolAvailable(\"read\") && skills.length > 0) {\n prompt += formatSkillsForPrompt(skills);\n }\n\n // Add model metadata, date, and working directory last\n prompt += `\\nModel name (used for commit attribution): ${modelName}`;\n prompt += `\\nModel reasoning level: ${modelReasoningLevel}`;\n prompt += `\\nCurrent date: ${date}`;\n prompt += `\\nCurrent working directory: ${promptCwd}`;\n\n return prompt;\n }\n\n // Get absolute paths to documentation and examples\n const readmePath = getReadmePath();\n const docsPath = getDocsPath();\n const examplesPath = getExamplesPath();\n\n // Build tools list based on selected tools.\n // A tool appears in Available tools only when the caller provides a one-line snippet.\n const tools = (selectedTools ?? DEFAULT_PROMPT_TOOLS).filter(\n (name) => !explicitlyExcludedTools.has(name),\n );\n const visibleTools = tools.filter((name) => !!toolSnippets?.[name]);\n const toolsList =\n visibleTools.length > 0\n ? visibleTools\n .map((name) => `- ${name}: ${toolSnippets![name]}`)\n .join(\"\\n\")\n : \"(none)\";\n\n // Build guidelines based on which tools are actually available\n const guidelinesList: string[] = [];\n const guidelinesSet = new Set<string>();\n const addGuideline = (guideline: string): void => {\n if (guidelinesSet.has(guideline)) {\n return;\n }\n guidelinesSet.add(guideline);\n guidelinesList.push(guideline);\n };\n\n const hasBash = tools.includes(\"bash\");\n const hasGrep = tools.includes(\"grep\");\n const hasFind = tools.includes(\"find\");\n const hasLs = tools.includes(\"ls\");\n const hasRead = tools.includes(\"read\");\n\n // File exploration guidelines\n if (hasBash && !hasGrep && !hasFind && !hasLs) {\n addGuideline(\"Use bash for file operations like ls, rg, find\");\n } else if (hasBash && (hasGrep || hasFind || hasLs)) {\n addGuideline(\n \"Prefer grep/find/ls tools over bash for file exploration (faster, respects .gitignore)\",\n );\n }\n\n for (const guideline of promptGuidelines ?? []) {\n const normalized = guideline.trim();\n if (normalized.length > 0) {\n addGuideline(normalized);\n }\n }\n\n // Always include these\n addGuideline(\"Be concise in your responses\");\n addGuideline(\"Show file paths clearly when working with files\");\n\n const guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n const askUserQuestionGuidance = explicitlyExcludedTools.has(\n \"ask_user_question\",\n )\n ? \"\"\n : \"- Always ask clarifying questions if the user's request is ambiguous or lacks necessary details. NEVER make assumptions about what the user wants. If you find yourself circling in thought and asking what the user \\\"really\\\" wants, stop and ask the user for clarification using the ask_user_question tool if available. It's better to clarify intent rather than to guess.\\n- **Asking the user is a strict requirement**: Whenever you need to ask the user anything — a clarification, a decision, a choice between options, a confirmation, or any yes/no question — you MUST ask it by calling the `ask_user_question` tool. Never pose a question to the user as plain assistant text. Every question you direct to the user goes through `ask_user_question`; writing the question in prose instead of calling the tool is not allowed.\";\n const todoGuidance = explicitlyExcludedTools.has(\"todo\")\n ? \"\"\n : \"- **To-do management**: If the user has a complex task that can be broken down into actionable steps, use the `todo` tool to create a task list before proceeding. This ensures clarity and alignment with the user's goals and that you have a way to track your work and ensure you are meeting the user's expectations.\";\n\n const subagentGuidance = explicitlyExcludedTools.has(\"subagent\")\n ? \"\"\n : `- **Subagent Orchestration**:\n - To avoid draining your context window, prefer to use subagents for complex tasks all non-trivial operations should be delegated to subagents.\n - You should delegate running bash commands (particularly ones that are likely to produce lots of output) such as investigating with the \\`aws\\` CLI, using the \\`gh\\` CLI, digging through logs to \\`bash\\` subagents.\n - You should use separate subagents for separate tasks, and you may launch them in parallel, but do not delegate multiple tasks that are likely to have significant overlap to separate subagents.\n - Sometimes subagents will take a long time. DO NOT attempt to do the job yourself while waiting for the subagent to respond Instead, use the time to plan out your next steps.\n - **Debugging**: When a user asks about debugging, spawn a debugger subagent first.\n - Do not attempt to debug or analyze code yourself without first consulting the debugger subagent.\n - Explain the debugger's insights to the user clearly and concisely.\n - Once the user confirms, implement the necessary code changes based on those insights.\n - If the user has follow-up questions, spawn additional debugger and research subagents as needed.`;\n\n const workflowGuidance = explicitlyExcludedTools.has(\"workflow\")\n ? \"\"\n : `- **Workflows**: Use the \\`workflow\\` tool for existing named workflows and for repeatable, inspectable, resumable, or multi-stage processes; use direct \\`task\\`, \\`tasks\\`, or \\`chain\\` workflow calls for one-off tracked work when that is useful.\n - For unfamiliar named workflows, discover with \\`action: \"list\"\\`, inspect with \\`action: \"get\"\\` or \\`action: \"inputs\"\\`, and run with \\`action: \"run\"\\`, \\`workflow\\`, and validated \\`inputs\\`; do not invent workflow names or input keys.\n - Once you run a workflow with the workflow tool, end your current turn and wait for the next user input or lifecycle notice.\n - You will automatically be alerted of key lifecycle events like start, finish, failure; do not attempt to track its progress yourself or read its logs or stages unless the user asks you to or you need to check in on it to get information for the next step.\n - If the user needs information from the workflow run, use \\`status\\`, \\`stages\\`, or \\`stage\\` calls to get targeted information instead of trying to read everything.\n - Offer to help the user on another task instead of anxiously polling or help the user run another workflow if they need.\n - Use run-control and messaging actions (\\`send\\`, \\`pause\\`, \\`resume\\`, \\`interrupt\\`, \\`kill\\`) only when needed to answer prompts, steer a stage, resume or interrupt paused work, or respond to user requests/control signals.\n - For transcripts, avoid reading whole session transcripts at once. Use \\`stages\\` or \\`stage\\` to get \\`sessionFile\\`/\\`transcriptPath\\`, quote the exact path without rewriting separators (preserve Windows backslashes), search it with \\`rg\\`/\\`grep\\`, and read small relevant ranges; use \\`transcript\\` with explicit \\`tail\\` or \\`limit\\` only for quick recent-context checks.\n - If a user asks to create or edit a workflow, use the create-spec skill when available and ask detailed clarifying questions until you understand its purpose, inputs, stages, handoffs, validation, and success criteria. Then read the workflow docs/examples and implement the workflow from the created spec directly as a TypeScript definition. After you implement the workflow, reload it to access it and run it with test inputs to validate it works as intended before presenting it to the user.\n - Tip: when designing workflows, implement it in a way that you pass information from stage to stage by writing it to a file or artifact (either deterministic or model-driven), pass the path with \\`reads\\`, and explicitly prompt the downstream agent with wording like \\`Read the file at <path>...\\`; do not inject large \\`previous\\` payloads or session history into the next prompt unless explicitly requested to.\n - If you run \\`ralph\\` or \\`goal\\` workflow, define an objective that includes tight scope, concrete and verifiable done criteria, and validation steps; then monitor progress as above instead of doing parallel implementation yourself.`;\n\n let prompt = `You are an expert coding assistant operating named Atomic, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.\n\nAvailable tools:\n${toolsList}\n\nIn addition to the tools above, you may have access to other custom tools depending on the project.\n\nGuidelines:\n${guidelines}\n${askUserQuestionGuidance}\n${todoGuidance}\n${subagentGuidance}\n${workflowGuidance}\n\nAtomic documentation (read only when the user asks about customizing Atomic itself, its SDK, creating workflows, packages, extensions, themes, skills, or TUI):\n- Main documentation: ${readmePath}\n- Additional docs: ${docsPath}\n- Examples: ${examplesPath} (extensions, custom tools, SDK)\n- Docs/examples references above must be resolved against these absolute roots; e.g. docs/foo.md means ${docsPath}/foo.md and examples/bar means ${examplesPath}/bar.\n- When asked about: atomic workflows (docs/workflows.md), extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), atomic packages (docs/packages.md)\n- When working on Atomic topics, read the docs and examples, and follow .md cross-references before implementing\n- Always read Atomic .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;\n\n if (appendSection) {\n prompt += appendSection;\n }\n\n // Append project context files\n if (contextFiles.length > 0) {\n prompt += \"\\n\\n# Project Context\\n\\n\";\n prompt += \"Project-specific instructions and guidelines:\\n\\n\";\n for (const { path: filePath, content } of contextFiles) {\n prompt += `<context_file path=\\\"${filePath}\\\">\\n${content}\\n</context_file>\\n\\n`;\n }\n }\n\n // Append skills section (only if read tool is available)\n if (hasRead && skills.length > 0) {\n prompt += formatSkillsForPrompt(skills);\n }\n\n // Add model metadata, date, and working directory last\n prompt += `\\nModel name (used for commit attribution): ${modelName}`;\n prompt += `\\nModel reasoning level: ${modelReasoningLevel}`;\n prompt += `\\nCurrent date: ${date}`;\n prompt += `\\nCurrent working directory: ${promptCwd}`;\n\n return prompt;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAWhE,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,+DAA+D;IAC/D,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CA+M3E","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.ts\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.ts\";\n\nconst DEFAULT_PROMPT_TOOLS = [\n \"read\",\n \"bash\",\n \"edit\",\n \"write\",\n \"ask_user_question\",\n \"todo\",\n] as const;\n\nexport interface SystemPromptModel {\n /** Provider identifier for the selected model. */\n provider: string;\n /** Stable provider-specific model identifier. */\n id: string;\n /** Human-readable model name, when available. */\n name?: string;\n}\n\nexport interface BuildSystemPromptOptions {\n /** Custom system prompt (replaces default). */\n customPrompt?: string;\n /** Tools to include in prompt. Default: [read, bash, edit, write, ask_user_question, todo] */\n selectedTools?: string[];\n /** Tool names explicitly excluded by the caller and omitted from generated guidance. */\n excludedTools?: string[];\n /** Optional one-line tool snippets keyed by tool name. */\n toolSnippets?: Record<string, string>;\n /** Additional guideline bullets appended to the default system prompt guidelines. */\n promptGuidelines?: string[];\n /** Text to append to system prompt. */\n appendSystemPrompt?: string;\n /** Working directory. */\n cwd: string;\n /** Currently selected model, used for model-aware prompt metadata. */\n selectedModel?: SystemPromptModel;\n /** Current reasoning/thinking level for the selected model. */\n selectedThinkingLevel?: string;\n /** Pre-loaded context files. */\n contextFiles?: Array<{ path: string; content: string }>;\n /** Pre-loaded skills. */\n skills?: Skill[];\n}\n\n/** Build the system prompt with tools, guidelines, and context */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n const {\n customPrompt,\n selectedTools,\n excludedTools,\n toolSnippets,\n promptGuidelines,\n appendSystemPrompt,\n cwd,\n selectedModel,\n selectedThinkingLevel,\n contextFiles: providedContextFiles,\n skills: providedSkills,\n } = options;\n const resolvedCwd = cwd;\n const promptCwd = resolvedCwd.replace(/\\\\/g, \"/\");\n\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, \"0\");\n const day = String(now.getDate()).padStart(2, \"0\");\n const date = `${year}-${month}-${day}`;\n\n const appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n const modelName =\n selectedModel?.name?.trim() || selectedModel?.id || \"unknown\";\n const modelReasoningLevel = selectedThinkingLevel?.trim() || \"off\";\n\n const contextFiles = providedContextFiles ?? [];\n const skills = providedSkills ?? [];\n const explicitlyExcludedTools = new Set(excludedTools ?? []);\n const isPromptToolAvailable = (name: string): boolean =>\n (!selectedTools || selectedTools.includes(name)) &&\n !explicitlyExcludedTools.has(name);\n\n if (customPrompt) {\n let prompt = customPrompt;\n\n if (appendSection) {\n prompt += appendSection;\n }\n\n // Append project context files\n if (contextFiles.length > 0) {\n prompt += \"\\n\\n# Project Context\\n\\n\";\n prompt += \"Project-specific instructions and guidelines:\\n\\n\";\n for (const { path: filePath, content } of contextFiles) {\n prompt += `<context_file path=\\\"${filePath}\\\">\\n${content}\\n</context_file>\\n\\n`;\n }\n }\n\n // Append skills section (only if read tool is available)\n if (isPromptToolAvailable(\"read\") && skills.length > 0) {\n prompt += formatSkillsForPrompt(skills);\n }\n\n // Add model metadata, date, and working directory last\n prompt += `\\nModel name (used for commit attribution): ${modelName}`;\n prompt += `\\nModel reasoning level: ${modelReasoningLevel}`;\n prompt += `\\nCurrent date: ${date}`;\n prompt += `\\nCurrent working directory: ${promptCwd}`;\n\n return prompt;\n }\n\n // Get absolute paths to documentation and examples\n const readmePath = getReadmePath();\n const docsPath = getDocsPath();\n const examplesPath = getExamplesPath();\n\n // Build tools list based on selected tools.\n // A tool appears in Available tools only when the caller provides a one-line snippet.\n const tools = (selectedTools ?? DEFAULT_PROMPT_TOOLS).filter(\n (name) => !explicitlyExcludedTools.has(name),\n );\n const visibleTools = tools.filter((name) => !!toolSnippets?.[name]);\n const toolsList =\n visibleTools.length > 0\n ? visibleTools\n .map((name) => `- ${name}: ${toolSnippets![name]}`)\n .join(\"\\n\")\n : \"(none)\";\n\n // Build guidelines based on which tools are actually available\n const guidelinesList: string[] = [];\n const guidelinesSet = new Set<string>();\n const addGuideline = (guideline: string): void => {\n if (guidelinesSet.has(guideline)) {\n return;\n }\n guidelinesSet.add(guideline);\n guidelinesList.push(guideline);\n };\n\n const hasBash = tools.includes(\"bash\");\n const hasGrep = tools.includes(\"grep\");\n const hasFind = tools.includes(\"find\");\n const hasLs = tools.includes(\"ls\");\n const hasRead = tools.includes(\"read\");\n\n // File exploration guidelines\n if (hasBash && !hasGrep && !hasFind && !hasLs) {\n addGuideline(\"Use bash for file operations like ls, rg, find\");\n } else if (hasBash && (hasGrep || hasFind || hasLs)) {\n addGuideline(\n \"Prefer grep/find/ls tools over bash for file exploration (faster, respects .gitignore)\",\n );\n }\n\n for (const guideline of promptGuidelines ?? []) {\n const normalized = guideline.trim();\n if (normalized.length > 0) {\n addGuideline(normalized);\n }\n }\n\n // Always include these\n addGuideline(\"Be concise in your responses\");\n addGuideline(\"Show file paths clearly when working with files\");\n\n const guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n const askUserQuestionGuidance = explicitlyExcludedTools.has(\n \"ask_user_question\",\n )\n ? \"\"\n : \"- Always ask clarifying questions if the user's request is ambiguous or lacks necessary details. NEVER make assumptions about what the user wants. If you find yourself circling in thought and asking what the user \\\"really\\\" wants, stop and ask the user for clarification using the ask_user_question tool if available. It's better to clarify intent rather than to guess.\\n- **Asking the user is a strict requirement**: Whenever you need to ask the user anything — a clarification, a decision, a choice between options, a confirmation, or any yes/no question — you MUST ask it by calling the `ask_user_question` tool. Never pose a question to the user as plain assistant text. Every question you direct to the user goes through `ask_user_question`; writing the question in prose instead of calling the tool is not allowed.\";\n const todoGuidance = explicitlyExcludedTools.has(\"todo\")\n ? \"\"\n : \"- **To-do management**: If the user has a complex task that can be broken down into actionable steps, use the `todo` tool to create a task list before proceeding. This ensures clarity and alignment with the user's goals and that you have a way to track your work and ensure you are meeting the user's expectations.\";\n\n const subagentGuidance = explicitlyExcludedTools.has(\"subagent\")\n ? \"\"\n : `- **Subagent Orchestration**:\n - To avoid draining your context window, prefer to use subagents for complex tasks all non-trivial operations should be delegated to subagents.\n - You should delegate running bash commands (particularly ones that are likely to produce lots of output) such as investigating with the \\`aws\\` CLI, using the \\`gh\\` CLI, digging through logs to \\`bash\\` subagents.\n - You should use separate subagents for separate tasks, and you may launch them in parallel, but do not delegate multiple tasks that are likely to have significant overlap to separate subagents.\n - Sometimes subagents will take a long time. DO NOT attempt to do the job yourself while waiting for the subagent to respond Instead, use the time to plan out your next steps.\n - **Debugging**: When a user asks about debugging, spawn a debugger subagent first.\n - Do not attempt to debug or analyze code yourself without first consulting the debugger subagent.\n - Explain the debugger's insights to the user clearly and concisely.\n - Once the user confirms, implement the necessary code changes based on those insights.\n - If the user has follow-up questions, spawn additional debugger and research subagents as needed.`;\n\n const workflowGuidance = explicitlyExcludedTools.has(\"workflow\")\n ? \"\"\n : `- **Workflows**: Use the \\`workflow\\` tool for existing named workflows and for repeatable, inspectable, resumable, or multi-stage processes; use direct \\`task\\`, \\`tasks\\`, or \\`chain\\` workflow calls for one-off tracked work when that is useful.\n - For unfamiliar named workflows, discover with \\`action: \"list\"\\`, inspect with \\`action: \"get\"\\` or \\`action: \"inputs\"\\`, and run with \\`action: \"run\"\\`, \\`workflow\\`, and validated \\`inputs\\`; do not invent workflow names or input keys.\n - When designing or editing workflows, read docs/workflows.md and reference its Workflow Starter Patterns: Classify-and-act, Fan-out-and-synthesize, Adversarial verification, Generate-and-filter, Tournament, and Loop until done. Choose or combine these patterns before inventing a custom stage graph, and reflect the selected pattern in the spec and Mermaid diagram when using the create-spec skill.\n - Once you run a workflow with the workflow tool, end your current turn and wait for the next user input or lifecycle notice.\n - You will automatically be alerted of key lifecycle events like start, finish, failure; do not micro-manage the run with sleep/status polling loops or read its logs/stages unless the user asks you to or you need information for the next step.\n - If the user needs information from the workflow run, use targeted \\`status\\`/\\`stages\\`/\\`stage\\` checks instead of trying to read everything.\n - Offer to help the user on another task instead of anxiously polling or help the user run another workflow if they need.\n - Use run-control and messaging actions (\\`send\\`, \\`pause\\`, \\`resume\\`, \\`interrupt\\`, \\`kill\\`) only when needed to answer prompts, steer a stage, resume or interrupt paused work, or respond to user requests/control signals.\n - For transcripts, avoid reading whole session transcripts at once. Use \\`stages\\` or \\`stage\\` to get \\`sessionFile\\`/\\`transcriptPath\\`, quote the exact path without rewriting separators (preserve Windows backslashes), search it with \\`rg\\`/\\`grep\\`, and read small relevant ranges; use \\`transcript\\` with explicit \\`tail\\` or \\`limit\\` only for quick recent-context checks.\n - If a user asks to create or edit a workflow, use the create-spec skill when available and ask detailed clarifying questions until you understand its purpose, inputs, stages, handoffs, validation, success criteria, and selected starter pattern. Then read the workflow docs/examples and implement the workflow from the created spec directly as a TypeScript definition. After you implement the workflow, reload it to access it and run it with test inputs to validate it works as intended before presenting it to the user.\n - Tip: when designing workflows, implement it in a way that you pass information from stage to stage by writing it to a file or artifact (either deterministic or model-driven), pass the path with \\`reads\\`, and explicitly prompt the downstream agent with wording like \\`Read the file at <path>...\\`; do not inject large \\`previous\\` payloads or session history into the next prompt unless explicitly requested to.\n - If you run \\`ralph\\` or \\`goal\\` workflow, define an objective that includes tight scope, concrete and verifiable done criteria, and validation steps; then monitor progress as above instead of doing parallel implementation yourself.`;\n\n let prompt = `You are an expert coding assistant operating named Atomic, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.\n\nAvailable tools:\n${toolsList}\n\nIn addition to the tools above, you may have access to other custom tools depending on the project.\n\nGuidelines:\n${guidelines}\n${askUserQuestionGuidance}\n${todoGuidance}\n${subagentGuidance}\n${workflowGuidance}\n\nAtomic documentation (read only when the user asks about customizing Atomic itself, its SDK, creating workflows, packages, extensions, themes, skills, or TUI):\n- Main documentation: ${readmePath}\n- Additional docs: ${docsPath}\n- Examples: ${examplesPath} (extensions, custom tools, SDK)\n- Docs/examples references above must be resolved against these absolute roots; e.g. docs/foo.md means ${docsPath}/foo.md and examples/bar means ${examplesPath}/bar.\n- When asked about: atomic workflows (docs/workflows.md), extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), atomic packages (docs/packages.md)\n- When working on Atomic topics, read the docs and examples, and follow .md cross-references before implementing\n- Always read Atomic .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;\n\n if (appendSection) {\n prompt += appendSection;\n }\n\n // Append project context files\n if (contextFiles.length > 0) {\n prompt += \"\\n\\n# Project Context\\n\\n\";\n prompt += \"Project-specific instructions and guidelines:\\n\\n\";\n for (const { path: filePath, content } of contextFiles) {\n prompt += `<context_file path=\\\"${filePath}\\\">\\n${content}\\n</context_file>\\n\\n`;\n }\n }\n\n // Append skills section (only if read tool is available)\n if (hasRead && skills.length > 0) {\n prompt += formatSkillsForPrompt(skills);\n }\n\n // Add model metadata, date, and working directory last\n prompt += `\\nModel name (used for commit attribution): ${modelName}`;\n prompt += `\\nModel reasoning level: ${modelReasoningLevel}`;\n prompt += `\\nCurrent date: ${date}`;\n prompt += `\\nCurrent working directory: ${promptCwd}`;\n\n return prompt;\n}\n"]}
|
|
@@ -120,13 +120,14 @@ export function buildSystemPrompt(options) {
|
|
|
120
120
|
? ""
|
|
121
121
|
: `- **Workflows**: Use the \`workflow\` tool for existing named workflows and for repeatable, inspectable, resumable, or multi-stage processes; use direct \`task\`, \`tasks\`, or \`chain\` workflow calls for one-off tracked work when that is useful.
|
|
122
122
|
- For unfamiliar named workflows, discover with \`action: "list"\`, inspect with \`action: "get"\` or \`action: "inputs"\`, and run with \`action: "run"\`, \`workflow\`, and validated \`inputs\`; do not invent workflow names or input keys.
|
|
123
|
+
- When designing or editing workflows, read docs/workflows.md and reference its Workflow Starter Patterns: Classify-and-act, Fan-out-and-synthesize, Adversarial verification, Generate-and-filter, Tournament, and Loop until done. Choose or combine these patterns before inventing a custom stage graph, and reflect the selected pattern in the spec and Mermaid diagram when using the create-spec skill.
|
|
123
124
|
- Once you run a workflow with the workflow tool, end your current turn and wait for the next user input or lifecycle notice.
|
|
124
|
-
- You will automatically be alerted of key lifecycle events like start, finish, failure; do not
|
|
125
|
-
- If the user needs information from the workflow run, use \`status
|
|
125
|
+
- You will automatically be alerted of key lifecycle events like start, finish, failure; do not micro-manage the run with sleep/status polling loops or read its logs/stages unless the user asks you to or you need information for the next step.
|
|
126
|
+
- If the user needs information from the workflow run, use targeted \`status\`/\`stages\`/\`stage\` checks instead of trying to read everything.
|
|
126
127
|
- Offer to help the user on another task instead of anxiously polling or help the user run another workflow if they need.
|
|
127
128
|
- Use run-control and messaging actions (\`send\`, \`pause\`, \`resume\`, \`interrupt\`, \`kill\`) only when needed to answer prompts, steer a stage, resume or interrupt paused work, or respond to user requests/control signals.
|
|
128
129
|
- For transcripts, avoid reading whole session transcripts at once. Use \`stages\` or \`stage\` to get \`sessionFile\`/\`transcriptPath\`, quote the exact path without rewriting separators (preserve Windows backslashes), search it with \`rg\`/\`grep\`, and read small relevant ranges; use \`transcript\` with explicit \`tail\` or \`limit\` only for quick recent-context checks.
|
|
129
|
-
- If a user asks to create or edit a workflow, use the create-spec skill when available and ask detailed clarifying questions until you understand its purpose, inputs, stages, handoffs, validation, and
|
|
130
|
+
- If a user asks to create or edit a workflow, use the create-spec skill when available and ask detailed clarifying questions until you understand its purpose, inputs, stages, handoffs, validation, success criteria, and selected starter pattern. Then read the workflow docs/examples and implement the workflow from the created spec directly as a TypeScript definition. After you implement the workflow, reload it to access it and run it with test inputs to validate it works as intended before presenting it to the user.
|
|
130
131
|
- Tip: when designing workflows, implement it in a way that you pass information from stage to stage by writing it to a file or artifact (either deterministic or model-driven), pass the path with \`reads\`, and explicitly prompt the downstream agent with wording like \`Read the file at <path>...\`; do not inject large \`previous\` payloads or session history into the next prompt unless explicitly requested to.
|
|
131
132
|
- If you run \`ralph\` or \`goal\` workflow, define an objective that includes tight scope, concrete and verifiable done criteria, and validation steps; then monitor progress as above instead of doing parallel implementation yourself.`;
|
|
132
133
|
let prompt = `You are an expert coding assistant operating named Atomic, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.
|