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,165 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from "bun:test"
|
|
2
|
+
import { Effect } from "effect"
|
|
3
|
+
import { Instance } from "../../src/project/instance"
|
|
4
|
+
import { Server } from "../../src/server/server"
|
|
5
|
+
import { Session as SessionNs } from "../../src/session"
|
|
6
|
+
import { Todo } from "../../src/session/todo"
|
|
7
|
+
import { TaskRegistry } from "../../src/task/registry"
|
|
8
|
+
import type { Task } from "../../src/task/schema"
|
|
9
|
+
import type { SessionID } from "../../src/session/schema"
|
|
10
|
+
import { Log } from "../../src/util"
|
|
11
|
+
import { tmpdir } from "../fixture/fixture"
|
|
12
|
+
|
|
13
|
+
void Log.init({ print: false })
|
|
14
|
+
|
|
15
|
+
function runSession<A, E>(fx: Effect.Effect<A, E, SessionNs.Service>) {
|
|
16
|
+
return Effect.runPromise(fx.pipe(Effect.provide(SessionNs.defaultLayer)))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function runTask<A, E>(fx: Effect.Effect<A, E, TaskRegistry.Service>) {
|
|
20
|
+
return Effect.runPromise(fx.pipe(Effect.provide(TaskRegistry.defaultLayer)))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function runTodo<A, E>(fx: Effect.Effect<A, E, Todo.Service>) {
|
|
24
|
+
return Effect.runPromise(fx.pipe(Effect.provide(Todo.defaultLayer)))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const createSession = () => runSession(SessionNs.Service.use((svc) => svc.create({})))
|
|
28
|
+
|
|
29
|
+
afterEach(async () => {
|
|
30
|
+
await Instance.disposeAll()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
async function withoutWatcher<T>(fn: () => Promise<T>) {
|
|
34
|
+
if (process.platform !== "win32") return fn()
|
|
35
|
+
const prev = process.env.tulingcode_EXPERIMENTAL_DISABLE_FILEWATCHER
|
|
36
|
+
process.env.tulingcode_EXPERIMENTAL_DISABLE_FILEWATCHER = "true"
|
|
37
|
+
try {
|
|
38
|
+
return await fn()
|
|
39
|
+
} finally {
|
|
40
|
+
if (prev === undefined) delete process.env.tulingcode_EXPERIMENTAL_DISABLE_FILEWATCHER
|
|
41
|
+
else process.env.tulingcode_EXPERIMENTAL_DISABLE_FILEWATCHER = prev
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe("session task route", () => {
|
|
46
|
+
test("GET /:sid/task returns [] for a fresh session, then created tasks", async () => {
|
|
47
|
+
await using tmp = await tmpdir({ git: true })
|
|
48
|
+
await withoutWatcher(() =>
|
|
49
|
+
Instance.provide({
|
|
50
|
+
directory: tmp.path,
|
|
51
|
+
fn: async () => {
|
|
52
|
+
const session = await createSession()
|
|
53
|
+
const app = Server.Default().app
|
|
54
|
+
|
|
55
|
+
const empty = await app.request(`/session/${session.id}/task`)
|
|
56
|
+
expect(empty.status).toBe(200)
|
|
57
|
+
expect(await empty.json()).toEqual([])
|
|
58
|
+
|
|
59
|
+
await runTask(TaskRegistry.Service.use((reg) => reg.create({ session_id: session.id, summary: "first" })))
|
|
60
|
+
await runTask(TaskRegistry.Service.use((reg) => reg.create({ session_id: session.id, summary: "second" })))
|
|
61
|
+
|
|
62
|
+
const res = await app.request(`/session/${session.id}/task`)
|
|
63
|
+
expect(res.status).toBe(200)
|
|
64
|
+
const body = (await res.json()) as Task[]
|
|
65
|
+
expect(body.map((t) => t.id)).toEqual(["T1", "T2"])
|
|
66
|
+
expect(body.map((t) => t.summary)).toEqual(["first", "second"])
|
|
67
|
+
expect(body.map((t) => t.status)).toEqual(["open", "open"])
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test("GET /:sid/task 404s for a missing session", async () => {
|
|
74
|
+
await using tmp = await tmpdir({ git: true })
|
|
75
|
+
await withoutWatcher(() =>
|
|
76
|
+
Instance.provide({
|
|
77
|
+
directory: tmp.path,
|
|
78
|
+
fn: async () => {
|
|
79
|
+
const app = Server.Default().app
|
|
80
|
+
const res = await app.request(`/session/ses_missing/task`)
|
|
81
|
+
expect(res.status).toBe(404)
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test("GET /:sid/todo projects task data with status mapping when tasks exist", async () => {
|
|
88
|
+
await using tmp = await tmpdir({ git: true })
|
|
89
|
+
await withoutWatcher(() =>
|
|
90
|
+
Instance.provide({
|
|
91
|
+
directory: tmp.path,
|
|
92
|
+
fn: async () => {
|
|
93
|
+
const session = await createSession()
|
|
94
|
+
|
|
95
|
+
const open = await runTask(
|
|
96
|
+
TaskRegistry.Service.use((reg) => reg.create({ session_id: session.id, summary: "still open" })),
|
|
97
|
+
)
|
|
98
|
+
const running = await runTask(
|
|
99
|
+
TaskRegistry.Service.use((reg) => reg.create({ session_id: session.id, summary: "running" })),
|
|
100
|
+
)
|
|
101
|
+
await runTask(TaskRegistry.Service.use((reg) => reg.start({ session_id: session.id, id: running.id })))
|
|
102
|
+
const finished = await runTask(
|
|
103
|
+
TaskRegistry.Service.use((reg) => reg.create({ session_id: session.id, summary: "finished" })),
|
|
104
|
+
)
|
|
105
|
+
await runTask(TaskRegistry.Service.use((reg) => reg.done({ session_id: session.id, id: finished.id })))
|
|
106
|
+
// open + then blocked -> projects to "pending"
|
|
107
|
+
const blocked = await runTask(
|
|
108
|
+
TaskRegistry.Service.use((reg) => reg.create({ session_id: session.id, summary: "blocked" })),
|
|
109
|
+
)
|
|
110
|
+
await runTask(TaskRegistry.Service.use((reg) => reg.block({ session_id: session.id, id: blocked.id })))
|
|
111
|
+
const abandoned = await runTask(
|
|
112
|
+
TaskRegistry.Service.use((reg) => reg.create({ session_id: session.id, summary: "abandoned" })),
|
|
113
|
+
)
|
|
114
|
+
await runTask(TaskRegistry.Service.use((reg) => reg.abandon({ session_id: session.id, id: abandoned.id })))
|
|
115
|
+
|
|
116
|
+
void open
|
|
117
|
+
|
|
118
|
+
const app = Server.Default().app
|
|
119
|
+
const res = await app.request(`/session/${session.id}/todo`)
|
|
120
|
+
expect(res.status).toBe(200)
|
|
121
|
+
const body = (await res.json()) as { content: string; status: string }[]
|
|
122
|
+
expect(body).toEqual([
|
|
123
|
+
{ content: "still open", status: "pending" },
|
|
124
|
+
{ content: "running", status: "in_progress" },
|
|
125
|
+
{ content: "finished", status: "completed" },
|
|
126
|
+
{ content: "blocked", status: "pending" },
|
|
127
|
+
{ content: "abandoned", status: "cancelled" },
|
|
128
|
+
])
|
|
129
|
+
},
|
|
130
|
+
}),
|
|
131
|
+
)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
test("GET /:sid/todo falls back to the todo table when no tasks exist", async () => {
|
|
135
|
+
await using tmp = await tmpdir({ git: true })
|
|
136
|
+
await withoutWatcher(() =>
|
|
137
|
+
Instance.provide({
|
|
138
|
+
directory: tmp.path,
|
|
139
|
+
fn: async () => {
|
|
140
|
+
const session = await createSession()
|
|
141
|
+
await runTodo(
|
|
142
|
+
Todo.Service.use((svc) =>
|
|
143
|
+
svc.update({
|
|
144
|
+
sessionID: session.id,
|
|
145
|
+
todos: [
|
|
146
|
+
{ content: "legacy todo a", status: "pending" },
|
|
147
|
+
{ content: "legacy todo b", status: "completed" },
|
|
148
|
+
],
|
|
149
|
+
}),
|
|
150
|
+
),
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
const app = Server.Default().app
|
|
154
|
+
const res = await app.request(`/session/${session.id}/todo`)
|
|
155
|
+
expect(res.status).toBe(200)
|
|
156
|
+
const body = (await res.json()) as { content: string; status: string }[]
|
|
157
|
+
expect(body).toEqual([
|
|
158
|
+
{ content: "legacy todo a", status: "pending" },
|
|
159
|
+
{ content: "legacy todo b", status: "completed" },
|
|
160
|
+
])
|
|
161
|
+
},
|
|
162
|
+
}),
|
|
163
|
+
)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { describe, expect } from "bun:test"
|
|
2
|
+
import { Effect, Layer } from "effect"
|
|
3
|
+
import { Bus } from "../../src/bus"
|
|
4
|
+
import { Config } from "../../src/config"
|
|
5
|
+
import { Plugin } from "../../src/plugin"
|
|
6
|
+
import { Agent } from "../../src/agent/agent"
|
|
7
|
+
import { Session as SessionNs } from "../../src/session"
|
|
8
|
+
import { MessageID, PartID } from "../../src/session/schema"
|
|
9
|
+
import { ProviderID, ModelID } from "../../src/provider/schema"
|
|
10
|
+
import { ProviderTest } from "../fake/provider"
|
|
11
|
+
import { Log } from "../../src/util"
|
|
12
|
+
import { testEffect } from "../lib/effect"
|
|
13
|
+
import { provideTmpdirInstance } from "../fixture/fixture"
|
|
14
|
+
import * as CrossSpawnSpawner from "../../src/effect/cross-spawn-spawner"
|
|
15
|
+
import { resolveCurrentAgent } from "../../src/server/routes/instance/session"
|
|
16
|
+
|
|
17
|
+
void Log.init({ print: false })
|
|
18
|
+
|
|
19
|
+
const ref = { providerID: ProviderID.make("test"), modelID: ModelID.make("test-model") }
|
|
20
|
+
|
|
21
|
+
// Session.create needs ChildProcessSpawner; mirror prune-main-slice/checkpoint-main-slice
|
|
22
|
+
// layer wiring so the harness path is identical — only the scenario differs.
|
|
23
|
+
const deps = Layer.mergeAll(
|
|
24
|
+
ProviderTest.fake().layer,
|
|
25
|
+
Agent.defaultLayer,
|
|
26
|
+
Plugin.defaultLayer,
|
|
27
|
+
Bus.layer,
|
|
28
|
+
Config.defaultLayer,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const env = Layer.mergeAll(
|
|
32
|
+
SessionNs.defaultLayer,
|
|
33
|
+
CrossSpawnSpawner.defaultLayer,
|
|
34
|
+
deps,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
const it = testEffect(env)
|
|
38
|
+
|
|
39
|
+
// Regression for the summarize HTTP route's currentAgent lookup. The handler
|
|
40
|
+
// previously walked the unfiltered message stream newest-first to pick the
|
|
41
|
+
// agent identity that drives compact.create. With subagents on the same
|
|
42
|
+
// sessionID, a checkpoint-writer's task user message at the tail flips
|
|
43
|
+
// currentAgent to the subagent — the server-side compaction then runs against
|
|
44
|
+
// the wrong prompt/tools. The fix pins the lookup to the main slice via the
|
|
45
|
+
// resolveCurrentAgent helper.
|
|
46
|
+
describe("summarize route — currentAgent lookup uses main slice", () => {
|
|
47
|
+
it.live(
|
|
48
|
+
"ignores trailing subagent user messages when picking currentAgent",
|
|
49
|
+
provideTmpdirInstance(() =>
|
|
50
|
+
Effect.gen(function* () {
|
|
51
|
+
const ssn = yield* SessionNs.Service
|
|
52
|
+
const info = yield* ssn.create({})
|
|
53
|
+
|
|
54
|
+
// Main user message: agent="build". This is the identity the
|
|
55
|
+
// summarize route should resolve to.
|
|
56
|
+
const mainID = MessageID.ascending()
|
|
57
|
+
yield* ssn.updateMessage({
|
|
58
|
+
id: mainID,
|
|
59
|
+
role: "user" as const,
|
|
60
|
+
sessionID: info.id,
|
|
61
|
+
agent: "build",
|
|
62
|
+
model: ref,
|
|
63
|
+
time: { created: Date.now() },
|
|
64
|
+
})
|
|
65
|
+
yield* ssn.updatePart({
|
|
66
|
+
id: PartID.ascending(),
|
|
67
|
+
messageID: mainID,
|
|
68
|
+
sessionID: info.id,
|
|
69
|
+
type: "text",
|
|
70
|
+
text: "user prompt",
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// Subagent user message at the tail. Without the main-slice pin,
|
|
74
|
+
// newest-first iteration picks this row up and currentAgent becomes
|
|
75
|
+
// "checkpoint-writer".
|
|
76
|
+
const subID = MessageID.ascending()
|
|
77
|
+
yield* ssn.updateMessage({
|
|
78
|
+
id: subID,
|
|
79
|
+
role: "user" as const,
|
|
80
|
+
sessionID: info.id,
|
|
81
|
+
agentID: "checkpoint-writer-1",
|
|
82
|
+
agent: "checkpoint-writer",
|
|
83
|
+
model: ref,
|
|
84
|
+
time: { created: Date.now() + 1 },
|
|
85
|
+
})
|
|
86
|
+
yield* ssn.updatePart({
|
|
87
|
+
id: PartID.ascending(),
|
|
88
|
+
messageID: subID,
|
|
89
|
+
sessionID: info.id,
|
|
90
|
+
type: "text",
|
|
91
|
+
text: "checkpoint task body",
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const got = yield* resolveCurrentAgent(info.id, "build")
|
|
95
|
+
expect(got).toBe("build")
|
|
96
|
+
}),
|
|
97
|
+
),
|
|
98
|
+
)
|
|
99
|
+
})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
import { paramToAttributeKey, requestAttributes } from "../../src/server/routes/instance/trace"
|
|
3
|
+
|
|
4
|
+
function fakeContext(method: string, url: string, params: Record<string, string>) {
|
|
5
|
+
return {
|
|
6
|
+
req: {
|
|
7
|
+
method,
|
|
8
|
+
url,
|
|
9
|
+
param: () => params,
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
describe("paramToAttributeKey", () => {
|
|
15
|
+
test("converts fooID to foo.id", () => {
|
|
16
|
+
expect(paramToAttributeKey("sessionID")).toBe("session.id")
|
|
17
|
+
expect(paramToAttributeKey("messageID")).toBe("message.id")
|
|
18
|
+
expect(paramToAttributeKey("partID")).toBe("part.id")
|
|
19
|
+
expect(paramToAttributeKey("projectID")).toBe("project.id")
|
|
20
|
+
expect(paramToAttributeKey("providerID")).toBe("provider.id")
|
|
21
|
+
expect(paramToAttributeKey("ptyID")).toBe("pty.id")
|
|
22
|
+
expect(paramToAttributeKey("permissionID")).toBe("permission.id")
|
|
23
|
+
expect(paramToAttributeKey("requestID")).toBe("request.id")
|
|
24
|
+
expect(paramToAttributeKey("workspaceID")).toBe("workspace.id")
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test("namespaces non-ID params under opencode.", () => {
|
|
28
|
+
expect(paramToAttributeKey("name")).toBe("opencode.name")
|
|
29
|
+
expect(paramToAttributeKey("slug")).toBe("opencode.slug")
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe("requestAttributes", () => {
|
|
34
|
+
test("includes http method and path", () => {
|
|
35
|
+
const attrs = requestAttributes(fakeContext("GET", "http://localhost/session", {}))
|
|
36
|
+
expect(attrs["http.method"]).toBe("GET")
|
|
37
|
+
expect(attrs["http.path"]).toBe("/session")
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test("strips query string from path", () => {
|
|
41
|
+
const attrs = requestAttributes(fakeContext("GET", "http://localhost/file/search?query=foo&limit=10", {}))
|
|
42
|
+
expect(attrs["http.path"]).toBe("/file/search")
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test("emits OTel-style <domain>.id for ID-shaped route params", () => {
|
|
46
|
+
const attrs = requestAttributes(
|
|
47
|
+
fakeContext("GET", "http://localhost/session/ses_abc/message/msg_def/part/prt_ghi", {
|
|
48
|
+
sessionID: "ses_abc",
|
|
49
|
+
messageID: "msg_def",
|
|
50
|
+
partID: "prt_ghi",
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
expect(attrs["session.id"]).toBe("ses_abc")
|
|
54
|
+
expect(attrs["message.id"]).toBe("msg_def")
|
|
55
|
+
expect(attrs["part.id"]).toBe("prt_ghi")
|
|
56
|
+
// No camelCase leftovers:
|
|
57
|
+
expect(attrs["opencode.sessionID"]).toBeUndefined()
|
|
58
|
+
expect(attrs["opencode.messageID"]).toBeUndefined()
|
|
59
|
+
expect(attrs["opencode.partID"]).toBeUndefined()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test("produces no param attributes when no params are matched", () => {
|
|
63
|
+
const attrs = requestAttributes(fakeContext("POST", "http://localhost/config", {}))
|
|
64
|
+
expect(Object.keys(attrs).filter((k) => k !== "http.method" && k !== "http.path")).toEqual([])
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test("namespaces non-ID params under opencode. (e.g. mcp :name)", () => {
|
|
68
|
+
const attrs = requestAttributes(
|
|
69
|
+
fakeContext("POST", "http://localhost/mcp/exa/connect", {
|
|
70
|
+
name: "exa",
|
|
71
|
+
}),
|
|
72
|
+
)
|
|
73
|
+
expect(attrs["opencode.name"]).toBe("exa")
|
|
74
|
+
expect(attrs["name"]).toBeUndefined()
|
|
75
|
+
})
|
|
76
|
+
})
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from "bun:test"
|
|
2
|
+
import { Effect, Exit, Cause } from "effect"
|
|
3
|
+
import { Log } from "../../src/util"
|
|
4
|
+
import { Instance } from "../../src/project/instance"
|
|
5
|
+
import { Server } from "../../src/server/server"
|
|
6
|
+
import { Session } from "../../src/session"
|
|
7
|
+
import { WorkflowPersistence } from "../../src/workflow/persistence"
|
|
8
|
+
import { WorkflowRuntime } from "../../src/workflow/runtime"
|
|
9
|
+
import { workflowRef } from "../../src/workflow/runtime-ref"
|
|
10
|
+
import { provideTmpdirServer, tmpdir } from "../fixture/fixture"
|
|
11
|
+
import { testEffect } from "../lib/effect"
|
|
12
|
+
import { makeLayer, ref, providerCfg } from "../workflow/lib"
|
|
13
|
+
|
|
14
|
+
void Log.init({ print: false })
|
|
15
|
+
|
|
16
|
+
afterEach(async () => {
|
|
17
|
+
workflowRef.current = undefined
|
|
18
|
+
await Instance.disposeAll()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
describe("workflows routes", () => {
|
|
22
|
+
test("GET /workflows returns [] when the workflow runtime is not running", async () => {
|
|
23
|
+
await using tmp = await tmpdir({ git: true })
|
|
24
|
+
await Instance.provide({
|
|
25
|
+
directory: tmp.path,
|
|
26
|
+
fn: async () => {
|
|
27
|
+
// #given the workflow runtime layer is not running (late-bound ref unset)
|
|
28
|
+
workflowRef.current = undefined
|
|
29
|
+
|
|
30
|
+
// #when — a valid session-shaped sessionID (now REQUIRED) is supplied
|
|
31
|
+
const app = Server.Default().app
|
|
32
|
+
const response = await app.request("/workflows?sessionID=ses_16ec185f2ffexEGkbWeMqWSucv", { method: "GET" })
|
|
33
|
+
|
|
34
|
+
// #then — runtime absent short-circuits to [] (the session passes validation)
|
|
35
|
+
expect(response.status).toBe(200)
|
|
36
|
+
expect(await response.json()).toEqual([])
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test("POST /workflows/:runID/resume returns { resumed: false } when the runtime is not running", async () => {
|
|
42
|
+
await using tmp = await tmpdir({ git: true })
|
|
43
|
+
await Instance.provide({
|
|
44
|
+
directory: tmp.path,
|
|
45
|
+
fn: async () => {
|
|
46
|
+
// #given the workflow runtime layer is not running
|
|
47
|
+
workflowRef.current = undefined
|
|
48
|
+
|
|
49
|
+
// #when — a real minted-shape runID (wf_ + 26 base62) with no persisted run
|
|
50
|
+
const app = Server.Default().app
|
|
51
|
+
const response = await app.request("/workflows/wf_16ec185f2ffexEGkbWeMqWSucv/resume", { method: "POST" })
|
|
52
|
+
|
|
53
|
+
// #then
|
|
54
|
+
expect(response.status).toBe(200)
|
|
55
|
+
expect(await response.json()).toEqual({ runID: "wf_16ec185f2ffexEGkbWeMqWSucv", resumed: false })
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// ── P0 (MR104 #3): path traversal via unvalidated runID ──────────────────
|
|
61
|
+
// resume(runID) → readScript(runID) → scriptPath = join(scriptDir, runID + ".js").
|
|
62
|
+
// A traversal runID escapes scriptDir, so the route MUST reject any runID that
|
|
63
|
+
// is not exactly `wf_` + base62. The proof is that the request is REFUSED at the
|
|
64
|
+
// route's param validator (400) — it never reaches the runtime/launch, so no file
|
|
65
|
+
// outside scriptDir is ever opened.
|
|
66
|
+
for (const evil of [
|
|
67
|
+
"../../../etc/passwd",
|
|
68
|
+
"../../foo",
|
|
69
|
+
"/etc/passwd",
|
|
70
|
+
"wf_../../../etc/passwd", // defeats a prefix-only (startsWith "wf") check
|
|
71
|
+
"wf_..", // bare dot-dot after a legit prefix
|
|
72
|
+
]) {
|
|
73
|
+
test(`POST /workflows/:runID/resume REJECTS traversal runID ${JSON.stringify(evil)}`, async () => {
|
|
74
|
+
await using tmp = await tmpdir({ git: true })
|
|
75
|
+
await Instance.provide({
|
|
76
|
+
directory: tmp.path,
|
|
77
|
+
fn: async () => {
|
|
78
|
+
// #given the runtime is absent — so if validation let this through it would
|
|
79
|
+
// hit the early `{ resumed: false }`; the only way to a 400 is param rejection.
|
|
80
|
+
workflowRef.current = undefined
|
|
81
|
+
|
|
82
|
+
// #when
|
|
83
|
+
const app = Server.Default().app
|
|
84
|
+
const response = await app.request(`/workflows/${encodeURIComponent(evil)}/resume`, { method: "POST" })
|
|
85
|
+
|
|
86
|
+
// #then — rejected by the param validator before any path.join / file read.
|
|
87
|
+
expect(response.status).toBe(400)
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ── P0 (MR104 #3): GET /workflows must NOT leak all-session runs ──────────
|
|
94
|
+
test("GET /workflows with NO sessionID returns 400 (does not list all runs)", async () => {
|
|
95
|
+
await using tmp = await tmpdir({ git: true })
|
|
96
|
+
await Instance.provide({
|
|
97
|
+
directory: tmp.path,
|
|
98
|
+
fn: async () => {
|
|
99
|
+
// #given a live-enough runtime is irrelevant: the missing required query param
|
|
100
|
+
// is rejected at the validator. (Keep it unset so a regression that drops the
|
|
101
|
+
// requirement would surface as a 200 [] rather than passing by accident.)
|
|
102
|
+
workflowRef.current = undefined
|
|
103
|
+
|
|
104
|
+
// #when — omit sessionID entirely
|
|
105
|
+
const app = Server.Default().app
|
|
106
|
+
const response = await app.request("/workflows", { method: "GET" })
|
|
107
|
+
|
|
108
|
+
// #then — rejected, NOT a 200 with the unfiltered all-runs branch.
|
|
109
|
+
expect(response.status).toBe(400)
|
|
110
|
+
},
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test("GET /workflows with a non-session-shaped sessionID returns 400", async () => {
|
|
115
|
+
await using tmp = await tmpdir({ git: true })
|
|
116
|
+
await Instance.provide({
|
|
117
|
+
directory: tmp.path,
|
|
118
|
+
fn: async () => {
|
|
119
|
+
workflowRef.current = undefined
|
|
120
|
+
const app = Server.Default().app
|
|
121
|
+
const response = await app.request("/workflows?sessionID=not-a-session", { method: "GET" })
|
|
122
|
+
expect(response.status).toBe(400)
|
|
123
|
+
},
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
// ── P0 (MR104 #3): defense-in-depth at the persistence layer ──────────────
|
|
128
|
+
// readScript / journal IO are reachable from the tool + TUI, not only the HTTP
|
|
129
|
+
// route, so the persistence path functions must themselves refuse a traversal
|
|
130
|
+
// runID. A direct readScript("../../../etc/passwd") must FAIL (the guard throws,
|
|
131
|
+
// surfacing as an Effect defect) rather than open a file outside scriptDir.
|
|
132
|
+
test("WorkflowPersistence.readScript fails safely on a traversal runID (no out-of-dir read)", async () => {
|
|
133
|
+
await using tmp = await tmpdir({ git: true })
|
|
134
|
+
await Instance.provide({
|
|
135
|
+
directory: tmp.path,
|
|
136
|
+
fn: async () => {
|
|
137
|
+
const exit = await Effect.runPromiseExit(WorkflowPersistence.readScript("../../../etc/passwd"))
|
|
138
|
+
// #then — the GUARD must reject it. Asserting only Exit.isFailure would
|
|
139
|
+
// also pass against unguarded code (ENOENT on `…/etc/passwd.js`), so assert
|
|
140
|
+
// the failure carries the guard's message — this fails closed if safeRunID
|
|
141
|
+
// is ever removed.
|
|
142
|
+
expect(Exit.isFailure(exit)).toBe(true)
|
|
143
|
+
if (Exit.isFailure(exit)) {
|
|
144
|
+
expect(Cause.pretty(exit.cause)).toContain("invalid workflow runID")
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test("WorkflowPersistence.readScript still reads a legit wf_ runID", async () => {
|
|
151
|
+
await using tmp = await tmpdir({ git: true })
|
|
152
|
+
await Instance.provide({
|
|
153
|
+
directory: tmp.path,
|
|
154
|
+
fn: async () => {
|
|
155
|
+
// #given a normally-minted runID with a persisted script
|
|
156
|
+
const runID = "wf_16ec185f2ffexEGkbWeMqWSucv"
|
|
157
|
+
await Effect.runPromise(WorkflowPersistence.writeScript(runID, "export const meta = {}\n"))
|
|
158
|
+
// #then — the guard does NOT break the legit path
|
|
159
|
+
const body = await Effect.runPromise(WorkflowPersistence.readScript(runID))
|
|
160
|
+
expect(body).toContain("export const meta")
|
|
161
|
+
},
|
|
162
|
+
})
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// The LIVE path the TUI /workflows dialog consumes: the route returns REAL run
|
|
167
|
+
// data (not the degenerate []). These run under the workflow test layer
|
|
168
|
+
// (makeLayer) so WorkflowRuntime.layer is live and populates the module-global
|
|
169
|
+
// `workflowRef` that the route reads through. Crucially the data path is the
|
|
170
|
+
// process-global `:memory:` DB (test/preload sets tulingcode_DB=:memory:, and the
|
|
171
|
+
// storage Client is a per-process singleton): the run writes its WorkflowRunTable
|
|
172
|
+
// row there, and the route's handler — run via AppRuntime, NOT this layer — reads
|
|
173
|
+
// the SAME DB. So `Server.Default().app.request("/workflows")` genuinely
|
|
174
|
+
// exercises the HTTP route end-to-end against a real run. The
|
|
175
|
+
// `x-tulingcode-directory` header makes InstanceMiddleware re-enter the SAME cached
|
|
176
|
+
// tmpdir Instance the run used (one entry per directory in Instance's cache), so
|
|
177
|
+
// resume's re-launch spawns in the run's own session context. We filter list by
|
|
178
|
+
// sessionID to stay robust against any residue in the shared in-memory DB.
|
|
179
|
+
const it = testEffect(makeLayer())
|
|
180
|
+
|
|
181
|
+
// Test ORDER is deliberate: the sandbox-free resume test runs FIRST and the
|
|
182
|
+
// agent-spawning list test runs LAST. An agent() run forks a quickjs sandbox
|
|
183
|
+
// (evalScript) whose teardown is CPU-sensitive — under load the 1ms pump interval
|
|
184
|
+
// can starve, leaving the forked fiber uninterruptible at scope close (the
|
|
185
|
+
// pre-existing quickjs-under-Bun condition; see runtime.test.ts). Keeping the only
|
|
186
|
+
// sandbox-bearing test last means its residue has no following evalScript test to
|
|
187
|
+
// destabilize. Verified 0 flakes across 16 process runs UNDER heavy CPU contention
|
|
188
|
+
// in this order; the reverse order flakes ~30%+.
|
|
189
|
+
//
|
|
190
|
+
// NOTE on resume coverage: we assert the resume route over a LIVE runtime returns
|
|
191
|
+
// the real { resumed: false } for an unknown run — this proves the route reaches
|
|
192
|
+
// the live `runtime.resume()` (distinct from the degenerate case above, where the
|
|
193
|
+
// runtime is absent and the route short-circuits before calling resume). We do NOT
|
|
194
|
+
// add an HTTP test for the positive { resumed: true } re-launch: a successful
|
|
195
|
+
// resume forks a fresh evalScript whose teardown deadlocks under CI CPU load
|
|
196
|
+
// regardless of how it is driven (HTTP or the service directly) — a runtime/sandbox
|
|
197
|
+
// limitation we cannot fix from a test. The re-launch semantics (resumed: true,
|
|
198
|
+
// cached replay, zero-spawn resume) are covered in the warmed-up
|
|
199
|
+
// test/workflow/runtime.test.ts suite.
|
|
200
|
+
describe("workflows routes — live runtime", () => {
|
|
201
|
+
it.live("POST /workflows/:runID/resume reaches the LIVE runtime (resumed: false for an unknown run)", () =>
|
|
202
|
+
provideTmpdirServer(
|
|
203
|
+
Effect.fnUntraced(function* ({ dir }) {
|
|
204
|
+
// #given the workflow runtime IS live (the layer set the late-bound ref) —
|
|
205
|
+
// this is what distinguishes this from the degenerate test above, where the
|
|
206
|
+
// ref is undefined and the route returns early without calling resume().
|
|
207
|
+
expect(workflowRef.current).toBeDefined()
|
|
208
|
+
|
|
209
|
+
// #when — POST resume over the REAL route for a runID with no persisted run.
|
|
210
|
+
// Use a valid minted-shape runID (wf_ + 26 base62) so it passes the param
|
|
211
|
+
// validator and genuinely reaches the live runtime.resume(), which loads no
|
|
212
|
+
// row and returns { resumed: false }. (async wrapper normalizes Hono's
|
|
213
|
+
// `Promise<Response> | Response` overload for Effect.promise.)
|
|
214
|
+
const response = yield* Effect.promise(async () =>
|
|
215
|
+
Server.Default().app.request(`/workflows/wf_00000000000000000000000000/resume`, {
|
|
216
|
+
method: "POST",
|
|
217
|
+
headers: { "x-tulingcode-directory": dir },
|
|
218
|
+
}),
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
// #then — the live runtime's real verdict flows back through the HTTP route.
|
|
222
|
+
expect(response.status).toBe(200)
|
|
223
|
+
expect(yield* Effect.promise(() => response.json())).toEqual({
|
|
224
|
+
runID: "wf_00000000000000000000000000",
|
|
225
|
+
resumed: false,
|
|
226
|
+
})
|
|
227
|
+
}),
|
|
228
|
+
{ git: true, config: providerCfg },
|
|
229
|
+
),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
it.live("GET /workflows returns a live run with real status + counters", () =>
|
|
233
|
+
provideTmpdirServer(
|
|
234
|
+
Effect.fnUntraced(function* ({ dir, llm }) {
|
|
235
|
+
const runtime = yield* WorkflowRuntime.Service
|
|
236
|
+
const session = yield* Session.Service
|
|
237
|
+
const parent = yield* session.create({
|
|
238
|
+
title: "wf route live",
|
|
239
|
+
permission: [{ permission: "*", pattern: "*", action: "allow" }],
|
|
240
|
+
})
|
|
241
|
+
yield* llm.text("done") // one reply for the single agent() spawn
|
|
242
|
+
const script = [`export const meta = { name: "t", description: "d" }`, `return await agent("x")`].join("\n")
|
|
243
|
+
const { runID } = yield* runtime.start({ script, sessionID: parent.id, parentActorID: "main", model: ref })
|
|
244
|
+
const outcome = yield* runtime.wait({ runID, timeoutMs: 8000 })
|
|
245
|
+
expect(outcome.status).toBe("completed")
|
|
246
|
+
|
|
247
|
+
// #when — drive the REAL HTTP route the TUI list reads. The directory header
|
|
248
|
+
// makes InstanceMiddleware re-enter the same cached tmpdir Instance the run
|
|
249
|
+
// used; sessionID scopes to this run. app.request's Hono overload is
|
|
250
|
+
// `Promise<Response> | Response`, so the async wrapper normalizes it to a
|
|
251
|
+
// Promise for Effect.promise.
|
|
252
|
+
const response = yield* Effect.promise(async () =>
|
|
253
|
+
Server.Default().app.request(`/workflows?sessionID=${parent.id}`, {
|
|
254
|
+
method: "GET",
|
|
255
|
+
headers: { "x-tulingcode-directory": dir },
|
|
256
|
+
}),
|
|
257
|
+
)
|
|
258
|
+
expect(response.status).toBe(200)
|
|
259
|
+
const rows = (yield* Effect.promise(() => response.json())) as Array<{
|
|
260
|
+
runID: string
|
|
261
|
+
status: string
|
|
262
|
+
succeeded: number
|
|
263
|
+
}>
|
|
264
|
+
|
|
265
|
+
// #then — the live run is visible over HTTP with its real fields: this is
|
|
266
|
+
// the exact data path the TUI /workflows list reads (counter from a real spawn).
|
|
267
|
+
const row = rows.find((r) => r.runID === runID)
|
|
268
|
+
expect(row).toBeDefined()
|
|
269
|
+
expect(row!.status).toBe("completed")
|
|
270
|
+
expect(row!.succeeded).toBeGreaterThanOrEqual(1)
|
|
271
|
+
}),
|
|
272
|
+
{ git: true, config: providerCfg },
|
|
273
|
+
),
|
|
274
|
+
// Headroom over the default 5s: this exercises a full Instance bootstrap +
|
|
275
|
+
// a real runtime run + an HTTP round-trip, and runs alongside the heavy
|
|
276
|
+
// live workflow/server suites where CI load can push past 5s.
|
|
277
|
+
15000,
|
|
278
|
+
)
|
|
279
|
+
})
|