goatcode-sh 0.0.1 → 0.1.2
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/.github/workflows/ci.yml +85 -0
- package/.github/workflows/release.yml +107 -0
- package/.opencode/plugins/goatcode.js +1 -0
- package/AGENTS.md +59 -0
- package/CONTRIBUTING.md +110 -0
- package/LICENSE +21 -0
- package/README.md +106 -12
- package/bun.lock +2081 -0
- package/bunfig.toml +3 -0
- package/dist/agents/advisor/config.d.ts +4 -0
- package/dist/agents/advisor/index.d.ts +2 -0
- package/dist/agents/advisor/plugin.d.ts +1 -0
- package/dist/agents/advisor/prompt-meta.d.ts +2 -0
- package/dist/agents/advisor/prompt.d.ts +1 -0
- package/dist/agents/agent-builder.d.ts +10 -0
- package/dist/agents/agent-registry.d.ts +8 -0
- package/dist/agents/builtin-agents.d.ts +2 -0
- package/dist/agents/deep-worker/config.d.ts +4 -0
- package/dist/agents/deep-worker/index.d.ts +2 -0
- package/dist/agents/deep-worker/plugin.d.ts +1 -0
- package/dist/agents/deep-worker/prompt-meta.d.ts +2 -0
- package/dist/agents/deep-worker/prompt.d.ts +1 -0
- package/dist/agents/explorer/config.d.ts +4 -0
- package/dist/agents/explorer/index.d.ts +2 -0
- package/dist/agents/explorer/plugin.d.ts +1 -0
- package/dist/agents/explorer/prompt-meta.d.ts +2 -0
- package/dist/agents/explorer/prompt.d.ts +1 -0
- package/dist/agents/fallback-chains.d.ts +2 -0
- package/dist/agents/index.d.ts +14 -0
- package/dist/agents/orchestrator/config.d.ts +4 -0
- package/dist/agents/orchestrator/index.d.ts +2 -0
- package/dist/agents/orchestrator/plugin.d.ts +1 -0
- package/dist/agents/orchestrator/prompt-meta.d.ts +2 -0
- package/dist/agents/orchestrator/prompt.d.ts +1 -0
- package/dist/agents/planner/config.d.ts +4 -0
- package/dist/agents/planner/index.d.ts +2 -0
- package/dist/agents/planner/plugin.d.ts +1 -0
- package/dist/agents/planner/prompt-meta.d.ts +2 -0
- package/dist/agents/planner/prompt.d.ts +1 -0
- package/dist/agents/prompt-meta.d.ts +11 -0
- package/dist/agents/prompt-registry.d.ts +4 -0
- package/dist/agents/researcher/config.d.ts +4 -0
- package/dist/agents/researcher/index.d.ts +2 -0
- package/dist/agents/researcher/plugin.d.ts +1 -0
- package/dist/agents/researcher/prompt-meta.d.ts +2 -0
- package/dist/agents/researcher/prompt.d.ts +1 -0
- package/dist/agents/tool-restrictions.d.ts +7 -0
- package/dist/agents/worker/config.d.ts +4 -0
- package/dist/agents/worker/index.d.ts +2 -0
- package/dist/agents/worker/plugin.d.ts +1 -0
- package/dist/agents/worker/prompt-meta.d.ts +2 -0
- package/dist/agents/worker/prompt.d.ts +1 -0
- package/dist/bootstrap.d.ts +3 -0
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/commands/install.d.ts +12 -0
- package/dist/cli/commands/update.d.ts +1 -0
- package/dist/cli/config-generator.d.ts +26 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/define-config.d.ts +27 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/loader.d.ts +3 -0
- package/dist/config/paths.d.ts +4 -0
- package/dist/config/schema.d.ts +273 -0
- package/dist/config/validator.d.ts +9 -0
- package/dist/features/auto-update/index.d.ts +3 -0
- package/dist/features/auto-update/plugin.d.ts +2 -0
- package/dist/features/auto-update/update-checker.d.ts +7 -0
- package/dist/features/background-agent/concurrency.d.ts +10 -0
- package/dist/features/background-agent/index.d.ts +6 -0
- package/dist/features/background-agent/manager.d.ts +18 -0
- package/dist/features/background-agent/poller.d.ts +17 -0
- package/dist/features/background-agent/singleton.d.ts +7 -0
- package/dist/features/background-agent/spawner.d.ts +6 -0
- package/dist/features/background-agent/types.d.ts +18 -0
- package/dist/features/builtin-features.d.ts +2 -0
- package/dist/features/categories/category-config.d.ts +9 -0
- package/dist/features/categories/category-resolver.d.ts +6 -0
- package/dist/features/categories/index.d.ts +3 -0
- package/dist/features/categories/prompt-appends.d.ts +10 -0
- package/dist/features/loops/file-store.d.ts +22 -0
- package/dist/features/loops/handler.d.ts +9 -0
- package/dist/features/loops/index.d.ts +5 -0
- package/dist/features/loops/memory-store.d.ts +11 -0
- package/dist/features/loops/plugin.d.ts +34 -0
- package/dist/features/loops/shared/event-utils.d.ts +7 -0
- package/dist/features/loops/state.d.ts +22 -0
- package/dist/features/prompt-builder/agent-table-builder.d.ts +6 -0
- package/dist/features/prompt-builder/category-section-builder.d.ts +2 -0
- package/dist/features/prompt-builder/dynamic-prompt-builder.d.ts +9 -0
- package/dist/features/prompt-builder/index.d.ts +7 -0
- package/dist/features/prompt-builder/skill-section-builder.d.ts +5 -0
- package/dist/features/session-state/index.d.ts +5 -0
- package/dist/features/session-state/session-cursor.d.ts +13 -0
- package/dist/features/session-state/session-store.d.ts +12 -0
- package/dist/features/session-state/session-tools-store.d.ts +4 -0
- package/dist/features/skills/builtin/git-master.d.ts +2 -0
- package/dist/features/skills/index.d.ts +10 -0
- package/dist/features/skills/skill-loader.d.ts +22 -0
- package/dist/features/skills/skill-merger.d.ts +2 -0
- package/dist/features/slash-commands/command-registry.d.ts +3 -0
- package/dist/features/slash-commands/commands/cancel-loop.d.ts +2 -0
- package/dist/features/slash-commands/commands/handoff.d.ts +2 -0
- package/dist/features/slash-commands/commands/init-deep.d.ts +2 -0
- package/dist/features/slash-commands/commands/loop.d.ts +2 -0
- package/dist/features/slash-commands/commands/start-work.d.ts +2 -0
- package/dist/features/slash-commands/commands/stop-continuation.d.ts +2 -0
- package/dist/features/slash-commands/index.d.ts +2 -0
- package/dist/features/slash-commands/types.d.ts +5 -0
- package/dist/hooks/anthropic-effort/handler.d.ts +5 -0
- package/dist/hooks/anthropic-effort/index.d.ts +3 -0
- package/dist/hooks/anthropic-effort/plugin.d.ts +1 -0
- package/dist/hooks/builtin-hooks.d.ts +2 -0
- package/dist/hooks/comment-checker/handler.d.ts +5 -0
- package/dist/hooks/comment-checker/index.d.ts +2 -0
- package/dist/hooks/comment-checker/plugin.d.ts +1 -0
- package/dist/hooks/compaction-context/handler.d.ts +2 -0
- package/dist/hooks/compaction-context/index.d.ts +2 -0
- package/dist/hooks/compaction-context/plugin.d.ts +1 -0
- package/dist/hooks/compaction-todo-preserver/handler.d.ts +4 -0
- package/dist/hooks/compaction-todo-preserver/index.d.ts +2 -0
- package/dist/hooks/compaction-todo-preserver/plugin.d.ts +1 -0
- package/dist/hooks/context-injector/handlers/agents.d.ts +1 -0
- package/dist/hooks/context-injector/handlers/readme.d.ts +1 -0
- package/dist/hooks/context-injector/handlers/rules.d.ts +1 -0
- package/dist/hooks/context-injector/index.d.ts +4 -0
- package/dist/hooks/context-injector/plugin.d.ts +1 -0
- package/dist/hooks/context-window-limit/handler.d.ts +6 -0
- package/dist/hooks/context-window-limit/index.d.ts +2 -0
- package/dist/hooks/context-window-limit/plugin.d.ts +1 -0
- package/dist/hooks/delegate-retry/handler.d.ts +16 -0
- package/dist/hooks/delegate-retry/index.d.ts +3 -0
- package/dist/hooks/delegate-retry/plugin.d.ts +1 -0
- package/dist/hooks/edit-error/handler.d.ts +6 -0
- package/dist/hooks/edit-error/index.d.ts +2 -0
- package/dist/hooks/edit-error/plugin.d.ts +1 -0
- package/dist/hooks/empty-response-detector/handler.d.ts +5 -0
- package/dist/hooks/empty-response-detector/index.d.ts +2 -0
- package/dist/hooks/empty-response-detector/plugin.d.ts +1 -0
- package/dist/hooks/error-diagnostics/handler.d.ts +6 -0
- package/dist/hooks/error-diagnostics/patterns.d.ts +3 -0
- package/dist/hooks/error-diagnostics/plugin.d.ts +1 -0
- package/dist/hooks/error-diagnostics/types.d.ts +14 -0
- package/dist/hooks/foreground-fallback/handler.d.ts +22 -0
- package/dist/hooks/foreground-fallback/index.d.ts +2 -0
- package/dist/hooks/foreground-fallback/plugin.d.ts +1 -0
- package/dist/hooks/hashline-diff-enhancer/handler.d.ts +28 -0
- package/dist/hooks/hashline-diff-enhancer/index.d.ts +2 -0
- package/dist/hooks/hashline-diff-enhancer/plugin.d.ts +1 -0
- package/dist/hooks/hashline-read-enhancer/handler.d.ts +4 -0
- package/dist/hooks/hashline-read-enhancer/index.d.ts +2 -0
- package/dist/hooks/hashline-read-enhancer/plugin.d.ts +1 -0
- package/dist/hooks/hook-composer.d.ts +4 -0
- package/dist/hooks/hook-ordering.d.ts +9 -0
- package/dist/hooks/hook-types.d.ts +3 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/json-error/handler.d.ts +6 -0
- package/dist/hooks/json-error/index.d.ts +2 -0
- package/dist/hooks/json-error/plugin.d.ts +1 -0
- package/dist/hooks/keyword-detector/handler.d.ts +8 -0
- package/dist/hooks/keyword-detector/index.d.ts +3 -0
- package/dist/hooks/keyword-detector/plugin.d.ts +1 -0
- package/dist/hooks/model-fallback/handler.d.ts +21 -0
- package/dist/hooks/model-fallback/index.d.ts +2 -0
- package/dist/hooks/model-fallback/plugin.d.ts +1 -0
- package/dist/hooks/phase-reminder/handler.d.ts +5 -0
- package/dist/hooks/phase-reminder/index.d.ts +2 -0
- package/dist/hooks/phase-reminder/plugin.d.ts +1 -0
- package/dist/hooks/post-read-nudge/handler.d.ts +5 -0
- package/dist/hooks/post-read-nudge/index.d.ts +2 -0
- package/dist/hooks/post-read-nudge/plugin.d.ts +1 -0
- package/dist/hooks/preemptive-compaction/handler.d.ts +31 -0
- package/dist/hooks/preemptive-compaction/index.d.ts +2 -0
- package/dist/hooks/preemptive-compaction/plugin.d.ts +1 -0
- package/dist/hooks/runtime-fallback/handler.d.ts +21 -0
- package/dist/hooks/runtime-fallback/index.d.ts +2 -0
- package/dist/hooks/runtime-fallback/plugin.d.ts +1 -0
- package/dist/hooks/safe-hook-wrapper.d.ts +2 -0
- package/dist/hooks/session-recovery/handler.d.ts +6 -0
- package/dist/hooks/session-recovery/index.d.ts +2 -0
- package/dist/hooks/session-recovery/plugin.d.ts +1 -0
- package/dist/hooks/skill-discovery/plugin.d.ts +1 -0
- package/dist/hooks/stop-guard/handler.d.ts +4 -0
- package/dist/hooks/stop-guard/index.d.ts +2 -0
- package/dist/hooks/stop-guard/plugin.d.ts +1 -0
- package/dist/hooks/task-resume-info/handler.d.ts +4 -0
- package/dist/hooks/task-resume-info/index.d.ts +2 -0
- package/dist/hooks/task-resume-info/plugin.d.ts +1 -0
- package/dist/hooks/think-mode/handler.d.ts +4 -0
- package/dist/hooks/think-mode/index.d.ts +2 -0
- package/dist/hooks/think-mode/plugin.d.ts +1 -0
- package/dist/hooks/thinking-block-validator/handler.d.ts +4 -0
- package/dist/hooks/thinking-block-validator/index.d.ts +2 -0
- package/dist/hooks/thinking-block-validator/plugin.d.ts +1 -0
- package/dist/hooks/todo-enforcer/handler.d.ts +4 -0
- package/dist/hooks/todo-enforcer/index.d.ts +2 -0
- package/dist/hooks/todo-enforcer/plugin.d.ts +1 -0
- package/dist/hooks/todowrite-disabler/handler.d.ts +6 -0
- package/dist/hooks/todowrite-disabler/index.d.ts +2 -0
- package/dist/hooks/todowrite-disabler/plugin.d.ts +1 -0
- package/dist/hooks/tool-output-truncator/handler.d.ts +4 -0
- package/dist/hooks/tool-output-truncator/index.d.ts +2 -0
- package/dist/hooks/tool-output-truncator/plugin.d.ts +1 -0
- package/dist/hooks/write-file-guard/handler.d.ts +7 -0
- package/dist/hooks/write-file-guard/index.d.ts +2 -0
- package/dist/hooks/write-file-guard/plugin.d.ts +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +8547 -0
- package/dist/plugin/compositor.d.ts +9 -0
- package/dist/plugin/index.d.ts +1 -0
- package/dist/plugin-api/define-plugin.d.ts +33 -0
- package/dist/plugin-api/index.d.ts +3 -0
- package/dist/plugin-api/types.d.ts +10 -0
- package/dist/registry/agent-aggregator.d.ts +3 -0
- package/dist/registry/contribution-aggregator.d.ts +10 -0
- package/dist/registry/dependency-resolver.d.ts +3 -0
- package/dist/registry/hook-aggregator.d.ts +2 -0
- package/dist/registry/index.d.ts +6 -0
- package/dist/registry/plugin-registry.d.ts +16 -0
- package/dist/registry/tool-aggregator.d.ts +3 -0
- package/dist/registry/types.d.ts +9 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/shared/data-path.d.ts +4 -0
- package/dist/shared/deep-merge.d.ts +13 -0
- package/dist/shared/fallback-chain.d.ts +1 -0
- package/dist/shared/index.d.ts +19 -0
- package/dist/shared/logger.d.ts +4 -0
- package/dist/shared/model-availability.d.ts +1 -0
- package/dist/shared/model-normalization.d.ts +6 -0
- package/dist/shared/model-prefix-map.d.ts +11 -0
- package/dist/shared/model-resolution-pipeline.d.ts +14 -0
- package/dist/shared/models-dev.d.ts +29 -0
- package/dist/shared/provider-discovery.d.ts +28 -0
- package/dist/shared/provider-registry.d.ts +16 -0
- package/dist/shared/safe-create-hook.d.ts +3 -0
- package/dist/shared/snake-case.d.ts +1 -0
- package/dist/shared/truncate-description.d.ts +1 -0
- package/dist/test-utils/index.d.ts +6 -0
- package/dist/test-utils/mock-agent-config.d.ts +5 -0
- package/dist/test-utils/mock-hook-inputs.d.ts +20 -0
- package/dist/test-utils/mock-hook-outputs.d.ts +20 -0
- package/dist/test-utils/mock-plugin-context.d.ts +6 -0
- package/dist/test-utils/mock-sdk-client.d.ts +41 -0
- package/dist/test-utils/mock-tool-context.d.ts +6 -0
- package/dist/tools/ast-grep/index.d.ts +4 -0
- package/dist/tools/ast-grep/replace/handler.d.ts +7 -0
- package/dist/tools/ast-grep/replace/plugin.d.ts +1 -0
- package/dist/tools/ast-grep/replace/types.d.ts +37 -0
- package/dist/tools/ast-grep/search/handler.d.ts +14 -0
- package/dist/tools/ast-grep/search/plugin.d.ts +1 -0
- package/dist/tools/ast-grep/search/types.d.ts +37 -0
- package/dist/tools/background-task/cancel/handler.d.ts +4 -0
- package/dist/tools/background-task/cancel/plugin.d.ts +2 -0
- package/dist/tools/background-task/cancel/types.d.ts +4 -0
- package/dist/tools/background-task/index.d.ts +2 -0
- package/dist/tools/background-task/output/handler.d.ts +3 -0
- package/dist/tools/background-task/output/plugin.d.ts +2 -0
- package/dist/tools/background-task/output/types.d.ts +11 -0
- package/dist/tools/bridge.d.ts +7 -0
- package/dist/tools/builtin-tools.d.ts +2 -0
- package/dist/tools/delegate-task/category-resolver.d.ts +4 -0
- package/dist/tools/delegate-task/constants.d.ts +3 -0
- package/dist/tools/delegate-task/executor.d.ts +10 -0
- package/dist/tools/delegate-task/handler.d.ts +3 -0
- package/dist/tools/delegate-task/index.d.ts +7 -0
- package/dist/tools/delegate-task/plugin.d.ts +2 -0
- package/dist/tools/delegate-task/types.d.ts +17 -0
- package/dist/tools/glob/handler.d.ts +7 -0
- package/dist/tools/glob/index.d.ts +2 -0
- package/dist/tools/glob/plugin.d.ts +1 -0
- package/dist/tools/glob/types.d.ts +7 -0
- package/dist/tools/grep/handler.d.ts +13 -0
- package/dist/tools/grep/index.d.ts +2 -0
- package/dist/tools/grep/plugin.d.ts +1 -0
- package/dist/tools/grep/types.d.ts +15 -0
- package/dist/tools/hashline-edit/constants.d.ts +4 -0
- package/dist/tools/hashline-edit/edit-operations.d.ts +4 -0
- package/dist/tools/hashline-edit/handler.d.ts +5 -0
- package/dist/tools/hashline-edit/hash-computation.d.ts +2 -0
- package/dist/tools/hashline-edit/index.d.ts +5 -0
- package/dist/tools/hashline-edit/plugin.d.ts +3 -0
- package/dist/tools/hashline-edit/types.d.ts +21 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/look-at/handler.d.ts +6 -0
- package/dist/tools/look-at/index.d.ts +3 -0
- package/dist/tools/look-at/plugin.d.ts +1 -0
- package/dist/tools/look-at/types.d.ts +9 -0
- package/dist/tools/lsp/client.d.ts +7 -0
- package/dist/tools/lsp/diagnostics/handler.d.ts +2 -0
- package/dist/tools/lsp/diagnostics/plugin.d.ts +1 -0
- package/dist/tools/lsp/diagnostics/types.d.ts +13 -0
- package/dist/tools/lsp/find-references/handler.d.ts +2 -0
- package/dist/tools/lsp/find-references/plugin.d.ts +1 -0
- package/dist/tools/lsp/find-references/types.d.ts +8 -0
- package/dist/tools/lsp/goto-definition/handler.d.ts +2 -0
- package/dist/tools/lsp/goto-definition/plugin.d.ts +1 -0
- package/dist/tools/lsp/goto-definition/types.d.ts +7 -0
- package/dist/tools/lsp/index.d.ts +6 -0
- package/dist/tools/lsp/prepare-rename/handler.d.ts +2 -0
- package/dist/tools/lsp/prepare-rename/plugin.d.ts +1 -0
- package/dist/tools/lsp/prepare-rename/types.d.ts +7 -0
- package/dist/tools/lsp/rename/handler.d.ts +2 -0
- package/dist/tools/lsp/rename/plugin.d.ts +1 -0
- package/dist/tools/lsp/rename/types.d.ts +8 -0
- package/dist/tools/lsp/symbols/handler.d.ts +2 -0
- package/dist/tools/lsp/symbols/plugin.d.ts +1 -0
- package/dist/tools/lsp/symbols/types.d.ts +11 -0
- package/dist/tools/session-manager/client-context.d.ts +3 -0
- package/dist/tools/session-manager/index.d.ts +5 -0
- package/dist/tools/session-manager/info/handler.d.ts +3 -0
- package/dist/tools/session-manager/info/plugin.d.ts +1 -0
- package/dist/tools/session-manager/info/types.d.ts +3 -0
- package/dist/tools/session-manager/list/handler.d.ts +3 -0
- package/dist/tools/session-manager/list/plugin.d.ts +1 -0
- package/dist/tools/session-manager/list/types.d.ts +6 -0
- package/dist/tools/session-manager/read/handler.d.ts +3 -0
- package/dist/tools/session-manager/read/plugin.d.ts +1 -0
- package/dist/tools/session-manager/read/types.d.ts +6 -0
- package/dist/tools/session-manager/search/handler.d.ts +3 -0
- package/dist/tools/session-manager/search/plugin.d.ts +1 -0
- package/dist/tools/session-manager/search/types.d.ts +6 -0
- package/dist/tools/session-manager/session-formatter.d.ts +29 -0
- package/dist/tools/session-manager/types.d.ts +36 -0
- package/dist/tools/shared/constants.d.ts +3 -0
- package/dist/tools/skill/handler.d.ts +4 -0
- package/dist/tools/skill/index.d.ts +3 -0
- package/dist/tools/skill/plugin.d.ts +1 -0
- package/dist/tools/skill/types.d.ts +12 -0
- package/dist/tools/skill-mcp/handler.d.ts +5 -0
- package/dist/tools/skill-mcp/index.d.ts +3 -0
- package/dist/tools/skill-mcp/plugin.d.ts +1 -0
- package/dist/tools/skill-mcp/types.d.ts +13 -0
- package/dist/tools/task/create/handler.d.ts +2 -0
- package/dist/tools/task/create/plugin.d.ts +1 -0
- package/dist/tools/task/format-task.d.ts +2 -0
- package/dist/tools/task/get/handler.d.ts +2 -0
- package/dist/tools/task/get/plugin.d.ts +1 -0
- package/dist/tools/task/index.d.ts +4 -0
- package/dist/tools/task/list/handler.d.ts +2 -0
- package/dist/tools/task/list/plugin.d.ts +1 -0
- package/dist/tools/task/storage.d.ts +7 -0
- package/dist/tools/task/types.d.ts +84 -0
- package/dist/tools/task/update/handler.d.ts +2 -0
- package/dist/tools/task/update/plugin.d.ts +1 -0
- package/dist/tools/tool-builder.d.ts +7 -0
- package/dist/tools/tool-registry-adapter.d.ts +3 -0
- package/dist/types/agent.d.ts +40 -0
- package/dist/types/category.d.ts +22 -0
- package/dist/types/config.d.ts +23 -0
- package/dist/types/hook.d.ts +18 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/plugin.d.ts +41 -0
- package/dist/types/tool.d.ts +7 -0
- package/eval/README.md +160 -0
- package/eval/ablation-config.yaml +43 -0
- package/eval/assertions/ablation-scorer.ts +81 -0
- package/eval/assertions/hook-impact.ts +152 -0
- package/eval/assertions/task-completion.ts +65 -0
- package/eval/assertions/tool-accuracy.ts +56 -0
- package/eval/promptfooconfig.yaml +42 -0
- package/eval/providers/opencode-baseline.ts +63 -0
- package/eval/providers/opencode-client.ts +112 -0
- package/eval/providers/opencode-provider.ts +66 -0
- package/eval/spike/config.yaml +13 -0
- package/eval/spike/provider.ts +15 -0
- package/npm-reserve/README.md +19 -0
- package/npm-reserve/package.json +24 -0
- package/opencode.json +6 -0
- package/package.json +47 -8
- package/src/agents/advisor/config.ts +6 -0
- package/src/agents/advisor/index.ts +2 -0
- package/src/agents/advisor/plugin.test.ts +48 -0
- package/src/agents/advisor/plugin.ts +17 -0
- package/src/agents/advisor/prompt-meta.ts +14 -0
- package/src/agents/advisor/prompt.ts +93 -0
- package/src/agents/agent-builder.test.ts +66 -0
- package/src/agents/agent-builder.ts +97 -0
- package/src/agents/agent-plugins.test.ts +98 -0
- package/src/agents/agent-registry.ts +25 -0
- package/src/agents/builtin-agents.ts +18 -0
- package/src/agents/deep-worker/config.ts +6 -0
- package/src/agents/deep-worker/index.ts +2 -0
- package/src/agents/deep-worker/plugin.test.ts +31 -0
- package/src/agents/deep-worker/plugin.ts +16 -0
- package/src/agents/deep-worker/prompt-meta.ts +14 -0
- package/src/agents/deep-worker/prompt.ts +121 -0
- package/src/agents/disabled/analyst/config.ts +6 -0
- package/src/agents/disabled/analyst/index.ts +2 -0
- package/src/agents/disabled/analyst/plugin.ts +16 -0
- package/src/agents/disabled/analyst/prompt.ts +1 -0
- package/src/agents/disabled/executor/config.ts +9 -0
- package/src/agents/disabled/executor/index.ts +2 -0
- package/src/agents/disabled/executor/plugin.ts +16 -0
- package/src/agents/disabled/executor/prompt.ts +1 -0
- package/src/agents/disabled/inspector/config.ts +6 -0
- package/src/agents/disabled/inspector/index.ts +2 -0
- package/src/agents/disabled/inspector/plugin.ts +18 -0
- package/src/agents/disabled/inspector/prompt.ts +1 -0
- package/src/agents/disabled/reviewer/config.ts +6 -0
- package/src/agents/disabled/reviewer/index.ts +2 -0
- package/src/agents/disabled/reviewer/plugin.ts +18 -0
- package/src/agents/disabled/reviewer/prompt.ts +1 -0
- package/src/agents/explorer/config.ts +6 -0
- package/src/agents/explorer/index.ts +2 -0
- package/src/agents/explorer/plugin.test.ts +36 -0
- package/src/agents/explorer/plugin.ts +15 -0
- package/src/agents/explorer/prompt-meta.ts +14 -0
- package/src/agents/explorer/prompt.ts +96 -0
- package/src/agents/fallback-chains.ts +13 -0
- package/src/agents/index.ts +18 -0
- package/src/agents/model-resolution.test.ts +79 -0
- package/src/agents/orchestrator/config.ts +10 -0
- package/src/agents/orchestrator/index.ts +2 -0
- package/src/agents/orchestrator/plugin.test.ts +31 -0
- package/src/agents/orchestrator/plugin.ts +16 -0
- package/src/agents/orchestrator/prompt-meta.ts +14 -0
- package/src/agents/orchestrator/prompt.ts +143 -0
- package/src/agents/planner/config.ts +6 -0
- package/src/agents/planner/index.ts +2 -0
- package/src/agents/planner/plugin.test.ts +31 -0
- package/src/agents/planner/plugin.ts +16 -0
- package/src/agents/planner/prompt-meta.ts +14 -0
- package/src/agents/planner/prompt.ts +138 -0
- package/src/agents/prompt-meta.ts +12 -0
- package/src/agents/prompt-registry.test.ts +98 -0
- package/src/agents/prompt-registry.ts +22 -0
- package/src/agents/researcher/config.ts +6 -0
- package/src/agents/researcher/index.ts +2 -0
- package/src/agents/researcher/plugin.test.ts +31 -0
- package/src/agents/researcher/plugin.ts +16 -0
- package/src/agents/researcher/prompt-meta.ts +14 -0
- package/src/agents/researcher/prompt.ts +116 -0
- package/src/agents/tool-restrictions.ts +87 -0
- package/src/agents/worker/config.ts +6 -0
- package/src/agents/worker/index.ts +2 -0
- package/src/agents/worker/plugin.test.ts +31 -0
- package/src/agents/worker/plugin.ts +15 -0
- package/src/agents/worker/prompt-meta.ts +14 -0
- package/src/agents/worker/prompt.ts +83 -0
- package/src/bootstrap.integration.test.ts +168 -0
- package/src/bootstrap.ts +171 -0
- package/src/cli/cli.ts +42 -0
- package/src/cli/commands/install.test.ts +40 -0
- package/src/cli/commands/install.ts +125 -0
- package/src/cli/commands/update.test.ts +84 -0
- package/src/cli/commands/update.ts +45 -0
- package/src/cli/config-generator.test.ts +178 -0
- package/src/cli/config-generator.ts +119 -0
- package/src/cli/index.test.ts +34 -0
- package/src/cli/index.ts +4 -0
- package/src/config/defaults.ts +24 -0
- package/src/config/define-config.ts +38 -0
- package/src/config/index.ts +6 -0
- package/src/config/loader.test.ts +218 -0
- package/src/config/loader.ts +89 -0
- package/src/config/paths.ts +30 -0
- package/src/config/schema.test.ts +69 -0
- package/src/config/schema.ts +57 -0
- package/src/config/validator.ts +24 -0
- package/src/features/auto-update/auto-update.test.ts +105 -0
- package/src/features/auto-update/index.ts +4 -0
- package/src/features/auto-update/plugin.ts +45 -0
- package/src/features/auto-update/update-checker.ts +66 -0
- package/src/features/background-agent/concurrency.test.ts +65 -0
- package/src/features/background-agent/concurrency.ts +44 -0
- package/src/features/background-agent/index.ts +12 -0
- package/src/features/background-agent/manager.ts +214 -0
- package/src/features/background-agent/poller.test.ts +33 -0
- package/src/features/background-agent/poller.ts +75 -0
- package/src/features/background-agent/singleton.ts +26 -0
- package/src/features/background-agent/spawner.ts +51 -0
- package/src/features/background-agent/types.ts +20 -0
- package/src/features/builtin-features.ts +5 -0
- package/src/features/categories/categories.test.ts +68 -0
- package/src/features/categories/category-config.ts +70 -0
- package/src/features/categories/category-resolver.ts +36 -0
- package/src/features/categories/index.ts +8 -0
- package/src/features/categories/prompt-appends.ts +38 -0
- package/src/features/loops/file-store.ts +151 -0
- package/src/features/loops/handler.ts +89 -0
- package/src/features/loops/index.ts +28 -0
- package/src/features/loops/loops.test.ts +175 -0
- package/src/features/loops/memory-store.ts +53 -0
- package/src/features/loops/plugin.ts +107 -0
- package/src/features/loops/shared/event-utils.ts +50 -0
- package/src/features/loops/state.ts +44 -0
- package/src/features/prompt-builder/agent-table-builder.ts +23 -0
- package/src/features/prompt-builder/category-section-builder.ts +21 -0
- package/src/features/prompt-builder/dynamic-prompt-builder.ts +42 -0
- package/src/features/prompt-builder/index.ts +7 -0
- package/src/features/prompt-builder/prompt-builder.test.ts +244 -0
- package/src/features/prompt-builder/skill-section-builder.ts +25 -0
- package/src/features/session-state/index.ts +17 -0
- package/src/features/session-state/session-cursor.test.ts +137 -0
- package/src/features/session-state/session-cursor.ts +80 -0
- package/src/features/session-state/session-store.test.ts +82 -0
- package/src/features/session-state/session-store.ts +37 -0
- package/src/features/session-state/session-tools-store.ts +18 -0
- package/src/features/skills/builtin/git-master.ts +109 -0
- package/src/features/skills/index.ts +97 -0
- package/src/features/skills/skill-loader.ts +133 -0
- package/src/features/skills/skill-merger.ts +15 -0
- package/src/features/skills/skills.test.ts +120 -0
- package/src/features/slash-commands/command-registry.ts +36 -0
- package/src/features/slash-commands/commands/cancel-loop.ts +17 -0
- package/src/features/slash-commands/commands/handoff.ts +59 -0
- package/src/features/slash-commands/commands/init-deep.ts +40 -0
- package/src/features/slash-commands/commands/loop.ts +39 -0
- package/src/features/slash-commands/commands/start-work.ts +39 -0
- package/src/features/slash-commands/commands/stop-continuation.ts +21 -0
- package/src/features/slash-commands/index.ts +2 -0
- package/src/features/slash-commands/slash-commands.test.ts +68 -0
- package/src/features/slash-commands/types.ts +5 -0
- package/src/hooks/anthropic-effort/handler.test.ts +156 -0
- package/src/hooks/anthropic-effort/handler.ts +64 -0
- package/src/hooks/anthropic-effort/index.ts +3 -0
- package/src/hooks/anthropic-effort/plugin.ts +17 -0
- package/src/hooks/builtin-hooks.ts +64 -0
- package/src/hooks/comment-checker/handler.test.ts +65 -0
- package/src/hooks/comment-checker/handler.ts +60 -0
- package/src/hooks/comment-checker/index.ts +2 -0
- package/src/hooks/comment-checker/plugin.ts +15 -0
- package/src/hooks/compaction-context/handler.test.ts +160 -0
- package/src/hooks/compaction-context/handler.ts +179 -0
- package/src/hooks/compaction-context/index.ts +5 -0
- package/src/hooks/compaction-context/plugin.ts +40 -0
- package/src/hooks/compaction-todo-preserver/handler.test.ts +155 -0
- package/src/hooks/compaction-todo-preserver/handler.ts +129 -0
- package/src/hooks/compaction-todo-preserver/index.ts +2 -0
- package/src/hooks/compaction-todo-preserver/plugin.ts +18 -0
- package/src/hooks/context-injection.test.ts +124 -0
- package/src/hooks/context-injector/handlers/agents.test.ts +90 -0
- package/src/hooks/context-injector/handlers/agents.ts +81 -0
- package/src/hooks/context-injector/handlers/readme.ts +55 -0
- package/src/hooks/context-injector/handlers/rules.ts +62 -0
- package/src/hooks/context-injector/index.ts +4 -0
- package/src/hooks/context-injector/plugin.ts +56 -0
- package/src/hooks/context-window-limit/handler.test.ts +103 -0
- package/src/hooks/context-window-limit/handler.ts +128 -0
- package/src/hooks/context-window-limit/index.ts +6 -0
- package/src/hooks/context-window-limit/plugin.ts +15 -0
- package/src/hooks/continuation.test.ts +103 -0
- package/src/hooks/delegate-retry/handler.test.ts +212 -0
- package/src/hooks/delegate-retry/handler.ts +137 -0
- package/src/hooks/delegate-retry/index.ts +8 -0
- package/src/hooks/delegate-retry/plugin.ts +15 -0
- package/src/hooks/edit-error/handler.test.ts +82 -0
- package/src/hooks/edit-error/handler.ts +50 -0
- package/src/hooks/edit-error/index.ts +6 -0
- package/src/hooks/edit-error/plugin.ts +15 -0
- package/src/hooks/empty-response-detector/handler.test.ts +133 -0
- package/src/hooks/empty-response-detector/handler.ts +62 -0
- package/src/hooks/empty-response-detector/index.ts +2 -0
- package/src/hooks/empty-response-detector/plugin.ts +18 -0
- package/src/hooks/error-diagnostics/error-diagnostics.test.ts +116 -0
- package/src/hooks/error-diagnostics/handler.test.ts +147 -0
- package/src/hooks/error-diagnostics/handler.ts +135 -0
- package/src/hooks/error-diagnostics/patterns.ts +93 -0
- package/src/hooks/error-diagnostics/plugin.ts +11 -0
- package/src/hooks/error-diagnostics/types.ts +26 -0
- package/src/hooks/error-recovery.test.ts +85 -0
- package/src/hooks/foreground-fallback/handler.test.ts +229 -0
- package/src/hooks/foreground-fallback/handler.ts +294 -0
- package/src/hooks/foreground-fallback/index.ts +2 -0
- package/src/hooks/foreground-fallback/plugin.ts +18 -0
- package/src/hooks/hashline-diff-enhancer/handler.test.ts +166 -0
- package/src/hooks/hashline-diff-enhancer/handler.ts +186 -0
- package/src/hooks/hashline-diff-enhancer/index.ts +6 -0
- package/src/hooks/hashline-diff-enhancer/plugin.ts +24 -0
- package/src/hooks/hashline-read-enhancer/handler.test.ts +121 -0
- package/src/hooks/hashline-read-enhancer/handler.ts +165 -0
- package/src/hooks/hashline-read-enhancer/index.ts +2 -0
- package/src/hooks/hashline-read-enhancer/plugin.ts +18 -0
- package/src/hooks/hook-composer.test.ts +52 -0
- package/src/hooks/hook-composer.ts +17 -0
- package/src/hooks/hook-composition.integration.test.ts +274 -0
- package/src/hooks/hook-ordering.ts +41 -0
- package/src/hooks/hook-types.ts +22 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/json-error/handler.test.ts +95 -0
- package/src/hooks/json-error/handler.ts +82 -0
- package/src/hooks/json-error/index.ts +6 -0
- package/src/hooks/json-error/plugin.ts +15 -0
- package/src/hooks/keyword-detector/handler.test.ts +113 -0
- package/src/hooks/keyword-detector/handler.ts +73 -0
- package/src/hooks/keyword-detector/index.ts +8 -0
- package/src/hooks/keyword-detector/plugin.ts +24 -0
- package/src/hooks/model-fallback/handler.test.ts +163 -0
- package/src/hooks/model-fallback/handler.ts +178 -0
- package/src/hooks/model-fallback/index.ts +2 -0
- package/src/hooks/model-fallback/plugin.ts +11 -0
- package/src/hooks/model-management.test.ts +121 -0
- package/src/hooks/phase-reminder/handler.test.ts +105 -0
- package/src/hooks/phase-reminder/handler.ts +54 -0
- package/src/hooks/phase-reminder/index.ts +2 -0
- package/src/hooks/phase-reminder/plugin.ts +18 -0
- package/src/hooks/post-read-nudge/handler.test.ts +106 -0
- package/src/hooks/post-read-nudge/handler.ts +28 -0
- package/src/hooks/post-read-nudge/index.ts +2 -0
- package/src/hooks/post-read-nudge/plugin.ts +18 -0
- package/src/hooks/preemptive-compaction/handler.test.ts +130 -0
- package/src/hooks/preemptive-compaction/handler.ts +84 -0
- package/src/hooks/preemptive-compaction/index.ts +2 -0
- package/src/hooks/preemptive-compaction/plugin.ts +15 -0
- package/src/hooks/productivity.test.ts +332 -0
- package/src/hooks/quality.test.ts +330 -0
- package/src/hooks/runtime-fallback/handler.test.ts +142 -0
- package/src/hooks/runtime-fallback/handler.ts +171 -0
- package/src/hooks/runtime-fallback/index.ts +2 -0
- package/src/hooks/runtime-fallback/plugin.ts +13 -0
- package/src/hooks/safe-hook-wrapper.test.ts +35 -0
- package/src/hooks/safe-hook-wrapper.ts +12 -0
- package/src/hooks/session-recovery/handler.test.ts +88 -0
- package/src/hooks/session-recovery/handler.ts +87 -0
- package/src/hooks/session-recovery/index.ts +6 -0
- package/src/hooks/session-recovery/plugin.ts +15 -0
- package/src/hooks/skill-discovery/plugin.ts +45 -0
- package/src/hooks/stop-guard/handler.test.ts +147 -0
- package/src/hooks/stop-guard/handler.ts +127 -0
- package/src/hooks/stop-guard/index.ts +2 -0
- package/src/hooks/stop-guard/plugin.ts +15 -0
- package/src/hooks/task-hooks.test.ts +324 -0
- package/src/hooks/task-resume-info/handler.test.ts +180 -0
- package/src/hooks/task-resume-info/handler.ts +61 -0
- package/src/hooks/task-resume-info/index.ts +2 -0
- package/src/hooks/task-resume-info/plugin.ts +15 -0
- package/src/hooks/think-mode/handler.test.ts +139 -0
- package/src/hooks/think-mode/handler.ts +50 -0
- package/src/hooks/think-mode/index.ts +2 -0
- package/src/hooks/think-mode/plugin.ts +15 -0
- package/src/hooks/thinking-block-validator/handler.test.ts +79 -0
- package/src/hooks/thinking-block-validator/handler.ts +93 -0
- package/src/hooks/thinking-block-validator/index.ts +2 -0
- package/src/hooks/thinking-block-validator/plugin.ts +18 -0
- package/src/hooks/todo-enforcer/handler.test.ts +153 -0
- package/src/hooks/todo-enforcer/handler.ts +100 -0
- package/src/hooks/todo-enforcer/index.ts +2 -0
- package/src/hooks/todo-enforcer/plugin.ts +15 -0
- package/src/hooks/todowrite-disabler/handler.test.ts +119 -0
- package/src/hooks/todowrite-disabler/handler.ts +50 -0
- package/src/hooks/todowrite-disabler/index.ts +6 -0
- package/src/hooks/todowrite-disabler/plugin.ts +46 -0
- package/src/hooks/tool-output-truncator/handler.test.ts +113 -0
- package/src/hooks/tool-output-truncator/handler.ts +83 -0
- package/src/hooks/tool-output-truncator/index.ts +2 -0
- package/src/hooks/tool-output-truncator/plugin.ts +18 -0
- package/src/hooks/tool-output.test.ts +238 -0
- package/src/hooks/workflow-reminders.test.ts +187 -0
- package/src/hooks/write-file-guard/handler.test.ts +107 -0
- package/src/hooks/write-file-guard/handler.ts +166 -0
- package/src/hooks/write-file-guard/index.ts +2 -0
- package/src/hooks/write-file-guard/plugin.ts +23 -0
- package/src/index.ts +8 -0
- package/src/plugin/compositor.ts +99 -0
- package/src/plugin/index.ts +1 -0
- package/src/plugin-api/define-plugin.test.ts +66 -0
- package/src/plugin-api/define-plugin.ts +36 -0
- package/src/plugin-api/index.ts +26 -0
- package/src/plugin-api/types.ts +28 -0
- package/src/registry/agent-aggregator.ts +13 -0
- package/src/registry/contribution-aggregator.test.ts +62 -0
- package/src/registry/contribution-aggregator.ts +114 -0
- package/src/registry/contribution-conflicts.integration.test.ts +186 -0
- package/src/registry/dependency-resolver.test.ts +35 -0
- package/src/registry/dependency-resolver.ts +64 -0
- package/src/registry/hook-aggregator.test.ts +78 -0
- package/src/registry/hook-aggregator.ts +63 -0
- package/src/registry/index.ts +6 -0
- package/src/registry/plugin-lifecycle.integration.test.ts +94 -0
- package/src/registry/plugin-overrides.integration.test.ts +140 -0
- package/src/registry/plugin-registry.test.ts +56 -0
- package/src/registry/plugin-registry.ts +82 -0
- package/src/registry/tool-aggregator.ts +13 -0
- package/src/registry/types.ts +11 -0
- package/src/runtime/index.ts +43 -0
- package/src/shared/data-path.ts +18 -0
- package/src/shared/deep-merge.test.ts +36 -0
- package/src/shared/deep-merge.ts +61 -0
- package/src/shared/fallback-chain.ts +8 -0
- package/src/shared/index.ts +59 -0
- package/src/shared/logger.ts +54 -0
- package/src/shared/model-availability.ts +18 -0
- package/src/shared/model-normalization.test.ts +75 -0
- package/src/shared/model-normalization.ts +28 -0
- package/src/shared/model-prefix-map.test.ts +75 -0
- package/src/shared/model-prefix-map.ts +58 -0
- package/src/shared/model-resolution-pipeline.test.ts +111 -0
- package/src/shared/model-resolution-pipeline.ts +55 -0
- package/src/shared/models-dev.test.ts +277 -0
- package/src/shared/models-dev.ts +176 -0
- package/src/shared/provider-discovery.test.ts +97 -0
- package/src/shared/provider-discovery.ts +73 -0
- package/src/shared/provider-registry.test.ts +212 -0
- package/src/shared/provider-registry.ts +157 -0
- package/src/shared/safe-create-hook.ts +15 -0
- package/src/shared/snake-case.ts +7 -0
- package/src/shared/truncate-description.ts +6 -0
- package/src/test-utils/index.ts +6 -0
- package/src/test-utils/mock-agent-config.ts +13 -0
- package/src/test-utils/mock-hook-inputs.ts +148 -0
- package/src/test-utils/mock-hook-outputs.ts +153 -0
- package/src/test-utils/mock-plugin-context.test.ts +32 -0
- package/src/test-utils/mock-plugin-context.ts +21 -0
- package/src/test-utils/mock-sdk-client.ts +52 -0
- package/src/test-utils/mock-tool-context.ts +24 -0
- package/src/tools/ast-grep/index.ts +4 -0
- package/src/tools/ast-grep/replace/handler.test.ts +93 -0
- package/src/tools/ast-grep/replace/handler.ts +89 -0
- package/src/tools/ast-grep/replace/plugin.ts +10 -0
- package/src/tools/ast-grep/replace/types.ts +14 -0
- package/src/tools/ast-grep/search/handler.test.ts +94 -0
- package/src/tools/ast-grep/search/handler.ts +93 -0
- package/src/tools/ast-grep/search/plugin.ts +10 -0
- package/src/tools/ast-grep/search/types.ts +42 -0
- package/src/tools/background-task/background-task.test.ts +185 -0
- package/src/tools/background-task/cancel/handler.test.ts +141 -0
- package/src/tools/background-task/cancel/handler.ts +52 -0
- package/src/tools/background-task/cancel/plugin.ts +30 -0
- package/src/tools/background-task/cancel/types.ts +4 -0
- package/src/tools/background-task/index.ts +2 -0
- package/src/tools/background-task/output/handler.test.ts +142 -0
- package/src/tools/background-task/output/handler.ts +93 -0
- package/src/tools/background-task/output/plugin.ts +60 -0
- package/src/tools/background-task/output/types.ts +11 -0
- package/src/tools/bridge.test.ts +55 -0
- package/src/tools/bridge.ts +13 -0
- package/src/tools/builtin-tools.ts +54 -0
- package/src/tools/code-search.test.ts +203 -0
- package/src/tools/delegate-task/category-resolver.ts +18 -0
- package/src/tools/delegate-task/constants.ts +43 -0
- package/src/tools/delegate-task/delegate-task.test.ts +245 -0
- package/src/tools/delegate-task/executor.ts +157 -0
- package/src/tools/delegate-task/handler.ts +74 -0
- package/src/tools/delegate-task/index.ts +7 -0
- package/src/tools/delegate-task/plugin.ts +21 -0
- package/src/tools/delegate-task/types.ts +19 -0
- package/src/tools/glob/handler.test.ts +80 -0
- package/src/tools/glob/handler.ts +74 -0
- package/src/tools/glob/index.ts +2 -0
- package/src/tools/glob/plugin.ts +10 -0
- package/src/tools/glob/types.ts +14 -0
- package/src/tools/grep/handler.test.ts +79 -0
- package/src/tools/grep/handler.ts +104 -0
- package/src/tools/grep/index.ts +2 -0
- package/src/tools/grep/plugin.ts +10 -0
- package/src/tools/grep/types.ts +28 -0
- package/src/tools/hashline-edit/constants.ts +10 -0
- package/src/tools/hashline-edit/edit-operations.ts +115 -0
- package/src/tools/hashline-edit/handler.test.ts +105 -0
- package/src/tools/hashline-edit/handler.ts +33 -0
- package/src/tools/hashline-edit/hash-computation.ts +20 -0
- package/src/tools/hashline-edit/hashline-edit.test.ts +62 -0
- package/src/tools/hashline-edit/index.ts +5 -0
- package/src/tools/hashline-edit/plugin.ts +28 -0
- package/src/tools/hashline-edit/types.ts +42 -0
- package/src/tools/index.ts +4 -0
- package/src/tools/look-at/handler.test.ts +189 -0
- package/src/tools/look-at/handler.ts +232 -0
- package/src/tools/look-at/index.ts +3 -0
- package/src/tools/look-at/look-at.test.ts +200 -0
- package/src/tools/look-at/plugin.ts +10 -0
- package/src/tools/look-at/types.ts +17 -0
- package/src/tools/lsp/client.ts +145 -0
- package/src/tools/lsp/diagnostics/handler.test.ts +94 -0
- package/src/tools/lsp/diagnostics/handler.ts +39 -0
- package/src/tools/lsp/diagnostics/plugin.ts +10 -0
- package/src/tools/lsp/diagnostics/types.ts +15 -0
- package/src/tools/lsp/find-references/handler.test.ts +79 -0
- package/src/tools/lsp/find-references/handler.ts +38 -0
- package/src/tools/lsp/find-references/plugin.ts +10 -0
- package/src/tools/lsp/find-references/types.ts +10 -0
- package/src/tools/lsp/goto-definition/handler.test.ts +80 -0
- package/src/tools/lsp/goto-definition/handler.ts +38 -0
- package/src/tools/lsp/goto-definition/plugin.ts +10 -0
- package/src/tools/lsp/goto-definition/types.ts +9 -0
- package/src/tools/lsp/index.ts +6 -0
- package/src/tools/lsp/lsp-tools.test.ts +150 -0
- package/src/tools/lsp/prepare-rename/handler.test.ts +81 -0
- package/src/tools/lsp/prepare-rename/handler.ts +34 -0
- package/src/tools/lsp/prepare-rename/plugin.ts +10 -0
- package/src/tools/lsp/prepare-rename/types.ts +9 -0
- package/src/tools/lsp/rename/handler.test.ts +87 -0
- package/src/tools/lsp/rename/handler.ts +34 -0
- package/src/tools/lsp/rename/plugin.ts +10 -0
- package/src/tools/lsp/rename/types.ts +10 -0
- package/src/tools/lsp/symbols/handler.test.ts +108 -0
- package/src/tools/lsp/symbols/handler.ts +43 -0
- package/src/tools/lsp/symbols/plugin.ts +10 -0
- package/src/tools/lsp/symbols/types.ts +13 -0
- package/src/tools/session-manager/client-context.ts +16 -0
- package/src/tools/session-manager/index.ts +5 -0
- package/src/tools/session-manager/info/handler.test.ts +100 -0
- package/src/tools/session-manager/info/handler.ts +27 -0
- package/src/tools/session-manager/info/plugin.ts +40 -0
- package/src/tools/session-manager/info/types.ts +3 -0
- package/src/tools/session-manager/list/handler.test.ts +122 -0
- package/src/tools/session-manager/list/handler.ts +56 -0
- package/src/tools/session-manager/list/plugin.ts +52 -0
- package/src/tools/session-manager/list/types.ts +6 -0
- package/src/tools/session-manager/read/handler.test.ts +114 -0
- package/src/tools/session-manager/read/handler.ts +36 -0
- package/src/tools/session-manager/read/plugin.ts +57 -0
- package/src/tools/session-manager/read/types.ts +6 -0
- package/src/tools/session-manager/search/handler.test.ts +115 -0
- package/src/tools/session-manager/search/handler.ts +72 -0
- package/src/tools/session-manager/search/plugin.ts +57 -0
- package/src/tools/session-manager/search/types.ts +6 -0
- package/src/tools/session-manager/session-formatter.ts +315 -0
- package/src/tools/session-manager/session-manager.test.ts +254 -0
- package/src/tools/session-manager/types.ts +41 -0
- package/src/tools/shared/constants.ts +3 -0
- package/src/tools/skill/handler.test.ts +57 -0
- package/src/tools/skill/handler.ts +27 -0
- package/src/tools/skill/index.ts +3 -0
- package/src/tools/skill/plugin.ts +41 -0
- package/src/tools/skill/types.ts +14 -0
- package/src/tools/skill-mcp/handler.test.ts +68 -0
- package/src/tools/skill-mcp/handler.ts +84 -0
- package/src/tools/skill-mcp/index.ts +3 -0
- package/src/tools/skill-mcp/plugin.ts +37 -0
- package/src/tools/skill-mcp/types.ts +15 -0
- package/src/tools/skill-tools.test.ts +172 -0
- package/src/tools/task/create/handler.test.ts +64 -0
- package/src/tools/task/create/handler.ts +43 -0
- package/src/tools/task/create/plugin.ts +10 -0
- package/src/tools/task/format-task.test.ts +37 -0
- package/src/tools/task/format-task.ts +19 -0
- package/src/tools/task/get/handler.test.ts +76 -0
- package/src/tools/task/get/handler.ts +35 -0
- package/src/tools/task/get/plugin.ts +10 -0
- package/src/tools/task/index.ts +4 -0
- package/src/tools/task/list/handler.test.ts +70 -0
- package/src/tools/task/list/handler.ts +48 -0
- package/src/tools/task/list/plugin.ts +10 -0
- package/src/tools/task/storage.ts +14 -0
- package/src/tools/task/task.test.ts +165 -0
- package/src/tools/task/types.ts +51 -0
- package/src/tools/task/update/handler.test.ts +86 -0
- package/src/tools/task/update/handler.ts +54 -0
- package/src/tools/task/update/plugin.ts +10 -0
- package/src/tools/tool-builder.test.ts +32 -0
- package/src/tools/tool-builder.ts +24 -0
- package/src/tools/tool-registry-adapter.test.ts +51 -0
- package/src/tools/tool-registry-adapter.ts +19 -0
- package/src/types/agent.ts +53 -0
- package/src/types/category.ts +32 -0
- package/src/types/config.ts +26 -0
- package/src/types/hook.ts +44 -0
- package/src/types/index.ts +12 -0
- package/src/types/plugin.ts +47 -0
- package/src/types/tool.ts +10 -0
- package/test-setup.ts +8 -0
- package/tsconfig.json +20 -0
- /package/{index.js → npm-reserve/index.js} +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { createDelegateRetryHandler, detectDelegateTaskError, buildRetryGuidance } from "./handler";
|
|
4
|
+
|
|
5
|
+
describe("createDelegateRetryHandler", () => {
|
|
6
|
+
describe("#given a task tool with an error output", () => {
|
|
7
|
+
describe("#when the output contains [ERROR] and run_in_background pattern", () => {
|
|
8
|
+
it("#then injects retry guidance with the correct error type", async () => {
|
|
9
|
+
const handler = createDelegateRetryHandler();
|
|
10
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
11
|
+
const output = {
|
|
12
|
+
title: "task",
|
|
13
|
+
output: "[ERROR] Invalid arguments: run_in_background is required",
|
|
14
|
+
metadata: {},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
await handler(input, output);
|
|
18
|
+
|
|
19
|
+
expect(output.output).toContain("[task CALL FAILED - IMMEDIATE RETRY REQUIRED]");
|
|
20
|
+
expect(output.output).toContain("missing_run_in_background");
|
|
21
|
+
expect(output.output).toContain("Action");
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("#when the output contains Invalid arguments with Unknown agent", () => {
|
|
26
|
+
it("#then injects guidance for unknown_agent error", async () => {
|
|
27
|
+
const handler = createDelegateRetryHandler();
|
|
28
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
29
|
+
const output = {
|
|
30
|
+
title: "task",
|
|
31
|
+
output: "Invalid arguments: Unknown agent 'badagent'. Available agents: explore, oracle",
|
|
32
|
+
metadata: {},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
await handler(input, output);
|
|
36
|
+
|
|
37
|
+
expect(output.output).toContain("unknown_agent");
|
|
38
|
+
expect(output.output).toContain("Available Options");
|
|
39
|
+
expect(output.output).toContain("explore, oracle");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe("#when the output contains Cannot call primary agent", () => {
|
|
44
|
+
it("#then injects guidance for primary_agent error", async () => {
|
|
45
|
+
const handler = createDelegateRetryHandler();
|
|
46
|
+
const input = { tool: "Task", sessionID: "s1", callID: "c1", args: {} };
|
|
47
|
+
const output = {
|
|
48
|
+
title: "task",
|
|
49
|
+
output: "[ERROR] Cannot call primary agent directly.",
|
|
50
|
+
metadata: {},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
await handler(input, output);
|
|
54
|
+
|
|
55
|
+
expect(output.output).toContain("primary_agent");
|
|
56
|
+
expect(output.output).toContain("subagent");
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("#given a task tool with a successful output", () => {
|
|
62
|
+
describe("#when the output has no error markers", () => {
|
|
63
|
+
it("#then does not modify the output", async () => {
|
|
64
|
+
const handler = createDelegateRetryHandler();
|
|
65
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
66
|
+
const original = "Agent completed the work successfully. Session ID: ses_abc";
|
|
67
|
+
const output = { title: "task", output: original, metadata: {} };
|
|
68
|
+
|
|
69
|
+
await handler(input, output);
|
|
70
|
+
|
|
71
|
+
expect(output.output).toBe(original);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe("#given a task tool with output that has no string output field", () => {
|
|
77
|
+
describe("#when output.output is undefined", () => {
|
|
78
|
+
it("#then does not modify the output", async () => {
|
|
79
|
+
const handler = createDelegateRetryHandler();
|
|
80
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
81
|
+
const output = { title: "task", output: undefined as unknown as string, metadata: {} };
|
|
82
|
+
|
|
83
|
+
await handler(input, output);
|
|
84
|
+
|
|
85
|
+
expect(output.output).toBeUndefined();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("#given a task tool with case-insensitive matching", () => {
|
|
91
|
+
describe("#when the tool name is TASK in uppercase", () => {
|
|
92
|
+
it("#then still detects the error and injects guidance", async () => {
|
|
93
|
+
const handler = createDelegateRetryHandler();
|
|
94
|
+
const input = { tool: "TASK", sessionID: "s1", callID: "c1", args: {} };
|
|
95
|
+
const output = {
|
|
96
|
+
title: "task",
|
|
97
|
+
output: "[ERROR] Agent name cannot be empty",
|
|
98
|
+
metadata: {},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
await handler(input, output);
|
|
102
|
+
|
|
103
|
+
expect(output.output).toContain("empty_agent");
|
|
104
|
+
expect(output.output).toContain("[task CALL FAILED - IMMEDIATE RETRY REQUIRED]");
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe("#given a non-task tool", () => {
|
|
110
|
+
describe("#when the tool is Bash with error markers in output", () => {
|
|
111
|
+
it("#then does not inject guidance", async () => {
|
|
112
|
+
const handler = createDelegateRetryHandler();
|
|
113
|
+
const input = { tool: "Bash", sessionID: "s1", callID: "c1", args: {} };
|
|
114
|
+
const original = "[ERROR] Invalid arguments: run_in_background is required";
|
|
115
|
+
const output = { title: "Bash", output: original, metadata: {} };
|
|
116
|
+
|
|
117
|
+
await handler(input, output);
|
|
118
|
+
|
|
119
|
+
expect(output.output).toBe(original);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe("detectDelegateTaskError", () => {
|
|
126
|
+
describe("#given output with [ERROR] and a known pattern", () => {
|
|
127
|
+
describe("#when output matches load_skills pattern", () => {
|
|
128
|
+
it("#then returns missing_load_skills error", () => {
|
|
129
|
+
const result = detectDelegateTaskError(
|
|
130
|
+
"[ERROR] Invalid arguments: load_skills parameter is missing",
|
|
131
|
+
);
|
|
132
|
+
expect(result).not.toBeNull();
|
|
133
|
+
expect(result?.errorType).toBe("missing_load_skills");
|
|
134
|
+
expect(result?.originalOutput).toContain("load_skills");
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe("#when output matches Skills not found pattern", () => {
|
|
139
|
+
it("#then returns unknown_skills error", () => {
|
|
140
|
+
const result = detectDelegateTaskError(
|
|
141
|
+
"[ERROR] Skills not found: badskill. Available skills: git-master",
|
|
142
|
+
);
|
|
143
|
+
expect(result).not.toBeNull();
|
|
144
|
+
expect(result?.errorType).toBe("unknown_skills");
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
describe("#given output with [ERROR] but no known pattern", () => {
|
|
150
|
+
describe("#when the error text does not match any pattern", () => {
|
|
151
|
+
it("#then returns null", () => {
|
|
152
|
+
const result = detectDelegateTaskError("[ERROR] Some completely unknown error occurred");
|
|
153
|
+
expect(result).toBeNull();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe("#given output without any error markers", () => {
|
|
159
|
+
describe("#when output is a success message", () => {
|
|
160
|
+
it("#then returns null", () => {
|
|
161
|
+
const result = detectDelegateTaskError("All tasks completed.");
|
|
162
|
+
expect(result).toBeNull();
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe("buildRetryGuidance", () => {
|
|
169
|
+
describe("#given a detected error with Available list in output", () => {
|
|
170
|
+
describe("#when the original output contains Available categories", () => {
|
|
171
|
+
it("#then includes the available options in guidance", () => {
|
|
172
|
+
const guidance = buildRetryGuidance({
|
|
173
|
+
errorType: "unknown_category",
|
|
174
|
+
originalOutput:
|
|
175
|
+
"[ERROR] Unknown category: foo. Available categories: general, quick, visual-engineering",
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
expect(guidance).toContain("Available Options");
|
|
179
|
+
expect(guidance).toContain("general, quick, visual-engineering");
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe("#given a detected error without Available list", () => {
|
|
185
|
+
describe("#when the original output has no Available section", () => {
|
|
186
|
+
it("#then returns guidance without Available Options", () => {
|
|
187
|
+
const guidance = buildRetryGuidance({
|
|
188
|
+
errorType: "missing_run_in_background",
|
|
189
|
+
originalOutput: "[ERROR] run_in_background is required",
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
expect(guidance).toContain("missing_run_in_background");
|
|
193
|
+
expect(guidance).toContain("IMMEDIATE RETRY REQUIRED");
|
|
194
|
+
expect(guidance).not.toContain("Available Options");
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe("#given an unrecognized error type", () => {
|
|
200
|
+
describe("#when errorType is not in DELEGATE_TASK_ERROR_PATTERNS", () => {
|
|
201
|
+
it("#then returns generic fallback guidance", () => {
|
|
202
|
+
const guidance = buildRetryGuidance({
|
|
203
|
+
errorType: "totally_made_up_error",
|
|
204
|
+
originalOutput: "[ERROR] something",
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
expect(guidance).toContain("[task ERROR]");
|
|
208
|
+
expect(guidance).toContain("Fix the error");
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { PluginHookContributions } from "../../types/hook";
|
|
2
|
+
import { log } from "../../shared/logger";
|
|
3
|
+
|
|
4
|
+
type PostToolUseHook = NonNullable<PluginHookContributions["tool.execute.after"]>;
|
|
5
|
+
|
|
6
|
+
export interface DelegateTaskErrorPattern {
|
|
7
|
+
pattern: string;
|
|
8
|
+
errorType: string;
|
|
9
|
+
fixHint: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const DELEGATE_TASK_ERROR_PATTERNS: DelegateTaskErrorPattern[] = [
|
|
13
|
+
{
|
|
14
|
+
pattern: "run_in_background",
|
|
15
|
+
errorType: "missing_run_in_background",
|
|
16
|
+
fixHint:
|
|
17
|
+
"Add run_in_background=false (for delegation) or run_in_background=true (for parallel exploration)",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
pattern: "load_skills",
|
|
21
|
+
errorType: "missing_load_skills",
|
|
22
|
+
fixHint:
|
|
23
|
+
"Add load_skills=[] parameter (empty array if no skills needed). Note: Calling Skill tool does NOT populate this.",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
pattern: "category OR subagent_type",
|
|
27
|
+
errorType: "mutual_exclusion",
|
|
28
|
+
fixHint:
|
|
29
|
+
"Provide ONLY one of: category (e.g., 'general', 'quick') OR subagent_type (e.g., 'oracle', 'explore')",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
pattern: "Must provide either category or subagent_type",
|
|
33
|
+
errorType: "missing_category_or_agent",
|
|
34
|
+
fixHint: "Add either category='general' OR subagent_type='explore'",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pattern: "Unknown category",
|
|
38
|
+
errorType: "unknown_category",
|
|
39
|
+
fixHint: "Use a valid category from the Available list in the error message",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
pattern: "Agent name cannot be empty",
|
|
43
|
+
errorType: "empty_agent",
|
|
44
|
+
fixHint: "Provide a non-empty subagent_type value",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
pattern: "Unknown agent",
|
|
48
|
+
errorType: "unknown_agent",
|
|
49
|
+
fixHint: "Use a valid agent from the Available agents list in the error message",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
pattern: "Cannot call primary agent",
|
|
53
|
+
errorType: "primary_agent",
|
|
54
|
+
fixHint:
|
|
55
|
+
"Primary agents cannot be called via task. Use a subagent like 'explore', 'oracle', or 'librarian'",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
pattern: "Skills not found",
|
|
59
|
+
errorType: "unknown_skills",
|
|
60
|
+
fixHint: "Use valid skill names from the Available list in the error message",
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
export interface DetectedError {
|
|
65
|
+
errorType: string;
|
|
66
|
+
originalOutput: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function detectDelegateTaskError(output: string): DetectedError | null {
|
|
70
|
+
if (!output.includes("[ERROR]") && !output.includes("Invalid arguments")) return null;
|
|
71
|
+
|
|
72
|
+
for (const errorPattern of DELEGATE_TASK_ERROR_PATTERNS) {
|
|
73
|
+
if (output.includes(errorPattern.pattern)) {
|
|
74
|
+
return {
|
|
75
|
+
errorType: errorPattern.errorType,
|
|
76
|
+
originalOutput: output,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function extractAvailableList(output: string): string | null {
|
|
85
|
+
const availableMatch = output.match(/Available[^:]*:\s*(.+)$/m);
|
|
86
|
+
return availableMatch ? (availableMatch[1]?.trim() ?? null) : null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function buildRetryGuidance(errorInfo: DetectedError): string {
|
|
90
|
+
const pattern = DELEGATE_TASK_ERROR_PATTERNS.find((p) => p.errorType === errorInfo.errorType);
|
|
91
|
+
|
|
92
|
+
if (!pattern) {
|
|
93
|
+
return `[task ERROR] Fix the error and retry with correct parameters.`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let guidance = `\n[task CALL FAILED - IMMEDIATE RETRY REQUIRED]\n\n**Error Type**: ${errorInfo.errorType}\n**Fix**: ${pattern.fixHint}\n`;
|
|
97
|
+
|
|
98
|
+
const availableList = extractAvailableList(errorInfo.originalOutput);
|
|
99
|
+
if (availableList) {
|
|
100
|
+
guidance += `\n**Available Options**: ${availableList}\n`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
guidance += `\n**Action**: Retry task NOW with corrected parameters.\n`;
|
|
104
|
+
|
|
105
|
+
return guidance;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
109
|
+
return typeof value === "object" && value !== null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function createDelegateRetryHandler(): PostToolUseHook {
|
|
113
|
+
return async (input: unknown, output: unknown) => {
|
|
114
|
+
if (!isRecord(input) || !isRecord(output)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const tool = input.tool;
|
|
119
|
+
if (typeof tool !== "string" || tool.toLowerCase() !== "task") {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const toolOutput = output.output;
|
|
124
|
+
if (typeof toolOutput !== "string") {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const errorInfo = detectDelegateTaskError(toolOutput);
|
|
129
|
+
if (!errorInfo) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const guidance = buildRetryGuidance(errorInfo);
|
|
134
|
+
output.output = `${toolOutput}\n${guidance}`;
|
|
135
|
+
log("[delegate-retry] injected retry guidance", { errorType: errorInfo.errorType });
|
|
136
|
+
};
|
|
137
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { delegateRetryPlugin } from "./plugin";
|
|
2
|
+
export {
|
|
3
|
+
createDelegateRetryHandler,
|
|
4
|
+
detectDelegateTaskError,
|
|
5
|
+
buildRetryGuidance,
|
|
6
|
+
DELEGATE_TASK_ERROR_PATTERNS,
|
|
7
|
+
} from "./handler";
|
|
8
|
+
export type { DelegateTaskErrorPattern, DetectedError } from "./handler";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { definePlugin } from "../../plugin-api/define-plugin";
|
|
2
|
+
import { safeCreateHook } from "../../shared/safe-create-hook";
|
|
3
|
+
import { createDelegateRetryHandler } from "./handler";
|
|
4
|
+
|
|
5
|
+
const toolExecuteAfterHook = safeCreateHook("delegate-retry", createDelegateRetryHandler);
|
|
6
|
+
|
|
7
|
+
export const delegateRetryPlugin = definePlugin({
|
|
8
|
+
name: "delegate-retry",
|
|
9
|
+
version: "0.1.0",
|
|
10
|
+
hooks: toolExecuteAfterHook
|
|
11
|
+
? {
|
|
12
|
+
"tool.execute.after": toolExecuteAfterHook,
|
|
13
|
+
}
|
|
14
|
+
: {},
|
|
15
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { createEditErrorHandler, EDIT_ERROR_RECOVERY_MESSAGE } from "./handler";
|
|
4
|
+
|
|
5
|
+
type UnknownHandler = (input: unknown, output: unknown) => Promise<void>;
|
|
6
|
+
|
|
7
|
+
describe("createEditErrorHandler", () => {
|
|
8
|
+
describe("#given a handler instance", () => {
|
|
9
|
+
const handler = createEditErrorHandler() as unknown as UnknownHandler;
|
|
10
|
+
|
|
11
|
+
describe("#when input.tool is 'edit' and output contains 'oldString not found'", () => {
|
|
12
|
+
it("#then appends EDIT_ERROR_RECOVERY_MESSAGE to output.output", async () => {
|
|
13
|
+
const input = { tool: "edit" };
|
|
14
|
+
const output = { output: "oldString not found in file" };
|
|
15
|
+
await handler(input, output);
|
|
16
|
+
expect(output.output).toContain("[EDIT ERROR RECOVERY]");
|
|
17
|
+
expect(output.output).toBe(`oldString not found in file\n${EDIT_ERROR_RECOVERY_MESSAGE}`);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe("#when input.tool is 'edit' and output contains 'oldString found multiple times'", () => {
|
|
22
|
+
it("#then appends EDIT_ERROR_RECOVERY_MESSAGE", async () => {
|
|
23
|
+
const input = { tool: "edit" };
|
|
24
|
+
const output = { output: "oldString found multiple times in file content" };
|
|
25
|
+
await handler(input, output);
|
|
26
|
+
expect(output.output).toContain("[EDIT ERROR RECOVERY]");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("#when input.tool is not 'edit'", () => {
|
|
31
|
+
it("#then output.output remains unchanged", async () => {
|
|
32
|
+
const input = { tool: "bash" };
|
|
33
|
+
const output = { output: "oldString not found in file" };
|
|
34
|
+
await handler(input, output);
|
|
35
|
+
expect(output.output).toBe("oldString not found in file");
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("#when output already contains recovery marker", () => {
|
|
40
|
+
it("#then does not double-append", async () => {
|
|
41
|
+
const input = { tool: "edit" };
|
|
42
|
+
const output = {
|
|
43
|
+
output: `oldString not found in file\n${EDIT_ERROR_RECOVERY_MESSAGE}`,
|
|
44
|
+
};
|
|
45
|
+
const before = output.output;
|
|
46
|
+
await handler(input, output);
|
|
47
|
+
expect(output.output).toBe(before);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("#when output.output is not a string", () => {
|
|
52
|
+
it("#then no-op", async () => {
|
|
53
|
+
const input = { tool: "edit" };
|
|
54
|
+
const output = { output: 42 };
|
|
55
|
+
await handler(input, output);
|
|
56
|
+
expect(output.output).toBe(42);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe("#when input or output is not a record", () => {
|
|
61
|
+
it("#then no-op for non-object input", async () => {
|
|
62
|
+
const output = { output: "oldString not found" };
|
|
63
|
+
await handler(null, output);
|
|
64
|
+
expect(output.output).toBe("oldString not found");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("#then no-op for non-object output", async () => {
|
|
68
|
+
const input = { tool: "edit" };
|
|
69
|
+
await handler(input, "not-an-object");
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe("#when input.tool is 'Edit' (case-insensitive)", () => {
|
|
74
|
+
it("#then still triggers recovery", async () => {
|
|
75
|
+
const input = { tool: "Edit" };
|
|
76
|
+
const output = { output: "oldString not found in file" };
|
|
77
|
+
await handler(input, output);
|
|
78
|
+
expect(output.output).toContain("[EDIT ERROR RECOVERY]");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { PluginHookContributions } from "../../types/hook";
|
|
2
|
+
import { log } from "../../shared/logger";
|
|
3
|
+
|
|
4
|
+
export const EDIT_ERROR_PATTERNS = [
|
|
5
|
+
/oldstring and newstring must be different/i,
|
|
6
|
+
/oldstring not found/i,
|
|
7
|
+
/oldstring found multiple times/i,
|
|
8
|
+
/string to replace not found/i,
|
|
9
|
+
] as const;
|
|
10
|
+
|
|
11
|
+
const EDIT_ERROR_RECOVERY_MARKER = "[EDIT ERROR RECOVERY]";
|
|
12
|
+
|
|
13
|
+
export const EDIT_ERROR_RECOVERY_MESSAGE = `${EDIT_ERROR_RECOVERY_MARKER}\nEdit failed because the target text did not match the current file state. Re-read the file, copy the exact current content, and retry the edit with an unambiguous oldString.`;
|
|
14
|
+
|
|
15
|
+
type PostToolUseHook = NonNullable<PluginHookContributions["tool.execute.after"]>;
|
|
16
|
+
|
|
17
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
18
|
+
return typeof value === "object" && value !== null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createEditErrorHandler(): PostToolUseHook {
|
|
22
|
+
return async (input: unknown, output: unknown) => {
|
|
23
|
+
if (!isRecord(input) || !isRecord(output)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const tool = input.tool;
|
|
28
|
+
const toolOutput = output.output;
|
|
29
|
+
|
|
30
|
+
if (typeof tool !== "string" || tool.toLowerCase() !== "edit") {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (typeof toolOutput !== "string") {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (toolOutput.includes(EDIT_ERROR_RECOVERY_MARKER)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const hasEditError = EDIT_ERROR_PATTERNS.some((pattern) => pattern.test(toolOutput));
|
|
43
|
+
if (!hasEditError) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
output.output = `${toolOutput}\n${EDIT_ERROR_RECOVERY_MESSAGE}`;
|
|
48
|
+
log("[edit-error] injected edit recovery message");
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { definePlugin } from "../../plugin-api/define-plugin";
|
|
2
|
+
import { safeCreateHook } from "../../shared/safe-create-hook";
|
|
3
|
+
import { createEditErrorHandler } from "./handler";
|
|
4
|
+
|
|
5
|
+
const toolExecuteAfterHook = safeCreateHook("edit-error", createEditErrorHandler);
|
|
6
|
+
|
|
7
|
+
export const editErrorPlugin = definePlugin({
|
|
8
|
+
name: "edit-error",
|
|
9
|
+
version: "0.1.0",
|
|
10
|
+
hooks: toolExecuteAfterHook
|
|
11
|
+
? {
|
|
12
|
+
"tool.execute.after": toolExecuteAfterHook,
|
|
13
|
+
}
|
|
14
|
+
: {},
|
|
15
|
+
});
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { createEmptyResponseDetectorHandler, EMPTY_RESPONSE_WARNING } from "./handler";
|
|
4
|
+
|
|
5
|
+
describe("createEmptyResponseDetectorHandler", () => {
|
|
6
|
+
describe("#given a task tool with empty output", () => {
|
|
7
|
+
describe("#when the output string is empty", () => {
|
|
8
|
+
it("#then replaces output with the warning message", async () => {
|
|
9
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
10
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
11
|
+
const output = { title: "task", output: "", metadata: {} };
|
|
12
|
+
|
|
13
|
+
await handler(input, output);
|
|
14
|
+
|
|
15
|
+
expect(output.output).toBe(EMPTY_RESPONSE_WARNING);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe("#given a task tool with near-empty output", () => {
|
|
21
|
+
describe("#when the output is under the threshold length", () => {
|
|
22
|
+
it("#then replaces output with the warning message", async () => {
|
|
23
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
24
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
25
|
+
const output = { title: "task", output: "short", metadata: {} };
|
|
26
|
+
|
|
27
|
+
await handler(input, output);
|
|
28
|
+
|
|
29
|
+
expect(output.output).toBe(EMPTY_RESPONSE_WARNING);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("#given a task tool with whitespace-only output", () => {
|
|
35
|
+
describe("#when the output is tabs and spaces", () => {
|
|
36
|
+
it("#then replaces output with the warning message", async () => {
|
|
37
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
38
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
39
|
+
const output = { title: "task", output: " \t\t ", metadata: {} };
|
|
40
|
+
|
|
41
|
+
await handler(input, output);
|
|
42
|
+
|
|
43
|
+
expect(output.output).toBe(EMPTY_RESPONSE_WARNING);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("#given a task tool with null output", () => {
|
|
49
|
+
describe("#when output.output is null", () => {
|
|
50
|
+
it("#then sets output to the warning message", async () => {
|
|
51
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
52
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
53
|
+
const output = { title: "task", output: null as unknown as string, metadata: {} };
|
|
54
|
+
|
|
55
|
+
await handler(input, output);
|
|
56
|
+
|
|
57
|
+
expect(output.output).toBe(EMPTY_RESPONSE_WARNING);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("#given a task tool with undefined output", () => {
|
|
63
|
+
describe("#when output.output is undefined", () => {
|
|
64
|
+
it("#then sets output to the warning message", async () => {
|
|
65
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
66
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
67
|
+
const output = { title: "task", output: undefined as unknown as string, metadata: {} };
|
|
68
|
+
|
|
69
|
+
await handler(input, output);
|
|
70
|
+
|
|
71
|
+
expect(output.output).toBe(EMPTY_RESPONSE_WARNING);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe("#given a task tool with meaningful content", () => {
|
|
77
|
+
describe("#when the output has substantial text", () => {
|
|
78
|
+
it("#then does not modify the output", async () => {
|
|
79
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
80
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
81
|
+
const original = "The agent completed all requested changes to the codebase.";
|
|
82
|
+
const output = { title: "task", output: original, metadata: {} };
|
|
83
|
+
|
|
84
|
+
await handler(input, output);
|
|
85
|
+
|
|
86
|
+
expect(output.output).toBe(original);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe("#given a task tool with output already containing the marker", () => {
|
|
92
|
+
describe("#when the output has EMPTY_RESPONSE_WARNING already", () => {
|
|
93
|
+
it("#then does not double-inject the warning", async () => {
|
|
94
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
95
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
96
|
+
const output = { title: "task", output: EMPTY_RESPONSE_WARNING, metadata: {} };
|
|
97
|
+
|
|
98
|
+
await handler(input, output);
|
|
99
|
+
|
|
100
|
+
expect(output.output).toBe(EMPTY_RESPONSE_WARNING);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe("#given a non-task tool", () => {
|
|
106
|
+
describe("#when the tool is Bash with empty output", () => {
|
|
107
|
+
it("#then does not modify the output", async () => {
|
|
108
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
109
|
+
const input = { tool: "Bash", sessionID: "s1", callID: "c1", args: {} };
|
|
110
|
+
const output = { title: "Bash", output: "", metadata: {} };
|
|
111
|
+
|
|
112
|
+
await handler(input, output);
|
|
113
|
+
|
|
114
|
+
expect(output.output).toBe("");
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("#given a task tool with output exactly at threshold boundary", () => {
|
|
120
|
+
describe("#when the trimmed output is exactly 10 characters", () => {
|
|
121
|
+
it("#then does not replace the output", async () => {
|
|
122
|
+
const handler = createEmptyResponseDetectorHandler();
|
|
123
|
+
const input = { tool: "task", sessionID: "s1", callID: "c1", args: {} };
|
|
124
|
+
const original = "1234567890";
|
|
125
|
+
const output = { title: "task", output: original, metadata: {} };
|
|
126
|
+
|
|
127
|
+
await handler(input, output);
|
|
128
|
+
|
|
129
|
+
expect(output.output).toBe(original);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
});
|