tulingcode 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +134 -0
- package/Dockerfile +18 -0
- package/README.md +15 -0
- package/bin/tuling +179 -0
- package/bunfig.toml +7 -0
- package/drizzle.config.ts +10 -0
- package/git +0 -0
- package/migration/20260127222353_familiar_lady_ursula/migration.sql +90 -0
- package/migration/20260127222353_familiar_lady_ursula/snapshot.json +796 -0
- package/migration/20260211171708_add_project_commands/migration.sql +1 -0
- package/migration/20260211171708_add_project_commands/snapshot.json +806 -0
- package/migration/20260213144116_wakeful_the_professor/migration.sql +11 -0
- package/migration/20260213144116_wakeful_the_professor/snapshot.json +897 -0
- package/migration/20260225215848_workspace/migration.sql +7 -0
- package/migration/20260225215848_workspace/snapshot.json +959 -0
- package/migration/20260227213759_add_session_workspace_id/migration.sql +2 -0
- package/migration/20260227213759_add_session_workspace_id/snapshot.json +983 -0
- package/migration/20260228203230_blue_harpoon/migration.sql +17 -0
- package/migration/20260228203230_blue_harpoon/snapshot.json +1102 -0
- package/migration/20260303231226_add_workspace_fields/migration.sql +5 -0
- package/migration/20260303231226_add_workspace_fields/snapshot.json +1013 -0
- package/migration/20260309230000_move_org_to_state/migration.sql +3 -0
- package/migration/20260309230000_move_org_to_state/snapshot.json +1156 -0
- package/migration/20260312043431_session_message_cursor/migration.sql +4 -0
- package/migration/20260312043431_session_message_cursor/snapshot.json +1168 -0
- package/migration/20260323234822_events/migration.sql +13 -0
- package/migration/20260323234822_events/snapshot.json +1271 -0
- package/migration/20260410174513_workspace-name/migration.sql +16 -0
- package/migration/20260410174513_workspace-name/snapshot.json +1271 -0
- package/migration/20260413175956_chief_energizer/migration.sql +13 -0
- package/migration/20260413175956_chief_energizer/snapshot.json +1399 -0
- package/migration/20260422160000_context_inheritance/migration.sql +3 -0
- package/migration/20260422170000_task_registry/migration.sql +18 -0
- package/migration/20260423145421_remove_session_entry/migration.sql +4 -0
- package/migration/20260515000000_actor_rename/migration.sql +7 -0
- package/migration/20260515010000_memory_fts/migration.sql +33 -0
- package/migration/20260515020000_user_task/migration.sql +29 -0
- package/migration/20260519000000_last_checkpoint_message_id/migration.sql +1 -0
- package/migration/20260521000000_message_agent_id/migration.sql +2 -0
- package/migration/20260521000100_actor_registry_v6/migration.sql +25 -0
- package/migration/20260521010000_memory_fts_v6/migration.sql +33 -0
- package/migration/20260521020000_memory_fts_triggers/migration.sql +17 -0
- package/migration/20260526000000_agent_id_main/migration.sql +14 -0
- package/migration/20260527000000_actor_lifecycle/migration.sql +8 -0
- package/migration/20260527000100_inbox/migration.sql +12 -0
- package/migration/20260529000000_task_todo_redesign/migration.sql +16 -0
- package/migration/20260603000000_task_in_progress_owner/migration.sql +1 -0
- package/migration/20260603000000_workflow_run/migration.sql +17 -0
- package/migration/20260604000000_workflow_script_sha/migration.sql +1 -0
- package/migration/20260608000000_claude_import/migration.sql +7 -0
- package/migration/20260608010000_claude_import_message_ids/migration.sql +1 -0
- package/migration/20260609000000_history_fts/migration.sql +29 -0
- package/migration/20260609230000_workflow_agent_timeout/migration.sql +1 -0
- package/package.json +196 -0
- package/parsers-config.ts +290 -0
- package/script/build.ts +267 -0
- package/script/check-migrations.ts +16 -0
- package/script/fix-node-pty.ts +28 -0
- package/script/generate.ts +23 -0
- package/script/postinstall.mjs +102 -0
- package/script/publish.ts +60 -0
- package/script/run-workspace-server +106 -0
- package/script/schema.ts +63 -0
- package/script/time.ts +6 -0
- package/script/trace-imports.ts +153 -0
- package/script/upgrade-opentui.ts +64 -0
- package/src/account/account.sql.ts +39 -0
- package/src/account/account.ts +456 -0
- package/src/account/repo.ts +166 -0
- package/src/account/schema.ts +99 -0
- package/src/account/url.ts +8 -0
- package/src/acp/README.md +174 -0
- package/src/acp/agent.ts +1783 -0
- package/src/acp/session.ts +116 -0
- package/src/acp/types.ts +24 -0
- package/src/actor/actor.sql.ts +38 -0
- package/src/actor/events.ts +67 -0
- package/src/actor/index.ts +2 -0
- package/src/actor/registry.ts +412 -0
- package/src/actor/return-header.ts +24 -0
- package/src/actor/schema.ts +47 -0
- package/src/actor/spawn-ref.ts +16 -0
- package/src/actor/spawn.ts +741 -0
- package/src/actor/turn.ts +49 -0
- package/src/actor/waiter.ts +166 -0
- package/src/agent/agent.ts +554 -0
- package/src/agent/config.ts +5 -0
- package/src/agent/generate.txt +75 -0
- package/src/agent/prompt/checkpoint-writer.txt +167 -0
- package/src/agent/prompt/compaction.txt +9 -0
- package/src/agent/prompt/distill.txt +199 -0
- package/src/agent/prompt/dream.txt +155 -0
- package/src/agent/prompt/explore.txt +18 -0
- package/src/agent/prompt/summary.txt +11 -0
- package/src/agent/prompt/title.txt +44 -0
- package/src/audio.d.ts +9 -0
- package/src/auth/index.ts +97 -0
- package/src/bus/bus-event.ts +33 -0
- package/src/bus/global.ts +12 -0
- package/src/bus/index.ts +193 -0
- package/src/cli/bootstrap.ts +33 -0
- package/src/cli/cmd/account.ts +258 -0
- package/src/cli/cmd/acp.ts +70 -0
- package/src/cli/cmd/agent.ts +248 -0
- package/src/cli/cmd/cmd.ts +7 -0
- package/src/cli/cmd/db.ts +120 -0
- package/src/cli/cmd/debug/agent.ts +192 -0
- package/src/cli/cmd/debug/config.ts +17 -0
- package/src/cli/cmd/debug/file.ts +100 -0
- package/src/cli/cmd/debug/index.ts +48 -0
- package/src/cli/cmd/debug/lsp.ts +61 -0
- package/src/cli/cmd/debug/ripgrep.ts +105 -0
- package/src/cli/cmd/debug/scrap.ts +16 -0
- package/src/cli/cmd/debug/skill.ts +23 -0
- package/src/cli/cmd/debug/snapshot.ts +53 -0
- package/src/cli/cmd/export.ts +306 -0
- package/src/cli/cmd/generate.ts +50 -0
- package/src/cli/cmd/github.ts +1647 -0
- package/src/cli/cmd/import.ts +208 -0
- package/src/cli/cmd/mcp.ts +812 -0
- package/src/cli/cmd/models.ts +88 -0
- package/src/cli/cmd/plug.ts +233 -0
- package/src/cli/cmd/pr.ts +138 -0
- package/src/cli/cmd/providers.ts +705 -0
- package/src/cli/cmd/run-completion.ts +77 -0
- package/src/cli/cmd/run.ts +694 -0
- package/src/cli/cmd/serve.ts +21 -0
- package/src/cli/cmd/session.ts +181 -0
- package/src/cli/cmd/stats.ts +413 -0
- package/src/cli/cmd/tui/app.tsx +1130 -0
- package/src/cli/cmd/tui/asset/TEN_VAD_LICENSE +12 -0
- package/src/cli/cmd/tui/asset/charge.wav +0 -0
- package/src/cli/cmd/tui/asset/pulse-a.wav +0 -0
- package/src/cli/cmd/tui/asset/pulse-b.wav +0 -0
- package/src/cli/cmd/tui/asset/pulse-c.wav +0 -0
- package/src/cli/cmd/tui/asset/ten_vad.wasm +0 -0
- package/src/cli/cmd/tui/asset/ten_vad_loader.js +30 -0
- package/src/cli/cmd/tui/attach.ts +83 -0
- package/src/cli/cmd/tui/component/background-image.tsx +150 -0
- package/src/cli/cmd/tui/component/bg-pulse.tsx +130 -0
- package/src/cli/cmd/tui/component/border.tsx +21 -0
- package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-command.tsx +208 -0
- package/src/cli/cmd/tui/component/dialog-console-org.tsx +103 -0
- package/src/cli/cmd/tui/component/dialog-go-upsell.tsx +157 -0
- package/src/cli/cmd/tui/component/dialog-image-list.tsx +111 -0
- package/src/cli/cmd/tui/component/dialog-logo-design.tsx +37 -0
- package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
- package/src/cli/cmd/tui/component/dialog-mimo-login.tsx +224 -0
- package/src/cli/cmd/tui/component/dialog-model.tsx +253 -0
- package/src/cli/cmd/tui/component/dialog-provider.tsx +490 -0
- package/src/cli/cmd/tui/component/dialog-session-delete-failed.tsx +101 -0
- package/src/cli/cmd/tui/component/dialog-session-list.tsx +269 -0
- package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-skill.tsx +42 -0
- package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
- package/src/cli/cmd/tui/component/dialog-status.tsx +170 -0
- package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
- package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
- package/src/cli/cmd/tui/component/dialog-variant.tsx +39 -0
- package/src/cli/cmd/tui/component/dialog-workflows.tsx +62 -0
- package/src/cli/cmd/tui/component/dialog-workspace-create.tsx +289 -0
- package/src/cli/cmd/tui/component/dialog-workspace-unavailable.tsx +81 -0
- package/src/cli/cmd/tui/component/dialog-worktree.tsx +90 -0
- package/src/cli/cmd/tui/component/error-component.tsx +92 -0
- package/src/cli/cmd/tui/component/logo.tsx +961 -0
- package/src/cli/cmd/tui/component/plugin-route-missing.tsx +14 -0
- package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +684 -0
- package/src/cli/cmd/tui/component/prompt/cwd.ts +0 -0
- package/src/cli/cmd/tui/component/prompt/frecency.tsx +90 -0
- package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
- package/src/cli/cmd/tui/component/prompt/index.tsx +1812 -0
- package/src/cli/cmd/tui/component/prompt/part.ts +16 -0
- package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
- package/src/cli/cmd/tui/component/spinner.tsx +24 -0
- package/src/cli/cmd/tui/component/starry-background.tsx +305 -0
- package/src/cli/cmd/tui/component/startup-loading.tsx +67 -0
- package/src/cli/cmd/tui/component/task-item.tsx +63 -0
- package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
- package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
- package/src/cli/cmd/tui/config/cwd.ts +5 -0
- package/src/cli/cmd/tui/config/tui-migrate.ts +151 -0
- package/src/cli/cmd/tui/config/tui-schema.ts +38 -0
- package/src/cli/cmd/tui/config/tui.ts +219 -0
- package/src/cli/cmd/tui/context/args.tsx +16 -0
- package/src/cli/cmd/tui/context/directory.ts +15 -0
- package/src/cli/cmd/tui/context/event.ts +45 -0
- package/src/cli/cmd/tui/context/exit.tsx +65 -0
- package/src/cli/cmd/tui/context/helper.tsx +25 -0
- package/src/cli/cmd/tui/context/keybind.tsx +105 -0
- package/src/cli/cmd/tui/context/kv.tsx +76 -0
- package/src/cli/cmd/tui/context/language.tsx +91 -0
- package/src/cli/cmd/tui/context/local.tsx +455 -0
- package/src/cli/cmd/tui/context/plugin-keybinds.ts +41 -0
- package/src/cli/cmd/tui/context/project.tsx +109 -0
- package/src/cli/cmd/tui/context/prompt.tsx +18 -0
- package/src/cli/cmd/tui/context/route.tsx +61 -0
- package/src/cli/cmd/tui/context/sdk.tsx +150 -0
- package/src/cli/cmd/tui/context/sync.tsx +828 -0
- package/src/cli/cmd/tui/context/theme/aura.json +69 -0
- package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
- package/src/cli/cmd/tui/context/theme/carbonfox.json +248 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +230 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +230 -0
- package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
- package/src/cli/cmd/tui/context/theme/cobalt2.json +225 -0
- package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
- package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
- package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
- package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
- package/src/cli/cmd/tui/context/theme/github.json +233 -0
- package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
- package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
- package/src/cli/cmd/tui/context/theme/lucent-orng.json +234 -0
- package/src/cli/cmd/tui/context/theme/material.json +235 -0
- package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
- package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
- package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
- package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
- package/src/cli/cmd/tui/context/theme/nord.json +223 -0
- package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
- package/src/cli/cmd/tui/context/theme/orng.json +249 -0
- package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
- package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
- package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
- package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
- package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
- package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
- package/src/cli/cmd/tui/context/theme/tulingcode.json +245 -0
- package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
- package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
- package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
- package/src/cli/cmd/tui/context/theme.tsx +1298 -0
- package/src/cli/cmd/tui/context/thinking.ts +48 -0
- package/src/cli/cmd/tui/context/tui-config.tsx +9 -0
- package/src/cli/cmd/tui/event.ts +56 -0
- package/src/cli/cmd/tui/feature-plugins/home/footer.tsx +93 -0
- package/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx +193 -0
- package/src/cli/cmd/tui/feature-plugins/home/tips.tsx +54 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/context.tsx +114 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/cwd.tsx +45 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/files.tsx +62 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/footer.tsx +93 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/goal.tsx +84 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/instructions.tsx +54 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/lsp.tsx +66 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/mcp.tsx +98 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/task.tsx +95 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/todo.tsx +51 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/tps.ts +31 -0
- package/src/cli/cmd/tui/feature-plugins/system/plugins.tsx +274 -0
- package/src/cli/cmd/tui/i18n/en.ts +397 -0
- package/src/cli/cmd/tui/i18n/es.ts +433 -0
- package/src/cli/cmd/tui/i18n/fr.ts +440 -0
- package/src/cli/cmd/tui/i18n/ja.ts +392 -0
- package/src/cli/cmd/tui/i18n/locales.ts +82 -0
- package/src/cli/cmd/tui/i18n/ru.ts +452 -0
- package/src/cli/cmd/tui/i18n/zh.ts +390 -0
- package/src/cli/cmd/tui/i18n/zht.ts +360 -0
- package/src/cli/cmd/tui/layer.ts +6 -0
- package/src/cli/cmd/tui/plugin/api.tsx +402 -0
- package/src/cli/cmd/tui/plugin/index.ts +3 -0
- package/src/cli/cmd/tui/plugin/internal.ts +35 -0
- package/src/cli/cmd/tui/plugin/runtime.ts +1030 -0
- package/src/cli/cmd/tui/plugin/slots.tsx +60 -0
- package/src/cli/cmd/tui/routes/home.tsx +165 -0
- package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +76 -0
- package/src/cli/cmd/tui/routes/session/dialog-message.tsx +116 -0
- package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +47 -0
- package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
- package/src/cli/cmd/tui/routes/session/footer.tsx +91 -0
- package/src/cli/cmd/tui/routes/session/index.tsx +2532 -0
- package/src/cli/cmd/tui/routes/session/permission.tsx +691 -0
- package/src/cli/cmd/tui/routes/session/question.tsx +488 -0
- package/src/cli/cmd/tui/routes/session/sidebar.tsx +97 -0
- package/src/cli/cmd/tui/routes/session/subagent-footer.tsx +142 -0
- package/src/cli/cmd/tui/thread.ts +246 -0
- package/src/cli/cmd/tui/ui/dialog-alert.tsx +61 -0
- package/src/cli/cmd/tui/ui/dialog-confirm.tsx +95 -0
- package/src/cli/cmd/tui/ui/dialog-export-options.tsx +223 -0
- package/src/cli/cmd/tui/ui/dialog-help.tsx +42 -0
- package/src/cli/cmd/tui/ui/dialog-prompt.tsx +123 -0
- package/src/cli/cmd/tui/ui/dialog-select.tsx +452 -0
- package/src/cli/cmd/tui/ui/dialog.tsx +207 -0
- package/src/cli/cmd/tui/ui/link.tsx +28 -0
- package/src/cli/cmd/tui/ui/spinner.ts +378 -0
- package/src/cli/cmd/tui/ui/toast.tsx +102 -0
- package/src/cli/cmd/tui/util/clipboard.ts +203 -0
- package/src/cli/cmd/tui/util/editor.ts +35 -0
- package/src/cli/cmd/tui/util/image-protocol.ts +35 -0
- package/src/cli/cmd/tui/util/index.ts +6 -0
- package/src/cli/cmd/tui/util/model.ts +23 -0
- package/src/cli/cmd/tui/util/provider-origin.ts +7 -0
- package/src/cli/cmd/tui/util/revert-diff.ts +18 -0
- package/src/cli/cmd/tui/util/scroll.ts +23 -0
- package/src/cli/cmd/tui/util/selection.ts +23 -0
- package/src/cli/cmd/tui/util/signal.ts +41 -0
- package/src/cli/cmd/tui/util/sound.ts +154 -0
- package/src/cli/cmd/tui/util/system-locale.ts +209 -0
- package/src/cli/cmd/tui/util/terminal.ts +110 -0
- package/src/cli/cmd/tui/util/transcript.ts +112 -0
- package/src/cli/cmd/tui/util/vad.ts +229 -0
- package/src/cli/cmd/tui/util/voice.ts +360 -0
- package/src/cli/cmd/tui/win32.ts +130 -0
- package/src/cli/cmd/tui/worker.ts +104 -0
- package/src/cli/cmd/uninstall.ts +351 -0
- package/src/cli/cmd/upgrade.ts +79 -0
- package/src/cli/cmd/web.ts +81 -0
- package/src/cli/effect/prompt.ts +25 -0
- package/src/cli/error.ts +82 -0
- package/src/cli/heap.ts +59 -0
- package/src/cli/i18n.ts +15 -0
- package/src/cli/logo.ts +53 -0
- package/src/cli/network.ts +62 -0
- package/src/cli/ui.ts +133 -0
- package/src/cli/upgrade.ts +41 -0
- package/src/command/index.ts +276 -0
- package/src/command/template/initialize.txt +66 -0
- package/src/command/template/review.txt +101 -0
- package/src/config/agent.ts +197 -0
- package/src/config/command.ts +69 -0
- package/src/config/config.ts +1024 -0
- package/src/config/console-state.ts +16 -0
- package/src/config/entry-name.ts +16 -0
- package/src/config/error.ts +21 -0
- package/src/config/formatter.ts +17 -0
- package/src/config/history.ts +21 -0
- package/src/config/index.ts +16 -0
- package/src/config/keybinds.ts +127 -0
- package/src/config/layout.ts +10 -0
- package/src/config/lsp.ts +45 -0
- package/src/config/managed.ts +70 -0
- package/src/config/markdown.ts +97 -0
- package/src/config/mcp.ts +172 -0
- package/src/config/model-id.ts +14 -0
- package/src/config/parse.ts +44 -0
- package/src/config/paths.ts +73 -0
- package/src/config/permission.ts +76 -0
- package/src/config/plugin.ts +88 -0
- package/src/config/provider.ts +118 -0
- package/src/config/server.ts +20 -0
- package/src/config/skills.ts +16 -0
- package/src/config/variable.ts +90 -0
- package/src/control-plane/adaptors/index.ts +52 -0
- package/src/control-plane/adaptors/worktree.ts +47 -0
- package/src/control-plane/dev/debug-workspace-plugin.ts +73 -0
- package/src/control-plane/schema.ts +19 -0
- package/src/control-plane/sse.ts +66 -0
- package/src/control-plane/types.ts +34 -0
- package/src/control-plane/util.ts +37 -0
- package/src/control-plane/workspace-context.ts +26 -0
- package/src/control-plane/workspace.sql.ts +17 -0
- package/src/control-plane/workspace.ts +615 -0
- package/src/effect/app-runtime.ts +146 -0
- package/src/effect/bootstrap-runtime.ts +33 -0
- package/src/effect/bridge.ts +48 -0
- package/src/effect/cross-spawn-spawner.ts +514 -0
- package/src/effect/index.ts +5 -0
- package/src/effect/instance-ref.ts +11 -0
- package/src/effect/instance-registry.ts +12 -0
- package/src/effect/instance-state.ts +81 -0
- package/src/effect/logger.ts +73 -0
- package/src/effect/memo-map.ts +3 -0
- package/src/effect/observability.ts +107 -0
- package/src/effect/run-service.ts +52 -0
- package/src/effect/runner.ts +210 -0
- package/src/effect/runtime.ts +19 -0
- package/src/env/index.ts +37 -0
- package/src/file/ignore.ts +81 -0
- package/src/file/index.ts +664 -0
- package/src/file/protected.ts +59 -0
- package/src/file/ripgrep.ts +485 -0
- package/src/file/watcher.ts +163 -0
- package/src/flag/flag.ts +164 -0
- package/src/format/formatter.ts +403 -0
- package/src/format/index.ts +203 -0
- package/src/git/index.ts +260 -0
- package/src/global/index.ts +54 -0
- package/src/history/backfill.ts +162 -0
- package/src/history/extract.ts +67 -0
- package/src/history/fts-query.ts +15 -0
- package/src/history/fts.sql.ts +20 -0
- package/src/history/index.ts +10 -0
- package/src/history/resolve.ts +65 -0
- package/src/history/service.ts +258 -0
- package/src/history/writer.ts +112 -0
- package/src/id/id.ts +87 -0
- package/src/ide/index.ts +73 -0
- package/src/inbox/inbox-ref.ts +38 -0
- package/src/inbox/inbox.sql.ts +26 -0
- package/src/inbox/inbox.ts +223 -0
- package/src/inbox/index.ts +3 -0
- package/src/inbox/render.ts +40 -0
- package/src/index.ts +260 -0
- package/src/installation/index.ts +351 -0
- package/src/installation/version.ts +8 -0
- package/src/lsp/client.ts +249 -0
- package/src/lsp/diagnostic.ts +29 -0
- package/src/lsp/index.ts +3 -0
- package/src/lsp/language.ts +120 -0
- package/src/lsp/launch.ts +21 -0
- package/src/lsp/lsp.ts +519 -0
- package/src/lsp/server.ts +1956 -0
- package/src/mcp/auth.ts +144 -0
- package/src/mcp/index.ts +944 -0
- package/src/mcp/oauth-callback.ts +232 -0
- package/src/mcp/oauth-provider.ts +214 -0
- package/src/memory/fts-query.ts +37 -0
- package/src/memory/fts.sql.ts +19 -0
- package/src/memory/index.ts +1 -0
- package/src/memory/paths.ts +116 -0
- package/src/memory/reconcile.ts +144 -0
- package/src/memory/service.ts +144 -0
- package/src/metrics/client.ts +40 -0
- package/src/metrics/event.ts +43 -0
- package/src/metrics/index.ts +5 -0
- package/src/metrics/installation.ts +18 -0
- package/src/metrics/subscriber.ts +58 -0
- package/src/metrics/util.ts +9 -0
- package/src/node.ts +6 -0
- package/src/npm/config.ts +0 -0
- package/src/npm/index.ts +293 -0
- package/src/npmcli-config.d.ts +43 -0
- package/src/patch/index.ts +680 -0
- package/src/permission/arity.ts +163 -0
- package/src/permission/evaluate.ts +15 -0
- package/src/permission/index.ts +379 -0
- package/src/permission/schema.ts +17 -0
- package/src/plugin/checkpoint-splitover.ts +60 -0
- package/src/plugin/cloud-ai.ts +329 -0
- package/src/plugin/cloudflare.ts +76 -0
- package/src/plugin/codex.ts +607 -0
- package/src/plugin/github-copilot/copilot.ts +368 -0
- package/src/plugin/github-copilot/models.ts +153 -0
- package/src/plugin/index.ts +493 -0
- package/src/plugin/install.ts +439 -0
- package/src/plugin/loader.ts +216 -0
- package/src/plugin/matcher.ts +33 -0
- package/src/plugin/meta.ts +188 -0
- package/src/plugin/mimo-free.ts +153 -0
- package/src/plugin/mimo.ts +124 -0
- package/src/plugin/shared.ts +323 -0
- package/src/plugin/subagent-progress-checker.ts +147 -0
- package/src/project/bootstrap.ts +59 -0
- package/src/project/index.ts +2 -0
- package/src/project/instance.ts +190 -0
- package/src/project/project-id.ts +48 -0
- package/src/project/project.sql.ts +16 -0
- package/src/project/project.ts +501 -0
- package/src/project/schema.ts +15 -0
- package/src/project/vcs.ts +227 -0
- package/src/provider/auth.ts +234 -0
- package/src/provider/error.ts +216 -0
- package/src/provider/index.ts +5 -0
- package/src/provider/models.ts +180 -0
- package/src/provider/provider.ts +1782 -0
- package/src/provider/schema.ts +36 -0
- package/src/provider/sdk/copilot/README.md +5 -0
- package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +170 -0
- package/src/provider/sdk/copilot/chat/get-response-metadata.ts +15 -0
- package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +19 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +64 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +815 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +28 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +83 -0
- package/src/provider/sdk/copilot/copilot-provider.ts +100 -0
- package/src/provider/sdk/copilot/index.ts +2 -0
- package/src/provider/sdk/copilot/openai-compatible-error.ts +27 -0
- package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +335 -0
- package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
- package/src/provider/sdk/copilot/responses/openai-config.ts +18 -0
- package/src/provider/sdk/copilot/responses/openai-error.ts +22 -0
- package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +214 -0
- package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +1770 -0
- package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +173 -0
- package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +1 -0
- package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +87 -0
- package/src/provider/sdk/copilot/responses/tool/file-search.ts +127 -0
- package/src/provider/sdk/copilot/responses/tool/image-generation.ts +114 -0
- package/src/provider/sdk/copilot/responses/tool/local-shell.ts +64 -0
- package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +103 -0
- package/src/provider/sdk/copilot/responses/tool/web-search.ts +102 -0
- package/src/provider/transform.ts +1322 -0
- package/src/pty/index.ts +364 -0
- package/src/pty/pty.bun.ts +26 -0
- package/src/pty/pty.node.ts +27 -0
- package/src/pty/pty.ts +25 -0
- package/src/pty/schema.ts +17 -0
- package/src/question/index.ts +252 -0
- package/src/question/schema.ts +17 -0
- package/src/server/adapter.bun.ts +40 -0
- package/src/server/adapter.node.ts +66 -0
- package/src/server/adapter.ts +21 -0
- package/src/server/error.ts +53 -0
- package/src/server/event.ts +7 -0
- package/src/server/fence.ts +81 -0
- package/src/server/mdns.ts +60 -0
- package/src/server/middleware.ts +92 -0
- package/src/server/projectors.ts +28 -0
- package/src/server/proxy.ts +171 -0
- package/src/server/routes/control/index.ts +160 -0
- package/src/server/routes/control/workspace.ts +203 -0
- package/src/server/routes/global.ts +287 -0
- package/src/server/routes/instance/bash-interactive.ts +82 -0
- package/src/server/routes/instance/config.ts +89 -0
- package/src/server/routes/instance/event.ts +88 -0
- package/src/server/routes/instance/experimental.ts +408 -0
- package/src/server/routes/instance/file.ts +190 -0
- package/src/server/routes/instance/httpapi/config.ts +51 -0
- package/src/server/routes/instance/httpapi/permission.ts +72 -0
- package/src/server/routes/instance/httpapi/project.ts +62 -0
- package/src/server/routes/instance/httpapi/provider.ts +142 -0
- package/src/server/routes/instance/httpapi/question.ts +121 -0
- package/src/server/routes/instance/httpapi/server.ts +136 -0
- package/src/server/routes/instance/index.ts +301 -0
- package/src/server/routes/instance/mcp.ts +260 -0
- package/src/server/routes/instance/middleware.ts +35 -0
- package/src/server/routes/instance/permission.ts +73 -0
- package/src/server/routes/instance/project.ts +122 -0
- package/src/server/routes/instance/provider.ts +158 -0
- package/src/server/routes/instance/pty.ts +247 -0
- package/src/server/routes/instance/question.ts +162 -0
- package/src/server/routes/instance/session.ts +1296 -0
- package/src/server/routes/instance/sync.ts +143 -0
- package/src/server/routes/instance/trace.ts +59 -0
- package/src/server/routes/instance/tui.ts +384 -0
- package/src/server/routes/instance/workflows.ts +72 -0
- package/src/server/routes/ui.ts +55 -0
- package/src/server/server.ts +136 -0
- package/src/server/workspace.ts +122 -0
- package/src/session/auto-dream.ts +123 -0
- package/src/session/boundary.ts +77 -0
- package/src/session/budgeted-read.ts +118 -0
- package/src/session/checkpoint-align.ts +29 -0
- package/src/session/checkpoint-context.ts +36 -0
- package/src/session/checkpoint-paths.ts +86 -0
- package/src/session/checkpoint-progress-reconcile.ts +111 -0
- package/src/session/checkpoint-retry.ts +192 -0
- package/src/session/checkpoint-templates.ts +114 -0
- package/src/session/checkpoint-validator.ts +259 -0
- package/src/session/checkpoint.ts +1478 -0
- package/src/session/classify.ts +92 -0
- package/src/session/claude-import.sql.ts +13 -0
- package/src/session/claude-import.ts +379 -0
- package/src/session/compaction.ts +543 -0
- package/src/session/goal.ts +232 -0
- package/src/session/index.ts +1 -0
- package/src/session/instruction.ts +276 -0
- package/src/session/last-message-info.ts +32 -0
- package/src/session/llm-request-prefix.ts +82 -0
- package/src/session/llm.ts +735 -0
- package/src/session/max-mode.ts +397 -0
- package/src/session/message-v2.ts +1136 -0
- package/src/session/message.ts +191 -0
- package/src/session/overflow.ts +53 -0
- package/src/session/prefix-capture-ref.ts +48 -0
- package/src/session/processor.ts +962 -0
- package/src/session/projectors.ts +137 -0
- package/src/session/prompt/anthropic.txt +154 -0
- package/src/session/prompt/beast.txt +155 -0
- package/src/session/prompt/build-switch.txt +5 -0
- package/src/session/prompt/codex.txt +79 -0
- package/src/session/prompt/compose.txt +115 -0
- package/src/session/prompt/copilot-gpt-5.txt +143 -0
- package/src/session/prompt/default.txt +151 -0
- package/src/session/prompt/gemini.txt +155 -0
- package/src/session/prompt/gpt.txt +107 -0
- package/src/session/prompt/kimi.txt +95 -0
- package/src/session/prompt/max-steps.txt +16 -0
- package/src/session/prompt/trinity.txt +97 -0
- package/src/session/prompt.ts +3355 -0
- package/src/session/prune.ts +481 -0
- package/src/session/retry.ts +166 -0
- package/src/session/revert.ts +161 -0
- package/src/session/run-state.ts +135 -0
- package/src/session/schema.ts +36 -0
- package/src/session/session.sql.ts +110 -0
- package/src/session/session.ts +908 -0
- package/src/session/status.ts +89 -0
- package/src/session/summary.ts +163 -0
- package/src/session/system.ts +86 -0
- package/src/session/todo.ts +77 -0
- package/src/share/index.ts +2 -0
- package/src/share/session.ts +57 -0
- package/src/share/share-next.ts +381 -0
- package/src/share/share.sql.ts +13 -0
- package/src/shell/shell.ts +110 -0
- package/src/skill/compose/.bundle/ask/SKILL.md +58 -0
- package/src/skill/compose/.bundle/brainstorm/SKILL.md +220 -0
- package/src/skill/compose/.bundle/brainstorm/scripts/frame-template.html +214 -0
- package/src/skill/compose/.bundle/brainstorm/scripts/helper.js +88 -0
- package/src/skill/compose/.bundle/brainstorm/scripts/server.cjs +354 -0
- package/src/skill/compose/.bundle/brainstorm/scripts/start-server.sh +148 -0
- package/src/skill/compose/.bundle/brainstorm/scripts/stop-server.sh +56 -0
- package/src/skill/compose/.bundle/brainstorm/spec-document-reviewer-prompt.md +50 -0
- package/src/skill/compose/.bundle/brainstorm/visual-companion.md +287 -0
- package/src/skill/compose/.bundle/debug/CREATION-LOG.md +119 -0
- package/src/skill/compose/.bundle/debug/SKILL.md +297 -0
- package/src/skill/compose/.bundle/debug/condition-based-waiting-example.ts +158 -0
- package/src/skill/compose/.bundle/debug/condition-based-waiting.md +115 -0
- package/src/skill/compose/.bundle/debug/defense-in-depth.md +122 -0
- package/src/skill/compose/.bundle/debug/find-polluter.sh +63 -0
- package/src/skill/compose/.bundle/debug/root-cause-tracing.md +169 -0
- package/src/skill/compose/.bundle/debug/test-academic.md +14 -0
- package/src/skill/compose/.bundle/debug/test-pressure-1.md +58 -0
- package/src/skill/compose/.bundle/debug/test-pressure-2.md +68 -0
- package/src/skill/compose/.bundle/debug/test-pressure-3.md +69 -0
- package/src/skill/compose/.bundle/execute/SKILL.md +71 -0
- package/src/skill/compose/.bundle/feedback/SKILL.md +214 -0
- package/src/skill/compose/.bundle/merge/SKILL.md +252 -0
- package/src/skill/compose/.bundle/new-skill/SKILL.md +656 -0
- package/src/skill/compose/.bundle/new-skill/anthropic-best-practices.md +1150 -0
- package/src/skill/compose/.bundle/new-skill/examples/CLAUDE_MD_TESTING.md +189 -0
- package/src/skill/compose/.bundle/new-skill/graphviz-conventions.dot +172 -0
- package/src/skill/compose/.bundle/new-skill/persuasion-principles.md +187 -0
- package/src/skill/compose/.bundle/new-skill/render-graphs.js +168 -0
- package/src/skill/compose/.bundle/new-skill/testing-skills-with-subagents.md +384 -0
- package/src/skill/compose/.bundle/parallel/SKILL.md +182 -0
- package/src/skill/compose/.bundle/plan/SKILL.md +161 -0
- package/src/skill/compose/.bundle/plan/plan-document-reviewer-prompt.md +50 -0
- package/src/skill/compose/.bundle/report/SKILL.md +180 -0
- package/src/skill/compose/.bundle/review/SKILL.md +104 -0
- package/src/skill/compose/.bundle/review/code-reviewer.md +171 -0
- package/src/skill/compose/.bundle/subagent/SKILL.md +344 -0
- package/src/skill/compose/.bundle/subagent/code-quality-reviewer-prompt.md +24 -0
- package/src/skill/compose/.bundle/subagent/implementer-prompt.md +126 -0
- package/src/skill/compose/.bundle/subagent/spec-reviewer-prompt.md +112 -0
- package/src/skill/compose/.bundle/tdd/SKILL.md +372 -0
- package/src/skill/compose/.bundle/tdd/testing-anti-patterns.md +299 -0
- package/src/skill/compose/.bundle/verify/SKILL.md +140 -0
- package/src/skill/compose/.bundle/worktree/SKILL.md +234 -0
- package/src/skill/compose/LICENSE-karpathy +28 -0
- package/src/skill/compose/LICENSE-superpowers +26 -0
- package/src/skill/compose/bundle.macro.ts +30 -0
- package/src/skill/compose/extract.ts +85 -0
- package/src/skill/discovery.ts +116 -0
- package/src/skill/index.ts +311 -0
- package/src/snapshot/index.ts +777 -0
- package/src/sql.d.ts +4 -0
- package/src/storage/db.bun.ts +8 -0
- package/src/storage/db.node.ts +8 -0
- package/src/storage/db.ts +172 -0
- package/src/storage/index.ts +26 -0
- package/src/storage/json-migration.ts +426 -0
- package/src/storage/schema.sql.ts +10 -0
- package/src/storage/schema.ts +7 -0
- package/src/storage/storage.ts +331 -0
- package/src/sync/README.md +179 -0
- package/src/sync/event.sql.ts +16 -0
- package/src/sync/index.ts +278 -0
- package/src/sync/schema.ts +14 -0
- package/src/task/events.ts +28 -0
- package/src/task/gate-state.ts +54 -0
- package/src/task/gate.ts +116 -0
- package/src/task/index.ts +1 -0
- package/src/task/registry.ts +387 -0
- package/src/task/schema.ts +43 -0
- package/src/task/task.sql.ts +50 -0
- package/src/team/events.ts +22 -0
- package/src/team/index.ts +113 -0
- package/src/team/schema.ts +31 -0
- package/src/temporary.ts +33 -0
- package/src/tool/actor.shell.txt +72 -0
- package/src/tool/actor.ts +803 -0
- package/src/tool/actor.txt +103 -0
- package/src/tool/apply_patch.ts +308 -0
- package/src/tool/apply_patch.txt +33 -0
- package/src/tool/bash-interactive.ts +183 -0
- package/src/tool/bash.ts +696 -0
- package/src/tool/bash.txt +123 -0
- package/src/tool/change-directory.ts +91 -0
- package/src/tool/codesearch.ts +63 -0
- package/src/tool/codesearch.txt +12 -0
- package/src/tool/edit.ts +685 -0
- package/src/tool/edit.txt +10 -0
- package/src/tool/external-directory.ts +132 -0
- package/src/tool/glob.ts +100 -0
- package/src/tool/glob.txt +6 -0
- package/src/tool/grep.ts +145 -0
- package/src/tool/grep.txt +8 -0
- package/src/tool/history.ts +146 -0
- package/src/tool/history.txt +17 -0
- package/src/tool/index.ts +4 -0
- package/src/tool/invalid.ts +20 -0
- package/src/tool/invocation-style.ts +17 -0
- package/src/tool/lsp.ts +91 -0
- package/src/tool/lsp.txt +19 -0
- package/src/tool/mcp-exa.ts +78 -0
- package/src/tool/memory-path-guard.ts +162 -0
- package/src/tool/memory.ts +81 -0
- package/src/tool/memory.txt +69 -0
- package/src/tool/multiedit.ts +61 -0
- package/src/tool/multiedit.txt +41 -0
- package/src/tool/plan-enter.txt +14 -0
- package/src/tool/plan-exit.txt +13 -0
- package/src/tool/plan.ts +90 -0
- package/src/tool/question.ts +67 -0
- package/src/tool/question.txt +10 -0
- package/src/tool/read.ts +327 -0
- package/src/tool/read.txt +14 -0
- package/src/tool/registry.ts +413 -0
- package/src/tool/schema.ts +17 -0
- package/src/tool/session-cwd.ts +35 -0
- package/src/tool/shell-tokenize.ts +346 -0
- package/src/tool/shell-wrap.ts +190 -0
- package/src/tool/skill.ts +76 -0
- package/src/tool/skill.txt +5 -0
- package/src/tool/task.shell.txt +57 -0
- package/src/tool/task.ts +456 -0
- package/src/tool/task.txt +56 -0
- package/src/tool/tool.ts +153 -0
- package/src/tool/truncate.ts +201 -0
- package/src/tool/truncation-dir.ts +4 -0
- package/src/tool/webfetch.ts +199 -0
- package/src/tool/webfetch.txt +13 -0
- package/src/tool/websearch/index.ts +104 -0
- package/src/tool/websearch/mimo.ts +118 -0
- package/src/tool/websearch/websearch.txt +14 -0
- package/src/tool/workflow.ts +164 -0
- package/src/tool/workflow.txt +25 -0
- package/src/tool/write.ts +88 -0
- package/src/tool/write.txt +9 -0
- package/src/util/abort.ts +35 -0
- package/src/util/archive.ts +15 -0
- package/src/util/color.ts +17 -0
- package/src/util/data-url.ts +9 -0
- package/src/util/defer.ts +10 -0
- package/src/util/effect-http-client.ts +11 -0
- package/src/util/effect-zod.ts +367 -0
- package/src/util/error.ts +78 -0
- package/src/util/filesystem.ts +243 -0
- package/src/util/fn.ts +21 -0
- package/src/util/format.ts +20 -0
- package/src/util/iife.ts +3 -0
- package/src/util/index.ts +12 -0
- package/src/util/keybind.ts +101 -0
- package/src/util/lazy.ts +18 -0
- package/src/util/local-context.ts +23 -0
- package/src/util/locale.ts +79 -0
- package/src/util/lock.ts +96 -0
- package/src/util/log.ts +197 -0
- package/src/util/media.ts +26 -0
- package/src/util/mimo-process.ts +24 -0
- package/src/util/network.ts +9 -0
- package/src/util/process.ts +174 -0
- package/src/util/queue.ts +32 -0
- package/src/util/record.ts +3 -0
- package/src/util/rpc.ts +64 -0
- package/src/util/schema.ts +53 -0
- package/src/util/scrap.ts +10 -0
- package/src/util/signal.ts +12 -0
- package/src/util/timeout.ts +14 -0
- package/src/util/token.ts +5 -0
- package/src/util/update-schema.ts +13 -0
- package/src/util/which.ts +14 -0
- package/src/util/wildcard.ts +57 -0
- package/src/workflow/builtin/deep-research.js +391 -0
- package/src/workflow/builtin.ts +54 -0
- package/src/workflow/events.ts +72 -0
- package/src/workflow/meta.ts +335 -0
- package/src/workflow/persistence.ts +312 -0
- package/src/workflow/resolve.ts +45 -0
- package/src/workflow/runtime-ref.ts +18 -0
- package/src/workflow/runtime.ts +1234 -0
- package/src/workflow/sandbox.ts +280 -0
- package/src/workflow/workflow.sql.ts +31 -0
- package/src/workflow/workspace.ts +69 -0
- package/src/worktree/index.ts +614 -0
- package/sst-env.d.ts +10 -0
- package/test/AGENTS.md +133 -0
- package/test/account/repo.test.ts +352 -0
- package/test/account/service.test.ts +456 -0
- package/test/acp/agent-interface.test.ts +51 -0
- package/test/acp/event-subscription.test.ts +725 -0
- package/test/actor/cancel-cascade.test.ts +432 -0
- package/test/actor/no-completion-listener.test.ts +41 -0
- package/test/actor/poststop-progress-write-permission.repro.test.ts +414 -0
- package/test/actor/registry-render.test.ts +113 -0
- package/test/actor/registry-status.test.ts +111 -0
- package/test/actor/registry.test.ts +619 -0
- package/test/actor/return-header.test.ts +40 -0
- package/test/actor/spawn-lifecycle.test.ts +346 -0
- package/test/actor/spawn-no-deadlock.test.ts +340 -0
- package/test/actor/spawn-notification.test.ts +393 -0
- package/test/actor/spawn-task-autostart.test.ts +530 -0
- package/test/actor/spawn.test.ts +1072 -0
- package/test/actor/status-event-payload.test.ts +132 -0
- package/test/actor/terminology.test.ts +39 -0
- package/test/actor/turn.test.ts +125 -0
- package/test/actor/waiter.test.ts +246 -0
- package/test/agent/agent.test.ts +874 -0
- package/test/agent/allowlist.test.ts +45 -0
- package/test/auth/auth.test.ts +86 -0
- package/test/bus/bus-effect.test.ts +162 -0
- package/test/bus/bus-integration.test.ts +87 -0
- package/test/bus/bus.test.ts +219 -0
- package/test/cli/account.test.ts +26 -0
- package/test/cli/cmd/tui/prompt-part.test.ts +47 -0
- package/test/cli/error.test.ts +18 -0
- package/test/cli/github-action.test.ts +198 -0
- package/test/cli/github-remote.test.ts +80 -0
- package/test/cli/import.test.ts +54 -0
- package/test/cli/plugin-auth-picker.test.ts +120 -0
- package/test/cli/run-completion.test.ts +131 -0
- package/test/cli/tui/keybind-plugin.test.ts +90 -0
- package/test/cli/tui/plugin-add.test.ts +111 -0
- package/test/cli/tui/plugin-install.test.ts +87 -0
- package/test/cli/tui/plugin-lifecycle.test.ts +224 -0
- package/test/cli/tui/plugin-loader-entrypoint.test.ts +484 -0
- package/test/cli/tui/plugin-loader-pure.test.ts +71 -0
- package/test/cli/tui/plugin-loader.test.ts +816 -0
- package/test/cli/tui/plugin-toggle.test.ts +157 -0
- package/test/cli/tui/revert-diff.test.ts +35 -0
- package/test/cli/tui/route-agent-id.test.ts +26 -0
- package/test/cli/tui/sidebar-tps.test.ts +63 -0
- package/test/cli/tui/slot-replace.test.tsx +47 -0
- package/test/cli/tui/sync-bucket.test.ts +29 -0
- package/test/cli/tui/theme-store.test.ts +51 -0
- package/test/cli/tui/thread.test.ts +121 -0
- package/test/cli/tui/transcript.test.ts +426 -0
- package/test/cli/tui/use-event.test.tsx +175 -0
- package/test/cli/tui/voice.test.ts +269 -0
- package/test/command/deep-research-command.test.ts +16 -0
- package/test/config/agent-color.test.ts +77 -0
- package/test/config/checkpoint-fork.test.ts +21 -0
- package/test/config/config.test.ts +2577 -0
- package/test/config/fixtures/empty-frontmatter.md +4 -0
- package/test/config/fixtures/frontmatter.md +28 -0
- package/test/config/fixtures/markdown-header.md +11 -0
- package/test/config/fixtures/no-frontmatter.md +1 -0
- package/test/config/fixtures/weird-model-id.md +13 -0
- package/test/config/lsp.test.ts +87 -0
- package/test/config/markdown.test.ts +228 -0
- package/test/config/plugin.test.ts +0 -0
- package/test/config/tui.test.ts +627 -0
- package/test/control-plane/adaptors.test.ts +71 -0
- package/test/control-plane/sse.test.ts +56 -0
- package/test/effect/app-runtime-logger.test.ts +92 -0
- package/test/effect/cross-spawn-spawner.test.ts +411 -0
- package/test/effect/instance-state.test.ts +482 -0
- package/test/effect/observability.test.ts +46 -0
- package/test/effect/run-service.test.ts +46 -0
- package/test/effect/runner-warn-log.test.ts +111 -0
- package/test/effect/runner.test.ts +494 -0
- package/test/fake/provider.ts +90 -0
- package/test/file/fsmonitor.test.ts +68 -0
- package/test/file/ignore.test.ts +10 -0
- package/test/file/index.test.ts +956 -0
- package/test/file/path-traversal.test.ts +204 -0
- package/test/file/ripgrep.test.ts +214 -0
- package/test/file/watcher.test.ts +249 -0
- package/test/filesystem/filesystem.test.ts +319 -0
- package/test/fixture/db.ts +11 -0
- package/test/fixture/fixture.test.ts +58 -0
- package/test/fixture/fixture.ts +190 -0
- package/test/fixture/flock-worker.ts +72 -0
- package/test/fixture/lsp/fake-lsp-server.js +75 -0
- package/test/fixture/plug-worker.ts +93 -0
- package/test/fixture/plugin-meta-worker.ts +19 -0
- package/test/fixture/skills/agents-sdk/SKILL.md +152 -0
- package/test/fixture/skills/agents-sdk/references/callable.md +92 -0
- package/test/fixture/skills/cloudflare/SKILL.md +211 -0
- package/test/fixture/skills/index.json +6 -0
- package/test/fixture/tui-plugin.ts +328 -0
- package/test/fixture/tui-runtime.ts +31 -0
- package/test/format/format.test.ts +244 -0
- package/test/git/git.test.ts +128 -0
- package/test/global/fixture/global-paths-worker.ts +17 -0
- package/test/global/mimocode-home.test.ts +143 -0
- package/test/history/backfill.test.ts +149 -0
- package/test/history/extract.test.ts +106 -0
- package/test/history/fts-query.test.ts +30 -0
- package/test/history/resolve.test.ts +130 -0
- package/test/history/service.test.ts +210 -0
- package/test/history/writer.test.ts +163 -0
- package/test/ide/ide.test.ts +82 -0
- package/test/inbox/drain-in-loop.test.ts +230 -0
- package/test/inbox/fork-agent-compat.test.ts +387 -0
- package/test/inbox/gc-on-init.test.ts +167 -0
- package/test/inbox/send-no-block.test.ts +120 -0
- package/test/inbox/sender-cancel-independence.test.ts +160 -0
- package/test/inbox/wake-matrix.test.ts +141 -0
- package/test/installation/installation.test.ts +226 -0
- package/test/keybind.test.ts +421 -0
- package/test/lib/effect.ts +53 -0
- package/test/lib/filesystem.ts +10 -0
- package/test/lib/llm-server.ts +770 -0
- package/test/lib/scripted-llm-server.ts +245 -0
- package/test/lsp/client.test.ts +98 -0
- package/test/lsp/index.test.ts +109 -0
- package/test/lsp/launch.test.ts +22 -0
- package/test/lsp/lifecycle.test.ts +184 -0
- package/test/mcp/headers.test.ts +178 -0
- package/test/mcp/lifecycle.test.ts +824 -0
- package/test/mcp/oauth-auto-connect.test.ts +281 -0
- package/test/mcp/oauth-browser.test.ts +268 -0
- package/test/mcp/oauth-callback.test.ts +34 -0
- package/test/memory/abort-leak-webfetch.ts +49 -0
- package/test/memory/abort-leak.test.ts +127 -0
- package/test/memory/cc-frontmatter.test.ts +85 -0
- package/test/memory/cc-paths.test.ts +60 -0
- package/test/memory/cc-reconcile.test.ts +239 -0
- package/test/memory/cc-search.test.ts +151 -0
- package/test/memory/fts-query.test.ts +48 -0
- package/test/memory/fts-rowid-stability.test.ts +271 -0
- package/test/memory/paths.test.ts +210 -0
- package/test/memory/reconcile.test.ts +115 -0
- package/test/memory/service.test.ts +169 -0
- package/test/npm.test.ts +18 -0
- package/test/patch/patch.test.ts +348 -0
- package/test/permission/abort.test.ts +116 -0
- package/test/permission/arity.test.ts +33 -0
- package/test/permission/disabled.test.ts +51 -0
- package/test/permission/next.test.ts +1080 -0
- package/test/permission/non-interactive.test.ts +55 -0
- package/test/permission-task.test.ts +326 -0
- package/test/plugin/actor-hooks.test.ts +1471 -0
- package/test/plugin/auth-override.test.ts +79 -0
- package/test/plugin/checkpoint-splitover.test.ts +434 -0
- package/test/plugin/cloudflare.test.ts +68 -0
- package/test/plugin/codex.test.ts +123 -0
- package/test/plugin/github-copilot-models.test.ts +163 -0
- package/test/plugin/install-concurrency.test.ts +140 -0
- package/test/plugin/install.test.ts +570 -0
- package/test/plugin/loader-shared.test.ts +1169 -0
- package/test/plugin/matcher.test.ts +97 -0
- package/test/plugin/meta.test.ts +137 -0
- package/test/plugin/mimo.test.ts +257 -0
- package/test/plugin/shared.test.ts +88 -0
- package/test/plugin/subagent-progress-checker.test.ts +227 -0
- package/test/plugin/trigger.test.ts +116 -0
- package/test/plugin/workspace-adaptor.test.ts +109 -0
- package/test/preload.ts +102 -0
- package/test/project/migrate-global.test.ts +150 -0
- package/test/project/project-id.test.ts +64 -0
- package/test/project/project.test.ts +481 -0
- package/test/project/vcs.test.ts +286 -0
- package/test/project/worktree-remove.test.ts +126 -0
- package/test/project/worktree.test.ts +214 -0
- package/test/provider/amazon-bedrock.test.ts +462 -0
- package/test/provider/copilot/convert-to-copilot-messages.test.ts +523 -0
- package/test/provider/copilot/copilot-chat-model.test.ts +592 -0
- package/test/provider/error.test.ts +160 -0
- package/test/provider/gitlab-duo.test.ts +413 -0
- package/test/provider/model-groups.test.ts +389 -0
- package/test/provider/provider-chunk-timeout.test.ts +23 -0
- package/test/provider/provider.test.ts +2648 -0
- package/test/provider/transform.test.ts +3379 -0
- package/test/pty/pty-output-isolation.test.ts +146 -0
- package/test/pty/pty-session.test.ts +102 -0
- package/test/pty/pty-shell.test.ts +69 -0
- package/test/question/question.test.ts +464 -0
- package/test/server/global-session-list.test.ts +105 -0
- package/test/server/project-init-git.test.ts +122 -0
- package/test/server/session-actions.test.ts +49 -0
- package/test/server/session-list.test.ts +110 -0
- package/test/server/session-messages.test.ts +220 -0
- package/test/server/session-prompt-busy.test.ts +146 -0
- package/test/server/session-select.test.ts +100 -0
- package/test/server/session-task-route.test.ts +165 -0
- package/test/server/summarize-route-main-slice.test.ts +99 -0
- package/test/server/trace-attributes.test.ts +76 -0
- package/test/server/workflows-route.test.ts +279 -0
- package/test/session/bootstrap-skip-system.test.ts +121 -0
- package/test/session/boundary.test.ts +33 -0
- package/test/session/budgeted-read.test.ts +74 -0
- package/test/session/checkpoint-align.test.ts +58 -0
- package/test/session/checkpoint-boundary.test.ts +186 -0
- package/test/session/checkpoint-child-session.test.ts +508 -0
- package/test/session/checkpoint-context.test.ts +141 -0
- package/test/session/checkpoint-drain.test.ts +188 -0
- package/test/session/checkpoint-extract-titles.test.ts +58 -0
- package/test/session/checkpoint-fork-mode.test.ts +576 -0
- package/test/session/checkpoint-main-slice.test.ts +259 -0
- package/test/session/checkpoint-paths.test.ts +78 -0
- package/test/session/checkpoint-permission.test.ts +136 -0
- package/test/session/checkpoint-progress-reconcile.test.ts +219 -0
- package/test/session/checkpoint-rebuild-unify.test.ts +143 -0
- package/test/session/checkpoint-rebuild-v3.test.ts +248 -0
- package/test/session/checkpoint-render-verify.test.ts +512 -0
- package/test/session/checkpoint-retry.test.ts +150 -0
- package/test/session/checkpoint-splitover-integration.test.ts +533 -0
- package/test/session/checkpoint-templates.test.ts +51 -0
- package/test/session/checkpoint-thresholds.test.ts +120 -0
- package/test/session/checkpoint-validator.test.ts +189 -0
- package/test/session/classify-integration.test.ts +476 -0
- package/test/session/classify.test.ts +335 -0
- package/test/session/compaction-agent-scope.test.ts +164 -0
- package/test/session/context-inheritance.test.ts +46 -0
- package/test/session/fork-prefix-invariant.test.ts +116 -0
- package/test/session/goal.test.ts +106 -0
- package/test/session/instruction.test.ts +387 -0
- package/test/session/invalid-output-continuation.test.ts +150 -0
- package/test/session/last-message-info.test.ts +47 -0
- package/test/session/length-tool-safety.test.ts +121 -0
- package/test/session/llm-request-prefix.test.ts +197 -0
- package/test/session/llm-retry.test.ts +59 -0
- package/test/session/llm-system-prompt.test.ts +479 -0
- package/test/session/llm.test.ts +1272 -0
- package/test/session/main-lifecycle.test.ts +51 -0
- package/test/session/main-runloop-history-invariant.test.ts +182 -0
- package/test/session/max-mode-econnreset.test.ts +229 -0
- package/test/session/max-mode.test.ts +54 -0
- package/test/session/message-v2-filter.test.ts +197 -0
- package/test/session/message-v2.test.ts +1119 -0
- package/test/session/messages-default-main.test.ts +105 -0
- package/test/session/messages-pagination.test.ts +888 -0
- package/test/session/overflow.test.ts +576 -0
- package/test/session/processor-effect.test.ts +853 -0
- package/test/session/prompt-effect.test.ts +1574 -0
- package/test/session/prompt-rebuild-loop.test.ts +108 -0
- package/test/session/prompt-rebuild-reset.test.ts +67 -0
- package/test/session/prompt-sweep.test.ts +145 -0
- package/test/session/prompt-task-gate.test.ts +127 -0
- package/test/session/prompt.test.ts +703 -0
- package/test/session/prune-main-slice.test.ts +272 -0
- package/test/session/prune-skip-system.test.ts +346 -0
- package/test/session/prune.test.ts +419 -0
- package/test/session/rebuild-microcompact.test.ts +318 -0
- package/test/session/recall-reminder.test.ts +37 -0
- package/test/session/retry.test.ts +410 -0
- package/test/session/revert-compact.test.ts +639 -0
- package/test/session/run-state-tuple-key.test.ts +152 -0
- package/test/session/session-create-registers-main.test.ts +70 -0
- package/test/session/session.test.ts +181 -0
- package/test/session/snapshot-tool-race.test.ts +301 -0
- package/test/session/structured-output-integration.test.ts +264 -0
- package/test/session/structured-output-retry.test.ts +127 -0
- package/test/session/structured-output.test.ts +397 -0
- package/test/session/summary-main-slice.test.ts +170 -0
- package/test/session/system.test.ts +72 -0
- package/test/share/share-next.test.ts +332 -0
- package/test/shell/shell.test.ts +73 -0
- package/test/skill/compose-review.test.ts +141 -0
- package/test/skill/discovery.test.ts +116 -0
- package/test/skill/skill.test.ts +465 -0
- package/test/snapshot/snapshot.test.ts +1531 -0
- package/test/storage/db.test.ts +16 -0
- package/test/storage/json-migration.test.ts +831 -0
- package/test/storage/storage.test.ts +293 -0
- package/test/sync/index.test.ts +237 -0
- package/test/task/gate-state.test.ts +66 -0
- package/test/task/gate.test.ts +167 -0
- package/test/task/registry.test.ts +152 -0
- package/test/task/state-machine.test.ts +292 -0
- package/test/team/migrate-to-inbox.test.ts +124 -0
- package/test/team/team.test.ts +75 -0
- package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
- package/test/tool/actor-cancel.test.ts +206 -0
- package/test/tool/actor-recover.test.ts +50 -0
- package/test/tool/actor-send.test.ts +200 -0
- package/test/tool/actor-status.test.ts +296 -0
- package/test/tool/actor-wait.test.ts +193 -0
- package/test/tool/actor.shell.test.ts +250 -0
- package/test/tool/actor.test.ts +748 -0
- package/test/tool/apply_patch.test.ts +626 -0
- package/test/tool/bash.test.ts +1195 -0
- package/test/tool/describe-workflow.test.ts +12 -0
- package/test/tool/edit.test.ts +691 -0
- package/test/tool/external-directory.test.ts +207 -0
- package/test/tool/fixtures/large-image.png +0 -0
- package/test/tool/fixtures/models-api.json +65179 -0
- package/test/tool/glob.test.ts +81 -0
- package/test/tool/grep.test.ts +114 -0
- package/test/tool/history.test.ts +144 -0
- package/test/tool/invocation-style.test.ts +30 -0
- package/test/tool/memory-edit-ask-skip.test.ts +62 -0
- package/test/tool/memory-path-guard.test.ts +594 -0
- package/test/tool/memory.test.ts +71 -0
- package/test/tool/question.test.ts +167 -0
- package/test/tool/read.test.ts +483 -0
- package/test/tool/registry-invocation-style.test.ts +121 -0
- package/test/tool/registry.test.ts +164 -0
- package/test/tool/shell-tokenize.test.ts +273 -0
- package/test/tool/shell-wrap-missing-script.test.ts +128 -0
- package/test/tool/shell-wrap.test.ts +257 -0
- package/test/tool/skill.test.ts +99 -0
- package/test/tool/task-recover.test.ts +36 -0
- package/test/tool/task.shell.test.ts +234 -0
- package/test/tool/task.test.ts +296 -0
- package/test/tool/tool-def-shell-shape.test.ts +23 -0
- package/test/tool/tool-define.test.ts +59 -0
- package/test/tool/truncation.test.ts +253 -0
- package/test/tool/webfetch.test.ts +103 -0
- package/test/tool/whitelist.test.ts +373 -0
- package/test/tool/write.test.ts +244 -0
- package/test/util/data-url.test.ts +14 -0
- package/test/util/effect-zod.test.ts +869 -0
- package/test/util/error.test.ts +38 -0
- package/test/util/filesystem.test.ts +656 -0
- package/test/util/format.test.ts +59 -0
- package/test/util/glob.test.ts +164 -0
- package/test/util/iife.test.ts +36 -0
- package/test/util/lazy.test.ts +50 -0
- package/test/util/lock.test.ts +72 -0
- package/test/util/log.test.ts +44 -0
- package/test/util/module.test.ts +59 -0
- package/test/util/process.test.ts +128 -0
- package/test/util/timeout.test.ts +21 -0
- package/test/util/which.test.ts +100 -0
- package/test/util/wildcard.test.ts +90 -0
- package/test/workflow/builtin.test.ts +22 -0
- package/test/workflow/deep-research-cluster.test.ts +47 -0
- package/test/workflow/lib.ts +243 -0
- package/test/workflow/meta.test.ts +142 -0
- package/test/workflow/model-routing.test.ts +68 -0
- package/test/workflow/persistence.test.ts +229 -0
- package/test/workflow/resolve.test.ts +37 -0
- package/test/workflow/runtime-nested.test.ts +419 -0
- package/test/workflow/runtime-worktree.test.ts +261 -0
- package/test/workflow/runtime.test.ts +1078 -0
- package/test/workflow/sandbox.test.ts +259 -0
- package/test/workflow/tool.test.ts +473 -0
- package/test/workflow/verify-wow.test.ts +144 -0
- package/test/workflow/workspace.test.ts +88 -0
- package/test/workspace/workspace-restore.test.ts +281 -0
- package/test/worktree/index.test.ts +30 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,741 @@
|
|
|
1
|
+
import { Effect, Deferred, Context, Fiber, Layer, Scope, Cause } from "effect"
|
|
2
|
+
import type { SessionID, MessageID } from "@/session/schema"
|
|
3
|
+
import type { ProviderID, ModelID } from "@/provider/schema"
|
|
4
|
+
import type { Tool as AITool, ModelMessage } from "ai"
|
|
5
|
+
import { Session } from "@/session"
|
|
6
|
+
import { SessionPrompt } from "@/session/prompt"
|
|
7
|
+
import { SessionRunState } from "@/session/run-state"
|
|
8
|
+
import { ActorRegistry } from "@/actor/registry"
|
|
9
|
+
import { TaskRegistry } from "@/task/registry"
|
|
10
|
+
import { TaskGate, MAX_TASK_GATE_SUBAGENT_REACT } from "@/task/gate"
|
|
11
|
+
import { Agent } from "@/agent/agent"
|
|
12
|
+
import { Permission } from "@/permission"
|
|
13
|
+
import type { SpawnMode, ContextMode, ToolWhitelist, Lifecycle } from "@/actor/schema"
|
|
14
|
+
import { runTurn } from "@/actor/turn"
|
|
15
|
+
import { spawnRef } from "@/actor/spawn-ref"
|
|
16
|
+
import { Bus } from "@/bus"
|
|
17
|
+
import { MessageV2 } from "@/session/message-v2"
|
|
18
|
+
import { Inbox } from "@/inbox"
|
|
19
|
+
import { renderActorNotification } from "@/inbox/render"
|
|
20
|
+
import { Plugin, HookEvent } from "@/plugin"
|
|
21
|
+
import { parseReturnHeader, type ReturnStatus } from "./return-header"
|
|
22
|
+
import { Log } from "@/util"
|
|
23
|
+
|
|
24
|
+
const log = Log.create({ service: "actor.spawn" })
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Cap on preStop ReAct re-entries per spawn — prevents infinite loops.
|
|
28
|
+
* TODO: lift to tulingcode.json config (e.g. actor.maxPreReact) and add per-hook
|
|
29
|
+
* `maxContinue` clamp at registration. Plan: platform cap = hard ceiling, hook
|
|
30
|
+
* cap may only narrow, never widen. See spec Future work.
|
|
31
|
+
*/
|
|
32
|
+
export const MAX_PRE_REACT = 3
|
|
33
|
+
/** Cap on postStop ReAct re-entries per spawn. See MAX_PRE_REACT TODO. */
|
|
34
|
+
export const MAX_POST_REACT = 3
|
|
35
|
+
const RETURN_FORMAT_INSTRUCTION = `
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Return format (required)
|
|
40
|
+
|
|
41
|
+
Your FINAL assistant message — what the spawning agent will receive — MUST start with this header block:
|
|
42
|
+
|
|
43
|
+
**Status**: success | partial | failed | blocked
|
|
44
|
+
**Summary**: <one sentence describing what happened>
|
|
45
|
+
|
|
46
|
+
After the header, include the actual deliverable (whatever the task asked for in its prompt).
|
|
47
|
+
|
|
48
|
+
If applicable, also include below the deliverable:
|
|
49
|
+
|
|
50
|
+
**Files touched**: <comma-separated paths or "(none)">
|
|
51
|
+
**Findings worth promoting**: <bullet list of cross-task transferable facts; "(none)" if just routine work>
|
|
52
|
+
|
|
53
|
+
This format lets the spawning agent and the checkpoint writer extract your progress without parsing free-form prose. Do NOT precede the header with an introduction — your final message must start with "**Status**:".
|
|
54
|
+
`
|
|
55
|
+
|
|
56
|
+
export interface ForkContext {
|
|
57
|
+
readonly system: string[]
|
|
58
|
+
/**
|
|
59
|
+
* Tool schema as parent would emit at watermark, captured for invariant
|
|
60
|
+
* verification only. NOT consumed by fork's runLoop for the actual LLM
|
|
61
|
+
* request — that uses `resolveTools(forkAgent)` for executable tools with
|
|
62
|
+
* dispatch closures. Schema parity is currently enforced because
|
|
63
|
+
* checkpoint-writer has no `toolAllowlist` (Task 2.6); both paths call
|
|
64
|
+
* `registry.tools` with equivalent agent inputs and produce identical
|
|
65
|
+
* schemas. If `toolAllowlist` is ever re-added, this field would still
|
|
66
|
+
* snapshot parent's schema while the runtime tools would diverge, silently
|
|
67
|
+
* breaking cache parity. Test guard: `test/agent/agent.test.ts` asserts
|
|
68
|
+
* `cp.toolAllowlist === undefined` for checkpoint-writer.
|
|
69
|
+
*/
|
|
70
|
+
readonly tools: Record<string, AITool>
|
|
71
|
+
/**
|
|
72
|
+
* Parent agent's permission ruleset, captured at spawn. The fork evaluates
|
|
73
|
+
* permissions and filters its LLM-visible tool list against THIS (the parent's)
|
|
74
|
+
* ruleset rather than the checkpoint-writer agent's own — restoring prompt-cache
|
|
75
|
+
* tool-visibility parity with the parent and keeping permission semantics
|
|
76
|
+
* consistent with the captor. Memory-tree writes are still governed by
|
|
77
|
+
* memory-path-guard (see askEditUnlessMemory), so an inherited `edit:deny`
|
|
78
|
+
* does not block the writer's own checkpoint files.
|
|
79
|
+
*/
|
|
80
|
+
readonly parentPermission: Permission.Ruleset
|
|
81
|
+
readonly inheritedMessages: ModelMessage[]
|
|
82
|
+
/**
|
|
83
|
+
* Boundary marker — the last main-slice message id at spawn. Used by fork's
|
|
84
|
+
* runLoop to filter ownNew messages (belt-and-braces alongside the agent_id
|
|
85
|
+
* check; agent_id is sufficient on its own, watermark is the documentary
|
|
86
|
+
* anchor). NEVER use this for slicing inheritedMessages — inheritedMessages
|
|
87
|
+
* is captured as a complete snapshot at spawn time.
|
|
88
|
+
* See docs/superpowers/specs/2026-05-26-fork-agent-prefix-cache-design.md
|
|
89
|
+
*/
|
|
90
|
+
readonly watermarkMsgID: MessageID
|
|
91
|
+
readonly model: { providerID: ProviderID; modelID: ModelID }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type AgentOutcome =
|
|
95
|
+
| {
|
|
96
|
+
status: "success"
|
|
97
|
+
finalText?: string
|
|
98
|
+
// Structured-output (json_schema) result — when the spawn requested a
|
|
99
|
+
// format, the validated object is surfaced here and takes precedence over
|
|
100
|
+
// finalText (DW spec P3).
|
|
101
|
+
structured?: unknown
|
|
102
|
+
// Subagent's self-reported header status (parsed from finalText), possibly
|
|
103
|
+
// overridden by the completion gate (DB truth wins — see onSuccess).
|
|
104
|
+
reportedStatus?: ReturnStatus
|
|
105
|
+
reportedSummary?: string
|
|
106
|
+
// Task IDs the subagent left non-terminal after the gate's cap. Present
|
|
107
|
+
// only when reportedStatus was downgraded to "partial"/"blocked".
|
|
108
|
+
incompleteTasks?: string[]
|
|
109
|
+
}
|
|
110
|
+
| { status: "failure"; error: string }
|
|
111
|
+
| { status: "cancelled" }
|
|
112
|
+
|
|
113
|
+
export interface SpawnInput {
|
|
114
|
+
mode: SpawnMode
|
|
115
|
+
sessionID: SessionID
|
|
116
|
+
/**
|
|
117
|
+
* Parent session id when the actor runs in a child session (Axis A: checkpoint
|
|
118
|
+
* writer spawns under a child session keyed on parent_id but writes to the
|
|
119
|
+
* parent's checkpoint.md / memory.md). Hooks (actor.preStop / actor.postStop)
|
|
120
|
+
* receive this so plugins re-deriving paths from sessionID can fall back to
|
|
121
|
+
* `parentSessionID ?? sessionID` and reach the parent's artifacts.
|
|
122
|
+
*
|
|
123
|
+
* Defaults to `sessionID` inside spawnSubagent when omitted, so existing
|
|
124
|
+
* callers (peer / dream / distill / regular subagents where parent ===
|
|
125
|
+
* session) need no change.
|
|
126
|
+
*/
|
|
127
|
+
parentSessionID?: SessionID
|
|
128
|
+
agentType: string
|
|
129
|
+
task: string
|
|
130
|
+
description?: string
|
|
131
|
+
context: ContextMode
|
|
132
|
+
tools: ToolWhitelist
|
|
133
|
+
model?: { providerID: ProviderID; modelID: ModelID }
|
|
134
|
+
background: boolean
|
|
135
|
+
parentActorID?: string
|
|
136
|
+
task_id?: string // Spec ②: bound user-task ID for postStop progress.md validation
|
|
137
|
+
cwd?: string
|
|
138
|
+
forkContext?: ForkContext // NEW
|
|
139
|
+
lifecycle?: Lifecycle
|
|
140
|
+
/**
|
|
141
|
+
* Optional structured-output format. When set to a json_schema format, the
|
|
142
|
+
* child's SessionPrompt.prompt requests structured output: the runLoop injects
|
|
143
|
+
* the StructuredOutput tool, forces toolChoice=required, and the validated
|
|
144
|
+
* object flows back via message.structured (see runAgentLoop). The validated
|
|
145
|
+
* object is surfaced on AgentOutcome.structured.
|
|
146
|
+
*/
|
|
147
|
+
format?: MessageV2.OutputFormat
|
|
148
|
+
/**
|
|
149
|
+
* Fired SYNCHRONOUSLY with the freshly-allocated actorID inside the spawn
|
|
150
|
+
* Effect — right after the actor is registered, BEFORE its work fiber detaches
|
|
151
|
+
* (forkWork forks into the actor scope). Lets a caller record the child id the
|
|
152
|
+
* instant the actor exists, closing the window where an in-flight spawn would
|
|
153
|
+
* otherwise be invisible to a concurrent cancel/reclaim. The WorkflowRuntime
|
|
154
|
+
* uses this to add the id to its reclaim set before detach (MR104 #2). Best-
|
|
155
|
+
* effort: a throw is swallowed so a buggy callback can't fail the spawn. Only
|
|
156
|
+
* the subagent path invokes it (the workflow spawns subagents); spawnPeer does
|
|
157
|
+
* not — peers are not orchestrated by the workflow runtime.
|
|
158
|
+
*/
|
|
159
|
+
onActorID?: (actorID: string) => void
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface SpawnResult {
|
|
163
|
+
actorID: string
|
|
164
|
+
sessionID: SessionID
|
|
165
|
+
outcome: Deferred.Deferred<AgentOutcome>
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface Interface {
|
|
169
|
+
readonly spawn: (input: SpawnInput) => Effect.Effect<SpawnResult>
|
|
170
|
+
readonly cancel: (sessionID: SessionID, actorID: string, mode: "graceful" | "forced") => Effect.Effect<void>
|
|
171
|
+
readonly getForkContext: (actorID: string) => Effect.Effect<ForkContext | undefined>
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export class Service extends Context.Service<Service, Interface>()("@tulingcode/Actor") {}
|
|
175
|
+
|
|
176
|
+
export const layer = Layer.effect(
|
|
177
|
+
Service,
|
|
178
|
+
Effect.gen(function* () {
|
|
179
|
+
const session = yield* Session.Service
|
|
180
|
+
const actorReg = yield* ActorRegistry.Service
|
|
181
|
+
const agents = yield* Agent.Service
|
|
182
|
+
const sessionPrompt = yield* SessionPrompt.Service
|
|
183
|
+
const inbox = yield* Inbox.Service
|
|
184
|
+
const state = yield* SessionRunState.Service
|
|
185
|
+
const plugin = yield* Plugin.Service
|
|
186
|
+
const bus = yield* Bus.Service
|
|
187
|
+
const taskRegistry = yield* TaskRegistry.Service
|
|
188
|
+
const scope = yield* Scope.Scope
|
|
189
|
+
|
|
190
|
+
// ForkContext snapshot per actor, captured at spawn for fork agents
|
|
191
|
+
// (contextMode = "full"). Read by fork's runLoop (see prompt.ts) and
|
|
192
|
+
// cleared on terminal status. Fiber tracking moved to SessionRunState.
|
|
193
|
+
const forkContexts = new Map<string, ForkContext>()
|
|
194
|
+
|
|
195
|
+
// Real agent loop: marks the actor running, then drives a SessionPrompt.prompt
|
|
196
|
+
// turn. The user message persisted by SessionPrompt carries the actor's
|
|
197
|
+
// agentID, which the projector writes to MessageTable.agent_id — that is the
|
|
198
|
+
// load-bearing piece this primitive exists for.
|
|
199
|
+
//
|
|
200
|
+
// Returns the assistant's final text (if any) so forkWork's onSuccess can
|
|
201
|
+
// pass it to inbox.send (notification body) and into the success Deferred.
|
|
202
|
+
const runAgentLoop = Effect.fn("Actor.runAgentLoop")(function* (input: {
|
|
203
|
+
sessionID: SessionID
|
|
204
|
+
actorID: string
|
|
205
|
+
agentType: string
|
|
206
|
+
task: string
|
|
207
|
+
task_id?: string
|
|
208
|
+
model?: { providerID: ProviderID; modelID: ModelID }
|
|
209
|
+
source: "spawn" | "hook"
|
|
210
|
+
provenance?: MessageV2.Provenance
|
|
211
|
+
format?: MessageV2.OutputFormat
|
|
212
|
+
}) {
|
|
213
|
+
const result = yield* sessionPrompt.prompt({
|
|
214
|
+
sessionID: input.sessionID,
|
|
215
|
+
agent: input.agentType,
|
|
216
|
+
agentID: input.actorID,
|
|
217
|
+
source: input.source,
|
|
218
|
+
provenance: input.provenance,
|
|
219
|
+
model: input.model,
|
|
220
|
+
task_id: input.task_id,
|
|
221
|
+
parts: [{ type: "text", text: input.task }],
|
|
222
|
+
...(input.format ? { format: input.format } : {}),
|
|
223
|
+
})
|
|
224
|
+
// structured output (json_schema) takes precedence over finalText: when the
|
|
225
|
+
// child produced a validated object it IS the authoritative result and the
|
|
226
|
+
// last text part (often a pre-tool-call preamble) is dropped to avoid
|
|
227
|
+
// duplicating the result downstream. See spec §5.2.
|
|
228
|
+
const info = (result as MessageV2.WithParts | undefined)?.info
|
|
229
|
+
const structured = info?.role === "assistant" ? info.structured : undefined
|
|
230
|
+
const finalText =
|
|
231
|
+
structured !== undefined
|
|
232
|
+
? undefined
|
|
233
|
+
: (result as MessageV2.WithParts | undefined)?.parts.findLast(
|
|
234
|
+
(p): p is Extract<MessageV2.Part, { type: "text" }> => p.type === "text",
|
|
235
|
+
)?.text
|
|
236
|
+
return { finalText, structured }
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
const forkWork = (input: {
|
|
240
|
+
sessionID: SessionID
|
|
241
|
+
parentSessionID: SessionID
|
|
242
|
+
parentActorID?: string
|
|
243
|
+
actorID: string
|
|
244
|
+
agentType: string
|
|
245
|
+
task: string
|
|
246
|
+
description?: string
|
|
247
|
+
background: boolean
|
|
248
|
+
model?: { providerID: ProviderID; modelID: ModelID }
|
|
249
|
+
lifecycle: "ephemeral" | "persistent"
|
|
250
|
+
task_id?: string
|
|
251
|
+
// True for non-specialized subagents (those that received
|
|
252
|
+
// RETURN_FORMAT_INSTRUCTION). Only these are subject to the completion
|
|
253
|
+
// gate; specialized/system agents and peers create no user tasks.
|
|
254
|
+
gateEligible?: boolean
|
|
255
|
+
format?: MessageV2.OutputFormat
|
|
256
|
+
}) =>
|
|
257
|
+
Effect.gen(function* () {
|
|
258
|
+
const outcome = yield* Deferred.make<AgentOutcome>()
|
|
259
|
+
const description = input.description ?? input.agentType
|
|
260
|
+
// Auto-start the bound task: spawning an actor for a task IS that task
|
|
261
|
+
// beginning work. Status transition is a structural side-effect of spawn,
|
|
262
|
+
// not a model action (the model maintains task status unreliably).
|
|
263
|
+
// `done` stays gate/model-driven. Uses parentSessionID because the task
|
|
264
|
+
// lives in the parent/main session, not a peer's child session.
|
|
265
|
+
// ignoreCause (not ignore): TaskRegistry.start raises a missing task_id as
|
|
266
|
+
// a *defect* (Effect.die), which Effect.ignore does NOT swallow — only
|
|
267
|
+
// ignoreCause does. A stale/missing task_id must never block the spawn,
|
|
268
|
+
// but log on swallow so a genuine bug in start() leaves a breadcrumb.
|
|
269
|
+
if (input.task_id) {
|
|
270
|
+
yield* taskRegistry
|
|
271
|
+
.start({ session_id: input.parentSessionID, id: input.task_id, owner: input.actorID })
|
|
272
|
+
.pipe(Effect.ignoreCause({ log: "Warn", message: `auto-start of task ${input.task_id} failed` }))
|
|
273
|
+
}
|
|
274
|
+
const notify = (
|
|
275
|
+
status: "completed" | "failed" | "cancelled",
|
|
276
|
+
extra: { result?: string; error?: string; reportedStatus?: ReturnStatus; reportedSummary?: string },
|
|
277
|
+
) =>
|
|
278
|
+
input.background && input.agentType !== "checkpoint-writer"
|
|
279
|
+
? inbox
|
|
280
|
+
.send({
|
|
281
|
+
receiverSessionID: input.parentSessionID,
|
|
282
|
+
receiverActorID: input.parentActorID ?? "main",
|
|
283
|
+
senderSessionID: input.sessionID,
|
|
284
|
+
senderActorID: input.actorID,
|
|
285
|
+
type: "actor_notification",
|
|
286
|
+
content: renderActorNotification({
|
|
287
|
+
actorID: input.actorID,
|
|
288
|
+
description,
|
|
289
|
+
status,
|
|
290
|
+
...extra,
|
|
291
|
+
}),
|
|
292
|
+
})
|
|
293
|
+
.pipe(Effect.ignore)
|
|
294
|
+
: Effect.void
|
|
295
|
+
|
|
296
|
+
// Derive actor mode from spawn shape: peer creates a new session, subagent shares parent's
|
|
297
|
+
const actorMode: "peer" | "subagent" = input.parentSessionID === input.sessionID ? "subagent" : "peer"
|
|
298
|
+
|
|
299
|
+
// Writability of THIS agent, derived from the same predicate the runtime uses to
|
|
300
|
+
// strip the Write tool (llm.ts resolveTools → Permission.disabled). Read-only agents
|
|
301
|
+
// (e.g. explore: "*":deny) → canWrite=false → postStop progress check is skipped for
|
|
302
|
+
// them (they cannot satisfy a "write the journal" nudge; their findings return via
|
|
303
|
+
// finalText). Agent-static: uses agentInfo.permission ONLY, not the session-merged
|
|
304
|
+
// ruleset resolveTools builds (merge(agent, session)). So canWrite diverges from
|
|
305
|
+
// runtime tool-stripping only under a session-level override — e.g. session "*":allow
|
|
306
|
+
// un-stripping a read-only agent's write (we skip though runtime allows), or session
|
|
307
|
+
// "*":deny on a writable agent (we nudge though runtime strips). Both are deliberately
|
|
308
|
+
// ignored: not reachable in normal usage (mimo run sets no such rule, spawn doesn't
|
|
309
|
+
// rewrite session.permission). See spec §Decision. Unknown agent → fail-open (true).
|
|
310
|
+
const forkAgentInfo = yield* agents.get(input.agentType)
|
|
311
|
+
const canWrite = forkAgentInfo ? !Permission.disabled(["write"], forkAgentInfo.permission).has("write") : true
|
|
312
|
+
|
|
313
|
+
const work = Effect.gen(function* () {
|
|
314
|
+
let finalText: string | undefined
|
|
315
|
+
let structured: unknown | undefined
|
|
316
|
+
let iteration = 0
|
|
317
|
+
let lastDecision:
|
|
318
|
+
| { reason: string; contributingPluginNames: string[]; contributingHookIDs: string[] }
|
|
319
|
+
| undefined
|
|
320
|
+
|
|
321
|
+
while (true) {
|
|
322
|
+
const reentryDecision = iteration > 0 ? lastDecision : undefined
|
|
323
|
+
const turn = yield* runTurn(
|
|
324
|
+
input.sessionID,
|
|
325
|
+
input.actorID,
|
|
326
|
+
runAgentLoop({
|
|
327
|
+
...input,
|
|
328
|
+
task: reentryDecision ? reentryDecision.reason : input.task,
|
|
329
|
+
source: reentryDecision ? "hook" : "spawn",
|
|
330
|
+
provenance: reentryDecision
|
|
331
|
+
? {
|
|
332
|
+
hookPhase: "pre",
|
|
333
|
+
hookIteration: iteration,
|
|
334
|
+
pluginNames: reentryDecision.contributingPluginNames,
|
|
335
|
+
hookIDs: reentryDecision.contributingHookIDs,
|
|
336
|
+
}
|
|
337
|
+
: undefined,
|
|
338
|
+
}),
|
|
339
|
+
)
|
|
340
|
+
finalText = turn.finalText
|
|
341
|
+
structured = turn.structured
|
|
342
|
+
|
|
343
|
+
iteration++
|
|
344
|
+
if (iteration > MAX_PRE_REACT) {
|
|
345
|
+
yield* bus.publish(HookEvent.ReActMaxReached, {
|
|
346
|
+
phase: "pre",
|
|
347
|
+
actorID: input.actorID,
|
|
348
|
+
agentType: input.agentType,
|
|
349
|
+
})
|
|
350
|
+
log.warn("actor.preStop hit MAX_PRE_REACT cap; skipping further hook checks", {
|
|
351
|
+
actorID: input.actorID,
|
|
352
|
+
totalTurns: iteration,
|
|
353
|
+
})
|
|
354
|
+
break
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const decision = yield* plugin.triggerActorPreStop({
|
|
358
|
+
sessionID: input.sessionID,
|
|
359
|
+
parentSessionID: input.parentSessionID,
|
|
360
|
+
actorID: input.actorID,
|
|
361
|
+
parentActorID: input.parentActorID,
|
|
362
|
+
agentType: input.agentType,
|
|
363
|
+
mode: actorMode,
|
|
364
|
+
lifecycle: input.lifecycle,
|
|
365
|
+
finalText,
|
|
366
|
+
task: input.task,
|
|
367
|
+
description: input.description,
|
|
368
|
+
task_id: input.task_id,
|
|
369
|
+
iteration: iteration - 1,
|
|
370
|
+
})
|
|
371
|
+
if (!decision.continue) break
|
|
372
|
+
if (!decision.reason) break // defense-in-depth — T4 invariant guarantees this won't fire
|
|
373
|
+
|
|
374
|
+
yield* bus.publish(HookEvent.ReActReentered, {
|
|
375
|
+
phase: "pre",
|
|
376
|
+
actorID: input.actorID,
|
|
377
|
+
agentType: input.agentType,
|
|
378
|
+
iteration,
|
|
379
|
+
triggeredByPlugins: decision.contributingPluginNames,
|
|
380
|
+
reasonPreview: decision.reason.slice(0, 200),
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
lastDecision = {
|
|
384
|
+
reason: decision.reason,
|
|
385
|
+
contributingPluginNames: decision.contributingPluginNames,
|
|
386
|
+
contributingHookIDs: decision.contributingHookIDs,
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return { finalText, structured }
|
|
391
|
+
}).pipe(
|
|
392
|
+
Effect.provideService(ActorRegistry.Service, actorReg),
|
|
393
|
+
Effect.matchCauseEffect({
|
|
394
|
+
onSuccess: ({ finalText, structured }) =>
|
|
395
|
+
Effect.gen(function* () {
|
|
396
|
+
// === COMPLETION GATE (B) + structured parse (A) ===
|
|
397
|
+
// Delegates the list/decide step to TaskGate.decide so the
|
|
398
|
+
// logic is shared with the main-session taskGate (prompt.ts).
|
|
399
|
+
// We retain the runTurn re-entry + delivered-text update here
|
|
400
|
+
// because that is gate-policy, not list-policy.
|
|
401
|
+
let deliveredText = finalText
|
|
402
|
+
if (input.gateEligible) {
|
|
403
|
+
let gateIter = 0
|
|
404
|
+
while (true) {
|
|
405
|
+
const decision = yield* TaskGate.decide({
|
|
406
|
+
session_id: input.parentSessionID,
|
|
407
|
+
owner: input.actorID,
|
|
408
|
+
reactCount: gateIter,
|
|
409
|
+
maxReact: MAX_TASK_GATE_SUBAGENT_REACT,
|
|
410
|
+
mode: "subagent",
|
|
411
|
+
}).pipe(Effect.provideService(TaskRegistry.Service, taskRegistry))
|
|
412
|
+
if (!decision.needReentry) break
|
|
413
|
+
gateIter++
|
|
414
|
+
const gateTurn = yield* runTurn(
|
|
415
|
+
input.sessionID,
|
|
416
|
+
input.actorID,
|
|
417
|
+
runAgentLoop({
|
|
418
|
+
...input,
|
|
419
|
+
task: decision.reentryText,
|
|
420
|
+
source: "hook",
|
|
421
|
+
provenance: { hookPhase: "post", hookIteration: gateIter, pluginNames: [], hookIDs: [] },
|
|
422
|
+
}),
|
|
423
|
+
).pipe(
|
|
424
|
+
Effect.catch(() =>
|
|
425
|
+
Effect.gen(function* () {
|
|
426
|
+
log.error("actor.gate runTurn failed", { actorID: input.actorID })
|
|
427
|
+
return { finalText: undefined as string | undefined, structured: undefined as unknown }
|
|
428
|
+
}),
|
|
429
|
+
),
|
|
430
|
+
Effect.provideService(ActorRegistry.Service, actorReg),
|
|
431
|
+
)
|
|
432
|
+
// The gate re-run's re-emitted text updates the delivered body
|
|
433
|
+
// (and structured, if it produced one) so the reconciliation +
|
|
434
|
+
// delivery below see the latest turn.
|
|
435
|
+
if (gateTurn.finalText !== undefined) deliveredText = gateTurn.finalText
|
|
436
|
+
if (gateTurn.structured !== undefined) structured = gateTurn.structured
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Reconcile: DB truth wins over the model's self-reported header.
|
|
441
|
+
const remaining = input.gateEligible
|
|
442
|
+
? yield* taskRegistry
|
|
443
|
+
.list({ session_id: input.parentSessionID, owner: input.actorID, include_terminal: false })
|
|
444
|
+
.pipe(Effect.orElseSucceed(() => []))
|
|
445
|
+
: []
|
|
446
|
+
const stillActionable = remaining.filter((t) => t.status === "open" || t.status === "in_progress")
|
|
447
|
+
const downgrade: ReturnStatus | undefined =
|
|
448
|
+
stillActionable.length > 0 ? "partial" : remaining.length > 0 ? "blocked" : undefined
|
|
449
|
+
const parsed = parseReturnHeader(deliveredText)
|
|
450
|
+
const reportedStatus = downgrade ?? parsed.status
|
|
451
|
+
const incompleteTasks = remaining.map((t) => t.id)
|
|
452
|
+
const reconciledText =
|
|
453
|
+
downgrade && incompleteTasks.length > 0
|
|
454
|
+
? `${deliveredText ?? ""}\n\n**Incomplete tasks**: ${incompleteTasks.join(", ")}`
|
|
455
|
+
: deliveredText
|
|
456
|
+
|
|
457
|
+
// === DELIVERY ===
|
|
458
|
+
// structured (json_schema result) takes precedence over text for the
|
|
459
|
+
// notification body (DW spec P3 §5.2); otherwise deliver the gate's
|
|
460
|
+
// reconciled text. The success outcome carries both the reconciled
|
|
461
|
+
// text + completion-gate fields AND structured when present.
|
|
462
|
+
const deliveryText =
|
|
463
|
+
structured !== undefined ? JSON.stringify(structured) : (reconciledText ?? "(no output)")
|
|
464
|
+
yield* notify("completed", {
|
|
465
|
+
result: deliveryText,
|
|
466
|
+
...(reportedStatus ? { reportedStatus } : {}),
|
|
467
|
+
...(parsed.summary ? { reportedSummary: parsed.summary } : {}),
|
|
468
|
+
})
|
|
469
|
+
yield* Deferred.succeed(outcome, {
|
|
470
|
+
status: "success" as const,
|
|
471
|
+
...(reconciledText !== undefined ? { finalText: reconciledText } : {}),
|
|
472
|
+
...(structured !== undefined ? { structured } : {}),
|
|
473
|
+
...(reportedStatus ? { reportedStatus } : {}),
|
|
474
|
+
...(parsed.summary ? { reportedSummary: parsed.summary } : {}),
|
|
475
|
+
...(incompleteTasks.length > 0 ? { incompleteTasks } : {}),
|
|
476
|
+
})
|
|
477
|
+
|
|
478
|
+
// === postStop ReAct loop ===
|
|
479
|
+
// Caller has already resolved; new finalTexts are not propagated.
|
|
480
|
+
// NOTE: parallel structure to preStop loop above — pre runs turn THEN checks,
|
|
481
|
+
// post checks THEN runs turn. Both give 1 (delivery) + MAX_POST_REACT re-entries.
|
|
482
|
+
let postIter = 0
|
|
483
|
+
let lastFinalText = finalText
|
|
484
|
+
let postReentry:
|
|
485
|
+
| { reason: string; contributingPluginNames: string[]; contributingHookIDs: string[] }
|
|
486
|
+
| undefined
|
|
487
|
+
|
|
488
|
+
while (true) {
|
|
489
|
+
const decision = yield* plugin.triggerActorPostStop({
|
|
490
|
+
sessionID: input.sessionID,
|
|
491
|
+
parentSessionID: input.parentSessionID,
|
|
492
|
+
actorID: input.actorID,
|
|
493
|
+
parentActorID: input.parentActorID,
|
|
494
|
+
agentType: input.agentType,
|
|
495
|
+
mode: actorMode,
|
|
496
|
+
lifecycle: input.lifecycle,
|
|
497
|
+
finalText: lastFinalText,
|
|
498
|
+
task: input.task,
|
|
499
|
+
description: input.description,
|
|
500
|
+
task_id: input.task_id,
|
|
501
|
+
outcome: "success",
|
|
502
|
+
iteration: postIter,
|
|
503
|
+
canWrite,
|
|
504
|
+
})
|
|
505
|
+
|
|
506
|
+
if (!decision.continue) break
|
|
507
|
+
if (!decision.reason) break // defense-in-depth
|
|
508
|
+
if (postIter >= MAX_POST_REACT) {
|
|
509
|
+
yield* bus.publish(HookEvent.ReActMaxReached, {
|
|
510
|
+
phase: "post",
|
|
511
|
+
actorID: input.actorID,
|
|
512
|
+
agentType: input.agentType,
|
|
513
|
+
})
|
|
514
|
+
log.warn("actor.postStop hit MAX_POST_REACT cap; skipping further hook checks", {
|
|
515
|
+
actorID: input.actorID,
|
|
516
|
+
totalTurns: postIter + 1,
|
|
517
|
+
})
|
|
518
|
+
break
|
|
519
|
+
}
|
|
520
|
+
postIter++
|
|
521
|
+
|
|
522
|
+
yield* bus.publish(HookEvent.ReActReentered, {
|
|
523
|
+
phase: "post",
|
|
524
|
+
actorID: input.actorID,
|
|
525
|
+
agentType: input.agentType,
|
|
526
|
+
iteration: postIter,
|
|
527
|
+
triggeredByPlugins: decision.contributingPluginNames,
|
|
528
|
+
reasonPreview: decision.reason.slice(0, 200),
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
postReentry = {
|
|
532
|
+
reason: decision.reason,
|
|
533
|
+
contributingPluginNames: decision.contributingPluginNames,
|
|
534
|
+
contributingHookIDs: decision.contributingHookIDs,
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Run another turn (new finalText is not written back to outcome)
|
|
538
|
+
const newTurn = yield* runTurn(
|
|
539
|
+
input.sessionID,
|
|
540
|
+
input.actorID,
|
|
541
|
+
runAgentLoop({
|
|
542
|
+
...input,
|
|
543
|
+
task: postReentry.reason,
|
|
544
|
+
source: "hook",
|
|
545
|
+
provenance: {
|
|
546
|
+
hookPhase: "post",
|
|
547
|
+
hookIteration: postIter,
|
|
548
|
+
pluginNames: postReentry.contributingPluginNames,
|
|
549
|
+
hookIDs: postReentry.contributingHookIDs,
|
|
550
|
+
},
|
|
551
|
+
}),
|
|
552
|
+
).pipe(
|
|
553
|
+
// postStop LLM failure: log + break loop, do NOT propagate
|
|
554
|
+
Effect.catch(() =>
|
|
555
|
+
Effect.gen(function* () {
|
|
556
|
+
log.error("actor.postStop runTurn failed", {
|
|
557
|
+
actorID: input.actorID,
|
|
558
|
+
})
|
|
559
|
+
return { finalText: undefined as string | undefined, structured: undefined as unknown }
|
|
560
|
+
}),
|
|
561
|
+
),
|
|
562
|
+
Effect.provideService(ActorRegistry.Service, actorReg),
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
if (newTurn.finalText === undefined) break
|
|
566
|
+
lastFinalText = newTurn.finalText
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
yield* Effect.sync(() => forkContexts.delete(input.actorID))
|
|
570
|
+
}),
|
|
571
|
+
onFailure: (cause) =>
|
|
572
|
+
Effect.gen(function* () {
|
|
573
|
+
const cancelled = Cause.hasInterruptsOnly(cause)
|
|
574
|
+
const error = Cause.pretty(cause)
|
|
575
|
+
yield* notify(cancelled ? "cancelled" : "failed", cancelled ? {} : { error })
|
|
576
|
+
yield* Deferred.succeed(
|
|
577
|
+
outcome,
|
|
578
|
+
cancelled ? { status: "cancelled" as const } : { status: "failure" as const, error },
|
|
579
|
+
)
|
|
580
|
+
yield* Effect.sync(() => forkContexts.delete(input.actorID))
|
|
581
|
+
}),
|
|
582
|
+
}),
|
|
583
|
+
)
|
|
584
|
+
const fiber = yield* work.pipe(Effect.forkIn(scope))
|
|
585
|
+
return { fiber, outcome }
|
|
586
|
+
})
|
|
587
|
+
|
|
588
|
+
const spawnPeer = Effect.fn("Actor.spawnPeer")(function* (input: SpawnInput) {
|
|
589
|
+
const child = yield* session.create({
|
|
590
|
+
parentID: input.sessionID,
|
|
591
|
+
contextFrom: input.context === "full" ? input.sessionID : undefined,
|
|
592
|
+
title: `${input.agentType}: ${input.task.slice(0, 40)}`,
|
|
593
|
+
})
|
|
594
|
+
yield* actorReg.register({
|
|
595
|
+
sessionID: child.id,
|
|
596
|
+
actorID: child.id,
|
|
597
|
+
mode: "peer",
|
|
598
|
+
parentActorID: input.parentActorID,
|
|
599
|
+
agent: input.agentType,
|
|
600
|
+
description: input.description ?? input.agentType,
|
|
601
|
+
contextMode: input.context,
|
|
602
|
+
contextWatermark: undefined,
|
|
603
|
+
background: input.background,
|
|
604
|
+
lifecycle: input.lifecycle ?? "persistent",
|
|
605
|
+
tools: input.tools,
|
|
606
|
+
})
|
|
607
|
+
if (input.forkContext) {
|
|
608
|
+
forkContexts.set(child.id, input.forkContext) // peer's actorID === child.id
|
|
609
|
+
}
|
|
610
|
+
const { fiber, outcome } = yield* forkWork({
|
|
611
|
+
sessionID: child.id,
|
|
612
|
+
parentSessionID: input.sessionID,
|
|
613
|
+
parentActorID: input.parentActorID,
|
|
614
|
+
actorID: child.id,
|
|
615
|
+
agentType: input.agentType,
|
|
616
|
+
task: input.task,
|
|
617
|
+
description: input.description,
|
|
618
|
+
background: input.background,
|
|
619
|
+
model: input.model,
|
|
620
|
+
lifecycle: input.lifecycle ?? "persistent",
|
|
621
|
+
task_id: input.task_id,
|
|
622
|
+
format: input.format,
|
|
623
|
+
})
|
|
624
|
+
if (!input.background) yield* Fiber.join(fiber).pipe(Effect.ignore)
|
|
625
|
+
return { actorID: child.id, sessionID: child.id, outcome }
|
|
626
|
+
})
|
|
627
|
+
|
|
628
|
+
const spawnSubagent = Effect.fn("Actor.spawnSubagent")(function* (input: SpawnInput) {
|
|
629
|
+
const actorID = yield* actorReg.allocateActorID(input.sessionID, input.agentType)
|
|
630
|
+
|
|
631
|
+
const watermark = input.context === "full" ? yield* session.lastMainMessageID(input.sessionID) : undefined
|
|
632
|
+
|
|
633
|
+
yield* actorReg.register({
|
|
634
|
+
sessionID: input.sessionID,
|
|
635
|
+
actorID,
|
|
636
|
+
mode: "subagent",
|
|
637
|
+
parentActorID: input.parentActorID,
|
|
638
|
+
agent: input.agentType,
|
|
639
|
+
description: input.description ?? input.agentType,
|
|
640
|
+
contextMode: input.context,
|
|
641
|
+
contextWatermark: watermark,
|
|
642
|
+
background: input.background,
|
|
643
|
+
lifecycle: input.lifecycle ?? "ephemeral",
|
|
644
|
+
tools: input.tools,
|
|
645
|
+
})
|
|
646
|
+
|
|
647
|
+
// The actor now EXISTS in the registry. Hand the caller its id before the
|
|
648
|
+
// work fiber detaches below, so a concurrent reclaim can see it (MR104 #2).
|
|
649
|
+
// Synchronous + best-effort: a throwing callback must not fail the spawn.
|
|
650
|
+
if (input.onActorID) yield* Effect.sync(() => input.onActorID!(actorID)).pipe(Effect.ignore)
|
|
651
|
+
|
|
652
|
+
if (input.forkContext) {
|
|
653
|
+
forkContexts.set(actorID, input.forkContext)
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Auto-inject return-format instruction for non-specialized subagents.
|
|
657
|
+
// Excluded: agents with hardcoded `prompt` (explore/title/summary — own
|
|
658
|
+
// contracts), checkpoint-writer (special — task is itself a complete
|
|
659
|
+
// writer-instruction string), and peer mode (routes via spawnPeer).
|
|
660
|
+
const agentInfo = yield* agents.get(input.agentType)
|
|
661
|
+
const gateEligible =
|
|
662
|
+
agentInfo?.mode === "subagent" && !agentInfo?.prompt && input.agentType !== "checkpoint-writer"
|
|
663
|
+
const taskWithFormat = gateEligible ? input.task + RETURN_FORMAT_INSTRUCTION : input.task
|
|
664
|
+
|
|
665
|
+
const { fiber, outcome } = yield* forkWork({
|
|
666
|
+
sessionID: input.sessionID,
|
|
667
|
+
parentSessionID: input.parentSessionID ?? input.sessionID,
|
|
668
|
+
parentActorID: input.parentActorID,
|
|
669
|
+
actorID,
|
|
670
|
+
agentType: input.agentType,
|
|
671
|
+
task: taskWithFormat,
|
|
672
|
+
description: input.description,
|
|
673
|
+
background: input.background,
|
|
674
|
+
model: input.model,
|
|
675
|
+
lifecycle: input.lifecycle ?? "ephemeral",
|
|
676
|
+
task_id: input.task_id,
|
|
677
|
+
gateEligible,
|
|
678
|
+
format: input.format,
|
|
679
|
+
})
|
|
680
|
+
if (!input.background) yield* Fiber.join(fiber).pipe(Effect.ignore)
|
|
681
|
+
return { actorID, sessionID: input.sessionID, outcome }
|
|
682
|
+
})
|
|
683
|
+
|
|
684
|
+
const spawn = Effect.fn("Actor.spawn")(function* (input: SpawnInput) {
|
|
685
|
+
if (input.mode === "peer") return yield* spawnPeer(input)
|
|
686
|
+
return yield* spawnSubagent(input)
|
|
687
|
+
})
|
|
688
|
+
|
|
689
|
+
const cancel: (sessionID: SessionID, actorID: string, mode: "graceful" | "forced") => Effect.Effect<void> =
|
|
690
|
+
Effect.fn("Actor.cancel")(function* (sessionID: SessionID, actorID: string, mode: "graceful" | "forced") {
|
|
691
|
+
const children = yield* actorReg.listByParent(sessionID, actorID)
|
|
692
|
+
yield* Effect.forEach(children, (c) => cancel(sessionID, c.actorID, mode), {
|
|
693
|
+
concurrency: "unbounded",
|
|
694
|
+
discard: true,
|
|
695
|
+
})
|
|
696
|
+
yield* state.cancelActor(sessionID, actorID)
|
|
697
|
+
yield* actorReg
|
|
698
|
+
.updateStatus(sessionID, actorID, { status: "idle", lastOutcome: "cancelled" })
|
|
699
|
+
.pipe(Effect.ignore)
|
|
700
|
+
yield* Effect.sync(() => forkContexts.delete(actorID))
|
|
701
|
+
})
|
|
702
|
+
|
|
703
|
+
const getForkContext = Effect.fn("Actor.getForkContext")(function* (actorID: string) {
|
|
704
|
+
return forkContexts.get(actorID)
|
|
705
|
+
})
|
|
706
|
+
|
|
707
|
+
const impl = Service.of({ spawn, cancel, getForkContext })
|
|
708
|
+
// Late-bind the impl so SessionCheckpoint.tryStartCheckpointWriter can resolve it
|
|
709
|
+
// without forming a layer cycle. See spawn-ref.ts for rationale.
|
|
710
|
+
spawnRef.current = impl
|
|
711
|
+
yield* Effect.addFinalizer(() =>
|
|
712
|
+
Effect.sync(() => {
|
|
713
|
+
if (spawnRef.current === impl) spawnRef.current = undefined
|
|
714
|
+
}),
|
|
715
|
+
)
|
|
716
|
+
return impl
|
|
717
|
+
}),
|
|
718
|
+
)
|
|
719
|
+
|
|
720
|
+
// Wrapped in Layer.suspend so the cross-module `.defaultLayer` reads defer to
|
|
721
|
+
// first use instead of running at module load. Without this, the
|
|
722
|
+
// spawn → prompt → app-runtime import cycle hits a load order where
|
|
723
|
+
// AppLayer's mergeAll runs while SessionPrompt is mid-init and throws
|
|
724
|
+
// "Cannot access 'defaultLayer' before initialization", breaking every
|
|
725
|
+
// it.live test harness. Same pattern session/prompt, session/checkpoint,
|
|
726
|
+
// tool/registry, provider, etc. already use.
|
|
727
|
+
export const defaultLayer = Layer.suspend(() =>
|
|
728
|
+
layer.pipe(
|
|
729
|
+
Layer.provide(Session.defaultLayer),
|
|
730
|
+
Layer.provide(ActorRegistry.defaultLayer),
|
|
731
|
+
Layer.provide(Agent.defaultLayer),
|
|
732
|
+
Layer.provide(SessionPrompt.defaultLayer),
|
|
733
|
+
Layer.provide(SessionRunState.defaultLayer),
|
|
734
|
+
Layer.provide(Inbox.defaultLayer),
|
|
735
|
+
Layer.provide(Plugin.defaultLayer),
|
|
736
|
+
Layer.provide(Bus.layer),
|
|
737
|
+
Layer.provide(TaskRegistry.defaultLayer),
|
|
738
|
+
),
|
|
739
|
+
)
|
|
740
|
+
|
|
741
|
+
export * as Actor from "./spawn"
|