@bastani/atomic 0.9.11-alpha.9 → 0.9.12-alpha.1
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 +147 -0
- package/README.md +1 -1
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/closed-workflow-stage-message.ts +1 -1
- package/dist/builtin/intercom/contact-supervisor-tool.ts +1 -1
- package/dist/builtin/intercom/index-heavy.ts +2 -2
- package/dist/builtin/intercom/intercom-tool.ts +2 -2
- package/dist/builtin/intercom/intercom-utils.ts +1 -1
- package/dist/builtin/intercom/lifecycle.ts +2 -2
- package/dist/builtin/intercom/overlay.ts +2 -2
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/reply-tracker.ts +1 -1
- package/dist/builtin/intercom/subagent-relay.ts +10 -7
- package/dist/builtin/mcp/CHANGELOG.md +16 -0
- package/dist/builtin/mcp/apps-cancellation.ts +1 -1
- package/dist/builtin/mcp/commands.ts +7 -7
- package/dist/builtin/mcp/direct-tool-executor.ts +1 -1
- package/dist/builtin/mcp/direct-tools.ts +3 -3
- package/dist/builtin/mcp/host-html-template.ts +1 -1
- package/dist/builtin/mcp/index.ts +3 -3
- package/dist/builtin/mcp/init.ts +6 -6
- package/dist/builtin/mcp/mcp-auth-flow.ts +1 -1
- package/dist/builtin/mcp/mcp-callback-server.ts +1 -1
- package/dist/builtin/mcp/mcp-panel-state.ts +1 -1
- package/dist/builtin/mcp/mcp-panel.ts +1 -1
- package/dist/builtin/mcp/metadata-cache.ts +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/mcp/proxy-call.ts +2 -2
- package/dist/builtin/mcp/proxy-info-modes.ts +2 -2
- package/dist/builtin/mcp/sampling-handler.ts +1 -1
- package/dist/builtin/mcp/server-manager.ts +3 -3
- package/dist/builtin/mcp/startup-warmup.ts +5 -5
- package/dist/builtin/mcp/state.ts +1 -1
- package/dist/builtin/mcp/tool-call-timeout.ts +1 -1
- package/dist/builtin/mcp/tool-metadata.ts +2 -2
- package/dist/builtin/mcp/types.ts +1 -1
- package/dist/builtin/mcp/ui-server.ts +4 -4
- package/dist/builtin/mcp/ui-session.ts +3 -3
- package/dist/builtin/subagents/CHANGELOG.md +26 -0
- package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
- package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
- package/dist/builtin/subagents/agents/worker.md +2 -2
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/notification-content.ts +14 -9
- package/dist/builtin/subagents/src/runs/background/notify.ts +20 -4
- package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +5 -5
- package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +1 -1
- package/dist/builtin/subagents/src/runs/background/result-status.ts +2 -2
- package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +2 -2
- package/dist/builtin/subagents/src/runs/background/result-watcher.ts +1 -1
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +1 -1
- package/dist/builtin/subagents/src/shared/artifacts.ts +1 -1
- package/dist/builtin/web-access/CHANGELOG.md +26 -0
- package/dist/builtin/web-access/content-tools.ts +1 -0
- package/dist/builtin/web-access/flat-string.ts +37 -0
- package/dist/builtin/web-access/github-api.ts +2 -1
- package/dist/builtin/web-access/github-extract.ts +3 -2
- package/dist/builtin/web-access/index-heavy.ts +1 -1
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +68 -0
- package/dist/builtin/workflows/README.md +1 -1
- package/dist/builtin/workflows/builtin/goal-ledger.ts +6 -4
- package/dist/builtin/workflows/builtin/goal-prompts.ts +4 -1
- package/dist/builtin/workflows/builtin/goal-runner.ts +2 -1
- package/dist/builtin/workflows/builtin/goal.ts +1 -1
- package/dist/builtin/workflows/builtin/ralph-core.ts +15 -13
- package/dist/builtin/workflows/builtin/ralph-forked-prompts.ts +7 -6
- package/dist/builtin/workflows/builtin/ralph-models.ts +4 -4
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +2 -1
- package/dist/builtin/workflows/builtin/ralph-runner.ts +7 -9
- package/dist/builtin/workflows/builtin/ralph.ts +2 -1
- package/dist/builtin/workflows/builtin/shared-prompts.ts +34 -7
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/authoring/keep-context.ts +46 -0
- package/dist/builtin/workflows/src/authoring.d.ts +11 -0
- package/dist/builtin/workflows/src/durable/completed-catalog.ts +14 -8
- package/dist/builtin/workflows/src/durable/completed-inspection.ts +10 -11
- package/dist/builtin/workflows/src/durable/resume-catalog.ts +1 -1
- package/dist/builtin/workflows/src/durable/resume-eligibility.ts +42 -0
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +36 -37
- package/dist/builtin/workflows/src/durable/tool-primitive.ts +10 -2
- package/dist/builtin/workflows/src/engine/run.ts +1 -0
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +12 -8
- package/dist/builtin/workflows/src/extension/hil-answer-notifications.ts +5 -2
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +2001 -897
- package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +6 -3
- package/dist/builtin/workflows/src/extension/postmortem-deps.ts +3 -2
- package/dist/builtin/workflows/src/extension/render-result.ts +4 -11
- package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +17 -20
- package/dist/builtin/workflows/src/extension/runtime.ts +3 -3
- package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +1 -1
- package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +3 -7
- package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +21 -24
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +4 -0
- package/dist/builtin/workflows/src/extension/workflow-resume-picker-rows.ts +38 -26
- package/dist/builtin/workflows/src/extension/workflow-resume-shadow.ts +2 -1
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +56 -64
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +2 -2
- package/dist/builtin/workflows/src/extension/workflow-status-summary.ts +0 -5
- package/dist/builtin/workflows/src/extension/workflow-targets.ts +17 -20
- package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +1 -1
- package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +24 -51
- package/dist/builtin/workflows/src/extension/workflow-tool-inspection.ts +7 -29
- package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +5 -13
- package/dist/builtin/workflows/src/extension/workflow-tool.ts +4 -13
- package/dist/builtin/workflows/src/runs/background/quit.ts +4 -3
- package/dist/builtin/workflows/src/runs/background/run-inspect.ts +8 -8
- package/dist/builtin/workflows/src/runs/background/status.ts +2 -1
- package/dist/builtin/workflows/src/runs/background/workflow-lifecycle-aggregate.ts +2 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +5 -5
- package/dist/builtin/workflows/src/runs/foreground/executor-lifecycle.ts +4 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-scheduler.ts +2 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +23 -8
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +6 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-task-prompts.ts +5 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +56 -10
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +6 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-output.ts +137 -6
- package/dist/builtin/workflows/src/sdk-surface.ts +1 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +2 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +2 -0
- package/dist/builtin/workflows/src/shared/expanded-workflow-graph.ts +159 -10
- package/dist/builtin/workflows/src/shared/flat-string.ts +33 -0
- package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +144 -0
- package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +2 -3
- package/dist/builtin/workflows/src/shared/run-id.ts +36 -0
- package/dist/builtin/workflows/src/shared/store-internal.ts +32 -3
- package/dist/builtin/workflows/src/shared/store-observation.ts +10 -0
- package/dist/builtin/workflows/src/shared/store-public-types.ts +8 -0
- package/dist/builtin/workflows/src/shared/store-run-methods.ts +14 -0
- package/dist/builtin/workflows/src/shared/store-types.ts +4 -0
- package/dist/builtin/workflows/src/shared/types.ts +2 -0
- package/dist/builtin/workflows/src/shared/workflow-artifacts.ts +261 -0
- package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +39 -23
- package/dist/builtin/workflows/src/tui/graph-canvas.ts +26 -9
- package/dist/builtin/workflows/src/tui/graph-view-constants.ts +3 -0
- package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +95 -98
- package/dist/builtin/workflows/src/tui/graph-view-render.ts +7 -20
- package/dist/builtin/workflows/src/tui/graph-view-state.ts +160 -13
- package/dist/builtin/workflows/src/tui/layout.ts +8 -2
- package/dist/builtin/workflows/src/tui/node-card.ts +57 -45
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +4 -2
- package/dist/builtin/workflows/src/tui/prompt-card-render.ts +291 -21
- package/dist/builtin/workflows/src/tui/prompt-card.ts +1 -1
- package/dist/builtin/workflows/src/tui/renderers.ts +0 -1
- package/dist/builtin/workflows/src/tui/run-detail.ts +52 -35
- package/dist/builtin/workflows/src/tui/run-identity-rows.ts +97 -0
- package/dist/builtin/workflows/src/tui/session-overlays.ts +24 -3
- package/dist/builtin/workflows/src/tui/session-picker.ts +94 -41
- package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +190 -26
- package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +52 -18
- package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +9 -5
- package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +44 -4
- package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +3 -1
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +3 -2
- package/dist/builtin/workflows/src/tui/status-list.ts +67 -45
- package/dist/builtin/workflows/src/tui/store-widget-installer.ts +7 -6
- package/dist/builtin/workflows/src/tui/widget.ts +49 -40
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +15 -10
- package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +21 -8
- package/dist/core/agent-session-accessors.d.ts.map +1 -1
- package/dist/core/agent-session-accessors.js +5 -0
- package/dist/core/agent-session-accessors.js.map +1 -1
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +5 -0
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +3 -0
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +2 -1
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts +3 -7
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +27 -13
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +6 -4
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.js +6 -3
- package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
- package/dist/core/agent-session-post-tool-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-post-tool-compaction.js +11 -2
- package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +5 -3
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-tree.d.ts.map +1 -1
- package/dist/core/agent-session-tree.js +4 -0
- package/dist/core/agent-session-tree.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +4 -0
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/async/session-manager.d.ts +1 -1
- package/dist/core/async/session-manager.js.map +1 -1
- package/dist/core/auth-storage-backends.d.ts.map +1 -1
- package/dist/core/auth-storage-backends.js +12 -1
- package/dist/core/auth-storage-backends.js.map +1 -1
- package/dist/core/bounded-model-refresh.d.ts +14 -0
- package/dist/core/bounded-model-refresh.d.ts.map +1 -0
- package/dist/core/bounded-model-refresh.js +38 -0
- package/dist/core/bounded-model-refresh.js.map +1 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction-boundary.d.ts +2 -2
- package/dist/core/compaction/compaction-boundary.js.map +1 -1
- package/dist/core/compaction/compaction-parameters.d.ts +5 -0
- package/dist/core/compaction/compaction-parameters.d.ts.map +1 -1
- package/dist/core/compaction/compaction-parameters.js +6 -5
- package/dist/core/compaction/compaction-parameters.js.map +1 -1
- package/dist/core/compaction/compaction-runner.d.ts +4 -0
- package/dist/core/compaction/compaction-runner.d.ts.map +1 -1
- package/dist/core/compaction/compaction-runner.js +5 -1
- package/dist/core/compaction/compaction-runner.js.map +1 -1
- package/dist/core/compaction/compaction-types.d.ts +7 -1
- package/dist/core/compaction/compaction-types.d.ts.map +1 -1
- package/dist/core/compaction/compaction-types.js.map +1 -1
- package/dist/core/compaction/deleted-ranges.d.ts.map +1 -1
- package/dist/core/compaction/deleted-ranges.js +2 -0
- package/dist/core/compaction/deleted-ranges.js.map +1 -1
- package/dist/core/compaction/fallback-planner.d.ts +1 -1
- package/dist/core/compaction/fallback-planner.js.map +1 -1
- package/dist/core/compaction/range-planner.d.ts +3 -3
- package/dist/core/compaction/range-planner.d.ts.map +1 -1
- package/dist/core/compaction/range-planner.js +12 -14
- package/dist/core/compaction/range-planner.js.map +1 -1
- package/dist/core/compaction/transcript-serialization.d.ts +12 -0
- package/dist/core/compaction/transcript-serialization.d.ts.map +1 -1
- package/dist/core/compaction/transcript-serialization.js +99 -1
- package/dist/core/compaction/transcript-serialization.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +3 -0
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +16 -0
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/context-tool-pairing.d.ts +4 -4
- package/dist/core/context-tool-pairing.js +4 -4
- package/dist/core/context-tool-pairing.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +26 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/messages.d.ts +18 -6
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +46 -18
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-refresh-timeout.d.ts +9 -0
- package/dist/core/model-refresh-timeout.d.ts.map +1 -0
- package/dist/core/model-refresh-timeout.js +9 -0
- package/dist/core/model-refresh-timeout.js.map +1 -0
- package/dist/core/model-runtime-snapshot.d.ts +3 -0
- package/dist/core/model-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/model-runtime-snapshot.js +59 -0
- package/dist/core/model-runtime-snapshot.js.map +1 -1
- package/dist/core/model-runtime.d.ts +7 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +72 -17
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +4 -3
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-core.d.ts +1 -1
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +2 -2
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-entries.d.ts +1 -1
- package/dist/core/session-manager-entries.d.ts.map +1 -1
- package/dist/core/session-manager-entries.js +2 -1
- package/dist/core/session-manager-entries.js.map +1 -1
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +2 -2
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/session-manager-types.d.ts +3 -0
- package/dist/core/session-manager-types.d.ts.map +1 -1
- package/dist/core/session-manager-types.js.map +1 -1
- package/dist/core/tools/bash-async-execution.d.ts +1 -1
- package/dist/core/tools/bash-async-execution.js.map +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/oversized-tool-result.js.map +1 -1
- package/dist/extensions/index.d.ts +1 -1
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/huggingface-ui.d.ts +2 -2
- package/dist/extensions/llama/huggingface-ui.js.map +1 -1
- package/dist/extensions/llama/index.d.ts +1 -1
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/ui.d.ts +1 -1
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main-app-mode.d.ts +1 -0
- package/dist/main-app-mode.d.ts.map +1 -1
- package/dist/main-app-mode.js +3 -0
- package/dist/main-app-mode.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +8 -3
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.d.ts +7 -2
- package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.js +13 -4
- package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-editor.d.ts +3 -1
- package/dist/modes/interactive/components/chat-session-host-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-editor.js +2 -2
- package/dist/modes/interactive/components/chat-session-host-editor.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.d.ts +3 -0
- package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.js +5 -4
- package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts +16 -2
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +35 -5
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +0 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +25 -35
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-editor-actions.js +2 -1
- package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +1 -1
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +4 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +4 -1
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-pause.d.ts +3 -1
- package/dist/modes/interactive/interactive-pause.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-pause.js +5 -1
- package/dist/modes/interactive/interactive-pause.js.map +1 -1
- package/dist/modes/interactive/interactive-queueing.js +3 -3
- package/dist/modes/interactive/interactive-queueing.js.map +1 -1
- package/dist/modes/interactive-engine/engine-health.d.ts +6 -0
- package/dist/modes/interactive-engine/engine-health.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-health.js +15 -1
- package/dist/modes/interactive-engine/engine-health.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-auth.js +1 -1
- package/dist/modes/interactive-engine/isolated-auth.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts +1 -0
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +7 -1
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/remote-model-catalog.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-model-catalog.js +5 -1
- package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
- package/dist/modes/interactive-engine/remote-queue-pause.d.ts +1 -1
- package/dist/modes/interactive-engine/remote-queue-pause.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +23 -7
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-input-scheduler.js +1 -1
- package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/compaction.md +24 -0
- package/docs/custom-provider.md +3 -3
- package/docs/extensions.md +3 -1
- package/docs/index.md +10 -0
- package/docs/keybindings.md +1 -1
- package/docs/models.md +2 -0
- package/docs/providers.md +7 -3
- package/docs/quickstart.md +7 -1
- package/docs/session-format.md +2 -0
- package/docs/termux.md +3 -1
- package/docs/usage.md +3 -2
- package/docs/workflows.md +138 -46
- package/npm-shrinkwrap.json +69 -37
- package/package.json +4 -4
- package/dist/builtin/workflows/src/tui/toast.ts +0 -107
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.12-alpha.1",
|
|
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": [
|
|
@@ -46,6 +46,6 @@
|
|
|
46
46
|
"linkedom": "^0.18.13",
|
|
47
47
|
"p-limit": "^7.3.0",
|
|
48
48
|
"turndown": "^7.2.0",
|
|
49
|
-
"unpdf": "
|
|
49
|
+
"unpdf": "1.7.0"
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -6,6 +6,74 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.12-alpha.1] - 2026-08-04
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added `keepContext` to the public authoring surface: `import { keepContext } from "@bastani/workflows"`. It wraps prompt text so compaction protects it verbatim regardless of the compression ratio, and is a pure, idempotent string helper rather than a `ctx.*` primitive — no graph node, no side effect, callable anywhere a prompt is assembled. `KEEP_CONTEXT_OPEN_TAG` and `KEEP_CONTEXT_CLOSE_TAG` are exported alongside it. Reserve it for text whose loss silently changes behavior — role constraints, acceptance criteria, explicit prohibitions, and identifiers a stage must not lose — and not for bulk context, since protected lines count against the keep target rather than raising it ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).
|
|
14
|
+
- `<keepContext>` tags also work in the run inputs and steering messages sent through the `workflow` tool, not only in authored stage prompts. Workflows inject inputs into their stage prompts, so a tagged clause in `prompt` or `acceptance_criteria` is inherited and protected by every stage that receives it, and a tagged `send` amendment survives until the stage acts on it instead of competing with the whole transcript for retention. Because `keepContext` is idempotent, an already-tagged input is not double-wrapped by a workflow that protects the same field. The workflow tool description and agent guidance now say so, so an agent can decide per launch or per steering message which clauses to protect ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Builtin workflows protect their own invariants with `keepContext`, so a long-running stage can no longer lose the rules that bound it: the steering propagation contract carried by every builtin stage prompt, the literal objective contract, scope discipline, worktree discipline, ralph's per-run acceptance criteria, ralph's research-only role constraint, and goal's reviewer "inspect and report; do not implement" constraint. Previously a research stage could be compacted past its own prohibition and start implementing, and a stage could lose the checkout it was bound to ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).
|
|
19
|
+
|
|
20
|
+
## [0.9.11] - 2026-08-03
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Added per-node cancellation and abort targeting to `ctx.tool`. Every callback receives a `WorkflowToolContext` (`{ signal }`) combining a per-invocation controller with the run signal, and `workflow({ action: "quit"|"interrupt", runId, stageId })` resolves a tool node by expanded id, local `tool:<argsHash>` id, or tool name. Aborting one node leaves siblings running; existing zero-argument callbacks are unchanged ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
|
|
25
|
+
- Added opt-in `ctx.tool(..., { failureMode: "return" })` for checks that may fail during repair flows, preserving bounded redacted `exitCode`, `stdout`, and `stderr` as typed durable data that replays without rerunning the callback ([#1993](https://github.com/bastani-inc/atomic/issues/1993)).
|
|
26
|
+
- Re-added the built-in Goal and Ralph workflows with their typed composition exports, command metadata, tests, and docs.
|
|
27
|
+
- Added a run-contract discipline to every builtin workflow: only the user may change a run's contract, mid-run steering and resume text are authoritative amendments, and each stage restates the amendments it received. Every bundled workflow wraps its context once through `withSteeringPropagationContext` (exported from `@bastani/workflows/builtin/steering-context`), so `ctx.task`, `ctx.chain`, and `ctx.parallel` prompts carry it automatically. Implementation stages also freeze acceptance criteria before writing code and keep a deferred list instead of a growing diff.
|
|
28
|
+
- Added a draft handoff for `ralph` runs that exhaust their review budget: with `create_pr` enabled, the run opens a draft pull request reproducing every unresolved blocking finding with priority and cited `file:line` instead of leaving the branch unpushed.
|
|
29
|
+
- Added the opt-in `autoAttach` workflow-definition field, which opens the graph overlay for interactive top-level named launches, and `ctx.models`, which optionally exposes the host session's model catalog to custom definitions.
|
|
30
|
+
- Embedded DBOS Postgres now works when Atomic runs as root on Linux (containers, CI sandboxes, eval harnesses) by resolving an unprivileged system account and keeping the cluster under `/var/lib/atomic-postgres`.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- Workflow invocations now assign a stable, non-`default` Intercom group from the top-level run identity and apply it to every Intercom-capable stage. Nested workflows, model fallback, pause/resume, durable replay, and subagent inheritance retain the group; separate runs stay isolated and explicit overrides still win, so authors no longer thread group names manually ([#1999](https://github.com/bastani-inc/atomic/issues/1999)).
|
|
35
|
+
- Adopted Claude Opus 5 as the primary model for the Ralph prompt-engineer, orchestrator, and reviewer-A stages, the Goal orchestrator and reviewer stages, and the Open Claude Design chain, with Copilot and OpenRouter mirrors added throughout. Ralph's research and reviewer-B chains keep GPT-5.6 primaries and gain Opus 5 fallbacks.
|
|
36
|
+
- Reworked the Goal, Ralph, Open Claude Design, and six pattern-workflow stage prompts, plus the bundled `prompt-engineer` skill (864 → 396 lines), for GPT-5.6, Claude Opus 5, and Claude Fable 5: artifacts before the final query, explicit output and stop contracts, evidence-grounded status claims, damped delegation, and no response prefilling or internal-reasoning requests. Schemas, convergence semantics, and exports are preserved.
|
|
37
|
+
- Changed the builtin Goal execution stage from a direct worker into a Ralph-style sub-agent orchestrator that delegates implementation, validation, and documentation through the `subagent` tool and writes `orchestrator-receipt.md`, while retaining Goal's ledger, reviewer, reducer, and optional PR flow.
|
|
38
|
+
- Strengthened reviewer prompts with a contract-probe playbook and a code-delta integrity contract: reviewers prove the delta exists in the review checkout before trusting receipts, treat claimed-but-absent work as blocking, and flag modified or deleted pre-existing tests ([#1973](https://github.com/bastani-inc/atomic/issues/1973)).
|
|
39
|
+
- Strengthened workflow-authoring and routing guidance to require DAG-only dynamic topologies with pre-launch cycle rejection, bounded loop unrolling, and topology sketches, and to triage multi-item queues into bounded concurrent top-level runs with separate worktrees ([#2010](https://github.com/bastani-inc/atomic/issues/2010), [#2012](https://github.com/bastani-inc/atomic/issues/2012)).
|
|
40
|
+
- Added a worktree-discipline contract to Goal and Ralph prompts (work stays in the invoking checkout), and made PR creation an explicitly authorized `create_pr=true` action rather than embedded task text.
|
|
41
|
+
- Documented deterministic delivery timing for stage messages: `steer` is consumed after the current response finishes its whole tool batch and before the next model request, `followUp` only when the agent would otherwise stop ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
|
|
42
|
+
- Workflow stage chat now renders Atomic's one-cell `∀` on the shared 88 ms luminance ramp, honours caller-supplied palettes through the detected terminal color mode, and drops redundant overlay status chrome.
|
|
43
|
+
|
|
44
|
+
### Removed
|
|
45
|
+
|
|
46
|
+
- Removed the parenthesized context-window authoring token (`(1m)`, `(1.1m)`, `(936k)`, `(long)`) from workflow model strings along with the `contextWindow` / `contextWindowStrict` stage options. Every stage session uses its model's catalog context window.
|
|
47
|
+
- Removed Cursor model fallbacks and Cursor-branded Impeccable harness compatibility ([#1994](https://github.com/bastani-inc/atomic/issues/1994)), and removed the built-in `deep-research-codebase` workflow.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- Fixed workflow graph rendering and memory on large fan-outs. Cards, edges, and composed rows clip to the viewport; store observation offers a synchronous invalidation channel plus one memoized immutable graph projection per store version, so a status update no longer `JSON.stringify`/`JSON.parse`-clones the full run payload; and truncated fields plus durable tool-result summaries copy into fresh flat strings, since a V8 SlicedString kept multi-megabyte results alive behind a 240-character summary ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
|
|
52
|
+
- Fixed graceful quit ignoring in-flight `ctx.tool` calls, which previously reported `No controllable stages on run <id>` and left callbacks running. Quit now counts running tool nodes as controllable work, closes the tool-admission boundary, aborts the whole root/nested set, and only then records the durable paused transition. Resume re-executes the cancelled call at the same node instead of replaying a cancellation as data, a caught cancellation cannot publish a completed run over quit's paused record, and a failed durable write still leaves the run controllable so a retried quit can upgrade the pause ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
|
|
53
|
+
- Fixed durable nested `ctx.workflow(...)` resume and completed hydration across fresh processes: boundary identity persists before child dispatch, ids stay stable under reversed parallel ordering, and stale, aliased, cyclic, or nonreciprocal records fail closed instead of flattening an unrelated run. Completed child work and `ctx.tool(...)` effects stay exactly-once, and ambiguous child-local stage ids no longer route to the first match.
|
|
54
|
+
- Fixed `ctx.tool()` calls durably completing side effects before a late empty-stage rejection. Tools now create ordered, inspectable, non-attachable graph nodes with live, failed, completed, cancelled, and cached states; tool-only workflows complete normally; and terminal publication closes admission so post-terminal calls reject before any callback runs ([#1991](https://github.com/bastani-inc/atomic/issues/1991)).
|
|
55
|
+
- Fixed host-session replacement (`/new`, `/resume`, `/fork`, `/reload`) leaving the process-global DBOS executor stopped, so every later run in the same process failed at its first durable checkpoint with `` `DBOS.launch()` must be called before running workflows ``. The executor lifetime is now process-scoped, and the backend factory never hands out a stopped backend ([#1957](https://github.com/bastani-inc/atomic/issues/1957)).
|
|
56
|
+
- Fixed stage message queues across detach and reattach: a typed Enter in an attached stage chat names steering explicitly instead of being demoted to a follow-up, the stage handle keeps its own projection of `queue_update` snapshots so pending rows survive detaching, the graph shows a `✉ N queued` badge, a session that arrives already holding queued messages replays the snapshot its listeners missed, and Escape restores queued steering and follow-ups into the editor ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
|
|
57
|
+
- Fixed controlled workflow pauses allowing queued or late-arriving work to run after a stage was visibly paused. A synchronous raw queue hold is established before one serialized abort boundary, and resume releases preserved steering, follow-up, custom, async, and user entries exactly once ([#1983](https://github.com/bastani-inc/atomic/issues/1983)).
|
|
58
|
+
- Fixed programmatic `workflow send` reopening retained stage conversations after the root workflow had terminated; terminal roots now return a structured `WORKFLOW_TERMINAL` failure before any session probing or delivery, while `/workflow attach` and Intercom keep their explicit post-mortem paths ([#2009](https://github.com/bastani-inc/atomic/issues/2009)).
|
|
59
|
+
- Fixed three `open-claude-design` faults: a failed `user-feedback-*` stage no longer converts into design approval and exports an unreviewed design ([#2123](https://github.com/bastani-inc/atomic/issues/2123)); research context now persists to `<artifact_dir>/design-context.md` and `references.md` and is read through `reads` instead of embedded inline, removing the `413 request_too_large` class ([#2121](https://github.com/bastani-inc/atomic/issues/2121)); and each refinement round raises a run-level prompt naming the preview path and `file://` URL instead of blocking on live review while reporting `running` ([#2060](https://github.com/bastani-inc/atomic/issues/2060)).
|
|
60
|
+
- Fixed the Ralph research stage destroying its own artifact by declaring the authored report path as its runner-owned `output`; research stages now return the full report as their final message. Fixed the Classify-and-act, Fan-out-and-synthesize, Generate-and-filter, Loop-until-done, and Tournament workflows returning whole terminal artifacts into the calling session's context — each `result` is now the compact artifact reference, with the full report on the existing path outputs.
|
|
61
|
+
- Fixed admitted durable `ctx.tool(...)` failures being misclassified as killed or cancelled, and fixed failed physical session appends leaving malformed JSONL tails, duplicate ids, or phantom parents after a partial write ([#2021](https://github.com/bastani-inc/atomic/issues/2021)).
|
|
62
|
+
- Fixed fresh-process resume and completed-run inspection losing nested child-workflow and parallel hierarchy, and fixed `workflow({ action: "resume", runId })` returning `Run not found` for eligible durably paused runs after session-local state was cleared ([#1924](https://github.com/bastani-inc/atomic/issues/1924)).
|
|
63
|
+
- Fixed session teardown crashing the process with exit code 1 after DBOS provisioning had failed, which turned otherwise-successful `--print` runs into nonzero exits. When no durable backend can be provisioned at all, workflows degrade to a loud non-durable in-memory backend instead of failing every action.
|
|
64
|
+
- Hardened the bundled `impeccable` live-mode scripts against four CodeQL findings (insecure randomness, resource exhaustion, regex injection, double escaping), preserving behaviour for all valid inputs.
|
|
65
|
+
- Fixed retained terminal stage chats dropping the Working indicator after Enter and before the follow-up turn started ([#1982](https://github.com/bastani-inc/atomic/issues/1982)).
|
|
66
|
+
|
|
67
|
+
## [0.9.11-alpha.11] - 2026-08-03
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- Fixed workflow graph rendering for large, wide fan-outs by clipping cards, edges, and composed rows to the visible viewport, retaining cached topology and layout across status-only updates, and making idle animation eligibility constant-time ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
|
|
72
|
+
- Fixed every interactive store mutation cloning the full run payload before the graph could repaint. A status or question update used to build a complete `JSON.stringify`/`JSON.parse` snapshot, traversing workflow inputs, authored stage result bodies, child output values, and tool input/output bodies, so mutation cost scaled with payload size rather than with the graph. Store observation now offers a synchronous invalidation-only channel plus one immutable memoized graph projection per store version, and the graph, overlay, attach pane, stage chat, widget, lifecycle and HIL notifications, resume picker, and send admission all read that projection. In the default configuration (`statusFile: false`), mutations no longer build the legacy full snapshot; enabling `statusFile` retains that snapshot and status-file serialization cost. Topology, status, timing, prompts, attachment state, notices, bounded returned-status fields, durable tool summaries, and child output counts are preserved; the existing `Store.snapshot()` / `Store.subscribe(snapshot)` contract is unchanged for external consumers ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
|
|
73
|
+
- Fixed the memoized graph projection keeping whole run results in memory. Truncating a result field with `slice()` leaves a V8 SlicedString that points at its untruncated parent, so a 1 KiB projected field kept a multi-megabyte run result alive — inside the store's cached projection, and inside every long-lived holder of one — long after the run itself was removed. Truncated fields are now copied into fresh flat strings, so a session with large workflow results no longer grows heap ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
|
|
74
|
+
- Fixed durable tool-result summaries retaining the payloads they summarize. `summarizeToolResult` and `summarizeCompletedToolResult` bounded a serialized value with `` `${serialized.slice(0, 237)}...` ``, which leaves a V8 SlicedString behind a ConsString, both pointing at the untruncated parent — so a 240-character summary written into a durable checkpoint or held in a completed-run catalog row kept the entire `JSON.stringify` output alive (measured at 8.4 MiB for one large tool result). Both summaries now copy into fresh flat strings via a shared `flattenTruncatedString` helper, which the memoized graph projection also uses ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
|
|
75
|
+
- Fixed Escape in an attached workflow-stage chat restoring queued steering and follow-up messages into the editor instead of leaving them stuck in the pending-message queue.
|
|
76
|
+
|
|
9
77
|
## [0.9.11-alpha.9] - 2026-08-01
|
|
10
78
|
|
|
11
79
|
### Added
|
|
@@ -608,7 +608,7 @@ Raw stage-chat prompt answer replay is live-memory only. `StageSnapshot.promptAn
|
|
|
608
608
|
```json
|
|
609
609
|
{
|
|
610
610
|
"name": "workflow",
|
|
611
|
-
"description": "Run named builtin, project, user, or package workflows; custom definitions may import reusable project/package workflows or builtin definitions from @bastani/workflows/builtin and nest them with ctx.workflow(...), including deeper composition within the configured maxDepth; when workflow execution fits but another shape would better achieve the task, author a custom TypeScript workflow({...}) inline with normal coding tools, reload it, and run it; after successfully creating and reloading a newly authored custom workflow, report the folder containing its generated code as 'Custom workflow created. You can inspect its code at: <workflow-folder-path>'; do this only for newly created custom workflows, never builtin or pre-existing workflows; discover with list/get/inputs/models, list session runs with status (no runId; statusFilter narrows the list), inspect status/stages/stage details, send prompt answers or steering only while the root workflow is nonterminal, pause/resume/interrupt/quit runs, and reload workflow resources. For large stage handoffs, write context to files/artifacts, pass paths via reads, and prompt downstream agents to 'Read the file at <path>...' instead of injecting large previous text. For transcripts, prefer status/stages/stage to get sessionFile/transcriptPath, quote the exact path without rewriting separators (Windows backslashes are valid), then search it with rg/grep and read small ranges; transcript is path-only by default when sessionFile/transcriptPath exists, explicit tail/limit returns bounded previews, and missing transcript paths fall back to a small preview. Use action 'models' to inspect models in the configured catalog; the result is a configured-auth snapshot showing what's present in the registry with configured authentication, not proof of credentials, entitlements, OAuth freshness, or live provider access. When authoring a workflow that should dynamically select a model, first call workflow({ action: 'models' }) to inspect the configured catalog, then select from the returned provider/id entries considering the isCurrent marker and available thinking levels.",
|
|
611
|
+
"description": "Run named builtin, project, user, or package workflows; custom definitions may import reusable project/package workflows or builtin definitions from @bastani/workflows/builtin and nest them with ctx.workflow(...), including deeper composition within the configured maxDepth; when workflow execution fits but another shape would better achieve the task, author a custom TypeScript workflow({...}) inline with normal coding tools, reload it, and run it; after successfully creating and reloading a newly authored custom workflow, report the folder containing its generated code as 'Custom workflow created. You can inspect its code at: <workflow-folder-path>'; do this only for newly created custom workflows, never builtin or pre-existing workflows; discover with list/get/inputs/models, list session runs with status (no runId; statusFilter narrows the list), inspect status/stages/stage details, send prompt answers or steering only while the root workflow is nonterminal, pause/resume/interrupt/quit runs, and reload workflow resources. For large stage handoffs, write context to files/artifacts, pass paths via reads, and prompt downstream agents to 'Read the file at <path>...' instead of injecting large previous text. Wrap critical parts of run inputs and steering messages in <keepContext>...</keepContext> so compaction preserves them verbatim in the stages that inherit them; tag role constraints, prohibitions, must-hold criteria, and identifiers, not background or bulk reference material. For transcripts, prefer status/stages/stage to get sessionFile/transcriptPath, quote the exact path without rewriting separators (Windows backslashes are valid), then search it with rg/grep and read small ranges; transcript is path-only by default when sessionFile/transcriptPath exists, explicit tail/limit returns bounded previews, and missing transcript paths fall back to a small preview. Use action 'models' to inspect models in the configured catalog; the result is a configured-auth snapshot showing what's present in the registry with configured authentication, not proof of credentials, entitlements, OAuth freshness, or live provider access. When authoring a workflow that should dynamically select a model, first call workflow({ action: 'models' }) to inspect the configured catalog, then select from the returned provider/id entries considering the isCurrent marker and available thinking levels.",
|
|
612
612
|
"parameters": {
|
|
613
613
|
"workflow": "string (optional) — workflow ID or normalized name",
|
|
614
614
|
"inputs": "object (optional) — key/value map of workflow inputs",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { createWorkflowArtifactDirectory } from "../src/shared/workflow-artifacts.js";
|
|
5
5
|
import { LEDGER_FILENAME, type GoalLedger, type GoalLifecycleEvent } from "./goal-types.js";
|
|
6
6
|
|
|
7
7
|
type ModelVisibleGoalLedger = Omit<
|
|
@@ -55,11 +55,13 @@ export function appendLifecycleEvent(
|
|
|
55
55
|
export async function createGoalLedger(
|
|
56
56
|
objective: string,
|
|
57
57
|
acceptanceCriteria = objective,
|
|
58
|
+
runId?: string,
|
|
58
59
|
): Promise<{ ledger: GoalLedger; ledgerPath: string; artifactDir: string }> {
|
|
59
|
-
const
|
|
60
|
+
const goalId = randomUUID();
|
|
61
|
+
const artifactDir = await createWorkflowArtifactDirectory(runId);
|
|
60
62
|
const now = new Date().toISOString();
|
|
61
63
|
const ledger: GoalLedger = {
|
|
62
|
-
goal_id:
|
|
64
|
+
goal_id: goalId,
|
|
63
65
|
objective,
|
|
64
66
|
acceptance_criteria: acceptanceCriteria,
|
|
65
67
|
status: "active",
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
SCOPE_DISCIPLINE_CONTRACT,
|
|
15
15
|
WORKER_PREFLIGHT_CONTRACT,
|
|
16
16
|
WORKTREE_DISCIPLINE_CONTRACT,
|
|
17
|
+
keepContext,
|
|
17
18
|
renderE2eQaVideoReviewGuidance,
|
|
18
19
|
} from "./shared-prompts.js";
|
|
19
20
|
import type { GoalLedger } from "./goal-types.js";
|
|
@@ -196,7 +197,9 @@ export function renderReviewerPrompt(args: {
|
|
|
196
197
|
"Lead with the verdict. Keep evidence, decisions, caveats, and next action; omit background and repetition while remaining readable rather than using fragments, arrow chains, or invented shorthand.",
|
|
197
198
|
].join("\n")],
|
|
198
199
|
["objective", [
|
|
199
|
-
|
|
200
|
+
keepContext(
|
|
201
|
+
"Act as an independent, skeptical, technically fair reviewer. Inspect and report; do not implement. Protect correctness, security, performance, maintainability, and full objective completion without bikeshedding.",
|
|
202
|
+
),
|
|
200
203
|
args.reviewerRole,
|
|
201
204
|
args.focus,
|
|
202
205
|
"Review the delivered change against the run objective stored in the goal ledger.",
|
|
@@ -64,6 +64,7 @@ function normalizeBranchInput(
|
|
|
64
64
|
}
|
|
65
65
|
type GoalRunnerContext = {
|
|
66
66
|
readonly inputs: GoalWorkflowInputs;
|
|
67
|
+
readonly runId?: string;
|
|
67
68
|
task(name: string, options: WorkflowTaskOptions): Promise<WorkflowTaskResult>;
|
|
68
69
|
parallel(steps: readonly WorkflowTaskStep[], options: WorkflowParallelOptions): Promise<WorkflowTaskResult[]>;
|
|
69
70
|
};
|
|
@@ -109,7 +110,7 @@ export async function runGoalWorkflow(ctx: GoalRunnerContext, options: GoalWorkf
|
|
|
109
110
|
const reviewQuorum = DEFAULT_REVIEW_QUORUM;
|
|
110
111
|
const blockerThreshold = Math.min(DEFAULT_BLOCKER_THRESHOLD, maxTurns);
|
|
111
112
|
const comparisonBaseBranch = normalizeBranchInput(inputs.base_branch, "origin/main");
|
|
112
|
-
const { ledger, ledgerPath, artifactDir } = await createGoalLedger(objective, acceptanceCriteria);
|
|
113
|
+
const { ledger, ledgerPath, artifactDir } = await createGoalLedger(objective, acceptanceCriteria, ctx.runId);
|
|
113
114
|
|
|
114
115
|
let latestReviews: ReviewRecord[] = [];
|
|
115
116
|
let latestReviewArtifactPaths: string[] = [];
|
|
@@ -47,7 +47,7 @@ export default workflow({
|
|
|
47
47
|
goal_id: Type.Optional(Type.String({ description: "Per-run goal identifier stored in the ledger." })),
|
|
48
48
|
objective: Type.Optional(Type.String({ description: "Raw goal objective used by the run." })),
|
|
49
49
|
acceptance_criteria: Type.Optional(Type.String({ description: "Immutable acceptance criteria used by the run." })),
|
|
50
|
-
ledger_path: Type.Optional(Type.String({ description: "
|
|
50
|
+
ledger_path: Type.Optional(Type.String({ description: "Durable run-scoped path to goal-ledger.json with receipts, reviewer decisions, blockers, and lifecycle events." })),
|
|
51
51
|
turns_completed: Type.Optional(Type.Number({ description: "Orchestrator/review turns completed." })),
|
|
52
52
|
iterations_completed: Type.Optional(Type.Number({ description: "Orchestrator/review turns completed, retained for status summaries." })),
|
|
53
53
|
receipts: Type.Optional(Type.Array(Type.Object({
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { mkdir,
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
2
|
import { dirname, join } from "node:path";
|
|
4
3
|
import { Type } from "typebox";
|
|
5
4
|
import type { WorkflowTaskResult } from "../src/shared/types.js";
|
|
5
|
+
import { createWorkflowArtifactDirectory } from "../src/shared/workflow-artifacts.js";
|
|
6
6
|
import {
|
|
7
7
|
E2E_VERIFICATION_GUIDANCE,
|
|
8
|
+
keepContext,
|
|
8
9
|
LITERAL_OBJECTIVE_CONTRACT,
|
|
9
10
|
} from "./shared-prompts.js";
|
|
10
11
|
import type { ReviewDecision, ReviewFinding } from "./ralph-review-gate.js";
|
|
@@ -170,8 +171,8 @@ export function defaultResearchPath(prompt: string, now = new Date()): string {
|
|
|
170
171
|
return join(DEFAULT_RESEARCH_DIR, `${date}-${slugifyResearchTopic(prompt)}.md`);
|
|
171
172
|
}
|
|
172
173
|
|
|
173
|
-
export async function createImplementationNotesFile(prompt: string): Promise<string> {
|
|
174
|
-
const notesDir = await
|
|
174
|
+
export async function createImplementationNotesFile(prompt: string, runId?: string): Promise<string> {
|
|
175
|
+
const notesDir = await createWorkflowArtifactDirectory(runId);
|
|
175
176
|
const notesPath = join(notesDir, IMPLEMENTATION_NOTES_FILENAME);
|
|
176
177
|
const initialNotes = [
|
|
177
178
|
"# Implementation Notes",
|
|
@@ -195,8 +196,8 @@ export async function createImplementationNotesFile(prompt: string): Promise<str
|
|
|
195
196
|
// write to it; the video file itself is produced by the orchestrator's QA pass
|
|
196
197
|
// (and overwritten each iteration so it always reflects the latest state). The
|
|
197
198
|
// final pull-request stage attaches it when it exists.
|
|
198
|
-
export async function createQaEvidenceVideoPath(): Promise<string> {
|
|
199
|
-
const qaDir = await
|
|
199
|
+
export async function createQaEvidenceVideoPath(runId?: string): Promise<string> {
|
|
200
|
+
const qaDir = await createWorkflowArtifactDirectory(runId);
|
|
200
201
|
return join(qaDir, QA_E2E_VIDEO_FILENAME);
|
|
201
202
|
}
|
|
202
203
|
|
|
@@ -336,7 +337,7 @@ export function renderResearchPromptRefinementPrompt(args: {
|
|
|
336
337
|
readonly latestReviewReportPath: string | undefined;
|
|
337
338
|
}): string {
|
|
338
339
|
return taggedPrompt([
|
|
339
|
-
["acceptance_criteria", args.acceptanceCriteria],
|
|
340
|
+
["acceptance_criteria", keepContext(args.acceptanceCriteria)],
|
|
340
341
|
["literal_contract", LITERAL_OBJECTIVE_CONTRACT],
|
|
341
342
|
args.workflowCwdContext,
|
|
342
343
|
[
|
|
@@ -351,7 +352,9 @@ export function renderResearchPromptRefinementPrompt(args: {
|
|
|
351
352
|
["objective", `Research the full requested task: ${args.request}`],
|
|
352
353
|
[
|
|
353
354
|
"output",
|
|
354
|
-
|
|
355
|
+
keepContext(
|
|
356
|
+
"Return only one concise, complete codebase and online research question. Do not implement code changes or write an RFC/spec.",
|
|
357
|
+
),
|
|
355
358
|
],
|
|
356
359
|
[
|
|
357
360
|
"instruction",
|
|
@@ -367,10 +370,9 @@ export function renderResearchPrompt(args: {
|
|
|
367
370
|
readonly acceptanceCriteria: string;
|
|
368
371
|
readonly workflowCwdContext: PromptSection;
|
|
369
372
|
readonly latestReviewReportPath: string | undefined;
|
|
370
|
-
readonly researchPath: string;
|
|
371
373
|
}): string {
|
|
372
374
|
return taggedPrompt([
|
|
373
|
-
["acceptance_criteria", args.acceptanceCriteria],
|
|
375
|
+
["acceptance_criteria", keepContext(args.acceptanceCriteria)],
|
|
374
376
|
["literal_contract", LITERAL_OBJECTIVE_CONTRACT],
|
|
375
377
|
args.workflowCwdContext,
|
|
376
378
|
[
|
|
@@ -386,11 +388,10 @@ export function renderResearchPrompt(args: {
|
|
|
386
388
|
[
|
|
387
389
|
"research_artifact",
|
|
388
390
|
[
|
|
389
|
-
"Return the complete research report as your final message.
|
|
390
|
-
`Do not write ${args.researchPath} yourself. Anything written there during this stage is replaced by your final message, so a file you author is lost and a final message that only points at the path leaves later stages with no findings. Skill-owned notes under research/docs/ and research/web/ are unaffected.`,
|
|
391
|
+
"Return the complete research report as your final message. Downstream implementation and review stages read it from there.",
|
|
391
392
|
"Produce a complete Markdown report with codebase and useful online/contextual findings, implementation guidance, relevant files/tests/docs, unresolved-finding analysis, and validation recommendations. Lead with conclusions; keep facts, caveats, and implementation-relevant next steps; drop background and repetition.",
|
|
392
393
|
"Before reporting progress, audit each claim against a tool result from this session. Report only work you can point to evidence for; say so explicitly when something is unverified.",
|
|
393
|
-
"Do not author an RFC/spec or implement code changes.",
|
|
394
|
+
keepContext("This stage researches only. Do not author an RFC/spec or implement code changes."),
|
|
394
395
|
].join("\n"),
|
|
395
396
|
],
|
|
396
397
|
[
|
|
@@ -417,6 +418,7 @@ export type RalphWorkflowOptions = {
|
|
|
417
418
|
readonly comparisonBaseBranch: string;
|
|
418
419
|
readonly workflowStartCwd: string;
|
|
419
420
|
readonly createPr: boolean;
|
|
421
|
+
readonly runId?: string;
|
|
420
422
|
};
|
|
421
423
|
|
|
422
424
|
export type RalphWorkflowResult = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Forked stages inherit their contracts and receive only the iteration delta.
|
|
2
2
|
import { taggedPrompt } from "./ralph-core.js";
|
|
3
|
+
import { keepContext } from "./shared-prompts.js";
|
|
3
4
|
|
|
4
5
|
export function renderForkedResearchPromptRefinementPrompt(args: {
|
|
5
6
|
readonly latestReviewReportPath: string | undefined;
|
|
@@ -16,7 +17,9 @@ export function renderForkedResearchPromptRefinementPrompt(args: {
|
|
|
16
17
|
],
|
|
17
18
|
[
|
|
18
19
|
"output",
|
|
19
|
-
|
|
20
|
+
keepContext(
|
|
21
|
+
"Return only one concise, complete codebase and online research question. Do not implement code changes or write an RFC/spec.",
|
|
22
|
+
),
|
|
20
23
|
],
|
|
21
24
|
[
|
|
22
25
|
"instruction",
|
|
@@ -28,7 +31,6 @@ export function renderForkedResearchPromptRefinementPrompt(args: {
|
|
|
28
31
|
export function renderForkedResearchPrompt(args: {
|
|
29
32
|
readonly transformedResearchQuestion: string;
|
|
30
33
|
readonly latestReviewReportPath: string | undefined;
|
|
31
|
-
readonly researchPath: string;
|
|
32
34
|
}): string {
|
|
33
35
|
return taggedPrompt([
|
|
34
36
|
[
|
|
@@ -43,10 +45,9 @@ export function renderForkedResearchPrompt(args: {
|
|
|
43
45
|
[
|
|
44
46
|
"research_artifact",
|
|
45
47
|
[
|
|
46
|
-
"Return the rewritten research report for this iteration as your final message.
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
"Do not author an RFC/spec or implement code changes.",
|
|
48
|
+
"Return the rewritten research report for this iteration as your final message.",
|
|
49
|
+
"Restate the still-applicable findings in full rather than referring back to the previous iteration's artifact; the current artifact and transcript are the authoritative records for this iteration.",
|
|
50
|
+
keepContext("This stage researches only. Do not author an RFC/spec or implement code changes."),
|
|
50
51
|
].join("\n"),
|
|
51
52
|
],
|
|
52
53
|
[
|
|
@@ -48,10 +48,10 @@ export const promptEngineerModelConfig = {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
export const researchModelConfig = {
|
|
51
|
-
model: "openai-codex/gpt-5.6-
|
|
51
|
+
model: "openai-codex/gpt-5.6-luna:max",
|
|
52
52
|
fallbackModels: [
|
|
53
|
-
"github-copilot/gpt-5.6-
|
|
54
|
-
"openai/gpt-5.6-
|
|
53
|
+
"github-copilot/gpt-5.6-luna:max",
|
|
54
|
+
"openai/gpt-5.6-luna:max",
|
|
55
55
|
"anthropic/claude-opus-5:low",
|
|
56
56
|
"github-copilot/claude-opus-5:low",
|
|
57
57
|
"anthropic/claude-fable-5:low",
|
|
@@ -64,7 +64,7 @@ export const researchModelConfig = {
|
|
|
64
64
|
"xai/grok-4.5:high",
|
|
65
65
|
"zai/glm-5.2:high",
|
|
66
66
|
"zai-coding-cn/glm-5.2:high",
|
|
67
|
-
"openrouter/openai/gpt-5.6-
|
|
67
|
+
"openrouter/openai/gpt-5.6-luna:max",
|
|
68
68
|
"openrouter/anthropic/claude-opus-5:low",
|
|
69
69
|
"openrouter/openai/gpt-5.5:medium",
|
|
70
70
|
"openrouter/anthropic/claude-fable-5:low",
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
REVIEWER_OVERIMPLEMENTATION_GUARD,
|
|
11
11
|
REVIEWER_SPEC_VS_OBJECTIVE_GUARD,
|
|
12
12
|
WORKTREE_DISCIPLINE_CONTRACT,
|
|
13
|
+
keepContext,
|
|
13
14
|
renderE2eQaVideoReviewGuidance,
|
|
14
15
|
} from "./shared-prompts.js";
|
|
15
16
|
import { taggedPrompt, type PromptSection } from "./ralph-core.js";
|
|
@@ -26,7 +27,7 @@ export function renderRalphReviewerPrompt(args: {
|
|
|
26
27
|
readonly createPr: boolean;
|
|
27
28
|
}): string {
|
|
28
29
|
return taggedPrompt([
|
|
29
|
-
["acceptance_criteria", args.acceptanceCriteria],
|
|
30
|
+
["acceptance_criteria", keepContext(args.acceptanceCriteria)],
|
|
30
31
|
[
|
|
31
32
|
"review_context",
|
|
32
33
|
[
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import { mkdtemp } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
2
|
import { join, resolve } from "node:path";
|
|
5
3
|
import type { WorkflowRunContext, WorkflowTaskResult } from "../src/shared/types.js";
|
|
4
|
+
import { createWorkflowArtifactDirectory } from "../src/shared/workflow-artifacts.js";
|
|
6
5
|
import {
|
|
7
6
|
ACCEPTANCE_MATRIX_CONTRACT,
|
|
8
7
|
CONTRACT_FIDELITY_AUDIT,
|
|
@@ -12,6 +11,7 @@ import {
|
|
|
12
11
|
SCOPE_DISCIPLINE_CONTRACT,
|
|
13
12
|
WORKER_PREFLIGHT_CONTRACT,
|
|
14
13
|
WORKTREE_DISCIPLINE_CONTRACT,
|
|
14
|
+
keepContext,
|
|
15
15
|
} from "./shared-prompts.js";
|
|
16
16
|
import { renderRalphReviewerPrompt } from "./ralph-reviewer-prompt.js";
|
|
17
17
|
import {
|
|
@@ -52,7 +52,7 @@ export async function runRalphWorkflow(
|
|
|
52
52
|
ctx: WorkflowRunContext<RalphInputs>,
|
|
53
53
|
options: RalphWorkflowOptions,
|
|
54
54
|
): Promise<RalphWorkflowResult> {
|
|
55
|
-
const { prompt, acceptanceCriteria, maxLoops, comparisonBaseBranch, workflowStartCwd, createPr } = options;
|
|
55
|
+
const { prompt, acceptanceCriteria, maxLoops, comparisonBaseBranch, workflowStartCwd, createPr, runId } = options;
|
|
56
56
|
let latestReviewReportPath: string | undefined;
|
|
57
57
|
let finalPlan = "";
|
|
58
58
|
let finalPlanPath = "";
|
|
@@ -63,9 +63,9 @@ export async function runRalphWorkflow(
|
|
|
63
63
|
const workflowCwdContext = workflowCwdContextSection(workflowStartCwd);
|
|
64
64
|
const workflowPrompt = prompt;
|
|
65
65
|
const workflowResearchPath = resolve(workflowStartCwd, defaultResearchPath(workflowPrompt));
|
|
66
|
-
const implementationNotesPath = await createImplementationNotesFile(workflowPrompt);
|
|
67
|
-
const qaVideoPath = await createQaEvidenceVideoPath();
|
|
68
|
-
const artifactDir = await
|
|
66
|
+
const implementationNotesPath = await createImplementationNotesFile(workflowPrompt, runId);
|
|
67
|
+
const qaVideoPath = await createQaEvidenceVideoPath(runId);
|
|
68
|
+
const artifactDir = await createWorkflowArtifactDirectory(runId);
|
|
69
69
|
let approved = false;
|
|
70
70
|
let iterationsCompleted = 0;
|
|
71
71
|
let previousResearchPromptRefinementSessionFile: string | undefined;
|
|
@@ -98,12 +98,10 @@ export async function runRalphWorkflow(
|
|
|
98
98
|
acceptanceCriteria,
|
|
99
99
|
workflowCwdContext,
|
|
100
100
|
latestReviewReportPath,
|
|
101
|
-
researchPath: workflowResearchPath,
|
|
102
101
|
})
|
|
103
102
|
: renderForkedResearchPrompt({
|
|
104
103
|
transformedResearchQuestion: researchPromptRefinement.text,
|
|
105
104
|
latestReviewReportPath,
|
|
106
|
-
researchPath: workflowResearchPath,
|
|
107
105
|
}),
|
|
108
106
|
reads: latestReviewReportPath === undefined ? [] : [latestReviewReportPath],
|
|
109
107
|
output: workflowResearchPath,
|
|
@@ -120,7 +118,7 @@ export async function runRalphWorkflow(
|
|
|
120
118
|
const orchestratorForkOptions = forkContinuationOptions(previousOrchestratorSessionFile);
|
|
121
119
|
const orchestratorPrompt = orchestratorForkOptions.forkFromSessionFile === undefined
|
|
122
120
|
? taggedPrompt([
|
|
123
|
-
["acceptance_criteria", acceptanceCriteria],
|
|
121
|
+
["acceptance_criteria", keepContext(acceptanceCriteria)],
|
|
124
122
|
["literal_contract", LITERAL_OBJECTIVE_CONTRACT],
|
|
125
123
|
["acceptance_matrix", ACCEPTANCE_MATRIX_CONTRACT],
|
|
126
124
|
["divergence_audit", CONTRACT_FIDELITY_AUDIT],
|
|
@@ -41,7 +41,7 @@ export default workflow({
|
|
|
41
41
|
plan_path: Type.Optional(Type.String({ description: "Backward-compatible alias for research_path." })),
|
|
42
42
|
research: Type.Optional(Type.String({ description: "Latest research report text or artifact reference." })),
|
|
43
43
|
research_path: Type.Optional(Type.String({ description: "Path to the latest generated research artifact under research/." })),
|
|
44
|
-
implementation_notes_path: Type.Optional(Type.String({ description: "
|
|
44
|
+
implementation_notes_path: Type.Optional(Type.String({ description: "Durable run-scoped notes file containing decisions, deviations, blockers, and validation notes." })),
|
|
45
45
|
qa_video_path: Type.Optional(Type.String({ description: "Absolute path to the reviewable QA end-to-end proof video recorded with playwright-cli for UI-applicable changes, when one was produced." })),
|
|
46
46
|
pr_report: Type.Optional(Type.String({ description: "Pull-request report emitted only when create_pr=true and the final pull-request stage runs." })),
|
|
47
47
|
approved: Type.Optional(Type.Boolean({ description: "Whether the reviewer loop approved before completion or optional final handoff." })),
|
|
@@ -72,6 +72,7 @@ export default workflow({
|
|
|
72
72
|
comparisonBaseBranch,
|
|
73
73
|
workflowStartCwd,
|
|
74
74
|
createPr,
|
|
75
|
+
runId: workflowCtx.runId,
|
|
75
76
|
});
|
|
76
77
|
},
|
|
77
78
|
});
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
// Builtin prompts use the same public `keepContext` helper workflow authors do, so the
|
|
2
|
+
// protection semantics cannot drift between builtin and user-authored workflows.
|
|
3
|
+
import { keepContext } from "../src/authoring/keep-context.js";
|
|
4
|
+
|
|
5
|
+
export { keepContext };
|
|
6
|
+
|
|
1
7
|
/**
|
|
2
8
|
* Steering propagation is a whole-repository pattern, not a per-workflow
|
|
3
9
|
* option: every builtin stage prompt carries STEERING_PROPAGATION_CONTRACT
|
|
@@ -29,10 +35,15 @@ export const STEERING_PROPAGATION_CONTRACT = [
|
|
|
29
35
|
* section, which carries the strongest positional weight. The contract is
|
|
30
36
|
* inserted immediately before that closing section rather than after it, so a
|
|
31
37
|
* stage's final words remain its instruction.
|
|
38
|
+
*
|
|
39
|
+
* The contract is `keepContext`-protected because only the user may amend a run's contract,
|
|
40
|
+
* and an amendment reaches later stages solely through this restatement duty. Compacted away,
|
|
41
|
+
* the run silently reverts to the launch contract while the implementer builds to the amended
|
|
42
|
+
* one — the exact split this pattern exists to prevent.
|
|
32
43
|
*/
|
|
33
44
|
export function withSteeringPropagation(prompt: string): string {
|
|
34
45
|
if (prompt.includes("<steering_propagation>")) return prompt;
|
|
35
|
-
const tagged = `<steering_propagation>\n${STEERING_PROPAGATION_CONTRACT}\n</steering_propagation>`;
|
|
46
|
+
const tagged = `<steering_propagation>\n${keepContext(STEERING_PROPAGATION_CONTRACT)}\n</steering_propagation>`;
|
|
36
47
|
const instructionAt = prompt.lastIndexOf("\n\n<instruction>");
|
|
37
48
|
if (instructionAt === -1) return `${prompt}\n\n${tagged}`;
|
|
38
49
|
return `${prompt.slice(0, instructionAt)}\n\n${tagged}${prompt.slice(instructionAt)}`;
|
|
@@ -69,7 +80,12 @@ export function renderE2eQaVideoReviewGuidance(
|
|
|
69
80
|
].join("\n");
|
|
70
81
|
}
|
|
71
82
|
|
|
72
|
-
|
|
83
|
+
/**
|
|
84
|
+
* `keepContext`-protected: this is the run's immutable contract and its central prohibition
|
|
85
|
+
* ("You may never widen the contract yourself"). A prohibition deleted from context reads as
|
|
86
|
+
* permission, so losing it turns scope creep into apparently sanctioned work.
|
|
87
|
+
*/
|
|
88
|
+
export const LITERAL_OBJECTIVE_CONTRACT = keepContext([
|
|
73
89
|
"Literal objective contract:",
|
|
74
90
|
"- The objective and acceptance criteria are the sole literal source of required behavior; the run objective must not contradict them.",
|
|
75
91
|
"- Only the user may change the contract. A mid-run user message — steering, a follow-up, or resume text — is authoritative: adopt it as required behavior from that point on, and carry it forward under the steering propagation contract. You may never widen the contract yourself; an improvement you thought of is deferred work, not a new criterion.",
|
|
@@ -78,7 +94,7 @@ export const LITERAL_OBJECTIVE_CONTRACT = [
|
|
|
78
94
|
"- That loud-error preference applies only to enumerated errors. Otherwise accept permissively: do not invent behavior, restrictions, validation errors, required fields, uniqueness/format constraints, or follow-up requirements.",
|
|
79
95
|
"- Produce named types, shapes, and formats exactly; do not substitute proxies, frozen collections, tuples-for-lists, or wrappers unless required because consumers may check identity.",
|
|
80
96
|
"- Where behavior is unspecified, preserve input verbatim rather than normalizing, deduplicating, reordering, or rewriting it.",
|
|
81
|
-
].join("\n");
|
|
97
|
+
].join("\n"));
|
|
82
98
|
|
|
83
99
|
export const REVIEWER_SPEC_VS_OBJECTIVE_GUARD =
|
|
84
100
|
"External spec/standard conformance alone does not make a wide trigger for an enumerated error defective; classify that spec-vs-objective tension as beyond_objective, not blocking.";
|
|
@@ -129,7 +145,12 @@ export const FINDINGS_CONSOLIDATION_CONTRACT = [
|
|
|
129
145
|
"Defer only a genuinely blocked or contract-contradicting finding, recording the reason in the receipt.",
|
|
130
146
|
].join("\n");
|
|
131
147
|
|
|
132
|
-
|
|
148
|
+
/**
|
|
149
|
+
* `keepContext`-protected: every clause here is a prohibition, and prohibitions are the class
|
|
150
|
+
* compaction erodes first — they are terse, stated once, and low-density next to the objective
|
|
151
|
+
* they bound. Losing this reads as license to keep going.
|
|
152
|
+
*/
|
|
153
|
+
export const SCOPE_DISCIPLINE_CONTRACT = keepContext([
|
|
133
154
|
"Scope discipline:",
|
|
134
155
|
"- Before writing code, state the goal in one sentence and list the acceptance criteria. That list is the contract. Freeze it.",
|
|
135
156
|
"- Done means the contract, not \"good.\" When all criteria pass, stop. Polish, refactors, and \"while I'm here\" fixes are new work, not this work.",
|
|
@@ -139,7 +160,7 @@ export const SCOPE_DISCIPLINE_CONTRACT = [
|
|
|
139
160
|
"- Watch for the tells. \"It would be cleaner if...\", \"we should also...\", \"this really ought to...\" mean you are about to move the goalpost. Stop and check the contract.",
|
|
140
161
|
"- Prefer the smallest diff that satisfies the contract: fewer files touched, fewer abstractions introduced, no speculative generality for futures nobody asked for.",
|
|
141
162
|
"- Report three things at the end: what the contract was, evidence each criterion passes, and the deferred list. Scope changes belong in the report, never in the diff.",
|
|
142
|
-
].join("\n");
|
|
163
|
+
].join("\n"));
|
|
143
164
|
|
|
144
165
|
export const EVIDENCE_CLOSURE_POLICY = [
|
|
145
166
|
"Convergence flag (stop_review_loop):",
|
|
@@ -149,10 +170,16 @@ export const EVIDENCE_CLOSURE_POLICY = [
|
|
|
149
170
|
"- If the bounded loop ends first, preserve unresolved findings and remaining work for a human rather than relabeling them.",
|
|
150
171
|
].join("\n");
|
|
151
172
|
|
|
152
|
-
|
|
173
|
+
/**
|
|
174
|
+
* `keepContext`-protected: this binds the stage to a specific checkout, and a checkout is
|
|
175
|
+
* exactly the kind of identifier a stage must not lose. Compacted away during a long run, an
|
|
176
|
+
* agent hitting a lock or dirty state invents a second worktree and the delivered delta lands
|
|
177
|
+
* somewhere the reviewers never look. It is two lines, so protection costs almost nothing.
|
|
178
|
+
*/
|
|
179
|
+
export const WORKTREE_DISCIPLINE_CONTRACT = keepContext([
|
|
153
180
|
"Work in the workflow-designated checkout. Do not create another worktree, clone, or repository copy unless the task requests it; conflicts, locks, dirty state, and failed commands do not authorize one.",
|
|
154
181
|
"Bring required work found elsewhere into this checkout by applying, cherry-picking, or replaying it before continuing.",
|
|
155
|
-
].join("\n");
|
|
182
|
+
].join("\n"));
|
|
156
183
|
|
|
157
184
|
export const REVIEW_CODE_DELTA_CONTRACT = [
|
|
158
185
|
"Code delta integrity:",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `keepContext` marks prompt text that compaction must never compress.
|
|
3
|
+
*
|
|
4
|
+
* This is a pure string transform rather than a `ctx.*` primitive: it creates no graph node,
|
|
5
|
+
* has no side effect, and needs no durability, so it is safe to call anywhere a prompt is
|
|
6
|
+
* assembled — including outside a run.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const KEEP_CONTEXT_OPEN_TAG = "<keepContext>";
|
|
10
|
+
export const KEEP_CONTEXT_CLOSE_TAG = "</keepContext>";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Wrap text so compaction protects it verbatim.
|
|
14
|
+
*
|
|
15
|
+
* Every line of the span, tag lines included, becomes a protected line, and protected lines are
|
|
16
|
+
* removed from the planner's deletion ranges after it responds, so the span survives regardless
|
|
17
|
+
* of the compression ratio. Because the tag lines are protected too, the span is re-detected on
|
|
18
|
+
* each subsequent boundary and stays protected for the life of the session.
|
|
19
|
+
*
|
|
20
|
+
* Tags must sit on their own line, and a span is scoped to one message. User and assistant
|
|
21
|
+
* messages may both protect, so an agent can pin its own core information as well as its prompt;
|
|
22
|
+
* tags inside tool results are inert, so file, page, or command output an agent reads cannot
|
|
23
|
+
* mark itself unreclaimable.
|
|
24
|
+
*
|
|
25
|
+
* Reserve it for text whose loss silently changes behavior — role constraints, acceptance
|
|
26
|
+
* criteria and immutable contracts, explicit prohibitions, and identifiers a stage must not
|
|
27
|
+
* lose such as a target branch, worktree path, or run ID. Compaction ranks lines individually,
|
|
28
|
+
* so a terse constraint loses to the verbose objective it qualifies, and a prohibition deleted
|
|
29
|
+
* from context reads as permission.
|
|
30
|
+
*
|
|
31
|
+
* Do not wrap bulk context. Protected lines count against the keep target rather than raising
|
|
32
|
+
* it, so a large protected span makes the surrounding transcript compress harder; tag the
|
|
33
|
+
* constraint, not the material it applies to, and pass that through files and `reads`.
|
|
34
|
+
*
|
|
35
|
+
* Nesting is flattened rather than rejected: an already-wrapped string is returned unchanged.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const prompt = `${keepContext("Research only. Do not implement code changes.")}\n\n${question}`;
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function keepContext(text: string): string {
|
|
43
|
+
const trimmed = text.trim();
|
|
44
|
+
if (trimmed.startsWith(KEEP_CONTEXT_OPEN_TAG) && trimmed.endsWith(KEEP_CONTEXT_CLOSE_TAG)) return trimmed;
|
|
45
|
+
return `${KEEP_CONTEXT_OPEN_TAG}\n${trimmed}\n${KEEP_CONTEXT_CLOSE_TAG}`;
|
|
46
|
+
}
|
|
@@ -44,6 +44,17 @@ export interface WorkflowRegistry {
|
|
|
44
44
|
*/
|
|
45
45
|
export declare const runWorkflow: never;
|
|
46
46
|
export declare function workflow<const TInputs extends WorkflowInputSchemaMap = Record<never, never>, const TOutputs extends WorkflowOutputSchemaMap = WorkflowOutputSchemaMap, TActualOutputs extends WorkflowOutputsFromSchemas<TOutputs> = WorkflowOutputsFromSchemas<TOutputs>>(spec: AuthoredWorkflowSpec<TInputs, TOutputs, TActualOutputs>): AuthoredWorkflowDefinition<TInputs, TOutputs>;
|
|
47
|
+
/**
|
|
48
|
+
* Wrap prompt text so compaction protects it verbatim, regardless of the compression ratio.
|
|
49
|
+
*
|
|
50
|
+
* Reserve it for text whose loss silently changes behavior: role constraints, acceptance
|
|
51
|
+
* criteria and immutable contracts, explicit prohibitions, and identifiers a stage must not
|
|
52
|
+
* lose. Do not wrap bulk context — protected lines count against the keep target rather than
|
|
53
|
+
* raising it, so a large span makes the surrounding transcript compress harder.
|
|
54
|
+
*/
|
|
55
|
+
export declare function keepContext(text: string): string;
|
|
56
|
+
export declare const KEEP_CONTEXT_OPEN_TAG: string;
|
|
57
|
+
export declare const KEEP_CONTEXT_CLOSE_TAG: string;
|
|
47
58
|
export declare function createRegistry<TDefinitions extends readonly AnyWorkflowDefinition[] = readonly AnyWorkflowDefinition[]>(initial?: TDefinitions): WorkflowRegistry;
|
|
48
59
|
export declare function normalizeWorkflowName(name: string): string;
|
|
49
60
|
export declare function workflowNamesEqual(a: string, b: string): boolean;
|