@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
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import type { WorkflowModelAttempt, WorkflowSerializableValue } from "../shared/types.js";
|
|
13
|
+
import type { DURABLE_FORMAT_VERSION } from "./format-version.js";
|
|
13
14
|
|
|
14
15
|
// ---------------------------------------------------------------------------
|
|
15
16
|
// Top-level workflow identity
|
|
@@ -156,6 +157,8 @@ export type WorkflowSerializableObject = Readonly<Record<string, WorkflowSeriali
|
|
|
156
157
|
* the minimal top-level metadata needed for `/workflow resume` discovery.
|
|
157
158
|
*/
|
|
158
159
|
export interface DurableCheckpointEntry {
|
|
160
|
+
/** Durable metadata schema version used to reject incompatible discovery rows. */
|
|
161
|
+
readonly formatVersion: typeof DURABLE_FORMAT_VERSION;
|
|
159
162
|
readonly type: "workflow.durable.checkpoint";
|
|
160
163
|
readonly workflowId: string;
|
|
161
164
|
readonly name: string;
|
|
@@ -86,6 +86,7 @@ function createTaskPrimitive(runtime: EngineRuntime): WorkflowTaskPrimitive {
|
|
|
86
86
|
{ ...options, worktree: true },
|
|
87
87
|
`${runtime.runId}-${name}-${crypto.randomUUID()}`,
|
|
88
88
|
name,
|
|
89
|
+
runtime.workflowInvocationCwd,
|
|
89
90
|
);
|
|
90
91
|
const preparedTask = prepared.tasks[0]!;
|
|
91
92
|
try {
|
|
@@ -19,7 +19,7 @@ import { stageControlRegistry as defaultStageControlRegistry } from "../runs/for
|
|
|
19
19
|
import type { RunOpts, RunResult } from "../runs/foreground/executor-types.js";
|
|
20
20
|
import { unknownErrorMessage, findWorkflowExitSignal, parentWorkflowExitAbortReason } from "../runs/foreground/executor-abort.js";
|
|
21
21
|
import { resolveAndValidateInputs, resolveInputConcurrency, resolveInputRuntimeDefaults } from "../runs/foreground/executor-inputs.js";
|
|
22
|
-
import {
|
|
22
|
+
import { createGitWorktreeSetupCacheOwner, workflowCwdWithInputWorktree, workflowInvocationMetadata } from "../runs/foreground/executor-direct-helpers.js";
|
|
23
23
|
import { createStageScheduler } from "../runs/foreground/executor-scheduler.js";
|
|
24
24
|
import { createRunFinalizers } from "../runs/foreground/executor-run-finalizers.js";
|
|
25
25
|
import { buildPromptNodeUiAdapter } from "../runs/foreground/executor-prompt-nodes.js";
|
|
@@ -152,7 +152,8 @@ export async function run<
|
|
|
152
152
|
|
|
153
153
|
const tracker = new GraphFrontierTracker();
|
|
154
154
|
const inputConcurrency = resolveInputConcurrency(def.inputs, resolvedInputs);
|
|
155
|
-
const inputRuntimeDefaults = resolveInputRuntimeDefaults(def, resolvedInputs),
|
|
155
|
+
const inputRuntimeDefaults = resolveInputRuntimeDefaults(def, resolvedInputs), gitWorktreeSetupCacheOwner = createGitWorktreeSetupCacheOwner(opts.gitWorktreeSetupCache);
|
|
156
|
+
const gitWorktreeSetupCache = gitWorktreeSetupCacheOwner.cache;
|
|
156
157
|
const workflowInvocationCwd = opts.cwd ?? process.cwd();
|
|
157
158
|
let workflowCwd: string | undefined;
|
|
158
159
|
const resolveWorkflowCwd = (): string => {
|
|
@@ -484,17 +485,16 @@ export async function run<
|
|
|
484
485
|
});
|
|
485
486
|
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "failed", error: metadata.errorMessage }, opts.onRunEnd);
|
|
486
487
|
} finally {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}
|
|
498
|
-
opts.cancellation?.unregister(runId);
|
|
488
|
+
try {
|
|
489
|
+
await finalizeDurableTerminalStatus({
|
|
490
|
+
runId,
|
|
491
|
+
runSnapshot,
|
|
492
|
+
isRoot: opts.parentRun === undefined,
|
|
493
|
+
durableBackend,
|
|
494
|
+
persistence: opts.persistence,
|
|
495
|
+
});
|
|
496
|
+
} finally {
|
|
497
|
+
gitWorktreeSetupCacheOwner.release(() => opts.cancellation?.unregister(runId));
|
|
498
|
+
}
|
|
499
499
|
}
|
|
500
500
|
}
|
|
@@ -4,6 +4,7 @@ import { cancellationRegistry } from "../runs/background/cancellation-registry.j
|
|
|
4
4
|
import { stageControlRegistry } from "../runs/foreground/stage-control-registry.js";
|
|
5
5
|
import { store } from "../shared/store.js";
|
|
6
6
|
import { restoreOnSessionStart } from "../shared/persistence-restore.js";
|
|
7
|
+
import { findResumableWorkflowNotices } from "../shared/resumable-workflow-notices.js";
|
|
7
8
|
import { installCompactionHook } from "../shared/persistence-compaction-policy.js";
|
|
8
9
|
import { clearForms } from "../tui/inline-form-store.js";
|
|
9
10
|
import { installStoreWidget } from "../tui/store-widget-installer.js";
|
|
@@ -57,7 +58,7 @@ export function registerWorkflowLifecycleHandlers(
|
|
|
57
58
|
return { cancel: true };
|
|
58
59
|
});
|
|
59
60
|
|
|
60
|
-
pi.on("session_start", async (
|
|
61
|
+
pi.on("session_start", async (event, ctx) => {
|
|
61
62
|
runtimeState.resetWorkflowDiscoveryForSession();
|
|
62
63
|
deAdvertiseAskUserQuestionWhenHeadless(pi, ctx?.hasUI);
|
|
63
64
|
await runtimeState.ensureWorkflowConfigLoaded();
|
|
@@ -85,16 +86,45 @@ export function registerWorkflowLifecycleHandlers(
|
|
|
85
86
|
if (sessionManager) {
|
|
86
87
|
const cfg = runtimeState.configLoadRef.current?.config;
|
|
87
88
|
withWorkflowLifecycleNotificationsSuppressed(runtimeState.lifecycleNotificationState, () => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
try {
|
|
90
|
+
restoreOnSessionStart(
|
|
91
|
+
sessionManager,
|
|
92
|
+
{
|
|
93
|
+
resumeInFlight: cfg?.resumeInFlight ?? "ask",
|
|
94
|
+
persistRuns: cfg?.persistRuns ?? true,
|
|
95
|
+
},
|
|
96
|
+
store,
|
|
97
|
+
);
|
|
98
|
+
} catch {
|
|
99
|
+
// Host session-entry failures must not prevent the session from starting.
|
|
100
|
+
}
|
|
96
101
|
seedWorkflowLifecycleNotificationState(runtimeState.lifecycleNotificationState, store.snapshot());
|
|
97
102
|
});
|
|
103
|
+
const reason = typeof event === "object" && event !== null && "reason" in event
|
|
104
|
+
? (event as { readonly reason?: string }).reason
|
|
105
|
+
: undefined;
|
|
106
|
+
if (reason === "startup" || reason === "resume") {
|
|
107
|
+
const getEntries = sessionManager.getEntries;
|
|
108
|
+
if (typeof getEntries === "function") {
|
|
109
|
+
let authoritativeCatalog: Awaited<ReturnType<typeof runtimeState.runtimeProxy.prepareDurableResumable>> = [];
|
|
110
|
+
try {
|
|
111
|
+
authoritativeCatalog = await runtimeState.runtimeProxy.prepareDurableResumable();
|
|
112
|
+
} catch {
|
|
113
|
+
// A resume-catalog failure must not prevent the host session from starting.
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const resumable = findResumableWorkflowNotices(getEntries.call(sessionManager), authoritativeCatalog);
|
|
117
|
+
if (resumable.length > 0) {
|
|
118
|
+
const commands = resumable
|
|
119
|
+
.map((workflow) => `\`${workflow.name}\` (${workflow.workflowId.slice(0, 8)}): /workflow resume ${workflow.workflowId}`)
|
|
120
|
+
.join("\n");
|
|
121
|
+
ctx?.ui?.notify?.(`This session has resumable workflows:\n${commands}`, "info");
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
// Host session-entry failures must not prevent the session from starting.
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
98
128
|
}
|
|
99
129
|
});
|
|
100
130
|
|
|
@@ -148,6 +148,16 @@ export function createWorkflowExtensionRuntimeState(
|
|
|
148
148
|
resumeDurableWorkflow(workflowIdOrPrefix, options) { return runtimeRef.current.resumeDurableWorkflow(workflowIdOrPrefix, options); },
|
|
149
149
|
listDurableResumable(sessionDir) { return runtimeRef.current.listDurableResumable(sessionDir); },
|
|
150
150
|
prepareDurableResumable(workflowIdOrPrefix, sessionDir) { return runtimeRef.current.prepareDurableResumable(workflowIdOrPrefix, sessionDir); },
|
|
151
|
+
prepareCompletedDurable() {
|
|
152
|
+
return runtimeRef.current.prepareCompletedDurable?.() ?? Promise.resolve([]);
|
|
153
|
+
},
|
|
154
|
+
openCompletedDurableWorkflow(workflowIdOrPrefix, catalog) {
|
|
155
|
+
const open = runtimeRef.current.openCompletedDurableWorkflow;
|
|
156
|
+
if (open === undefined) {
|
|
157
|
+
return { ok: false, reason: "not_found", message: `No completed durable workflow found for id/prefix: ${workflowIdOrPrefix}` };
|
|
158
|
+
}
|
|
159
|
+
return open(workflowIdOrPrefix, catalog);
|
|
160
|
+
},
|
|
151
161
|
};
|
|
152
162
|
|
|
153
163
|
function workflowModelCatalogFromContext(ctx?: PiModelContext): WorkflowModelCatalogPort | undefined {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { WorkflowExecutionPolicy } from "../shared/types.js";
|
|
2
|
+
import type { StageAdapters } from "../runs/foreground/stage-runner.js";
|
|
3
|
+
import type { RunOpts } from "../runs/foreground/executor.js";
|
|
4
|
+
import type { Store } from "../shared/store.js";
|
|
5
|
+
import type { WorkflowRegistry } from "../workflows/registry.js";
|
|
6
|
+
import {
|
|
7
|
+
prepareRuntimeDurableResumable,
|
|
8
|
+
purgeSuppressedWorkflowRuns,
|
|
9
|
+
resumeDurableWorkflow as resumeDurableWorkflowAdapter,
|
|
10
|
+
type ResumeDurableDeps,
|
|
11
|
+
type ResumeDurableResult,
|
|
12
|
+
} from "../durable/resume-runtime.js";
|
|
13
|
+
import { getDurableBackend } from "../durable/factory.js";
|
|
14
|
+
import { scanResumableWorkflows } from "../durable/resume-catalog.js";
|
|
15
|
+
import { isDurableWorkflowResumable } from "../durable/resume-eligibility.js";
|
|
16
|
+
import { listOpenableCompletedWorkflows } from "../durable/completed-catalog.js";
|
|
17
|
+
import {
|
|
18
|
+
openCompletedDurableWorkflow as openCompletedSnapshot,
|
|
19
|
+
type OpenCompletedDurableResult,
|
|
20
|
+
} from "../durable/completed-inspection.js";
|
|
21
|
+
import type { ResumableWorkflowEntry } from "../durable/types.js";
|
|
22
|
+
|
|
23
|
+
export interface DurableResumeRuntime {
|
|
24
|
+
resumeDurableWorkflow(
|
|
25
|
+
workflowIdOrPrefix: string,
|
|
26
|
+
options?: { readonly policy?: WorkflowExecutionPolicy },
|
|
27
|
+
): ResumeDurableResult;
|
|
28
|
+
listDurableResumable(sessionDir?: string): readonly ResumableWorkflowEntry[];
|
|
29
|
+
prepareDurableResumable(
|
|
30
|
+
workflowIdOrPrefix?: string,
|
|
31
|
+
sessionDir?: string,
|
|
32
|
+
): Promise<readonly ResumableWorkflowEntry[]>;
|
|
33
|
+
prepareCompletedDurable?(): Promise<readonly ResumableWorkflowEntry[]>;
|
|
34
|
+
openCompletedDurableWorkflow?(
|
|
35
|
+
workflowIdOrPrefix: string,
|
|
36
|
+
catalog?: readonly ResumableWorkflowEntry[],
|
|
37
|
+
): OpenCompletedDurableResult;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface DurableResumeRuntimeDeps {
|
|
41
|
+
readonly registry: WorkflowRegistry;
|
|
42
|
+
readonly store: Store;
|
|
43
|
+
readonly adapters?: StageAdapters;
|
|
44
|
+
readonly runtimeCwd: string;
|
|
45
|
+
readonly ensureReady: () => Promise<void>;
|
|
46
|
+
readonly resolveDefaultStageSessionDir?: () => string | undefined;
|
|
47
|
+
readonly baseRunOpts: (policy?: WorkflowExecutionPolicy) => RunOpts;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function createDurableResumeRuntime(
|
|
51
|
+
deps: DurableResumeRuntimeDeps,
|
|
52
|
+
): DurableResumeRuntime {
|
|
53
|
+
const hydrateStoredWorkflowCandidates = async (backend: ReturnType<typeof getDurableBackend>, target?: string): Promise<void> => {
|
|
54
|
+
if (backend.hydrateWorkflow === undefined) return;
|
|
55
|
+
const ids = deps.store.runs()
|
|
56
|
+
.map((run) => run.id)
|
|
57
|
+
.filter((id) => target === undefined || id === target || id.startsWith(target));
|
|
58
|
+
for (const id of ids) await backend.hydrateWorkflow(id);
|
|
59
|
+
};
|
|
60
|
+
let preparedCatalog: readonly ResumableWorkflowEntry[] = [];
|
|
61
|
+
return {
|
|
62
|
+
resumeDurableWorkflow(workflowIdOrPrefix, options): ResumeDurableResult {
|
|
63
|
+
const adapterDeps: ResumeDurableDeps = {
|
|
64
|
+
registry: deps.registry,
|
|
65
|
+
baseRunOpts: deps.baseRunOpts(options?.policy),
|
|
66
|
+
durableBackend: getDurableBackend(),
|
|
67
|
+
};
|
|
68
|
+
return resumeDurableWorkflowAdapter(workflowIdOrPrefix, adapterDeps, preparedCatalog);
|
|
69
|
+
},
|
|
70
|
+
listDurableResumable(sessionDir): readonly ResumableWorkflowEntry[] {
|
|
71
|
+
const backend = getDurableBackend();
|
|
72
|
+
const live = backend.listResumableWorkflows();
|
|
73
|
+
const dir = sessionDir ?? deps.resolveDefaultStageSessionDir?.();
|
|
74
|
+
if (dir === undefined) return live;
|
|
75
|
+
const scanned = scanResumableWorkflows(dir);
|
|
76
|
+
const liveIds = new Set(live.map((entry) => entry.workflowId));
|
|
77
|
+
const compatible = scanned.filter((entry) => {
|
|
78
|
+
const handle = backend.getWorkflow(entry.workflowId);
|
|
79
|
+
return !liveIds.has(entry.workflowId) && handle !== undefined && isDurableWorkflowResumable(handle);
|
|
80
|
+
});
|
|
81
|
+
return [...live, ...compatible];
|
|
82
|
+
},
|
|
83
|
+
async prepareDurableResumable(workflowIdOrPrefix, sessionDir) {
|
|
84
|
+
await deps.ensureReady();
|
|
85
|
+
const backend = getDurableBackend();
|
|
86
|
+
try {
|
|
87
|
+
await hydrateStoredWorkflowCandidates(backend, workflowIdOrPrefix);
|
|
88
|
+
preparedCatalog = await prepareRuntimeDurableResumable(
|
|
89
|
+
() => backend,
|
|
90
|
+
() => deps.resolveDefaultStageSessionDir?.(),
|
|
91
|
+
workflowIdOrPrefix,
|
|
92
|
+
sessionDir,
|
|
93
|
+
);
|
|
94
|
+
return preparedCatalog;
|
|
95
|
+
} finally {
|
|
96
|
+
purgeSuppressedWorkflowRuns(backend, deps.store);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
async prepareCompletedDurable() {
|
|
100
|
+
await deps.ensureReady();
|
|
101
|
+
const backend = getDurableBackend();
|
|
102
|
+
try {
|
|
103
|
+
await backend.hydrateResumableWorkflows?.();
|
|
104
|
+
await hydrateStoredWorkflowCandidates(backend);
|
|
105
|
+
return listOpenableCompletedWorkflows(backend);
|
|
106
|
+
} finally {
|
|
107
|
+
purgeSuppressedWorkflowRuns(backend, deps.store);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
openCompletedDurableWorkflow(workflowIdOrPrefix, catalog) {
|
|
111
|
+
const backend = getDurableBackend();
|
|
112
|
+
const entry = resolveCatalogEntry(workflowIdOrPrefix, catalog ?? []);
|
|
113
|
+
const handle = backend.getWorkflow(entry?.workflowId ?? workflowIdOrPrefix);
|
|
114
|
+
return openCompletedSnapshot(workflowIdOrPrefix, {
|
|
115
|
+
durableBackend: backend,
|
|
116
|
+
store: deps.store,
|
|
117
|
+
adapters: deps.adapters,
|
|
118
|
+
cwd: handle?.workflowCwd ?? handle?.invocationCwd ?? deps.runtimeCwd,
|
|
119
|
+
defaultSessionDir: deps.resolveDefaultStageSessionDir?.(),
|
|
120
|
+
}, catalog);
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function resolveCatalogEntry(
|
|
126
|
+
workflowIdOrPrefix: string,
|
|
127
|
+
catalog: readonly ResumableWorkflowEntry[],
|
|
128
|
+
): ResumableWorkflowEntry | undefined {
|
|
129
|
+
const exact = catalog.find((entry) => entry.workflowId === workflowIdOrPrefix);
|
|
130
|
+
if (exact !== undefined) return exact;
|
|
131
|
+
const matches = catalog.filter((entry) => entry.workflowId.startsWith(workflowIdOrPrefix));
|
|
132
|
+
return matches.length === 1 ? matches[0] : undefined;
|
|
133
|
+
}
|
|
@@ -43,11 +43,12 @@ import { runDetached } from "../runs/background/runner.js";
|
|
|
43
43
|
import type { JobTracker } from "../runs/background/job-tracker.js";
|
|
44
44
|
import { appendRunEnd } from "../shared/persistence-session-entries.js";
|
|
45
45
|
import { classifyWorkflowFailure } from "../shared/workflow-failures.js";
|
|
46
|
-
import {
|
|
47
|
-
import { getDurableBackend, initializeDbosDurableBackendFromEnv } from "../durable/factory.js";
|
|
48
|
-
import { scanResumableWorkflows } from "../durable/resume-catalog.js";
|
|
49
|
-
import type { ResumableWorkflowEntry } from "../durable/types.js";
|
|
46
|
+
import { initializeDbosDurableBackendFromEnv } from "../durable/factory.js";
|
|
50
47
|
import { directMode, directModelRequests, directOptions, directProgressTotal } from "./runtime-direct.js";
|
|
48
|
+
import {
|
|
49
|
+
createDurableResumeRuntime,
|
|
50
|
+
type DurableResumeRuntime,
|
|
51
|
+
} from "./runtime-durable-resume.js";
|
|
51
52
|
|
|
52
53
|
// ---------------------------------------------------------------------------
|
|
53
54
|
// Options
|
|
@@ -98,7 +99,7 @@ export type ResumeFailedRunResult =
|
|
|
98
99
|
| { ok: true; runId: string; sourceRunId: string; resumeFromStageId: string; message: string }
|
|
99
100
|
| { ok: false; reason: "run_not_found" | "not_resumable" | "workflow_not_found" | "insufficient_state"; message: string };
|
|
100
101
|
|
|
101
|
-
export interface ExtensionRuntime {
|
|
102
|
+
export interface ExtensionRuntime extends DurableResumeRuntime {
|
|
102
103
|
/**
|
|
103
104
|
* Live registry — read-only reference.
|
|
104
105
|
* Reflects all definitions registered at startup.
|
|
@@ -117,16 +118,6 @@ export interface ExtensionRuntime {
|
|
|
117
118
|
/** Start a linked continuation for a failed resumable named workflow run. */
|
|
118
119
|
resumeFailedRun(sourceRunId: string, stageId?: string, options?: RuntimeDispatchOptions): ResumeFailedRunResult;
|
|
119
120
|
|
|
120
|
-
/**
|
|
121
|
-
* Resume a durable workflow by top-level workflow id when no live run exists.
|
|
122
|
-
* Re-dispatches the workflow with the cached inputs and original workflow id
|
|
123
|
-
* so durable checkpoints replay (skipping completed side effects).
|
|
124
|
-
*
|
|
125
|
-
* cross-ref: issue #1498 — cross-session /workflow resume selector.
|
|
126
|
-
*/
|
|
127
|
-
resumeDurableWorkflow(workflowIdOrPrefix: string, options?: RuntimeDispatchOptions): import("../durable/resume-runtime.js").ResumeDurableResult;
|
|
128
|
-
listDurableResumable(sessionDir?: string): readonly import("../durable/types.js").ResumableWorkflowEntry[];
|
|
129
|
-
prepareDurableResumable(workflowIdOrPrefix?: string, sessionDir?: string): Promise<readonly import("../durable/types.js").ResumableWorkflowEntry[]>;
|
|
130
121
|
}
|
|
131
122
|
export interface RuntimeDispatchOptions {
|
|
132
123
|
readonly policy?: WorkflowExecutionPolicy;
|
|
@@ -163,7 +154,6 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
|
|
|
163
154
|
const resolveDefaultStageSessionDir = opts.resolveDefaultStageSessionDir;
|
|
164
155
|
const dbosReady = initializeDbosDurableBackendFromEnv().catch((err) => process.emitWarning(`Atomic workflow DBOS durability unavailable; using file-backed durability: ${err instanceof Error ? err.message : String(err)}`));
|
|
165
156
|
const ensureDbosReady = async (): Promise<void> => { await dbosReady; };
|
|
166
|
-
let preparedDurableCatalog: readonly ResumableWorkflowEntry[] = [];
|
|
167
157
|
|
|
168
158
|
function runOptions(args: WorkflowToolArgs, policy?: WorkflowExecutionPolicy): RunOpts {
|
|
169
159
|
const argConcurrency =
|
|
@@ -471,30 +461,15 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
|
|
|
471
461
|
},
|
|
472
462
|
|
|
473
463
|
resumeFailedRun,
|
|
464
|
+
...createDurableResumeRuntime({
|
|
465
|
+
registry,
|
|
466
|
+
store: activeStore,
|
|
467
|
+
adapters,
|
|
468
|
+
runtimeCwd,
|
|
469
|
+
ensureReady: ensureDbosReady,
|
|
470
|
+
resolveDefaultStageSessionDir,
|
|
471
|
+
baseRunOpts: (policy) => runOptions({ workflow: "", inputs: {} }, policy),
|
|
472
|
+
}),
|
|
474
473
|
|
|
475
|
-
resumeDurableWorkflow(workflowIdOrPrefix: string, options?: RuntimeDispatchOptions): ResumeDurableResult {
|
|
476
|
-
const adapterDeps: ResumeDurableDeps = {
|
|
477
|
-
registry,
|
|
478
|
-
baseRunOpts: runOptions({ workflow: "", inputs: {} }, options?.policy),
|
|
479
|
-
durableBackend: getDurableBackend(),
|
|
480
|
-
};
|
|
481
|
-
return resumeDurableWorkflowAdapter(workflowIdOrPrefix, adapterDeps, preparedDurableCatalog);
|
|
482
|
-
},
|
|
483
|
-
listDurableResumable(sessionDir?: string): readonly ResumableWorkflowEntry[] {
|
|
484
|
-
const backend = getDurableBackend();
|
|
485
|
-
const live = backend.listResumableWorkflows();
|
|
486
|
-
const dir = sessionDir ?? resolveDefaultStageSessionDir?.();
|
|
487
|
-
if (dir === undefined) return live;
|
|
488
|
-
const scanned = scanResumableWorkflows(dir);
|
|
489
|
-
const liveIds = new Set(live.map((e) => e.workflowId));
|
|
490
|
-
const compatible = scanned.filter((e) => !liveIds.has(e.workflowId) && backend.getWorkflow(e.workflowId) !== undefined && !isBackendTerminal(backend, e.workflowId));
|
|
491
|
-
return [...live, ...compatible];
|
|
492
|
-
},
|
|
493
|
-
|
|
494
|
-
async prepareDurableResumable(workflowIdOrPrefix?: string, sessionDir?: string): Promise<readonly ResumableWorkflowEntry[]> {
|
|
495
|
-
await ensureDbosReady();
|
|
496
|
-
preparedDurableCatalog = await prepareRuntimeDurableResumable(getDurableBackend, () => resolveDefaultStageSessionDir?.(), workflowIdOrPrefix, sessionDir);
|
|
497
|
-
return preparedDurableCatalog;
|
|
498
|
-
},
|
|
499
474
|
};
|
|
500
475
|
}
|
|
@@ -140,14 +140,17 @@ async function createTestAgentSession(_options?: CreateAgentSessionOptions): Pro
|
|
|
140
140
|
},
|
|
141
141
|
async compact(): ReturnType<StageSessionRuntime["compact"]> {
|
|
142
142
|
return {
|
|
143
|
-
|
|
143
|
+
compactedText: "[User]: retained",
|
|
144
|
+
firstKeptEntryId: "kept",
|
|
145
|
+
tokensBefore: 0,
|
|
146
|
+
promptVersion: 3,
|
|
144
147
|
parameters: { compression_ratio: 0.5, preserve_recent: 2, query: "auto-detected" },
|
|
145
|
-
|
|
146
|
-
protectedEntryIds: [],
|
|
148
|
+
rung: "planned",
|
|
147
149
|
stats: {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
linesBefore: 0,
|
|
151
|
+
linesDeleted: 0,
|
|
152
|
+
linesKept: 0,
|
|
153
|
+
rangeCount: 0,
|
|
151
154
|
tokensBefore: 0,
|
|
152
155
|
tokensAfter: 0,
|
|
153
156
|
percentReduction: 0,
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { WorkflowPersistencePort } from "../shared/types.js";
|
|
2
|
+
import { store } from "../shared/store.js";
|
|
3
|
+
import type { RunSnapshot } from "../shared/store-types.js";
|
|
4
|
+
import { openWorkflowResumeSelector } from "../tui/workflow-resume-selector.js";
|
|
5
|
+
import type { GraphOverlayPort } from "../tui/overlay-adapter.js";
|
|
6
|
+
import { formatResumableWorkflowList } from "../durable/resume-catalog.js";
|
|
7
|
+
import { getDurableBackend } from "../durable/factory.js";
|
|
8
|
+
import { listOpenableCompletedWorkflows } from "../durable/completed-catalog.js";
|
|
9
|
+
import { openCompletedDurableWorkflow } from "../durable/completed-inspection.js";
|
|
10
|
+
import type { ResumableWorkflowEntry } from "../durable/types.js";
|
|
11
|
+
import type { ExtensionRuntime } from "./runtime.js";
|
|
12
|
+
import type { ExtensionAPI, PiCommandContext } from "./public-types.js";
|
|
13
|
+
import type { WorkflowCommandReporter } from "./workflow-command-utils.js";
|
|
14
|
+
import { workflowPolicyFromContext } from "./workflow-policy.js";
|
|
15
|
+
import { formatWorkflowResourceLoadWarning } from "./workflow-command-surfaces.js";
|
|
16
|
+
import { overlaySurfaceFromContext } from "./workflow-targets.js";
|
|
17
|
+
|
|
18
|
+
export interface WorkflowRunControlDeps {
|
|
19
|
+
pi: ExtensionAPI;
|
|
20
|
+
overlay: GraphOverlayPort;
|
|
21
|
+
getPersistence: () => WorkflowPersistencePort | undefined;
|
|
22
|
+
runtimeForContext: (ctx?: PiCommandContext) => ExtensionRuntime;
|
|
23
|
+
ensureWorkflowResourcesLoaded: () => Promise<void> | void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface WorkflowResumeCatalog {
|
|
27
|
+
readonly resumable: readonly ResumableWorkflowEntry[];
|
|
28
|
+
readonly completed: readonly ResumableWorkflowEntry[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface WorkflowResumeTarget {
|
|
32
|
+
readonly kind: "live" | "durable" | "completed";
|
|
33
|
+
readonly workflowId: string;
|
|
34
|
+
readonly name: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type WorkflowResumeTargetResolution = WorkflowResumeTarget
|
|
38
|
+
| { readonly kind: "ambiguous"; readonly matches: readonly WorkflowResumeTarget[] }
|
|
39
|
+
| { readonly kind: "not_found" };
|
|
40
|
+
|
|
41
|
+
export async function prepareWorkflowResumeCatalog(
|
|
42
|
+
runtime: ExtensionRuntime,
|
|
43
|
+
activeLiveIds: ReadonlySet<string>,
|
|
44
|
+
target?: string,
|
|
45
|
+
): Promise<WorkflowResumeCatalog> {
|
|
46
|
+
const prepared = await runtime.prepareDurableResumable(target);
|
|
47
|
+
const backend = getDurableBackend();
|
|
48
|
+
const resumable = filterSelectorDurableEntries(runtime, prepared)
|
|
49
|
+
.filter((entry) => !activeLiveIds.has(entry.workflowId) && backend.isWorkflowLoadable(entry.workflowId));
|
|
50
|
+
const completed = runtime.prepareCompletedDurable !== undefined
|
|
51
|
+
? await runtime.prepareCompletedDurable()
|
|
52
|
+
: listOpenableCompletedWorkflows(backend);
|
|
53
|
+
return {
|
|
54
|
+
resumable,
|
|
55
|
+
completed: completed.filter((entry) => !activeLiveIds.has(entry.workflowId) && backend.isWorkflowLoadable(entry.workflowId)),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function handleDurableResume(
|
|
60
|
+
target: string | undefined,
|
|
61
|
+
ctx: PiCommandContext,
|
|
62
|
+
reporter: WorkflowCommandReporter,
|
|
63
|
+
deps: WorkflowRunControlDeps,
|
|
64
|
+
): Promise<boolean> {
|
|
65
|
+
const print = (message: string): void => reporter.info(message);
|
|
66
|
+
const fail = (message: string): void => reporter.error(message);
|
|
67
|
+
try {
|
|
68
|
+
await deps.ensureWorkflowResourcesLoaded();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
ctx.ui?.notify(formatWorkflowResourceLoadWarning(error), "warning");
|
|
71
|
+
}
|
|
72
|
+
const runtime = deps.runtimeForContext(ctx);
|
|
73
|
+
const policy = workflowPolicyFromContext(ctx);
|
|
74
|
+
const catalog = await prepareWorkflowResumeCatalog(runtime, new Set(), target);
|
|
75
|
+
const allOpenable = [...catalog.resumable, ...catalog.completed];
|
|
76
|
+
|
|
77
|
+
if (target !== undefined) {
|
|
78
|
+
const resolved = resolveWorkflowResumeTarget(
|
|
79
|
+
target,
|
|
80
|
+
[],
|
|
81
|
+
catalog.resumable,
|
|
82
|
+
getDurableBackend().listCompletedWorkflows(),
|
|
83
|
+
);
|
|
84
|
+
if (resolved.kind === "ambiguous") {
|
|
85
|
+
fail(`Ambiguous workflow prefix "${target}" matches: ${formatMatches(resolved.matches)}`);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (resolved.kind === "completed") {
|
|
89
|
+
return openCompletedTarget(resolved.workflowId, catalog.completed, ctx, reporter, deps, runtime);
|
|
90
|
+
}
|
|
91
|
+
if (resolved.kind === "durable") {
|
|
92
|
+
return resumeDurableTarget(resolved.workflowId, ctx, reporter, deps, runtime);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const completedAttempt = openCompleted(runtime, target, catalog.completed);
|
|
96
|
+
if (!completedAttempt.ok && completedAttempt.reason !== "not_found") {
|
|
97
|
+
fail(completedAttempt.message);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
const result = runtime.resumeDurableWorkflow(target, { policy });
|
|
101
|
+
fail(allOpenable.length === 0
|
|
102
|
+
? result.message
|
|
103
|
+
: `${result.message}\n\n${formatResumableWorkflowList(allOpenable)}`);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (allOpenable.length === 0) {
|
|
108
|
+
fail("No resumable or completed durable workflows found. Usage: /workflow resume <id> (or /resume for Atomic sessions).");
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
if (!policy.allowInputPicker) {
|
|
112
|
+
const instruction = catalog.completed.length === 0 ? "Resume with" : "Resume/open with";
|
|
113
|
+
print(`${formatResumableWorkflowList(allOpenable)}\n\n${instruction}: /workflow resume <id>`);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
const picked = await openWorkflowResumeSelector(ctx.ui, [], catalog.resumable, catalog.completed);
|
|
117
|
+
if (picked.kind === "durable") {
|
|
118
|
+
return resumeDurableTarget(picked.workflowId, ctx, reporter, deps, runtime);
|
|
119
|
+
}
|
|
120
|
+
if (picked.kind === "completed") {
|
|
121
|
+
return openCompletedTarget(picked.workflowId, catalog.completed, ctx, reporter, deps, runtime);
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function filterSelectorDurableEntries(
|
|
127
|
+
runtime: ExtensionRuntime,
|
|
128
|
+
entries: readonly ResumableWorkflowEntry[],
|
|
129
|
+
): readonly ResumableWorkflowEntry[] {
|
|
130
|
+
const registry = runtime.registry as { has(name: string): boolean } | undefined;
|
|
131
|
+
if (registry === undefined) return entries;
|
|
132
|
+
return entries.filter((entry) => {
|
|
133
|
+
const requiresDefinition = entry.status === "running" || entry.status === "failed" || entry.status === "blocked";
|
|
134
|
+
return !requiresDefinition || registry.has(entry.name);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function resolveWorkflowResumeTarget(
|
|
139
|
+
target: string,
|
|
140
|
+
liveRuns: readonly RunSnapshot[],
|
|
141
|
+
resumable: readonly ResumableWorkflowEntry[],
|
|
142
|
+
completed: readonly ResumableWorkflowEntry[],
|
|
143
|
+
): WorkflowResumeTargetResolution {
|
|
144
|
+
const targets = new Map<string, WorkflowResumeTarget>();
|
|
145
|
+
for (const entry of resumable) {
|
|
146
|
+
targets.set(entry.workflowId, { kind: "durable", workflowId: entry.workflowId, name: entry.name });
|
|
147
|
+
}
|
|
148
|
+
for (const entry of completed) {
|
|
149
|
+
targets.set(entry.workflowId, { kind: "completed", workflowId: entry.workflowId, name: entry.name });
|
|
150
|
+
}
|
|
151
|
+
for (const run of liveRuns.filter(isExplicitResumeCandidate)) {
|
|
152
|
+
targets.set(run.id, {
|
|
153
|
+
kind: run.status === "completed" ? "completed" : "live",
|
|
154
|
+
workflowId: run.id,
|
|
155
|
+
name: run.name,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const exact = targets.get(target);
|
|
159
|
+
if (exact !== undefined) return exact;
|
|
160
|
+
const matches = [...targets.values()].filter((candidate) => candidate.workflowId.startsWith(target));
|
|
161
|
+
if (matches.length === 0) return { kind: "not_found" };
|
|
162
|
+
if (matches.length === 1) return matches[0]!;
|
|
163
|
+
return { kind: "ambiguous", matches };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function isExplicitResumeCandidate(run: RunSnapshot): boolean {
|
|
167
|
+
if (run.status === "completed" || run.status === "paused" || run.exitReason === "quit") return true;
|
|
168
|
+
if (run.stages.some((stage) => stage.status === "paused")) return true;
|
|
169
|
+
if (run.status === "failed") return run.resumable !== false;
|
|
170
|
+
if (run.endedAt !== undefined) return false;
|
|
171
|
+
if (run.status === "running") return true;
|
|
172
|
+
return run.resumable === true && run.failureRecoverability === "recoverable";
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function resumeDurableTarget(
|
|
176
|
+
workflowId: string,
|
|
177
|
+
ctx: PiCommandContext,
|
|
178
|
+
reporter: WorkflowCommandReporter,
|
|
179
|
+
deps: WorkflowRunControlDeps,
|
|
180
|
+
runtime: ExtensionRuntime,
|
|
181
|
+
): boolean {
|
|
182
|
+
const result = runtime.resumeDurableWorkflow(workflowId, { policy: workflowPolicyFromContext(ctx) });
|
|
183
|
+
if (!result.ok) reporter.error(result.message);
|
|
184
|
+
else {
|
|
185
|
+
reporter.info(result.message);
|
|
186
|
+
if (workflowPolicyFromContext(ctx).allowInputPicker) {
|
|
187
|
+
deps.overlay.open(result.runId, overlaySurfaceFromContext(ctx));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function openCompletedTarget(
|
|
194
|
+
workflowId: string,
|
|
195
|
+
catalog: readonly ResumableWorkflowEntry[],
|
|
196
|
+
ctx: PiCommandContext,
|
|
197
|
+
reporter: WorkflowCommandReporter,
|
|
198
|
+
deps: WorkflowRunControlDeps,
|
|
199
|
+
runtime: ExtensionRuntime,
|
|
200
|
+
): boolean {
|
|
201
|
+
const result = openCompleted(runtime, workflowId, catalog);
|
|
202
|
+
if (!result.ok) reporter.error(result.message);
|
|
203
|
+
else {
|
|
204
|
+
reporter.info(result.message);
|
|
205
|
+
if (workflowPolicyFromContext(ctx).allowInputPicker) {
|
|
206
|
+
deps.overlay.open(result.runId, overlaySurfaceFromContext(ctx));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function openCompleted(
|
|
213
|
+
runtime: ExtensionRuntime,
|
|
214
|
+
workflowIdOrPrefix: string,
|
|
215
|
+
catalog: readonly ResumableWorkflowEntry[],
|
|
216
|
+
) {
|
|
217
|
+
return runtime.openCompletedDurableWorkflow?.(workflowIdOrPrefix, catalog)
|
|
218
|
+
?? openCompletedDurableWorkflow(workflowIdOrPrefix, {
|
|
219
|
+
durableBackend: getDurableBackend(),
|
|
220
|
+
store,
|
|
221
|
+
}, catalog);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function formatMatches(entries: readonly WorkflowResumeTarget[]): string {
|
|
225
|
+
return entries.map((entry) => `${entry.name} (${entry.workflowId.slice(0, 8)})`).join(", ");
|
|
226
|
+
}
|
|
@@ -23,6 +23,7 @@ export const DEFAULT_PROMPT_GUIDANCE: string[] = [
|
|
|
23
23
|
`**Workflow discovery and lifecycle**:
|
|
24
24
|
- For unfamiliar named workflows, discover with \`action: "list"\`, inspect with \`action: "get"\` or \`action: "inputs"\`, and run with \`action: "run"\`, \`workflow\`, and validated \`inputs\`; do not invent workflow names or input keys.
|
|
25
25
|
- In interactive chat, launch every workflow in the background. Named workflow launches are already detached; direct \`task\`, \`tasks\`, and \`chain\` launches must set top-level \`async: true\`. This applies only to launches, not inspection or control calls (\`status\`, \`stages\`, \`stage\`, \`transcript\`, \`send\`, \`pause\`, \`resume\`, \`interrupt\`, \`kill\`). Use foreground execution only when the user explicitly requests it or it is technically required, and tell the user before launching it.
|
|
26
|
+
- Natural-language instructions to create or use a worktree do not enable runner isolation. For write-capable direct tasks, set \`worktree: true\` or \`gitWorktreeDir\`; \`cwd\` only selects the starting directory and runs in that checkout. For independent queues, prefer one run per independent item with its own reusable worktree.
|
|
26
27
|
- Once you run a workflow, end the current turn and wait for user input or a lifecycle notice. Do not use sleep/status polling loops: key start, finish, and failure events arrive automatically. Use targeted \`status\`/\`stages\`/\`stage\` checks only when the user asks or the next step needs them, and use \`send\`/\`pause\`/\`resume\`/\`interrupt\`/\`kill\` only to answer, steer, or honor control requests.
|
|
27
28
|
- For transcripts, avoid whole-file reads. Get \`sessionFile\`/\`transcriptPath\` from \`stages\` or \`stage\`, preserve the exact path and platform separators, search with \`rg\`/\`grep\`, and read small relevant ranges; use explicit \`tail\` or \`limit\` only for a bounded preview.`,
|
|
28
29
|
`**Workflow authoring and handoffs**:
|