goatcode-sh 0.0.1 → 0.1.3
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 +6 -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 +8623 -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 +4 -0
- package/dist/tools/delegate-task/index.d.ts +7 -0
- package/dist/tools/delegate-task/plugin.d.ts +4 -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 +166 -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 +140 -0
- package/src/hooks/context-injector/handlers/agents.ts +101 -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 +159 -0
- package/src/hooks/post-read-nudge/handler.ts +64 -0
- package/src/hooks/post-read-nudge/index.ts +6 -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 +107 -0
- package/src/tools/delegate-task/index.ts +7 -0
- package/src/tools/delegate-task/plugin.ts +30 -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,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
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { PluginHookContributions } from "../../types/hook";
|
|
2
|
+
import { log } from "../../shared/logger";
|
|
3
|
+
|
|
4
|
+
type PostToolUseHook = NonNullable<PluginHookContributions["tool.execute.after"]>;
|
|
5
|
+
|
|
6
|
+
const EMPTY_RESPONSE_MARKER = "[EMPTY RESPONSE WARNING]";
|
|
7
|
+
|
|
8
|
+
export const EMPTY_RESPONSE_WARNING = `${EMPTY_RESPONSE_MARKER}
|
|
9
|
+
Task invocation completed but returned no response. This indicates the agent either:
|
|
10
|
+
- Failed to execute properly
|
|
11
|
+
- Did not terminate correctly
|
|
12
|
+
- Returned an empty result
|
|
13
|
+
|
|
14
|
+
Note: The call has already completed - you are NOT waiting for a response. Proceed accordingly.`;
|
|
15
|
+
|
|
16
|
+
const NEAR_EMPTY_THRESHOLD = 10;
|
|
17
|
+
|
|
18
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
19
|
+
return typeof value === "object" && value !== null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isTaskTool(tool: string): boolean {
|
|
23
|
+
return tool.toLowerCase() === "task";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isEmptyOrNearEmpty(text: string): boolean {
|
|
27
|
+
const trimmed = text.trim();
|
|
28
|
+
return trimmed.length === 0 || trimmed.length < NEAR_EMPTY_THRESHOLD;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createEmptyResponseDetectorHandler(): PostToolUseHook {
|
|
32
|
+
return async (input: unknown, output: unknown) => {
|
|
33
|
+
if (!isRecord(input) || !isRecord(output)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const tool = input.tool;
|
|
38
|
+
if (typeof tool !== "string" || !isTaskTool(tool)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const toolOutput = output.output;
|
|
43
|
+
if (typeof toolOutput !== "string") {
|
|
44
|
+
if (toolOutput === undefined || toolOutput === null) {
|
|
45
|
+
output.output = EMPTY_RESPONSE_WARNING;
|
|
46
|
+
log("[empty-response-detector] injected warning for undefined/null output");
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (toolOutput.includes(EMPTY_RESPONSE_MARKER)) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!isEmptyOrNearEmpty(toolOutput)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
output.output = EMPTY_RESPONSE_WARNING;
|
|
60
|
+
log("[empty-response-detector] injected warning for empty/near-empty output");
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { definePlugin } from "../../plugin-api/define-plugin";
|
|
2
|
+
import { safeCreateHook } from "../../shared/safe-create-hook";
|
|
3
|
+
import { createEmptyResponseDetectorHandler } from "./handler";
|
|
4
|
+
|
|
5
|
+
const toolExecuteAfterHook = safeCreateHook(
|
|
6
|
+
"empty-response-detector",
|
|
7
|
+
createEmptyResponseDetectorHandler,
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export const emptyResponseDetectorPlugin = definePlugin({
|
|
11
|
+
name: "empty-response-detector",
|
|
12
|
+
version: "0.1.0",
|
|
13
|
+
hooks: toolExecuteAfterHook
|
|
14
|
+
? {
|
|
15
|
+
"tool.execute.after": toolExecuteAfterHook,
|
|
16
|
+
}
|
|
17
|
+
: {},
|
|
18
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { createEventErrorHandler, createToolErrorHandler } from "./handler";
|
|
4
|
+
import { matchDiagnostic } from "./patterns";
|
|
5
|
+
import type { ErrorCategory } from "./types";
|
|
6
|
+
|
|
7
|
+
describe("error-diagnostics", () => {
|
|
8
|
+
describe("matchDiagnostic", () => {
|
|
9
|
+
it("matches each category", () => {
|
|
10
|
+
const cases: Array<{ input: string; category: ErrorCategory }> = [
|
|
11
|
+
{ input: "Error 429: too many requests", category: "rate-limit" },
|
|
12
|
+
{ input: "authentication failed with invalid API key", category: "auth" },
|
|
13
|
+
{ input: "request ETIMEDOUT after 30000ms", category: "timeout" },
|
|
14
|
+
{ input: "EACCES: permission denied, open '/tmp/file'", category: "permission" },
|
|
15
|
+
{ input: "ENOENT: no such file or directory", category: "file-system" },
|
|
16
|
+
{ input: "fetch failed due to ECONNREFUSED", category: "network" },
|
|
17
|
+
{ input: "JavaScript heap out of memory", category: "memory" },
|
|
18
|
+
{ input: "SyntaxError: unexpected token ;", category: "syntax" },
|
|
19
|
+
{ input: "TypeError: value is not a function", category: "type-error" },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
for (const testCase of cases) {
|
|
23
|
+
const result = matchDiagnostic(testCase.input);
|
|
24
|
+
expect(result).not.toBeNull();
|
|
25
|
+
expect(result?.category).toBe(testCase.category);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("returns null for unknown text", () => {
|
|
30
|
+
const result = matchDiagnostic("all operations completed successfully");
|
|
31
|
+
expect(result).toBeNull();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("createToolErrorHandler", () => {
|
|
36
|
+
it("injects diagnostic block into matched tool output", async () => {
|
|
37
|
+
const handler = createToolErrorHandler() as (
|
|
38
|
+
input: unknown,
|
|
39
|
+
output: unknown,
|
|
40
|
+
) => Promise<void> | void;
|
|
41
|
+
const output = { output: "Request failed with 429 too many requests" };
|
|
42
|
+
|
|
43
|
+
await handler({}, output);
|
|
44
|
+
|
|
45
|
+
expect(output.output).toContain("[ERROR DIAGNOSTIC]");
|
|
46
|
+
expect(output.output).toContain("Category: rate-limit");
|
|
47
|
+
expect(output.output).toContain("Severity: warning");
|
|
48
|
+
expect(output.output).toContain("Suggestion:");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("skips non-error output", async () => {
|
|
52
|
+
const handler = createToolErrorHandler() as (
|
|
53
|
+
input: unknown,
|
|
54
|
+
output: unknown,
|
|
55
|
+
) => Promise<void> | void;
|
|
56
|
+
const output = { output: "everything is healthy and complete" };
|
|
57
|
+
|
|
58
|
+
await handler({}, output);
|
|
59
|
+
|
|
60
|
+
expect(output.output).toBe("everything is healthy and complete");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("skips output that already contains diagnostics", async () => {
|
|
64
|
+
const handler = createToolErrorHandler() as (
|
|
65
|
+
input: unknown,
|
|
66
|
+
output: unknown,
|
|
67
|
+
) => Promise<void> | void;
|
|
68
|
+
const output = {
|
|
69
|
+
output:
|
|
70
|
+
"Error 429: too many requests\n[ERROR DIAGNOSTIC]\nCategory: rate-limit\nSeverity: warning\nSuggestion: wait",
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
await handler({}, output);
|
|
74
|
+
|
|
75
|
+
const markerCount = (output.output.match(/\[ERROR DIAGNOSTIC\]/g) ?? []).length;
|
|
76
|
+
expect(markerCount).toBe(1);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe("createEventErrorHandler", () => {
|
|
81
|
+
it("processes session.error and appends recoveryContext diagnostic", async () => {
|
|
82
|
+
const handler = createEventErrorHandler() as (input: unknown) => Promise<void> | void;
|
|
83
|
+
const payload = {
|
|
84
|
+
event: {
|
|
85
|
+
type: "session.error",
|
|
86
|
+
properties: {
|
|
87
|
+
error: "Permission denied while accessing /tmp",
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
await handler(payload);
|
|
93
|
+
|
|
94
|
+
const properties = payload.event.properties as { recoveryContext?: string };
|
|
95
|
+
expect(properties.recoveryContext).toContain("[ERROR DIAGNOSTIC]");
|
|
96
|
+
expect(properties.recoveryContext).toContain("Category: permission");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("ignores non-session.error event types", async () => {
|
|
100
|
+
const handler = createEventErrorHandler() as (input: unknown) => Promise<void> | void;
|
|
101
|
+
const payload = {
|
|
102
|
+
event: {
|
|
103
|
+
type: "session.idle",
|
|
104
|
+
properties: {
|
|
105
|
+
error: "Permission denied while accessing /tmp",
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
await handler(payload);
|
|
111
|
+
|
|
112
|
+
const properties = payload.event.properties as { recoveryContext?: string };
|
|
113
|
+
expect(properties.recoveryContext).toBeUndefined();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { createToolErrorHandler, createEventErrorHandler } from "./handler";
|
|
4
|
+
|
|
5
|
+
type UnknownToolHandler = (input: unknown, output: unknown) => Promise<void>;
|
|
6
|
+
type UnknownEventHandler = (input: unknown) => Promise<void>;
|
|
7
|
+
|
|
8
|
+
describe("createToolErrorHandler", () => {
|
|
9
|
+
describe("#given a handler instance", () => {
|
|
10
|
+
const handler = createToolErrorHandler() as unknown as UnknownToolHandler;
|
|
11
|
+
|
|
12
|
+
describe("#when output contains a known error pattern (rate limit)", () => {
|
|
13
|
+
it("#then appends diagnostic with category, severity, suggestion", async () => {
|
|
14
|
+
const input = {};
|
|
15
|
+
const output = { output: "Error: rate limit exceeded, try again later" };
|
|
16
|
+
await handler(input, output);
|
|
17
|
+
expect(output.output).toContain("[ERROR DIAGNOSTIC]");
|
|
18
|
+
expect(output.output).toContain("Category: rate-limit");
|
|
19
|
+
expect(output.output).toContain("Severity: warning");
|
|
20
|
+
expect(output.output).toContain("Suggestion:");
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("#when output contains a permission error pattern", () => {
|
|
25
|
+
it("#then appends diagnostic with category permission", async () => {
|
|
26
|
+
const input = {};
|
|
27
|
+
const output = { output: "EACCES: permission denied, open '/etc/shadow'" };
|
|
28
|
+
await handler(input, output);
|
|
29
|
+
expect(output.output).toContain("[ERROR DIAGNOSTIC]");
|
|
30
|
+
expect(output.output).toContain("Category: permission");
|
|
31
|
+
expect(output.output).toContain("Severity: error");
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("#when output does not match any error pattern", () => {
|
|
36
|
+
it("#then no-op", async () => {
|
|
37
|
+
const input = {};
|
|
38
|
+
const output = { output: "success: operation completed" };
|
|
39
|
+
await handler(input, output);
|
|
40
|
+
expect(output.output).toBe("success: operation completed");
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("#when output already contains diagnostic marker", () => {
|
|
45
|
+
it("#then does not double-append", async () => {
|
|
46
|
+
const input = {};
|
|
47
|
+
const output = {
|
|
48
|
+
output:
|
|
49
|
+
"rate limit exceeded\n[ERROR DIAGNOSTIC]\nCategory: rate-limit\nSeverity: warning\nSuggestion: Wait.",
|
|
50
|
+
};
|
|
51
|
+
const before = output.output;
|
|
52
|
+
await handler(input, output);
|
|
53
|
+
expect(output.output).toBe(before);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("#when output.output is not a string", () => {
|
|
58
|
+
it("#then no-op", async () => {
|
|
59
|
+
const input = {};
|
|
60
|
+
const output = { output: 999 };
|
|
61
|
+
await handler(input, output);
|
|
62
|
+
expect(output.output).toBe(999);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe("#when output is not a record", () => {
|
|
67
|
+
it("#then no-op", async () => {
|
|
68
|
+
await handler({}, "not-a-record");
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe("createEventErrorHandler", () => {
|
|
75
|
+
describe("#given a handler instance", () => {
|
|
76
|
+
const handler = createEventErrorHandler() as unknown as UnknownEventHandler;
|
|
77
|
+
|
|
78
|
+
describe("#when event is session.error with a matching error pattern", () => {
|
|
79
|
+
it("#then sets recoveryContext with diagnostic", async () => {
|
|
80
|
+
const properties: Record<string, unknown> = { error: "ECONNREFUSED: connection refused" };
|
|
81
|
+
const input = {
|
|
82
|
+
event: { type: "session.error", properties },
|
|
83
|
+
};
|
|
84
|
+
await handler(input);
|
|
85
|
+
expect(properties.recoveryContext).toContain("[ERROR DIAGNOSTIC]");
|
|
86
|
+
expect(properties.recoveryContext).toContain("Category: network");
|
|
87
|
+
expect(properties.recoveryContext).toContain("Severity: error");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe("#when event is session.error with timeout error", () => {
|
|
92
|
+
it("#then sets recoveryContext with timeout diagnostic", async () => {
|
|
93
|
+
const properties: Record<string, unknown> = { error: "request timed out" };
|
|
94
|
+
const input = {
|
|
95
|
+
event: { type: "session.error", properties },
|
|
96
|
+
};
|
|
97
|
+
await handler(input);
|
|
98
|
+
expect(properties.recoveryContext).toContain("[ERROR DIAGNOSTIC]");
|
|
99
|
+
expect(properties.recoveryContext).toContain("Category: timeout");
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe("#when event type is not session.error", () => {
|
|
104
|
+
it("#then no-op", async () => {
|
|
105
|
+
const properties: Record<string, unknown> = { error: "ECONNREFUSED" };
|
|
106
|
+
const input = {
|
|
107
|
+
event: { type: "session.idle", properties },
|
|
108
|
+
};
|
|
109
|
+
await handler(input);
|
|
110
|
+
expect(properties.recoveryContext).toBeUndefined();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("#when event error does not match any pattern", () => {
|
|
115
|
+
it("#then no recoveryContext set", async () => {
|
|
116
|
+
const properties: Record<string, unknown> = { error: "something completely normal" };
|
|
117
|
+
const input = {
|
|
118
|
+
event: { type: "session.error", properties },
|
|
119
|
+
};
|
|
120
|
+
await handler(input);
|
|
121
|
+
expect(properties.recoveryContext).toBeUndefined();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe("#when recoveryContext already contains diagnostic marker", () => {
|
|
126
|
+
it("#then does not double-append", async () => {
|
|
127
|
+
const existingDiag =
|
|
128
|
+
"[ERROR DIAGNOSTIC]\nCategory: network\nSeverity: error\nSuggestion: Check.";
|
|
129
|
+
const properties: Record<string, unknown> = {
|
|
130
|
+
error: "ECONNREFUSED",
|
|
131
|
+
recoveryContext: existingDiag,
|
|
132
|
+
};
|
|
133
|
+
const input = {
|
|
134
|
+
event: { type: "session.error", properties },
|
|
135
|
+
};
|
|
136
|
+
await handler(input);
|
|
137
|
+
expect(properties.recoveryContext).toBe(existingDiag);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe("#when input is not a record", () => {
|
|
142
|
+
it("#then no-op", async () => {
|
|
143
|
+
await handler(null);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|