@bastani/atomic 0.9.8 → 0.9.9-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 +28 -0
- package/dist/builtin/cursor/CHANGELOG.md +6 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +6 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +6 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +2 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +7 -1
- package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +2 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +8 -2
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +2 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +2 -0
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +6 -0
- package/dist/builtin/subagents/src/shared/types-config.ts +4 -0
- package/dist/builtin/subagents/src/shared/types-depth.ts +29 -2
- package/dist/builtin/web-access/CHANGELOG.md +6 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +22 -0
- package/dist/builtin/workflows/README.md +17 -8
- package/dist/builtin/workflows/builtin/goal-prompts.ts +8 -2
- package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +26 -9
- package/dist/builtin/workflows/builtin/ralph-forked-prompts.ts +1 -1
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +8 -3
- package/dist/builtin/workflows/builtin/ralph-runner.ts +2 -0
- package/dist/builtin/workflows/builtin/shared-prompts.ts +24 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/durable/backend.ts +53 -15
- package/dist/builtin/workflows/src/durable/completed-catalog.ts +245 -0
- package/dist/builtin/workflows/src/durable/completed-inspection.ts +213 -0
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +120 -170
- package/dist/builtin/workflows/src/durable/dbos-envelope.ts +84 -8
- package/dist/builtin/workflows/src/durable/dbos-metadata.ts +98 -0
- package/dist/builtin/workflows/src/durable/dbos-tombstone.ts +27 -0
- package/dist/builtin/workflows/src/durable/factory.ts +1 -1
- package/dist/builtin/workflows/src/durable/file-backend.ts +247 -241
- package/dist/builtin/workflows/src/durable/file-lock.ts +153 -0
- package/dist/builtin/workflows/src/durable/file-state.ts +104 -0
- package/dist/builtin/workflows/src/durable/format-version.ts +12 -0
- package/dist/builtin/workflows/src/durable/index.ts +12 -0
- package/dist/builtin/workflows/src/durable/resume-catalog.ts +16 -27
- package/dist/builtin/workflows/src/durable/resume-eligibility.ts +20 -0
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +29 -29
- package/dist/builtin/workflows/src/durable/scoped-backend.ts +20 -3
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +29 -8
- package/dist/builtin/workflows/src/durable/types.ts +3 -0
- package/dist/builtin/workflows/src/engine/primitives/task.ts +1 -0
- package/dist/builtin/workflows/src/engine/run.ts +14 -14
- package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +39 -9
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +10 -0
- package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +133 -0
- package/dist/builtin/workflows/src/extension/runtime.ts +15 -40
- package/dist/builtin/workflows/src/extension/wiring.ts +9 -6
- package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +226 -0
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +1 -0
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +66 -112
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +5 -5
- package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +16 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +50 -43
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-output.ts +91 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-direct.ts +95 -46
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +3 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-task-prompts.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +3 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +36 -7
- package/dist/builtin/workflows/src/runs/shared/worktree-cache-lifecycle.ts +25 -0
- package/dist/builtin/workflows/src/runs/shared/worktree-cwd.ts +103 -0
- package/dist/builtin/workflows/src/runs/shared/worktree-generation.ts +57 -0
- package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +134 -8
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -0
- package/dist/builtin/workflows/src/shared/resumable-workflow-notices.ts +43 -0
- package/dist/builtin/workflows/src/shared/timing.ts +4 -0
- package/dist/builtin/workflows/src/shared/types.ts +5 -3
- package/dist/builtin/workflows/src/tui/graph-view-constants.ts +1 -0
- package/dist/builtin/workflows/src/tui/graph-view-input.ts +24 -14
- package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +43 -13
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +5 -7
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +6 -34
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +95 -233
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts +0 -4
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +1 -5
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +5 -6
- 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-types.d.ts +2 -12
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction-boundary.d.ts +9 -0
- package/dist/core/compaction/compaction-boundary.d.ts.map +1 -0
- package/dist/core/compaction/compaction-boundary.js +115 -0
- package/dist/core/compaction/compaction-boundary.js.map +1 -0
- package/dist/core/compaction/compaction-parameters.d.ts +5 -0
- package/dist/core/compaction/compaction-parameters.d.ts.map +1 -0
- package/dist/core/compaction/compaction-parameters.js +27 -0
- package/dist/core/compaction/compaction-parameters.js.map +1 -0
- package/dist/core/compaction/compaction-runner.d.ts +14 -0
- package/dist/core/compaction/compaction-runner.d.ts.map +1 -0
- package/dist/core/compaction/compaction-runner.js +29 -0
- package/dist/core/compaction/compaction-runner.js.map +1 -0
- package/dist/core/compaction/compaction-types.d.ts +79 -0
- package/dist/core/compaction/compaction-types.d.ts.map +1 -0
- package/dist/core/compaction/compaction-types.js +6 -0
- package/dist/core/compaction/compaction-types.js.map +1 -0
- package/dist/core/compaction/deleted-ranges.d.ts +6 -0
- package/dist/core/compaction/deleted-ranges.d.ts.map +1 -0
- package/dist/core/compaction/deleted-ranges.js +134 -0
- package/dist/core/compaction/deleted-ranges.js.map +1 -0
- package/dist/core/compaction/index.d.ts +7 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +7 -1
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/range-planner.d.ts +21 -0
- package/dist/core/compaction/range-planner.d.ts.map +1 -0
- package/dist/core/compaction/range-planner.js +145 -0
- package/dist/core/compaction/range-planner.js.map +1 -0
- package/dist/core/compaction/transcript-serialization.d.ts +11 -0
- package/dist/core/compaction/transcript-serialization.d.ts.map +1 -0
- package/dist/core/compaction/transcript-serialization.js +104 -0
- package/dist/core/compaction/transcript-serialization.js.map +1 -0
- package/dist/core/extensions/context-types.d.ts +2 -2
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/event-results.d.ts +2 -2
- package/dist/core/extensions/event-results.d.ts.map +1 -1
- package/dist/core/extensions/event-results.js.map +1 -1
- package/dist/core/extensions/session-events.d.ts +7 -7
- package/dist/core/extensions/session-events.d.ts.map +1 -1
- package/dist/core/extensions/session-events.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/messages.d.ts +4 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +11 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/provider-context-usage.d.ts.map +1 -1
- package/dist/core/provider-context-usage.js +1 -2
- package/dist/core/provider-context-usage.js.map +1 -1
- package/dist/core/session-manager-archive.d.ts +2 -1
- package/dist/core/session-manager-archive.d.ts.map +1 -1
- package/dist/core/session-manager-archive.js +2 -2
- package/dist/core/session-manager-archive.js.map +1 -1
- package/dist/core/session-manager-classification.d.ts +9 -0
- package/dist/core/session-manager-classification.d.ts.map +1 -0
- package/dist/core/session-manager-classification.js +37 -0
- package/dist/core/session-manager-classification.js.map +1 -0
- package/dist/core/session-manager-core.d.ts +4 -4
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +13 -8
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-entries.d.ts +4 -3
- package/dist/core/session-manager-entries.d.ts.map +1 -1
- package/dist/core/session-manager-entries.js +12 -10
- package/dist/core/session-manager-entries.js.map +1 -1
- package/dist/core/session-manager-history.d.ts +6 -23
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +23 -256
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/session-manager-list.d.ts.map +1 -1
- package/dist/core/session-manager-list.js +3 -3
- package/dist/core/session-manager-list.js.map +1 -1
- package/dist/core/session-manager-storage.d.ts +1 -1
- package/dist/core/session-manager-storage.d.ts.map +1 -1
- package/dist/core/session-manager-storage.js +3 -2
- package/dist/core/session-manager-storage.js.map +1 -1
- package/dist/core/session-manager-types.d.ts +14 -15
- package/dist/core/session-manager-types.d.ts.map +1 -1
- package/dist/core/session-manager-types.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +1 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main-session.d.ts +1 -0
- package/dist/main-session.d.ts.map +1 -1
- package/dist/main-session.js +7 -0
- package/dist/main-session.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +4 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js +12 -22
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- 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 -11
- package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.js +3 -0
- package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.d.ts +1 -0
- package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.js +1 -0
- package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.js +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +1 -0
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts +20 -0
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-boundary-message.js +48 -0
- package/dist/modes/interactive/components/compaction-boundary-message.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-list.js +3 -0
- package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +3 -47
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +5 -3
- 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-render-chat.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +21 -12
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +3 -5
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +1 -6
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +0 -4
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -11
- 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 +97 -772
- package/docs/extensions.md +25 -29
- package/docs/json.md +2 -2
- package/docs/rpc.md +32 -24
- package/docs/sdk.md +3 -3
- package/docs/session-format.md +49 -30
- package/docs/sessions.md +5 -3
- package/docs/settings.md +14 -4
- package/docs/usage.md +1 -1
- package/docs/workflows.md +30 -15
- package/examples/extensions/custom-compaction.ts +14 -58
- package/examples/extensions/handoff.ts +2 -3
- package/npm-shrinkwrap.json +23 -23
- package/package.json +2 -2
- package/dist/core/compaction/context-assistant-turns.d.ts +0 -42
- package/dist/core/compaction/context-assistant-turns.d.ts.map +0 -1
- package/dist/core/compaction/context-assistant-turns.js +0 -87
- package/dist/core/compaction/context-assistant-turns.js.map +0 -1
- package/dist/core/compaction/context-compaction-critical.d.ts +0 -15
- package/dist/core/compaction/context-compaction-critical.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-critical.js +0 -57
- package/dist/core/compaction/context-compaction-critical.js.map +0 -1
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +0 -18
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-eviction-alternates.js +0 -186
- package/dist/core/compaction/context-compaction-eviction-alternates.js.map +0 -1
- package/dist/core/compaction/context-compaction-eviction.d.ts +0 -12
- package/dist/core/compaction/context-compaction-eviction.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-eviction.js +0 -222
- package/dist/core/compaction/context-compaction-eviction.js.map +0 -1
- package/dist/core/compaction/context-compaction-metrics.d.ts +0 -28
- package/dist/core/compaction/context-compaction-metrics.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-metrics.js +0 -107
- package/dist/core/compaction/context-compaction-metrics.js.map +0 -1
- package/dist/core/compaction/context-compaction-prompt.d.ts +0 -9
- package/dist/core/compaction/context-compaction-prompt.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-prompt.js +0 -163
- package/dist/core/compaction/context-compaction-prompt.js.map +0 -1
- package/dist/core/compaction/context-compaction-runner.d.ts +0 -11
- package/dist/core/compaction/context-compaction-runner.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-runner.js +0 -273
- package/dist/core/compaction/context-compaction-runner.js.map +0 -1
- package/dist/core/compaction/context-compaction-strategy.d.ts +0 -5
- package/dist/core/compaction/context-compaction-strategy.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-strategy.js +0 -27
- package/dist/core/compaction/context-compaction-strategy.js.map +0 -1
- package/dist/core/compaction/context-compaction-types.d.ts +0 -75
- package/dist/core/compaction/context-compaction-types.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-types.js +0 -6
- package/dist/core/compaction/context-compaction-types.js.map +0 -1
- package/dist/core/compaction/context-compaction.d.ts +0 -10
- package/dist/core/compaction/context-compaction.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction.js +0 -8
- package/dist/core/compaction/context-compaction.js.map +0 -1
- package/dist/core/compaction/context-deletion-application.d.ts +0 -14
- package/dist/core/compaction/context-deletion-application.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-application.js +0 -261
- package/dist/core/compaction/context-deletion-application.js.map +0 -1
- package/dist/core/compaction/context-deletion-store.d.ts +0 -78
- package/dist/core/compaction/context-deletion-store.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-store.js +0 -162
- package/dist/core/compaction/context-deletion-store.js.map +0 -1
- package/dist/core/compaction/context-deletion-targets.d.ts +0 -43
- package/dist/core/compaction/context-deletion-targets.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-targets.js +0 -292
- package/dist/core/compaction/context-deletion-targets.js.map +0 -1
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts +0 -193
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-tool-definitions.js +0 -98
- package/dist/core/compaction/context-deletion-tool-definitions.js.map +0 -1
- package/dist/core/compaction/context-deletion-tool-helpers.d.ts +0 -19
- package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-tool-helpers.js +0 -210
- package/dist/core/compaction/context-deletion-tool-helpers.js.map +0 -1
- package/dist/core/compaction/context-deletion-tools.d.ts +0 -4
- package/dist/core/compaction/context-deletion-tools.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-tools.js +0 -403
- package/dist/core/compaction/context-deletion-tools.js.map +0 -1
- package/dist/core/compaction/context-transcript-analysis.d.ts +0 -11
- package/dist/core/compaction/context-transcript-analysis.d.ts.map +0 -1
- package/dist/core/compaction/context-transcript-analysis.js +0 -228
- package/dist/core/compaction/context-transcript-analysis.js.map +0 -1
- package/dist/core/session-manager-tool-dependencies.d.ts +0 -10
- package/dist/core/session-manager-tool-dependencies.d.ts.map +0 -1
- package/dist/core/session-manager-tool-dependencies.js +0 -133
- package/dist/core/session-manager-tool-dependencies.js.map +0 -1
- package/dist/modes/interactive/components/context-compaction-summary-message.d.ts +0 -17
- package/dist/modes/interactive/components/context-compaction-summary-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/context-compaction-summary-message.js +0 -83
- package/dist/modes/interactive/components/context-compaction-summary-message.js.map +0 -1
package/docs/workflows.md
CHANGED
|
@@ -249,6 +249,8 @@ Goal worker/reviewer prompts treat the objective and acceptance criteria as the
|
|
|
249
249
|
|
|
250
250
|
The worker may claim readiness, but it cannot finalize completion. Workers start from an observable acceptance/contract matrix derived from the literal objective/acceptance criteria (one row per clause, each mapped to the concrete check that proves it), and are prompted to model states, transitions, and invariants explicitly when the work is stateful. Reviewer findings from the latest round are consolidated into a deduplicated cross-reviewer batch persisted in the round artifact (`consolidated_findings` in `review-round-latest.json`), and the next worker turn is instructed to plan and repair the whole batch — with durable regression evidence for reproduced findings — rather than fixing one finding per turn. Workers and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. Goal reviewers also look for any QA E2E video referenced by the ledger or receipt and must inspect the actual video before treating it as proof. Three reviewers independently inspect the ledger, worker receipt, repository state, and diff against `base_branch`; each starts in a clean, non-forked context, matching Ralph's reviewer context behavior, and every Goal reviewer uses Ralph's `reviewer-a` model chain with Claude Fable 5 as the primary model. Each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the worker receipt or worker-authored tests, and each returns structured JSON with findings, evidence, verification still remaining, and an optional blocker. A TypeScript reducer marks the goal complete when reviewer quorum approves via the `stop_review_loop` booleans, marks blocked only when the same dependency/tool blocker repeats for the blocker threshold, continues while quorum is missing (recording the reviewers' remaining work in the decision reason), and returns `needs_human` when `max_turns` is exhausted or worker execution fails, so the bounded loop always stops with an inspectable reason.
|
|
251
251
|
|
|
252
|
+
At the start of every Goal review, each concurrent reviewer uses Intercom to initialize/check coordination and discover the sibling reviewers in the same workflow run. Before validation, reviewers communicate their plans and intended ownership, claim expensive or lock-prone checks, and serialize commands that can conflict in a shared checkout or environment, including full test suites, build or test commands, package-manager operations, browser/E2E sessions, migrations, and generated-artifact steps. They announce each coordinated check's start and completion, release every claimed resource and send siblings an explicit resource-release update, and share reusable command outcomes/evidence where appropriate. This operational coordination prevents collisions and duplicate conflicting work; it does not replace independent patch inspection, analysis, or each reviewer's own verdict.
|
|
253
|
+
|
|
252
254
|
When Goal's reducer returns `needs_human`, `blocked`, or another incomplete status, the top-level workflow run is not reported as a successful completion. `/workflow status` and lifecycle notices surface it as blocked/failed according to the run's terminal condition. Atomic also preserves structured recoverable failure metadata from the run's blocking stage (`failedStageId`) or run-level failure metadata, so auth, rate-limit, and provider fallback exhaustion remains blocked/resumable even if the workflow later returns ordinary outputs instead of a reserved `status` value. Tolerated branch failures from non-fail-fast parallel work do not reclassify an otherwise completed run.
|
|
253
255
|
|
|
254
256
|
Every Goal review round also persists an explicit convergence summary. Each reviewer record and review artifact distinguishes schema-parse status from the review verdict with `parsed`, `approved`, `stopReviewLoop`, `nextAction`, `finalActionRemaining`, and `diagnostics` fields; malformed or missing structured reviewer output is reported as a parse failure rather than as an ordinary finding/rejection. When `create_pr=true`, reviewers are told that PR/MR/review creation is a post-approval final action: if implementation and validation requirements are proven and only PR creation remains, the implementation can approve with `finalActionRemaining: true` and `nextAction: "pull-request"` instead of consuming another worker turn. The ledger's reducer decision repeats the same concise fields for the controller outcome, so a successful quorum records `approved: true`, `stopReviewLoop: true`, and `nextAction: "pull-request"` when `create_pr=true` (otherwise `"finish"`) before any final handoff runs.
|
|
@@ -295,6 +297,8 @@ Run examples:
|
|
|
295
297
|
|
|
296
298
|
Each `ralph` run uses the raw `prompt` exactly as supplied as the operative objective for research, orchestration, and review, and stores `acceptance_criteria` as the immutable literal contract (defaulting to the prompt when omitted). Shared literal-contract prompt language forbids adding behaviors, restrictions, or error conditions beyond the prompt/acceptance criteria and requires surfacing conflicts with external knowledge; Ralph does not run an initial prompt-refinement stage. Each iteration transforms that raw prompt with `/skill:prompt-engineer Transform the following user request into a codebase and online research question which can be thoroughly explored: ...` (`research-prompt-refinement`), researches that transformed question with `/skill:research-codebase ...`, and writes the findings under `research/`. The research, orchestrator, and reviewer prompts carry `acceptance_criteria` next to the literal contract, so orchestrators should pass the ORIGINAL task text when launching follow-up Ralph runs from reviewer findings. The orchestrator starts from an observable acceptance/contract matrix derived from the literal prompt/acceptance criteria (one row per clause mapped to the concrete observable check that proves it) and is prompted to model states, transitions, and invariants explicitly when the work is stateful; it treats the research artifact as its primary implementation context, initializes/updates an OS-temp implementation notes file while generating verifiable evidence for any claims it records in the notes and reviewer artifacts, delegates implementation through sub-agents, repairs unresolved reviewer findings as one consolidated batch (with durable regression evidence for reproduced findings) rather than one finding per iteration, and asks two independent reviewers (`reviewer-a` and `reviewer-b`) to inspect the patch directly against `base_branch`. The reviewer fan-out runs reviewers on different primary model families (Claude Fable 5 and GPT-5.5 Codex, with shared fallbacks) so the adversarial review gets cross-model coverage instead of repeated passes from one model, and each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the implementation notes, orchestrator report, or worker-authored tests. Ralph's orchestrator and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. For UI-applicable or full-stack changes, the orchestrator runs a `playwright-cli` end-to-end QA pass and records a reviewable proof video (referenced in the implementation notes and surfaced as `qa_video_path`); reviewers receive that path and must inspect the actual video before treating it as proof. When `create_pr=true`, the final `pull-request` stage attaches or links that video to the created PR/MR/review after reviewer approval. If reviewers find issues, the next `research-prompt-refinement` and research stages receive the review artifact path (whose `review-round-latest.json` now also carries a deduplicated cross-reviewer `consolidated_findings` batch) so follow-up research can address unresolved findings, and research stages fork from prior research session data when available. The loop stops only when both reviewers independently approve or `max_loops` is reached, so the bounded loop always stops with an inspectable review round. Ralph findings include the same `objective_alignment` classification used by Goal, and each reviewer derives a single authoritative `stop_review_loop` boolean from that evidence: `required_by_objective` findings mean `false` at any priority (P3 included, because severity labels alone never dismiss objective-relevant findings), `consistent_with_objective` P0/P1/P2 findings mean `false` while P3 remains a non-blocking nice-to-have, and `beyond_objective`/`contradicts_objective` findings are surfaced but non-blocking so they are not silently converted into new requirements. The loop gate approves deterministically on `stop_review_loop=true` plus a null `reviewer_error` (parse failures count as non-approval) without recomputing approval from the findings arrays. Ralph review decisions also include `requirements_traceability`, a clause-by-clause evidence map over every explicit prompt/acceptance-criteria requirement kept as audit evidence for deriving the flag; reviewers are explicitly told that process-only clauses (reviewer quorum, and the authorized post-approval PR/MR/review final action when `create_pr=true`) must never hold the flag at `false`. Worker-authored tests or snapshots passing are circular evidence unless tied to independent current-state proof. By default Ralph does not start the final `pull-request` stage, and `pr_report` is omitted. Prompt text alone does not opt in. Pass `create_pr=true` only when you explicitly want the final `pull-request` stage to inspect provider credentials and attempt provider-appropriate PR/MR/review creation, such as GitHub `gh`, Azure Repos `az repos pr create`, or Sapling/Phabricator tooling; Ralph's own PR-creation instructions live in that final stage and run only after approval.
|
|
297
299
|
|
|
300
|
+
At the start of every Ralph review, each concurrent reviewer uses Intercom to initialize/check coordination and discover the sibling reviewer in the same workflow run. Before validation, reviewers communicate their plans and intended ownership, claim expensive or lock-prone checks, and serialize commands that can conflict in a shared checkout or environment, including full test suites, build or test commands, package-manager operations, browser/E2E sessions, migrations, and generated-artifact steps. They announce each coordinated check's start and completion, release every claimed resource and send the sibling an explicit resource-release update, and share reusable command outcomes/evidence where appropriate. This operational coordination prevents collisions and duplicate conflicting work; it does not replace independent patch inspection, analysis, or each reviewer's own verdict.
|
|
301
|
+
|
|
298
302
|
Each Ralph review artifact and `review-round-latest.json` includes a `convergence_decision` summary with `parsed`, `approved`, `stopReviewLoop`, `nextAction`, `finalActionRemaining`, and `diagnostics`. This makes malformed or missing structured reviewer output visible as a parse failure, separate from a parsed reviewer rejection or blocking finding. When `create_pr=true`, reviewers are told that PR/MR/review creation is a post-approval final action: if implementation and validation requirements are proven and only PR creation remains, the implementation can approve with `finalActionRemaining: true` and `nextAction: "pull-request"` instead of consuming another orchestration iteration. When both reviewers converge, the latest round records `approved: true`, `stopReviewLoop: true`, and `nextAction: "pull-request"` when `create_pr=true` (otherwise `"finish"`), and the implementation loop stops before the final handoff stage.
|
|
299
303
|
|
|
300
304
|
Set `git_worktree_dir` when you want Ralph's worker stages isolated in a reusable Git worktree. Relative paths resolve from the invoking repository root, existing same-repository worktree roots are reused, and missing paths are created from `base_branch`. Ralph preserves the invoking repo-relative cwd inside the worktree, so launching from `repo/packages/api` with `git_worktree_dir=../repo-wt` runs stages from `../repo-wt/packages/api`.
|
|
@@ -410,9 +414,9 @@ Named runs go to the background. Common controls:
|
|
|
410
414
|
|
|
411
415
|
When a paused stage is resumed with a message, Atomic lets the stage answer that resume message, then (if the stage has not already finalized) injects `Continue where you left off. If you believe you are finished with your original task (or a redefined task if the user told you), stop.` into the same stage session before normal stage completion/readiness handling. This keeps interrupted work moving without asking you to manually type a second continuation prompt while also preventing stages that already finished their scoped work from overstepping.
|
|
412
416
|
|
|
413
|
-
Durable `/workflow resume` preserves completed stage metadata and graph topology.
|
|
417
|
+
Durable `/workflow resume` preserves completed stage metadata, active-stage elapsed time, and graph topology. While an LM stage or task is active, repeated durable checkpoints refresh its accumulated pause-adjusted duration even when its session file does not change. Each new Atomic process that reopens the unfinished session mid-chat starts from the latest saved baseline and uses the same continuation prompt shown above, so repeated process-boundary resumes keep status, graph, stored, and lifecycle duration cumulative without double-counting pauses from earlier process segments. Replayed `ctx.stage`, `ctx.task`, `ctx.chain`, `ctx.parallel`, and child-workflow checkpoints keep their original summaries, timing, session/model metadata, and parallel fanout parentage instead of appearing as freshly flattened replay nodes.
|
|
414
418
|
|
|
415
|
-
Workflow stage sessions are
|
|
419
|
+
Workflow stage sessions and first-party subagent transcripts created inside them are classified as **internal** at creation and excluded from the standard `/resume`, `atomic -r`, `--continue`, and global history surfaces. Fork-context stages and subagents inherit the owning run/stage marker in their initial JSONL header, avoiding a briefly visible ordinary session. They remain resumable and inspectable through the workflow-specific commands and tool actions shown here (`/workflow resume`, `/workflow attach`, `workflow({ action: "status" | "stages" | "stage" | "resume" })`), which read the run/stage store and its `sessionFile` links directly. Passing a stage session's file path to `--session` still opens it explicitly. Classification requires exact `internal: true` plus complete run/stage metadata; malformed legacy markers and ordinary user forks remain in standard history. Legacy workflow sessions created before this marker behavior lack provable ownership and continue to appear until they age out.
|
|
416
420
|
|
|
417
421
|
Human-in-the-loop prompts from `ctx.ui.input`, `ctx.ui.confirm`, `ctx.ui.select`, `ctx.ui.editor`, and `ctx.ui.custom<T>` appear as awaiting-input nodes in the workflow graph viewer, not as chat modals — use `/workflow connect <run-id>` (or F2), then press Enter on the focused node or click a visible graph node directly to focus and open/attach it for local answers.
|
|
418
422
|
|
|
@@ -978,7 +982,7 @@ In non-interactive (`-p`, `--print`, or `--mode json`) sessions, named workflow
|
|
|
978
982
|
/workflow reload
|
|
979
983
|
```
|
|
980
984
|
|
|
981
|
-
Use `connect` for the workflow graph. Use `attach` when you want a chat pane for a specific stage. Attached stage chats capture mouse/trackpad wheel events by default so scrolling stays inside the active stage transcript or prompt instead of falling through to terminal/main-chat scrollback. Live `subagent` tool calls in stage chats use the same single, parallel, and chain progress widgets as main chat, including after exiting and re-attaching to an in-flight stage; press Ctrl+O (the `app.tools.expand` binding) to expand live detail for every child, including current tool activity and artifact paths. If an async/background subagent is running while the fullscreen workflow graph is open, the graph statusline mirrors the async summary so the background run remains visible; hide the graph with `h`/Ctrl+D or reconnect later to return to the full below-editor async widget. Press `ctrl+t` inside an attached stage chat to toggle **copy mode**: copy mode disables workflow-chat mouse reporting so normal terminal/tmux text selection can work; press `ctrl+t` again to leave copy mode and restore transcript or prompt scrolling. Archived read-only stage transcripts expose the same footer and copy-mode status, so their text can also be selected and copied; `esc` closes the transcript and `ctrl+d` returns to the graph. While copy mode is on, wheel/trackpad gestures are handled by the terminal/tmux and may scroll terminal scrollback, so leave copy mode before using the wheel again. Use `interrupt`, `pause`, and `resume` for resumable live work; `resume` on a non-paused run reopens the saved snapshot or overlay. Use `kill` only when the run should be terminated; killed runs are retained in live history/status for read-only inspection. Use `/workflow reload` after adding, editing, installing, or removing workflow resources or package manifest workflow entries and you want Atomic to rediscover them in-process. `/workflow status` lists all retained active and terminal top-level runs by default; implementation-owned nested child runs are flattened into their parent workflow rather than listed separately. `/workflow status --all` is retained as a compatibility alias.
|
|
985
|
+
Use `connect` for the workflow graph. Use `attach` when you want a chat pane for a specific stage. While the workflow graph is active, vertical wheel/trackpad gestures pan it up and down, and horizontal gestures pan wide graphs left and right when the terminal exposes horizontal wheel events; these gestures remain scoped to the graph instead of leaking into the main chat or terminal scrollback. Attached stage chats capture mouse/trackpad wheel events by default so scrolling stays inside the active stage transcript or prompt instead of falling through to terminal/main-chat scrollback. Live `subagent` tool calls in stage chats use the same single, parallel, and chain progress widgets as main chat, including after exiting and re-attaching to an in-flight stage; press Ctrl+O (the `app.tools.expand` binding) to expand live detail for every child, including current tool activity and artifact paths. If an async/background subagent is running while the fullscreen workflow graph is open, the graph statusline mirrors the async summary so the background run remains visible; hide the graph with `h`/Ctrl+D or reconnect later to return to the full below-editor async widget. Press `ctrl+t` inside an attached stage chat to toggle **copy mode**: copy mode disables workflow-chat mouse reporting so normal terminal/tmux text selection can work; press `ctrl+t` again to leave copy mode and restore transcript or prompt scrolling. Archived read-only stage transcripts expose the same footer and copy-mode status, so their text can also be selected and copied; `esc` closes the transcript and `ctrl+d` returns to the graph. While copy mode is on, wheel/trackpad gestures are handled by the terminal/tmux and may scroll terminal scrollback, so leave copy mode before using the wheel again. Use `interrupt`, `pause`, and `resume` for resumable live work; `resume` on a non-paused run reopens the saved snapshot or overlay. Use `kill` only when the run should be terminated; killed runs are retained in live history/status for read-only inspection. Use `/workflow reload` after adding, editing, installing, or removing workflow resources or package manifest workflow entries and you want Atomic to rediscover them in-process. `/workflow status` lists all retained active and terminal top-level runs by default; implementation-owned nested child runs are flattened into their parent workflow rather than listed separately. `/workflow status --all` is retained as a compatibility alias.
|
|
982
986
|
|
|
983
987
|
<p align="center"><img src="images/workflow-graph.png" alt="Workflow Graph Viewer" width="600" /></p>
|
|
984
988
|
|
|
@@ -1048,13 +1052,14 @@ Atomic workflows support **cross-session resumability** via a durable workflow b
|
|
|
1048
1052
|
- **Durable `ctx.tool`**: `ctx.tool(name, args, fn)` runs TypeScript and caches the result by stable call order plus content hash of `name` + `args`. Repeated same-name/same-args calls are distinct within one workflow and replay in order after resume. DBOS-backed checkpoint writes are serialized and awaited before the tool returns, so a completed side effect is not exposed to workflow code before its checkpoint is durable; retry backoff observes workflow cancellation before later attempts run.
|
|
1049
1053
|
- **Durable `ctx.ui`**: Completed `ctx.ui.input` / `confirm` / `select` / `editor` / `custom` responses are cached by prompt identity, including prompt kind, label/message, options, and call order so repeated prompts do not collide. On resume an already-answered prompt returns its cached response instead of re-asking the user, including `ctx.ui.custom` prompts that intentionally complete with `undefined`/void.
|
|
1050
1054
|
- **Durable `ctx.stage` / `ctx.task` / `ctx.chain` / `ctx.parallel` / `ctx.workflow`**: Completed stage-like operations are recorded with stable replay keys. `ctx.chain` and `ctx.parallel` reuse the durable task primitive for each item, and child `ctx.workflow` calls checkpoint the completed child result at the parent workflow boundary with a dedicated replay-key counter so repeated same-child calls do not desync ordinal sequencing across resume. Schema-backed `ctx.stage(..., { schema }).prompt(...)` checkpoints preserve the parsed structured value, not just the rendered text. The live stage finalizer awaits durable writes before returning control where practical; if finalization fails, Atomic releases stage handles and concurrency limiter slots before reporting the finalization error instead of marking the workflow completed without a durable checkpoint. Workflow terminal status — including `ctx.exit` terminal states (`cancelled`, `blocked`, `skipped`) — is flushed to durable metadata before the run reports completion. On resume, cached operations are skipped and represented in the workflow graph as completed durable-replay nodes so status/overlay views still show progress.
|
|
1051
|
-
- **Session-file cache**: Because the default backend is persistent, top-level workflow metadata is mirrored as Atomic custom entries (`customType: "workflow.durable.checkpoint"`) in the session JSONL so a new session can discover resumable root workflows without scanning the durable store directly. Child workflows are hidden from this
|
|
1055
|
+
- **Session-file cache**: Because the default backend is persistent, top-level workflow metadata is mirrored as Atomic custom entries (`customType: "workflow.durable.checkpoint"`) in the session JSONL so a new session can discover resumable root workflows without scanning the durable store directly. Child workflows are hidden from this cache. The durable backend remains the checkpoint source of truth; the session cache is only a discovery index. `/workflow resume` refuses a cache-only resumable entry as `stale` instead of silently re-running from scratch. Completed inspection is cataloged separately from resumability and requires an authoritative completed backend handle, durable checkpoints, and at least one retained stage conversation. Each retained transcript must be a regular, parseable Atomic session file with prior message context; empty, malformed, header-only, missing, and directory paths are stale.
|
|
1052
1056
|
- **Child side-effect scoping**: A child workflow launched via `ctx.workflow(child)` checkpoints its internal `ctx.tool`/`ctx.ui`/`ctx.stage` side effects under the parent (root) durable workflow, keyed by a stable child-boundary scope. If the parent is interrupted while a child is mid-flight, resuming the parent re-runs the child but replays the child's already-completed side effects from the root store instead of re-executing them (no split-brain per-run UUID checkpoints).
|
|
1053
|
-
- **Crash-safe file backend**: Default file-backed durability stores each root workflow in its own lock-protected JSON file under `~/.atomic/workflow-durable` instead of one shared state file.
|
|
1057
|
+
- **Crash-safe file backend**: Default file-backed durability stores each root workflow in its own lock-protected JSON file under `~/.atomic/workflow-durable` instead of one shared state file. Successful completed workflow files are retained for read-only inspection through `/workflow resume`; cancelled and explicitly non-resumable failed/blocked files are pruned. Writes use `0700` directories and `0600` state/owner files where the platform supports chmod, and stale locks are reclaimed only when their owner marker belongs to a dead process. If Atomic cannot resolve `HOME`/`USERPROFILE`, it fails closed to in-memory durability instead of writing state under `/tmp`. Durable replay identities use a SHA-256 digest over canonical JSON so distinct tool/stage identities never collide.
|
|
1058
|
+
- **Versioned compatibility cleanup**: File state, DBOS metadata/checkpoint envelopes, and session discovery entries share one durable format version. Current records remain resumable; records explicitly marked as the incompatible legacy v1 format are permanently removed from the file or DBOS backend before they can appear in resume selectors, completed catalogs, startup notices, or related listings. After compatibility preparation, matching restored/live run snapshots and notices are purged too, including when DBOS deletion fails, so failure fallbacks and live resume paths cannot restore or dispatch the row. Future-version, malformed, and unavailable records are hidden but preserved rather than guessed at, deleted, or overwritten; unsupported marked DBOS envelopes are not reinterpreted as raw legacy outputs. Cleanup is idempotent, and a failed DBOS deletion remains suppressed while a later discovery retries the permanent deletion.
|
|
1054
1059
|
|
|
1055
1060
|
**Privacy and retention.** File and DBOS durability persist workflow inputs, completed `ctx.tool` outputs, answered `ctx.ui` responses, stage outputs, and stage-session paths as plaintext durable state so replay can skip completed work. Treat `~/.atomic/workflow-durable` and the configured DBOS database as sensitive. To opt out of cross-session checkpoint persistence for a session, start Atomic with `ATOMIC_WORKFLOW_DURABLE=0` (also accepts `false`, `off`, `memory`, or `in-memory`); workflows then use process-local in-memory durability and cannot be resumed after the process exits.
|
|
1056
1061
|
|
|
1057
|
-
The default file backend
|
|
1062
|
+
The default file backend retains running or paused workflows with a durable checkpoint or pending prompt, failed or blocked workflows unless explicitly marked `resumable: false`, and successful completed workflows with checkpoint progress. Completed state remains available so `/workflow resume` can reconstruct an immutable final graph and reopen retained stage transcripts without dispatching the workflow. Cancelled and explicitly non-resumable failed/blocked files are removed. Retained files contain the plaintext durable data described above; use `/workflow kill <id>` before completion when you want to cancel and remove a durable run, or delete the corresponding `workflow-<encoded-id>.json` file under `~/.atomic/workflow-durable` when you intentionally want to discard retained completed or abandoned state outside Atomic.
|
|
1058
1063
|
|
|
1059
1064
|
**Resume after editing a workflow.** Replay identity is based on workflow id plus each `ctx.*` call's stable content hash and ordinal. Editing a workflow between quit/crash and resume can intentionally invalidate or shift checkpoints: changed prompts/arguments/stage names re-run, and inserted/reordered `ctx.*` calls may not match old ordinal checkpoints. Prefer finishing or killing old durable runs before deploying reordered workflow definitions; otherwise treat resume as best-effort from compatible checkpoint identities.
|
|
1060
1065
|
|
|
@@ -1087,23 +1092,31 @@ export default workflow({
|
|
|
1087
1092
|
|
|
1088
1093
|
### `/workflow resume` — cross-session resume selector
|
|
1089
1094
|
|
|
1090
|
-
The `/workflow resume` command mirrors `/resume` ergonomics and
|
|
1095
|
+
The `/workflow resume` command mirrors `/resume` ergonomics and uses the same searchable/threaded Atomic session-selector chrome. With no id, it builds one deduplicated picker containing paused or recoverably failed live runs, compatible cross-session resumable runs, and authoritative successful completed runs. Atomic globally orders that picker newest-first: live rows use their latest run or stage activity, durable and completed rows use their latest durable update, and equal timestamps use workflow ID as a deterministic tie-breaker so source enumeration order cannot affect the result. Live rows take precedence over matching durable rows, and resumable durable rows take precedence over matching completed rows. Completed rows use the existing green `✓ completed` visual language. Durable catalogs are asynchronously hydrated from DBOS when configured even when live rows exist, stale cache-only data is filtered, and actively executing runs remain excluded to prevent double dispatch. A selector mount failure closes cleanly instead of leaving the command pending.
|
|
1096
|
+
|
|
1097
|
+
Only entries using the current durable format are selectable. An explicitly legacy durable row is cleaned from its authoritative backend during discovery, so an old session-cache entry cannot make it appear loadable. Unknown or future formats stay hidden without destructive migration; upgrade Atomic to a version that understands them instead of editing their stored data.
|
|
1098
|
+
|
|
1099
|
+
Selecting a paused, failed, blocked, or crash-recovery target follows the existing resume path unchanged: Atomic re-dispatches the workflow with its cached inputs and the **original workflow id**, so previously completed `ctx.tool`, `ctx.ui`, stage/task/chain/parallel items, and child workflow boundaries replay from durable checkpoints rather than executing again. Selecting a completed target follows a separate open path. Atomic reconstructs a completed run/stage snapshot from authoritative checkpoints and opens the detail/chat overlay without calling the durable resume dispatcher or re-running workflow stages, tools, tasks, prompts, or workflow code.
|
|
1100
|
+
|
|
1101
|
+
Completed detail state is read-only. A retained stage transcript can still be opened and continued conversationally: the stage's Atomic session is reopened lazily and a new follow-up is appended to that chat only. Follow-up chat does not change the completed run or durable handle back to `running`, does not replay workflow side effects, and does not make the completed workflow resumable.
|
|
1102
|
+
|
|
1103
|
+
When Atomic starts with an existing session or resumes one, it shows an informational notice for root workflows referenced by that session whose authoritative durable state is resumable: `running`/`paused` entries need checkpoint progress or a pending prompt, while `failed`/`blocked` entries are eligible unless they explicitly set `resumable: false`. Completed, cancelled, zero-progress running/paused, nested-child, explicitly non-resumable failed/blocked, and stale cache-only entries without durable backend state are omitted. Current and legacy checkpoint entry shapes are recognized only to associate a workflow with the restored session; the authoritative durable catalog supplies its current name and eligibility. The notice provides `/workflow resume <id>` commands, and the command validates the current workflow registry again before dispatch.
|
|
1091
1104
|
|
|
1092
1105
|
```text
|
|
1093
|
-
/workflow resume
|
|
1094
|
-
/workflow resume <workflow-id-or-prefix>
|
|
1106
|
+
/workflow resume # Mixed picker: resumable + completed
|
|
1107
|
+
/workflow resume <workflow-id-or-prefix> # Resume unfinished work or open completed detail/chat
|
|
1095
1108
|
```
|
|
1096
1109
|
|
|
1097
|
-
|
|
1110
|
+
Explicit full IDs take precedence, while prefixes resolve across live, resumable durable, and completed targets as one namespace. Ambiguous prefixes use the existing-style ambiguity diagnostic. A completed backend row with no checkpoints or no usable retained stage conversation is hidden from the picker; an explicit target reports that it is stale or missing required durable checkpoint/session data. A completed run remains inspectable when at least one stage has a usable transcript; missing, empty, directory, context-empty, or partially malformed transcript paths are omitted from stage chat attachment. Validation uses the final retained transcript for a repeated stage replay key, so an obsolete superseded checkpoint path does not hide an otherwise valid completed run. Reopening inspection refreshes a changed authoritative retained-chat handle. Session-cache-only rows are likewise hidden because the backend is authoritative. Cancelled, killed, non-resumable failed, and other terminal non-success states are never added. Normal `/resume`, `atomic -r`, and `--continue` behavior for internal workflow stage sessions is unchanged.
|
|
1098
1111
|
|
|
1099
1112
|
### Cancellation, failure, and retry semantics
|
|
1100
1113
|
|
|
1101
1114
|
| Scenario | Behavior |
|
|
1102
1115
|
| --- | --- |
|
|
1103
1116
|
| **Workflow killed/cancelled** | Marked `cancelled` in durable state and excluded from `/workflow resume` discovery. Start a new workflow run if you intentionally want to retry cancelled work. |
|
|
1104
|
-
| **Stage failure (recoverable)** | Workflow marked `failed`
|
|
1105
|
-
| **Stage failure (non-recoverable)** | Workflow marked `failed`,
|
|
1106
|
-
| **Process crash** | Workflow remains `running` in durable state. On next session start, it appears in
|
|
1117
|
+
| **Stage failure (recoverable)** | Workflow marked `failed` or `blocked` and remains resumable by default. `/workflow resume <id>` continues from the last completed checkpoint unless durable metadata explicitly sets `resumable: false`. |
|
|
1118
|
+
| **Stage failure (non-recoverable)** | Workflow marked `failed` or `blocked` with `resumable: false`, so it is excluded from resume discovery. |
|
|
1119
|
+
| **Process crash** | Workflow remains `running` in durable state. On next session start, it appears in resume discovery when it has a durable checkpoint or pending prompt. Resume re-executes from the last completed checkpoint. |
|
|
1107
1120
|
| **`ctx.tool` retry** | When `retriesAllowed: true`, the tool function is retried with exponential backoff. Cancellation is checked before each attempt and during retry backoff, so later attempts do not run after the workflow is cancelled. After exhausting retries, the error propagates and the workflow fails. |
|
|
1108
1121
|
| **`ctx.ui` pending prompt** | If a UI prompt was not answered before interruption, resume leaves off on that prompt — the user must answer it to continue. |
|
|
1109
1122
|
|
|
@@ -1115,7 +1128,7 @@ File-backed durability is the default and requires no setup. For production-grad
|
|
|
1115
1128
|
export DBOS_SYSTEM_DATABASE_URL="postgresql://user:password@localhost:5432/atomic_dbos_sys"
|
|
1116
1129
|
```
|
|
1117
1130
|
|
|
1118
|
-
When `/workflow resume` lists or resumes a DBOS-backed workflow in a fresh process, Atomic first hydrates its in-memory replay mirror from DBOS. Checkpoints are stored as structured DBOS outputs containing the checkpoint kind, id, tool argument hash, UI prompt hash, stage replay key, and completed output, so replay can skip completed `ctx.tool`, `ctx.ui`, `ctx.stage`, `ctx.task`, `ctx.chain`, `ctx.parallel`, and `ctx.workflow` work without relying on prior in-process state. Atomic updates the in-memory replay mirror for awaited DBOS checkpoints only after DBOS accepts the write, and root metadata is mirrored as versioned DBOS records where the latest timestamp wins during hydration.
|
|
1131
|
+
When `/workflow resume` lists or resumes a DBOS-backed workflow in a fresh process, Atomic first hydrates its in-memory replay mirror from DBOS. Checkpoints are stored as structured, versioned DBOS outputs containing the checkpoint kind, id, tool argument hash, UI prompt hash, stage replay key, and completed output, so replay can skip completed `ctx.tool`, `ctx.ui`, `ctx.stage`, `ctx.task`, `ctx.chain`, `ctx.parallel`, and `ctx.workflow` work without relying on prior in-process state. Atomic updates the in-memory replay mirror for awaited DBOS checkpoints only after DBOS accepts the write, and root metadata is mirrored as versioned DBOS records where the latest timestamp wins during hydration. Unmarked raw-output checkpoint records remain readable as generic stage checkpoints when their workflow has compatible current metadata; marked envelopes with unsupported versions are ignored rather than decoded as raw output.
|
|
1119
1132
|
|
|
1120
1133
|
The default file backend needs no environment variable or database. It writes one lock-protected JSON state file per root workflow in `~/.atomic/workflow-durable`, making cross-session `/workflow resume` immediately available on a normal Atomic install while avoiding shared-state growth across unrelated workflows.
|
|
1121
1134
|
|
|
@@ -1207,6 +1220,8 @@ Direct mode supports top-level/default options and per-task options such as `con
|
|
|
1207
1220
|
|
|
1208
1221
|
For large fan-outs, prefer `outputMode: "file-only"` so the parent result contains compact file references instead of full output. Treat intercom payloads from async direct runs as user-visible workflow output.
|
|
1209
1222
|
|
|
1223
|
+
Worktree isolation is an explicit runtime option, not a property inferred from task text. Natural-language instructions to create or use a worktree do not enable runner isolation, and `cwd` only selects the starting directory; a write-capable direct run without a worktree option executes in that checkout. Set `worktree: true` for runner-managed temporary per-task worktrees, or set `gitWorktreeDir` for a runner-managed reusable same-repository worktree. Invalid, empty, foreign-repository, or conflicting worktree requests fail with an actionable diagnostic rather than falling back to the invoking checkout. For independent task queues, prefer one run per item with its own reusable worktree instead of a monolithic chain rooted in the primary checkout.
|
|
1224
|
+
|
|
1210
1225
|
## Fast Inference for Workflow Stages
|
|
1211
1226
|
|
|
1212
1227
|
Workflow stages can opt into faster, higher-priority inference on supported providers so multi-stage runs finish sooner. This is currently delivered through Codex fast mode.
|
|
@@ -1902,7 +1917,7 @@ Workflow stages inherit the active host session directory only when the host is
|
|
|
1902
1917
|
|
|
1903
1918
|
Workflow stages use the same upstream-compatible `bash` tool as normal Atomic sessions. If `bash` is enabled for a stage, commands run through the configured shell with the stage process permissions; workflow options no longer include a command-level allow/deny field for shell text. Use `tools`/`noTools` to expose or hide shell access, prefer narrower custom tools for repeatable operations, and run workflows inside a container, VM, or other sandbox when command allowlisting or stronger isolation is required.
|
|
1904
1919
|
|
|
1905
|
-
`gitWorktreeDir` selects a reusable Git worktree root for `ctx.stage`, `ctx.task`, `ctx.chain`, and `ctx.parallel`. If the path is missing, Atomic creates it with `git worktree add --detach <path> <baseBranch>`; if it exists, it must be a same-repository worktree root. The default stage cwd becomes the matching cwd inside the worktree and preserves the invoking repo-relative subdirectory.
|
|
1920
|
+
`gitWorktreeDir` selects a reusable Git worktree root for `ctx.stage`, `ctx.task`, `ctx.chain`, and `ctx.parallel`. If the path is missing, Atomic creates it with `git worktree add --detach <path> <baseBranch>`; if it exists, it must be a same-repository worktree root located outside the invoking checkout. The invoking checkout itself, nested targets inside it, and missing targets whose symlinked parent resolves inside it are rejected before Git creates or reuses a worktree. The default stage cwd becomes the matching cwd inside the worktree and preserves the invoking repo-relative subdirectory. An explicit absolute `cwd` inside the invoking repository is remapped to the corresponding location inside the selected worktree; an absolute `cwd` already inside that worktree is preserved. Relative values resolve from the worktree cwd and cannot escape it. Any `cwd` that would escape either lexically or through a symlink fails before the stage session starts instead of silently running elsewhere. Runner-managed reusable-worktree relative direct output paths follow the effective worktree cwd and cannot traverse or follow symlinks outside the selected worktree. Temporary-worktree relative direct outputs are persisted under distinct per-task runner-owned temporary artifact directories before cleanup so returned artifacts remain readable, including with `outputMode: "file-only"`; they likewise cannot escape their output root, and Atomic rejects a pre-existing symlink or junction at the trusted artifact root. Explicit absolute outputs and nonblank explicit `chainDir` locations remain caller-selected, while blank `chainDir` values are treated as omitted. `gitWorktreeDir` is mutually exclusive with `worktree: true`: use `gitWorktreeDir` for named/reusable worktrees and `worktree: true` for temporary direct-mode worktrees that are cleaned up even when startup fails before the workflow callback. Temporary isolation defaults to the runner invocation cwd when a task cwd is omitted, and relative task cwd values resolve from that invocation cwd. Atomic caches reusable setup by canonical repository and target identity within a workflow run, independent of equivalent path spelling or `baseBranch`, and revalidates the selected checkout identity before reuse, retries one transient timeout from read-only Git repository probes, and reports the exact Git command, cwd, timeout, elapsed time, exit status/signal, and spawn error details when preflight fails. Worktrees provide checkout and cwd isolation, not an operating-system security sandbox; use a container, VM, or another OS-enforced boundary for untrusted code that can race or mutate arbitrary filesystem paths.
|
|
1906
1921
|
|
|
1907
1922
|
To bind user inputs to a workflow-wide worktree default, set `worktreeFromInputs` in `workflow({...})`:
|
|
1908
1923
|
|
|
@@ -1,64 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* generated summary. This example shows how to provide an exact deletion request
|
|
6
|
-
* before Atomic's internal planner runs. Atomic still validates the requested
|
|
7
|
-
* entry IDs locally before appending a context_compaction entry.
|
|
8
|
-
*
|
|
9
|
-
* This policy deletes older, unprotected, successful bash execution entries once
|
|
10
|
-
* they are large enough to matter. If no safe candidates are present, it returns
|
|
11
|
-
* nothing and Atomic uses its default deletion planner.
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* atomic --extension examples/extensions/custom-compaction.ts
|
|
2
|
+
* Offline custom compaction: extensions may replace the prepared region string
|
|
3
|
+
* before Atomic resolves model credentials. The runtime keeps the boundary and
|
|
4
|
+
* persists this text verbatim.
|
|
15
5
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const candidates = preparation.transcript.entries
|
|
26
|
-
.filter((entry) => !entry.protected)
|
|
27
|
-
.filter((entry) => entry.message.role === "bashExecution" && entry.message.exitCode === 0)
|
|
28
|
-
.filter((entry) => entry.tokenEstimate >= MIN_BASH_OUTPUT_TOKENS)
|
|
29
|
-
.slice(0, MAX_DELETIONS_PER_RUN);
|
|
30
|
-
|
|
31
|
-
if (candidates.length === 0) {
|
|
32
|
-
if (ctx.hasUI) {
|
|
33
|
-
ctx.ui.notify("Custom compaction policy found no safe bash output to delete; using default planner", "info");
|
|
34
|
-
}
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const deletions: ContextDeletionRequest["deletions"] = candidates.map((entry) => ({
|
|
39
|
-
kind: "entry",
|
|
40
|
-
entryId: entry.entryId,
|
|
41
|
-
rationale: "Large successful bash output selected by custom compaction policy",
|
|
42
|
-
}));
|
|
43
|
-
|
|
44
|
-
if (ctx.hasUI) {
|
|
45
|
-
const tokenEstimate = candidates.reduce((sum, entry) => sum + entry.tokenEstimate, 0);
|
|
46
|
-
ctx.ui.notify(
|
|
47
|
-
`Custom compaction (${reason ?? "manual"}/${mode}): requesting ${deletions.length} deletion(s), about ${tokenEstimate.toLocaleString()} tokens`,
|
|
48
|
-
"info",
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
deletionRequest: { deletions },
|
|
54
|
-
};
|
|
6
|
+
import type { ExtensionAPI } from "@bastani/atomic";
|
|
7
|
+
|
|
8
|
+
export default function customCompaction(pi: ExtensionAPI): void {
|
|
9
|
+
pi.on("session_before_compact", async (event) => {
|
|
10
|
+
const lines = event.preparation.region.lines;
|
|
11
|
+
if (lines.length === 0) return;
|
|
12
|
+
const kept = lines.filter((line, index) => index === 0 || /^\[(User|Assistant|Assistant thinking|Assistant tool calls|Tool result)\]: /.test(line));
|
|
13
|
+
if (kept.length === lines.length) return;
|
|
14
|
+
return { compactedText: kept.join("\n") };
|
|
55
15
|
});
|
|
56
16
|
|
|
57
|
-
pi.on("session_compact", async (event
|
|
58
|
-
|
|
59
|
-
ctx.ui.notify(
|
|
60
|
-
`Custom compaction policy deleted ${event.result.stats.objectsDeleted} object(s)`,
|
|
61
|
-
"info",
|
|
62
|
-
);
|
|
17
|
+
pi.on("session_compact", async (event) => {
|
|
18
|
+
console.log(`Compacted ${event.result.stats.linesBefore} to ${event.result.stats.linesKept} lines (${event.result.rung})`);
|
|
63
19
|
});
|
|
64
20
|
}
|
|
@@ -58,9 +58,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
// Gather the
|
|
62
|
-
//
|
|
63
|
-
// records as archival metadata, not replacement conversation context.
|
|
61
|
+
// Gather the active provider context. Durable verbatim compaction boundaries
|
|
62
|
+
// are already reconstructed as a boundary message plus their kept tail.
|
|
64
63
|
const messages = buildSessionContext(ctx.sessionManager.getEntries(), ctx.sessionManager.getLeafId()).messages;
|
|
65
64
|
|
|
66
65
|
if (messages.length === 0) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.9-alpha.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bastani/atomic",
|
|
9
|
-
"version": "0.9.
|
|
9
|
+
"version": "0.9.9-alpha.1",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@bastani/atomic-natives": "0.9.
|
|
12
|
+
"@bastani/atomic-natives": "0.9.9-alpha.1",
|
|
13
13
|
"@bufbuild/protobuf": "^2.12.1",
|
|
14
14
|
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
15
15
|
"@earendil-works/pi-ai": "^0.80.6",
|
|
@@ -515,16 +515,16 @@
|
|
|
515
515
|
}
|
|
516
516
|
},
|
|
517
517
|
"node_modules/@bastani/atomic-natives": {
|
|
518
|
-
"version": "0.9.
|
|
519
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.
|
|
518
|
+
"version": "0.9.9-alpha.1",
|
|
519
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.9-alpha.1.tgz",
|
|
520
520
|
"license": "MIT",
|
|
521
521
|
"optionalDependencies": {
|
|
522
|
-
"@bastani/atomic-natives-darwin-arm64": "0.9.
|
|
523
|
-
"@bastani/atomic-natives-darwin-x64": "0.9.
|
|
524
|
-
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.
|
|
525
|
-
"@bastani/atomic-natives-linux-x64-gnu": "0.9.
|
|
526
|
-
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.
|
|
527
|
-
"@bastani/atomic-natives-win32-x64-msvc": "0.9.
|
|
522
|
+
"@bastani/atomic-natives-darwin-arm64": "0.9.9-alpha.1",
|
|
523
|
+
"@bastani/atomic-natives-darwin-x64": "0.9.9-alpha.1",
|
|
524
|
+
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.9-alpha.1",
|
|
525
|
+
"@bastani/atomic-natives-linux-x64-gnu": "0.9.9-alpha.1",
|
|
526
|
+
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.9-alpha.1",
|
|
527
|
+
"@bastani/atomic-natives-win32-x64-msvc": "0.9.9-alpha.1"
|
|
528
528
|
},
|
|
529
529
|
"engines": {
|
|
530
530
|
"bun": ">=1.3.14",
|
|
@@ -532,8 +532,8 @@
|
|
|
532
532
|
}
|
|
533
533
|
},
|
|
534
534
|
"node_modules/@bastani/atomic-natives-darwin-arm64": {
|
|
535
|
-
"version": "0.9.
|
|
536
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.
|
|
535
|
+
"version": "0.9.9-alpha.1",
|
|
536
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.9-alpha.1.tgz",
|
|
537
537
|
"license": "MIT",
|
|
538
538
|
"os": [
|
|
539
539
|
"darwin"
|
|
@@ -544,8 +544,8 @@
|
|
|
544
544
|
"optional": true
|
|
545
545
|
},
|
|
546
546
|
"node_modules/@bastani/atomic-natives-darwin-x64": {
|
|
547
|
-
"version": "0.9.
|
|
548
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.
|
|
547
|
+
"version": "0.9.9-alpha.1",
|
|
548
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.9-alpha.1.tgz",
|
|
549
549
|
"license": "MIT",
|
|
550
550
|
"os": [
|
|
551
551
|
"darwin"
|
|
@@ -556,8 +556,8 @@
|
|
|
556
556
|
"optional": true
|
|
557
557
|
},
|
|
558
558
|
"node_modules/@bastani/atomic-natives-linux-arm64-gnu": {
|
|
559
|
-
"version": "0.9.
|
|
560
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.
|
|
559
|
+
"version": "0.9.9-alpha.1",
|
|
560
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.9-alpha.1.tgz",
|
|
561
561
|
"license": "MIT",
|
|
562
562
|
"os": [
|
|
563
563
|
"linux"
|
|
@@ -571,8 +571,8 @@
|
|
|
571
571
|
"optional": true
|
|
572
572
|
},
|
|
573
573
|
"node_modules/@bastani/atomic-natives-linux-x64-gnu": {
|
|
574
|
-
"version": "0.9.
|
|
575
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.
|
|
574
|
+
"version": "0.9.9-alpha.1",
|
|
575
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.9-alpha.1.tgz",
|
|
576
576
|
"license": "MIT",
|
|
577
577
|
"os": [
|
|
578
578
|
"linux"
|
|
@@ -586,8 +586,8 @@
|
|
|
586
586
|
"optional": true
|
|
587
587
|
},
|
|
588
588
|
"node_modules/@bastani/atomic-natives-win32-arm64-msvc": {
|
|
589
|
-
"version": "0.9.
|
|
590
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.
|
|
589
|
+
"version": "0.9.9-alpha.1",
|
|
590
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.9-alpha.1.tgz",
|
|
591
591
|
"license": "MIT",
|
|
592
592
|
"os": [
|
|
593
593
|
"win32"
|
|
@@ -598,8 +598,8 @@
|
|
|
598
598
|
"optional": true
|
|
599
599
|
},
|
|
600
600
|
"node_modules/@bastani/atomic-natives-win32-x64-msvc": {
|
|
601
|
-
"version": "0.9.
|
|
602
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.
|
|
601
|
+
"version": "0.9.9-alpha.1",
|
|
602
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.9-alpha.1.tgz",
|
|
603
603
|
"license": "MIT",
|
|
604
604
|
"os": [
|
|
605
605
|
"win32"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.9-alpha.1",
|
|
4
4
|
"description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"atomicConfig": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"prepublishOnly": "bun run clean && bun run build && bun run shrinkwrap"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@bastani/atomic-natives": "0.9.
|
|
80
|
+
"@bastani/atomic-natives": "0.9.9-alpha.1",
|
|
81
81
|
"@bufbuild/protobuf": "^2.12.1",
|
|
82
82
|
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
83
83
|
"@earendil-works/pi-ai": "^0.80.6",
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { CompactableContentBlock, CompactableTranscript, CompactableTranscriptEntry } from "./context-compaction-types.js";
|
|
2
|
-
export declare function assistantEntryHasThinkingContentBlock(entry: CompactableTranscriptEntry): boolean;
|
|
3
|
-
export interface AssistantTurnEntry {
|
|
4
|
-
entryId: string;
|
|
5
|
-
role: string;
|
|
6
|
-
hasSignedThinking: boolean;
|
|
7
|
-
startsNewTurn: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface AssistantToolUseTurn {
|
|
10
|
-
entryIds: string[];
|
|
11
|
-
assistantEntryIds: string[];
|
|
12
|
-
signedThinkingEntryIds: string[];
|
|
13
|
-
active: boolean;
|
|
14
|
-
}
|
|
15
|
-
export type CompactableTranscriptDeletionTarget = {
|
|
16
|
-
readonly kind: "entry";
|
|
17
|
-
readonly entryId: string;
|
|
18
|
-
} | {
|
|
19
|
-
readonly kind: "content_block";
|
|
20
|
-
readonly entryId: string;
|
|
21
|
-
readonly blockIndex: number;
|
|
22
|
-
};
|
|
23
|
-
export interface CompactableAssistantTurnAnalysis {
|
|
24
|
-
deletedEntryIds: ReadonlySet<string>;
|
|
25
|
-
deletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>;
|
|
26
|
-
turns: AssistantToolUseTurn[];
|
|
27
|
-
}
|
|
28
|
-
export declare function compactableContentBlockIsLlmVisible(entry: CompactableTranscriptEntry, block: CompactableContentBlock): boolean;
|
|
29
|
-
export declare function transcriptEntryStartsNewTurn(entry: CompactableTranscriptEntry, deletedContentBlocks?: ReadonlySet<number>): boolean;
|
|
30
|
-
export declare function isTranscriptEntryEffectivelyDeleted(entry: CompactableTranscriptEntry, deletedEntryIds: ReadonlySet<string>, deletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>): boolean;
|
|
31
|
-
/** Shared adaptation from compactable transcript entries to logical assistant-turn inputs. */
|
|
32
|
-
export declare function compactableTranscriptToAssistantTurnEntries(transcript: CompactableTranscript, deletedEntryIds: ReadonlySet<string>, deletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>): AssistantTurnEntry[];
|
|
33
|
-
/** Analyze assistant turns after projecting a compactable transcript through deletion targets. */
|
|
34
|
-
export declare function analyzeCompactableAssistantTurns(transcript: CompactableTranscript, targets: readonly CompactableTranscriptDeletionTarget[]): CompactableAssistantTurnAnalysis;
|
|
35
|
-
/**
|
|
36
|
-
* Analyze chronological LLM-visible entries as logical assistant tool-use turns.
|
|
37
|
-
* Callers adapt each context-visible user-like message into `startsNewTurn`;
|
|
38
|
-
* tool results remain in the current turn. A trailing input-only turn is omitted,
|
|
39
|
-
* intentionally leaving the preceding assistant turn historical rather than active.
|
|
40
|
-
*/
|
|
41
|
-
export declare function analyzeAssistantToolUseTurns(entries: readonly AssistantTurnEntry[]): AssistantToolUseTurn[];
|
|
42
|
-
//# sourceMappingURL=context-assistant-turns.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-assistant-turns.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/context-assistant-turns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,MAAM,+BAA+B,CAAC;AAGvC,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAMhG;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,MAAM,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,mCAAmC,GAC5C;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F,MAAM,WAAW,gCAAgC;IAChD,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,KAAK,EAAE,oBAAoB,EAAE,CAAC;CAC9B;AAED,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,0BAA0B,EACjC,KAAK,EAAE,uBAAuB,GAC5B,OAAO,CAIT;AAED,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,0BAA0B,EACjC,oBAAoB,GAAE,WAAW,CAAC,MAAM,CAAqB,GAC3D,OAAO,CAWT;AAED,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,0BAA0B,EACjC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,EACpC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,GAC5D,OAAO,CAQT;AAED,8FAA8F;AAC9F,wBAAgB,2CAA2C,CAC1D,UAAU,EAAE,qBAAqB,EACjC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,EACpC,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,GAC5D,kBAAkB,EAAE,CAStB;AAED,kGAAkG;AAClG,wBAAgB,gCAAgC,CAC/C,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,SAAS,mCAAmC,EAAE,GACrD,gCAAgC,CAmBlC;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,GAAG,oBAAoB,EAAE,CAmB3G","sourcesContent":["import { messageStartsLlmUserTurn, userLikeContentBlockIsLlmVisible } from \"../messages.js\";\nimport type {\n\tCompactableContentBlock,\n\tCompactableTranscript,\n\tCompactableTranscriptEntry,\n} from \"./context-compaction-types.js\";\nimport { isAssistantThinkingBlockType, messageHasAssistantThinkingContentBlock } from \"../thinking-blocks.js\";\n\nexport function assistantEntryHasThinkingContentBlock(entry: CompactableTranscriptEntry): boolean {\n\treturn (\n\t\tentry.role === \"assistant\" &&\n\t\t(entry.contentBlocks.some((block) => isAssistantThinkingBlockType(block.type)) ||\n\t\t\tmessageHasAssistantThinkingContentBlock(entry.message))\n\t);\n}\n\nexport interface AssistantTurnEntry {\n\tentryId: string;\n\trole: string;\n\thasSignedThinking: boolean;\n\tstartsNewTurn: boolean;\n}\n\nexport interface AssistantToolUseTurn {\n\tentryIds: string[];\n\tassistantEntryIds: string[];\n\tsignedThinkingEntryIds: string[];\n\tactive: boolean;\n}\n\nexport type CompactableTranscriptDeletionTarget =\n\t| { readonly kind: \"entry\"; readonly entryId: string }\n\t| { readonly kind: \"content_block\"; readonly entryId: string; readonly blockIndex: number };\n\nexport interface CompactableAssistantTurnAnalysis {\n\tdeletedEntryIds: ReadonlySet<string>;\n\tdeletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>;\n\tturns: AssistantToolUseTurn[];\n}\n\nexport function compactableContentBlockIsLlmVisible(\n\tentry: CompactableTranscriptEntry,\n\tblock: CompactableContentBlock,\n): boolean {\n\tif (typeof block.llmVisible === \"boolean\") return block.llmVisible;\n\tconst rawContent = (entry.message as { content?: unknown }).content;\n\treturn Array.isArray(rawContent) && userLikeContentBlockIsLlmVisible(rawContent[block.blockIndex]);\n}\n\nexport function transcriptEntryStartsNewTurn(\n\tentry: CompactableTranscriptEntry,\n\tdeletedContentBlocks: ReadonlySet<number> = new Set<number>(),\n): boolean {\n\tif (entry.role === \"user\" || entry.role === \"custom\") {\n\t\tconst content = (entry.message as { content?: unknown }).content;\n\t\tif (typeof content === \"string\" || entry.contentBlocks.length === 0) {\n\t\t\treturn messageStartsLlmUserTurn(entry.message, deletedContentBlocks);\n\t\t}\n\t\treturn entry.contentBlocks.some(\n\t\t\t(block) => !deletedContentBlocks.has(block.blockIndex) && compactableContentBlockIsLlmVisible(entry, block),\n\t\t);\n\t}\n\treturn messageStartsLlmUserTurn(entry.message, deletedContentBlocks);\n}\n\nexport function isTranscriptEntryEffectivelyDeleted(\n\tentry: CompactableTranscriptEntry,\n\tdeletedEntryIds: ReadonlySet<string>,\n\tdeletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>,\n): boolean {\n\tif (deletedEntryIds.has(entry.entryId)) return true;\n\tconst deletedBlocks = deletedContentBlocks.get(entry.entryId);\n\treturn (\n\t\tentry.contentBlocks.length > 0 &&\n\t\tdeletedBlocks !== undefined &&\n\t\tentry.contentBlocks.every((block) => deletedBlocks.has(block.blockIndex))\n\t);\n}\n\n/** Shared adaptation from compactable transcript entries to logical assistant-turn inputs. */\nexport function compactableTranscriptToAssistantTurnEntries(\n\ttranscript: CompactableTranscript,\n\tdeletedEntryIds: ReadonlySet<string>,\n\tdeletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>,\n): AssistantTurnEntry[] {\n\treturn transcript.entries.map((entry) => ({\n\t\tentryId: entry.entryId,\n\t\trole: entry.role,\n\t\thasSignedThinking: assistantEntryHasThinkingContentBlock(entry),\n\t\tstartsNewTurn:\n\t\t\t!isTranscriptEntryEffectivelyDeleted(entry, deletedEntryIds, deletedContentBlocks) &&\n\t\t\ttranscriptEntryStartsNewTurn(entry, deletedContentBlocks.get(entry.entryId)),\n\t}));\n}\n\n/** Analyze assistant turns after projecting a compactable transcript through deletion targets. */\nexport function analyzeCompactableAssistantTurns(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly CompactableTranscriptDeletionTarget[],\n): CompactableAssistantTurnAnalysis {\n\tconst deletedEntryIds = new Set<string>();\n\tconst deletedContentBlocks = new Map<string, Set<number>>();\n\tfor (const target of targets) {\n\t\tif (target.kind === \"entry\") {\n\t\t\tdeletedEntryIds.add(target.entryId);\n\t\t\tcontinue;\n\t\t}\n\t\tconst blockIndexes = deletedContentBlocks.get(target.entryId) ?? new Set<number>();\n\t\tblockIndexes.add(target.blockIndex);\n\t\tdeletedContentBlocks.set(target.entryId, blockIndexes);\n\t}\n\treturn {\n\t\tdeletedEntryIds,\n\t\tdeletedContentBlocks,\n\t\tturns: analyzeAssistantToolUseTurns(\n\t\t\tcompactableTranscriptToAssistantTurnEntries(transcript, deletedEntryIds, deletedContentBlocks),\n\t\t),\n\t};\n}\n\n/**\n * Analyze chronological LLM-visible entries as logical assistant tool-use turns.\n * Callers adapt each context-visible user-like message into `startsNewTurn`;\n * tool results remain in the current turn. A trailing input-only turn is omitted,\n * intentionally leaving the preceding assistant turn historical rather than active.\n */\nexport function analyzeAssistantToolUseTurns(entries: readonly AssistantTurnEntry[]): AssistantToolUseTurn[] {\n\tconst groups: Array<Omit<AssistantToolUseTurn, \"active\">> = [];\n\tlet current: Omit<AssistantToolUseTurn, \"active\"> | undefined;\n\n\tfor (const entry of entries) {\n\t\tif (entry.startsNewTurn || current === undefined) {\n\t\t\tcurrent = { entryIds: [], assistantEntryIds: [], signedThinkingEntryIds: [] };\n\t\t\tgroups.push(current);\n\t\t}\n\t\tcurrent.entryIds.push(entry.entryId);\n\t\tif (entry.role !== \"assistant\") continue;\n\t\tcurrent.assistantEntryIds.push(entry.entryId);\n\t\tif (entry.hasSignedThinking) current.signedThinkingEntryIds.push(entry.entryId);\n\t}\n\n\tconst activeIndex = groups.length - 1;\n\treturn groups\n\t\t.map((turn, index) => ({ ...turn, active: index === activeIndex }))\n\t\t.filter((turn) => turn.assistantEntryIds.length > 0);\n}\n"]}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { messageStartsLlmUserTurn, userLikeContentBlockIsLlmVisible } from "../messages.js";
|
|
2
|
-
import { isAssistantThinkingBlockType, messageHasAssistantThinkingContentBlock } from "../thinking-blocks.js";
|
|
3
|
-
export function assistantEntryHasThinkingContentBlock(entry) {
|
|
4
|
-
return (entry.role === "assistant" &&
|
|
5
|
-
(entry.contentBlocks.some((block) => isAssistantThinkingBlockType(block.type)) ||
|
|
6
|
-
messageHasAssistantThinkingContentBlock(entry.message)));
|
|
7
|
-
}
|
|
8
|
-
export function compactableContentBlockIsLlmVisible(entry, block) {
|
|
9
|
-
if (typeof block.llmVisible === "boolean")
|
|
10
|
-
return block.llmVisible;
|
|
11
|
-
const rawContent = entry.message.content;
|
|
12
|
-
return Array.isArray(rawContent) && userLikeContentBlockIsLlmVisible(rawContent[block.blockIndex]);
|
|
13
|
-
}
|
|
14
|
-
export function transcriptEntryStartsNewTurn(entry, deletedContentBlocks = new Set()) {
|
|
15
|
-
if (entry.role === "user" || entry.role === "custom") {
|
|
16
|
-
const content = entry.message.content;
|
|
17
|
-
if (typeof content === "string" || entry.contentBlocks.length === 0) {
|
|
18
|
-
return messageStartsLlmUserTurn(entry.message, deletedContentBlocks);
|
|
19
|
-
}
|
|
20
|
-
return entry.contentBlocks.some((block) => !deletedContentBlocks.has(block.blockIndex) && compactableContentBlockIsLlmVisible(entry, block));
|
|
21
|
-
}
|
|
22
|
-
return messageStartsLlmUserTurn(entry.message, deletedContentBlocks);
|
|
23
|
-
}
|
|
24
|
-
export function isTranscriptEntryEffectivelyDeleted(entry, deletedEntryIds, deletedContentBlocks) {
|
|
25
|
-
if (deletedEntryIds.has(entry.entryId))
|
|
26
|
-
return true;
|
|
27
|
-
const deletedBlocks = deletedContentBlocks.get(entry.entryId);
|
|
28
|
-
return (entry.contentBlocks.length > 0 &&
|
|
29
|
-
deletedBlocks !== undefined &&
|
|
30
|
-
entry.contentBlocks.every((block) => deletedBlocks.has(block.blockIndex)));
|
|
31
|
-
}
|
|
32
|
-
/** Shared adaptation from compactable transcript entries to logical assistant-turn inputs. */
|
|
33
|
-
export function compactableTranscriptToAssistantTurnEntries(transcript, deletedEntryIds, deletedContentBlocks) {
|
|
34
|
-
return transcript.entries.map((entry) => ({
|
|
35
|
-
entryId: entry.entryId,
|
|
36
|
-
role: entry.role,
|
|
37
|
-
hasSignedThinking: assistantEntryHasThinkingContentBlock(entry),
|
|
38
|
-
startsNewTurn: !isTranscriptEntryEffectivelyDeleted(entry, deletedEntryIds, deletedContentBlocks) &&
|
|
39
|
-
transcriptEntryStartsNewTurn(entry, deletedContentBlocks.get(entry.entryId)),
|
|
40
|
-
}));
|
|
41
|
-
}
|
|
42
|
-
/** Analyze assistant turns after projecting a compactable transcript through deletion targets. */
|
|
43
|
-
export function analyzeCompactableAssistantTurns(transcript, targets) {
|
|
44
|
-
const deletedEntryIds = new Set();
|
|
45
|
-
const deletedContentBlocks = new Map();
|
|
46
|
-
for (const target of targets) {
|
|
47
|
-
if (target.kind === "entry") {
|
|
48
|
-
deletedEntryIds.add(target.entryId);
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
const blockIndexes = deletedContentBlocks.get(target.entryId) ?? new Set();
|
|
52
|
-
blockIndexes.add(target.blockIndex);
|
|
53
|
-
deletedContentBlocks.set(target.entryId, blockIndexes);
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
deletedEntryIds,
|
|
57
|
-
deletedContentBlocks,
|
|
58
|
-
turns: analyzeAssistantToolUseTurns(compactableTranscriptToAssistantTurnEntries(transcript, deletedEntryIds, deletedContentBlocks)),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Analyze chronological LLM-visible entries as logical assistant tool-use turns.
|
|
63
|
-
* Callers adapt each context-visible user-like message into `startsNewTurn`;
|
|
64
|
-
* tool results remain in the current turn. A trailing input-only turn is omitted,
|
|
65
|
-
* intentionally leaving the preceding assistant turn historical rather than active.
|
|
66
|
-
*/
|
|
67
|
-
export function analyzeAssistantToolUseTurns(entries) {
|
|
68
|
-
const groups = [];
|
|
69
|
-
let current;
|
|
70
|
-
for (const entry of entries) {
|
|
71
|
-
if (entry.startsNewTurn || current === undefined) {
|
|
72
|
-
current = { entryIds: [], assistantEntryIds: [], signedThinkingEntryIds: [] };
|
|
73
|
-
groups.push(current);
|
|
74
|
-
}
|
|
75
|
-
current.entryIds.push(entry.entryId);
|
|
76
|
-
if (entry.role !== "assistant")
|
|
77
|
-
continue;
|
|
78
|
-
current.assistantEntryIds.push(entry.entryId);
|
|
79
|
-
if (entry.hasSignedThinking)
|
|
80
|
-
current.signedThinkingEntryIds.push(entry.entryId);
|
|
81
|
-
}
|
|
82
|
-
const activeIndex = groups.length - 1;
|
|
83
|
-
return groups
|
|
84
|
-
.map((turn, index) => ({ ...turn, active: index === activeIndex }))
|
|
85
|
-
.filter((turn) => turn.assistantEntryIds.length > 0);
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=context-assistant-turns.js.map
|