@ebowwa/coder 0.2.1 → 0.7.64
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/README.md +31 -32
- package/dist/core/__tests__/permissions.test.d.ts +12 -0
- package/dist/core/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/core/__tests__/permissions.test.js +851 -0
- package/dist/core/agent-loop/__tests__/compaction.test.d.ts +5 -0
- package/dist/core/agent-loop/__tests__/compaction.test.d.ts.map +1 -0
- package/dist/core/agent-loop/__tests__/compaction.test.js +209 -0
- package/dist/core/agent-loop/__tests__/formatters.test.d.ts +5 -0
- package/dist/core/agent-loop/__tests__/formatters.test.d.ts.map +1 -0
- package/dist/core/agent-loop/__tests__/formatters.test.js +195 -0
- package/dist/core/agent-loop/__tests__/index.test.d.ts +5 -0
- package/dist/core/agent-loop/__tests__/index.test.d.ts.map +1 -0
- package/dist/core/agent-loop/__tests__/index.test.js +121 -0
- package/dist/core/agent-loop/__tests__/loop-state.test.d.ts +5 -0
- package/dist/core/agent-loop/__tests__/loop-state.test.d.ts.map +1 -0
- package/dist/core/agent-loop/__tests__/loop-state.test.js +340 -0
- package/dist/core/agent-loop/__tests__/message-builder.test.d.ts +5 -0
- package/dist/core/agent-loop/__tests__/message-builder.test.d.ts.map +1 -0
- package/dist/core/agent-loop/__tests__/message-builder.test.js +178 -0
- package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts +5 -0
- package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts.map +1 -0
- package/dist/core/agent-loop/__tests__/tool-executor.test.js +331 -0
- package/dist/core/agent-loop/compaction.d.ts +39 -0
- package/dist/core/agent-loop/compaction.d.ts.map +1 -0
- package/dist/core/agent-loop/compaction.js +51 -0
- package/dist/core/agent-loop/formatters.d.ts +21 -0
- package/dist/core/agent-loop/formatters.d.ts.map +1 -0
- package/dist/core/agent-loop/formatters.js +42 -0
- package/dist/core/agent-loop/index.d.ts +25 -0
- package/dist/core/agent-loop/index.d.ts.map +1 -0
- package/dist/core/agent-loop/index.js +83 -0
- package/dist/core/agent-loop/loop-state.d.ts +74 -0
- package/dist/core/agent-loop/loop-state.d.ts.map +1 -0
- package/dist/core/agent-loop/loop-state.js +147 -0
- package/dist/core/agent-loop/message-builder.d.ts +13 -0
- package/dist/core/agent-loop/message-builder.d.ts.map +1 -0
- package/dist/core/agent-loop/message-builder.js +49 -0
- package/dist/core/agent-loop/tool-executor.d.ts +23 -0
- package/dist/core/agent-loop/tool-executor.d.ts.map +1 -0
- package/dist/core/agent-loop/tool-executor.js +152 -0
- package/dist/core/agent-loop/turn-executor.d.ts +57 -0
- package/dist/core/agent-loop/turn-executor.d.ts.map +1 -0
- package/dist/core/agent-loop/turn-executor.js +124 -0
- package/dist/core/agent-loop/types.d.ts +141 -0
- package/dist/core/agent-loop/types.d.ts.map +1 -0
- package/dist/core/agent-loop/types.js +4 -0
- package/dist/core/agent-loop.d.ts +17 -0
- package/dist/core/agent-loop.d.ts.map +1 -0
- package/dist/core/agent-loop.js +16 -0
- package/dist/core/api-client-impl.d.ts +62 -0
- package/dist/core/api-client-impl.d.ts.map +1 -0
- package/dist/core/api-client-impl.js +479 -0
- package/dist/core/api-client.d.ts +6 -0
- package/dist/core/api-client.d.ts.map +1 -0
- package/dist/core/api-client.js +5 -0
- package/dist/core/checkpoints.d.ts +128 -0
- package/dist/core/checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints.js +438 -0
- package/dist/core/claude-md.d.ts +71 -0
- package/dist/core/claude-md.d.ts.map +1 -0
- package/dist/core/claude-md.js +198 -0
- package/dist/core/cognitive-security/hooks.d.ts +138 -0
- package/dist/core/cognitive-security/hooks.d.ts.map +1 -0
- package/dist/core/cognitive-security/hooks.js +389 -0
- package/dist/core/cognitive-security/index.d.ts +751 -0
- package/dist/core/cognitive-security/index.d.ts.map +1 -0
- package/dist/core/cognitive-security/index.js +1123 -0
- package/dist/core/cognitive-security/middleware.d.ts +136 -0
- package/dist/core/cognitive-security/middleware.d.ts.map +1 -0
- package/dist/core/cognitive-security/middleware.js +376 -0
- package/dist/core/config-loader.d.ts +127 -0
- package/dist/core/config-loader.d.ts.map +1 -0
- package/dist/core/config-loader.js +219 -0
- package/dist/core/context-compaction.d.ts +87 -0
- package/dist/core/context-compaction.d.ts.map +1 -0
- package/dist/core/context-compaction.js +428 -0
- package/dist/core/git-status.d.ts +25 -0
- package/dist/core/git-status.d.ts.map +1 -0
- package/dist/core/git-status.js +204 -0
- package/dist/core/image.d.ts +69 -0
- package/dist/core/image.d.ts.map +1 -0
- package/dist/core/image.js +290 -0
- package/dist/core/image.test.d.ts +2 -0
- package/dist/core/image.test.d.ts.map +1 -0
- package/dist/core/image.test.js +149 -0
- package/dist/core/models.d.ts +123 -0
- package/dist/core/models.d.ts.map +1 -0
- package/dist/core/models.js +325 -0
- package/dist/core/permissions.d.ts +81 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +327 -0
- package/dist/core/retry.d.ts +25 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/retry.js +121 -0
- package/dist/core/session-store.d.ts +9 -0
- package/dist/core/session-store.d.ts.map +1 -0
- package/dist/core/session-store.js +10 -0
- package/dist/core/sessions/export.d.ts +47 -0
- package/dist/core/sessions/export.d.ts.map +1 -0
- package/dist/core/sessions/export.js +256 -0
- package/dist/core/sessions/index.d.ts +132 -0
- package/dist/core/sessions/index.d.ts.map +1 -0
- package/dist/core/sessions/index.js +442 -0
- package/dist/core/sessions/metadata.d.ts +77 -0
- package/dist/core/sessions/metadata.d.ts.map +1 -0
- package/dist/core/sessions/metadata.js +233 -0
- package/dist/core/sessions/persistence.d.ts +72 -0
- package/dist/core/sessions/persistence.d.ts.map +1 -0
- package/dist/core/sessions/persistence.js +201 -0
- package/dist/core/sessions/types.d.ts +110 -0
- package/dist/core/sessions/types.d.ts.map +1 -0
- package/dist/core/sessions/types.js +4 -0
- package/dist/core/stream-highlighter.d.ts +18 -0
- package/dist/core/stream-highlighter.d.ts.map +1 -0
- package/dist/core/stream-highlighter.js +916 -0
- package/dist/core/system-reminders.d.ts +89 -0
- package/dist/core/system-reminders.d.ts.map +1 -0
- package/dist/core/system-reminders.js +285 -0
- package/dist/ecosystem/hooks/__tests__/index.test.d.ts +5 -0
- package/dist/ecosystem/hooks/__tests__/index.test.d.ts.map +1 -0
- package/dist/ecosystem/hooks/__tests__/index.test.js +458 -0
- package/dist/ecosystem/hooks/index.d.ts +59 -0
- package/dist/ecosystem/hooks/index.d.ts.map +1 -0
- package/dist/ecosystem/hooks/index.js +294 -0
- package/dist/ecosystem/hooks/prompt-evaluator.d.ts +32 -0
- package/dist/ecosystem/hooks/prompt-evaluator.d.ts.map +1 -0
- package/dist/ecosystem/hooks/prompt-evaluator.js +229 -0
- package/dist/ecosystem/skills/index.d.ts +55 -0
- package/dist/ecosystem/skills/index.d.ts.map +1 -0
- package/dist/ecosystem/skills/index.js +258 -0
- package/dist/ecosystem/tools/__tests__/index.test.d.ts +7 -0
- package/dist/ecosystem/tools/__tests__/index.test.d.ts.map +1 -0
- package/dist/ecosystem/tools/__tests__/index.test.js +856 -0
- package/dist/ecosystem/tools/index.d.ts +24 -0
- package/dist/ecosystem/tools/index.d.ts.map +1 -0
- package/dist/ecosystem/tools/index.js +1709 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -2
- package/dist/interfaces/mcp/client.d.ts +40 -0
- package/dist/interfaces/mcp/client.d.ts.map +1 -0
- package/dist/interfaces/mcp/client.js +309 -0
- package/dist/interfaces/ui/index.d.ts +36 -0
- package/dist/interfaces/ui/index.d.ts.map +1 -0
- package/dist/interfaces/ui/index.js +61 -0
- package/dist/interfaces/ui/spinner.d.ts +140 -0
- package/dist/interfaces/ui/spinner.d.ts.map +1 -0
- package/dist/interfaces/ui/spinner.js +342 -0
- package/dist/interfaces/ui/terminal/cli/index.d.ts +12 -0
- package/dist/interfaces/ui/terminal/cli/index.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/cli/index.js +167 -0
- package/dist/interfaces/ui/terminal/shared/args.d.ts +39 -0
- package/dist/interfaces/ui/terminal/shared/args.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/shared/args.js +176 -0
- package/dist/interfaces/ui/terminal/shared/index.d.ts +11 -0
- package/dist/interfaces/ui/terminal/shared/index.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/shared/index.js +16 -0
- package/dist/interfaces/ui/terminal/shared/loading-state.d.ts +124 -0
- package/dist/interfaces/ui/terminal/shared/loading-state.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/shared/loading-state.js +246 -0
- package/dist/interfaces/ui/terminal/shared/query.d.ts +22 -0
- package/dist/interfaces/ui/terminal/shared/query.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/shared/query.js +100 -0
- package/dist/interfaces/ui/terminal/shared/setup.d.ts +33 -0
- package/dist/interfaces/ui/terminal/shared/setup.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/shared/setup.js +226 -0
- package/dist/interfaces/ui/terminal/shared/status-line.d.ts +117 -0
- package/dist/interfaces/ui/terminal/shared/status-line.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/shared/status-line.js +267 -0
- package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts +38 -0
- package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/shared/system-prompt.js +102 -0
- package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts +39 -0
- package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/HelpPanel.js +215 -0
- package/dist/interfaces/ui/terminal/tui/InputContext.d.ts +91 -0
- package/dist/interfaces/ui/terminal/tui/InputContext.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/InputContext.js +154 -0
- package/dist/interfaces/ui/terminal/tui/InputField.d.ts +18 -0
- package/dist/interfaces/ui/terminal/tui/InputField.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/InputField.js +41 -0
- package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts +16 -0
- package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/InteractiveTUI.js +451 -0
- package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts +10 -0
- package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/MessageArea.js +91 -0
- package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts +48 -0
- package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/MessageStore.js +151 -0
- package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts +9 -0
- package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/StatusBar.js +36 -0
- package/dist/interfaces/ui/terminal/tui/commands.d.ts +21 -0
- package/dist/interfaces/ui/terminal/tui/commands.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/commands.js +359 -0
- package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts +115 -0
- package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.js +306 -0
- package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts +92 -0
- package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/components/MultilineInput.js +399 -0
- package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts +59 -0
- package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/components/PaneManager.js +139 -0
- package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts +68 -0
- package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/components/Sidebar.js +340 -0
- package/dist/interfaces/ui/terminal/tui/components/index.d.ts +23 -0
- package/dist/interfaces/ui/terminal/tui/components/index.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/components/index.js +51 -0
- package/dist/interfaces/ui/terminal/tui/console.d.ts +20 -0
- package/dist/interfaces/ui/terminal/tui/console.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/console.js +46 -0
- package/dist/interfaces/ui/terminal/tui/index.d.ts +20 -0
- package/dist/interfaces/ui/terminal/tui/index.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/index.js +28 -0
- package/dist/interfaces/ui/terminal/tui/run.d.ts +13 -0
- package/dist/interfaces/ui/terminal/tui/run.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/run.js +31 -0
- package/dist/interfaces/ui/terminal/tui/spinner.d.ts +44 -0
- package/dist/interfaces/ui/terminal/tui/spinner.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/spinner.js +59 -0
- package/dist/interfaces/ui/terminal/tui/tui-app.d.ts +39 -0
- package/dist/interfaces/ui/terminal/tui/tui-app.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/tui-app.js +198 -0
- package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts +167 -0
- package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/tui-footer.js +330 -0
- package/dist/interfaces/ui/terminal/tui/types.d.ts +165 -0
- package/dist/interfaces/ui/terminal/tui/types.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/types.js +5 -0
- package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts +23 -0
- package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/useInputHandler.js +72 -0
- package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts +90 -0
- package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts.map +1 -0
- package/dist/interfaces/ui/terminal/tui/useNativeInput.js +188 -0
- package/dist/native/index.d.ts +480 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +1625 -0
- package/dist/teammates/index.d.ts +161 -0
- package/dist/teammates/index.d.ts.map +1 -0
- package/dist/teammates/index.js +827 -0
- package/dist/types/index.d.ts +482 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +52 -0
- package/native/README.md +5 -5
- package/native/index.darwin-arm64.node +0 -0
- package/native/index.node +0 -0
- package/native/package.json +4 -4
- package/package.json +33 -16
- package/packages/src/core/__tests__/permissions.test.ts +1091 -0
- package/packages/src/core/agent-loop/__tests__/compaction.test.ts +280 -0
- package/packages/src/core/agent-loop/__tests__/formatters.test.ts +234 -0
- package/packages/src/core/agent-loop/__tests__/index.test.ts +162 -0
- package/packages/src/core/agent-loop/__tests__/loop-state.test.ts +413 -0
- package/packages/src/core/agent-loop/__tests__/message-builder.test.ts +229 -0
- package/packages/src/core/agent-loop/__tests__/tool-executor.test.ts +457 -0
- package/packages/src/core/agent-loop/compaction.ts +88 -0
- package/packages/src/core/agent-loop/formatters.ts +50 -0
- package/packages/src/core/agent-loop/index.ts +135 -0
- package/packages/src/core/agent-loop/loop-state.ts +187 -0
- package/packages/src/core/agent-loop/message-builder.ts +62 -0
- package/packages/src/core/agent-loop/tool-executor.ts +211 -0
- package/packages/src/core/agent-loop/turn-executor.ts +222 -0
- package/packages/src/core/agent-loop/types.ts +148 -0
- package/packages/src/core/agent-loop.ts +18 -0
- package/packages/src/core/api-client-impl.ts +619 -0
- package/packages/src/core/api-client.ts +6 -0
- package/packages/src/core/checkpoints.ts +606 -0
- package/packages/src/core/claude-md.ts +272 -0
- package/packages/src/core/cognitive-security/hooks.ts +590 -0
- package/packages/src/core/cognitive-security/index.ts +2041 -0
- package/packages/src/core/cognitive-security/middleware.ts +536 -0
- package/packages/src/core/config-loader.ts +324 -0
- package/packages/src/core/context-compaction.ts +578 -0
- package/packages/src/core/git-status.ts +262 -0
- package/packages/src/core/image.test.ts +180 -0
- package/packages/src/core/image.ts +350 -0
- package/packages/src/core/lmdb.db +0 -0
- package/packages/src/core/lmdb.db-lock +0 -0
- package/packages/src/core/models.ts +430 -0
- package/packages/src/core/normalizers/todo +4 -0
- package/packages/src/core/permissions.ts +431 -0
- package/packages/src/core/retry.ts +170 -0
- package/packages/src/core/session-store.ts +36 -0
- package/packages/src/core/sessions/export.ts +329 -0
- package/packages/src/core/sessions/index.ts +587 -0
- package/packages/src/core/sessions/metadata.ts +309 -0
- package/packages/src/core/sessions/persistence.ts +244 -0
- package/packages/src/core/sessions/types.ts +169 -0
- package/packages/src/core/stream-highlighter.ts +1123 -0
- package/packages/src/core/system-reminders.ts +402 -0
- package/packages/src/core/todo +8 -0
- package/packages/src/ecosystem/hooks/__tests__/index.test.ts +561 -0
- package/packages/src/ecosystem/hooks/index.ts +341 -0
- package/packages/src/ecosystem/hooks/prompt-evaluator.ts +300 -0
- package/packages/src/ecosystem/skills/index.ts +295 -0
- package/packages/src/ecosystem/tools/__tests__/index.test.ts +1335 -0
- package/packages/src/ecosystem/tools/index.ts +1877 -0
- package/packages/src/index.ts +120 -0
- package/packages/src/interfaces/mcp/client.ts +389 -0
- package/packages/src/interfaces/ui/Screenshot 2026-03-02 at 9.23.10/342/200/257PM.png +0 -0
- package/packages/src/interfaces/ui/Screenshot 2026-03-03 at 10.55.11/342/200/257AM.png +0 -0
- package/packages/src/interfaces/ui/index.ts +161 -0
- package/packages/src/interfaces/ui/lmdb.db +0 -0
- package/packages/src/interfaces/ui/lmdb.db-lock +0 -0
- package/packages/src/interfaces/ui/spinner.ts +451 -0
- package/packages/src/interfaces/ui/terminal/cli/index.ts +228 -0
- package/packages/src/interfaces/ui/terminal/lmdb.db +0 -0
- package/packages/src/interfaces/ui/terminal/lmdb.db-lock +0 -0
- package/packages/src/interfaces/ui/terminal/shared/args.ts +222 -0
- package/packages/src/interfaces/ui/terminal/shared/index.ts +71 -0
- package/packages/src/interfaces/ui/terminal/shared/loading-state.ts +322 -0
- package/packages/src/interfaces/ui/terminal/shared/query.ts +146 -0
- package/packages/src/interfaces/ui/terminal/shared/setup.ts +295 -0
- package/packages/src/interfaces/ui/terminal/shared/status-line.ts +358 -0
- package/packages/src/interfaces/ui/terminal/shared/system-prompt.ts +146 -0
- package/packages/src/interfaces/ui/terminal/tui/HelpPanel.tsx +262 -0
- package/packages/src/interfaces/ui/terminal/tui/InputContext.tsx +232 -0
- package/packages/src/interfaces/ui/terminal/tui/InputField.tsx +62 -0
- package/packages/src/interfaces/ui/terminal/tui/InteractiveTUI.tsx +537 -0
- package/packages/src/interfaces/ui/terminal/tui/MessageArea.tsx +107 -0
- package/packages/src/interfaces/ui/terminal/tui/MessageStore.tsx +240 -0
- package/packages/src/interfaces/ui/terminal/tui/StatusBar.tsx +54 -0
- package/packages/src/interfaces/ui/terminal/tui/commands.ts +438 -0
- package/packages/src/interfaces/ui/terminal/tui/components/InteractiveElements.tsx +584 -0
- package/packages/src/interfaces/ui/terminal/tui/components/MultilineInput.tsx +614 -0
- package/packages/src/interfaces/ui/terminal/tui/components/PaneManager.tsx +333 -0
- package/packages/src/interfaces/ui/terminal/tui/components/Sidebar.tsx +604 -0
- package/packages/src/interfaces/ui/terminal/tui/components/index.ts +118 -0
- package/packages/src/interfaces/ui/terminal/tui/console.ts +49 -0
- package/packages/src/interfaces/ui/terminal/tui/index.ts +90 -0
- package/packages/src/interfaces/ui/terminal/tui/run.tsx +42 -0
- package/packages/src/interfaces/ui/terminal/tui/spinner.ts +69 -0
- package/packages/src/interfaces/ui/terminal/tui/tui-app.tsx +390 -0
- package/packages/src/interfaces/ui/terminal/tui/tui-footer.ts +422 -0
- package/packages/src/interfaces/ui/terminal/tui/types.ts +186 -0
- package/packages/src/interfaces/ui/terminal/tui/useInputHandler.ts +104 -0
- package/packages/src/interfaces/ui/terminal/tui/useNativeInput.ts +239 -0
- package/packages/src/lmdb.db +0 -0
- package/packages/src/lmdb.db-lock +0 -0
- package/packages/src/native/index.ts +2345 -0
- package/packages/src/teammates/index.ts +982 -0
- package/packages/src/types/index.ts +722 -0
- package/dist/cli.js +0 -148
- package/dist/index-0pkak453.js +0 -136
- package/dist/index-0qd0x8b4.js +0 -110
- package/dist/index-0x3kprq6.js +0 -240
- package/dist/index-1eawy937.js +0 -308
- package/dist/index-24m2aygy.js +0 -240
- package/dist/index-29xcjnne.js +0 -280
- package/dist/index-2avyytn5.js +0 -349
- package/dist/index-4ms367ey.js +0 -136
- package/dist/index-4w2t3b0m.js +0 -240
- package/dist/index-4xfgd8nz.js +0 -261
- package/dist/index-5acjp9gc.js +0 -157
- package/dist/index-5s15hr56.js +0 -136
- package/dist/index-6e4wf341.js +0 -349
- package/dist/index-6fvnkedw.js +0 -240
- package/dist/index-6rqpmd4g.js +0 -128
- package/dist/index-77ckwnbm.js +0 -280
- package/dist/index-9knxy49k.js +0 -128
- package/dist/index-9zrnw4zx.js +0 -128
- package/dist/index-bk21w99v.js +0 -280
- package/dist/index-c41n76fv.js +0 -240
- package/dist/index-cb4ppjdt.js +0 -255
- package/dist/index-cfb2edt6.js +0 -240
- package/dist/index-cmfa38hh.js +0 -308
- package/dist/index-datjz8q1.js +0 -257
- package/dist/index-eadf4wvn.js +0 -240
- package/dist/index-em5k0m3z.js +0 -345
- package/dist/index-gh8r333a.js +0 -110
- package/dist/index-gkx6k2tr.js +0 -261
- package/dist/index-h5cabfks.js +0 -155
- package/dist/index-hcrpwyy3.js +0 -261
- package/dist/index-hk7fwwa8.js +0 -257
- package/dist/index-jb8cw7f8.js +0 -136
- package/dist/index-kbyw4th1.js +0 -347
- package/dist/index-kgj5gqnm.js +0 -345
- package/dist/index-mdf6xp1z.js +0 -255
- package/dist/index-mrhv8kvc.js +0 -280
- package/dist/index-mt4743dd.js +0 -161
- package/dist/index-qnwsg97q.js +0 -240
- package/dist/index-qwdy6x44.js +0 -261
- package/dist/index-rmj77261.js +0 -157
- package/dist/index-sbbw1a61.js +0 -349
- package/dist/index-svy5bcpn.js +0 -345
- package/dist/index-tvmy7tm9.js +0 -261
- package/dist/index-tzz4vzkj.js +0 -312
- package/dist/index-vz80zmhe.js +0 -110
- package/dist/index-wed2fk67.js +0 -240
- package/dist/index-wksgzz8e.js +0 -280
- package/dist/index-wn2m4wma.js +0 -240
- package/dist/index-xha05vjc.js +0 -257
- package/dist/index-yc6eh8p8.js +0 -136
- package/dist/index-ycjxx9ft.js +0 -240
- package/dist/index-z0gzd0fc.js +0 -110
- package/dist/index-z8cwtf8j.js +0 -240
- package/dist/index-zy5mtt00.js +0 -128
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook System - Lifecycle event handlers
|
|
3
|
+
*/
|
|
4
|
+
import { spawn } from "child_process";
|
|
5
|
+
export class HookManager {
|
|
6
|
+
hooks = new Map();
|
|
7
|
+
timeout;
|
|
8
|
+
promptEvaluator;
|
|
9
|
+
constructor(timeout = 60000, promptEvaluator) {
|
|
10
|
+
this.timeout = timeout;
|
|
11
|
+
this.promptEvaluator = promptEvaluator;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Set the prompt evaluator for LLM-based hooks
|
|
15
|
+
*/
|
|
16
|
+
setPromptEvaluator(evaluator) {
|
|
17
|
+
this.promptEvaluator = evaluator;
|
|
18
|
+
}
|
|
19
|
+
register(event, definition) {
|
|
20
|
+
if (!this.hooks.has(event)) {
|
|
21
|
+
this.hooks.set(event, []);
|
|
22
|
+
}
|
|
23
|
+
this.hooks.get(event)?.push(definition);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Register an in-process handler for an event
|
|
27
|
+
*/
|
|
28
|
+
registerHandler(event, handler, options) {
|
|
29
|
+
this.register(event, {
|
|
30
|
+
event,
|
|
31
|
+
command: "", // Not used for in-process handlers
|
|
32
|
+
handler,
|
|
33
|
+
timeout: options?.timeout,
|
|
34
|
+
enabled: options?.enabled ?? true,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
registerAll(hooks) {
|
|
38
|
+
for (const [event, definitions] of Object.entries(hooks)) {
|
|
39
|
+
for (const def of definitions) {
|
|
40
|
+
this.register(event, def);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async execute(event, input) {
|
|
45
|
+
const definitions = this.hooks.get(event);
|
|
46
|
+
if (!definitions || definitions.length === 0) {
|
|
47
|
+
return { decision: "allow" };
|
|
48
|
+
}
|
|
49
|
+
const fullInput = {
|
|
50
|
+
...input,
|
|
51
|
+
event,
|
|
52
|
+
timestamp: Date.now(),
|
|
53
|
+
};
|
|
54
|
+
for (const def of definitions) {
|
|
55
|
+
if (def.enabled === false)
|
|
56
|
+
continue;
|
|
57
|
+
// Check matcher if present
|
|
58
|
+
if (def._matcher && input.tool_name) {
|
|
59
|
+
try {
|
|
60
|
+
const regex = new RegExp(def._matcher);
|
|
61
|
+
if (!regex.test(input.tool_name)) {
|
|
62
|
+
// Matcher doesn't match, skip this hook
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Invalid regex, skip
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const result = await this.executeHook(def, fullInput);
|
|
72
|
+
if (result.decision === "deny" || result.decision === "block") {
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
// Apply modified input if provided
|
|
76
|
+
if (result.modified_input) {
|
|
77
|
+
Object.assign(input, result.modified_input);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { decision: "allow" };
|
|
81
|
+
}
|
|
82
|
+
async executeHook(def, input) {
|
|
83
|
+
// If handler function is provided, use it directly
|
|
84
|
+
if (def.handler) {
|
|
85
|
+
try {
|
|
86
|
+
return await def.handler(input);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
90
|
+
return {
|
|
91
|
+
decision: "deny",
|
|
92
|
+
reason: `Hook handler error: ${errorMessage}`,
|
|
93
|
+
errors: [errorMessage],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// If prompt is provided, use LLM evaluation
|
|
98
|
+
if (def.prompt && this.promptEvaluator) {
|
|
99
|
+
try {
|
|
100
|
+
return await this.promptEvaluator(def.prompt, input);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
104
|
+
return {
|
|
105
|
+
decision: "deny",
|
|
106
|
+
reason: `Prompt hook error: ${errorMessage}`,
|
|
107
|
+
errors: [errorMessage],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Skip hooks with empty commands (e.g., prompt-type hooks without evaluator)
|
|
112
|
+
if (!def.command || def.command.trim() === "") {
|
|
113
|
+
// Allow the operation to proceed if there's no command to execute
|
|
114
|
+
return { decision: "allow" };
|
|
115
|
+
}
|
|
116
|
+
// Shell command execution
|
|
117
|
+
const timeout = def.timeout || this.timeout;
|
|
118
|
+
try {
|
|
119
|
+
const result = await new Promise((resolve, reject) => {
|
|
120
|
+
const proc = spawn(def.command, [], {
|
|
121
|
+
shell: true,
|
|
122
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
123
|
+
});
|
|
124
|
+
let stdout = "";
|
|
125
|
+
let stderr = "";
|
|
126
|
+
let timedOut = false;
|
|
127
|
+
const timer = setTimeout(() => {
|
|
128
|
+
timedOut = true;
|
|
129
|
+
proc.kill();
|
|
130
|
+
resolve({
|
|
131
|
+
decision: "deny",
|
|
132
|
+
reason: "Hook timeout",
|
|
133
|
+
errors: ["Hook execution timed out"],
|
|
134
|
+
});
|
|
135
|
+
}, timeout);
|
|
136
|
+
proc.stdout?.on("data", (data) => {
|
|
137
|
+
stdout += data.toString();
|
|
138
|
+
});
|
|
139
|
+
proc.stderr?.on("data", (data) => {
|
|
140
|
+
stderr += data.toString();
|
|
141
|
+
});
|
|
142
|
+
proc.on("close", (code) => {
|
|
143
|
+
clearTimeout(timer);
|
|
144
|
+
if (timedOut)
|
|
145
|
+
return; // Already resolved
|
|
146
|
+
// Try to parse JSON from stdout first (works for all exit codes)
|
|
147
|
+
let parsedOutput = null;
|
|
148
|
+
if (stdout.trim()) {
|
|
149
|
+
try {
|
|
150
|
+
parsedOutput = JSON.parse(stdout);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// stdout not valid JSON, ignore
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (code === 0) {
|
|
157
|
+
// Success - use parsed output or default to allow
|
|
158
|
+
resolve(parsedOutput || { decision: "allow" });
|
|
159
|
+
}
|
|
160
|
+
else if (code === 1) {
|
|
161
|
+
// Deny - use parsed output or fall back to stderr
|
|
162
|
+
if (parsedOutput) {
|
|
163
|
+
resolve(parsedOutput);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
resolve({
|
|
167
|
+
decision: "deny",
|
|
168
|
+
reason: stderr || "Hook denied execution",
|
|
169
|
+
errors: stderr ? [stderr] : ["Hook denied execution"],
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else if (code === 2) {
|
|
174
|
+
// Block - use parsed output or fall back to stderr
|
|
175
|
+
if (parsedOutput) {
|
|
176
|
+
resolve(parsedOutput);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
resolve({
|
|
180
|
+
decision: "block",
|
|
181
|
+
reason: stderr || "Hook blocked execution",
|
|
182
|
+
errors: stderr ? [stderr] : ["Hook blocked execution"],
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
// Other error - default to deny
|
|
188
|
+
resolve({
|
|
189
|
+
decision: "deny",
|
|
190
|
+
reason: `Hook exited with code ${code}`,
|
|
191
|
+
errors: [`Hook exited with code ${code}`],
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
proc.on("error", (error) => {
|
|
196
|
+
clearTimeout(timer);
|
|
197
|
+
resolve({
|
|
198
|
+
decision: "deny",
|
|
199
|
+
reason: `Hook error: ${error.message}`,
|
|
200
|
+
errors: [error.message],
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
// Send input via stdin
|
|
204
|
+
proc.stdin?.write(JSON.stringify(input));
|
|
205
|
+
proc.stdin?.end();
|
|
206
|
+
});
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
211
|
+
return {
|
|
212
|
+
decision: "deny",
|
|
213
|
+
reason: `Hook execution failed: ${errorMessage}`,
|
|
214
|
+
errors: [errorMessage],
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
getHooks(event) {
|
|
219
|
+
return this.hooks.get(event) || [];
|
|
220
|
+
}
|
|
221
|
+
clear(event) {
|
|
222
|
+
if (event) {
|
|
223
|
+
this.hooks.delete(event);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
this.hooks.clear();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// ============================================
|
|
231
|
+
// BUILT-IN HOOKS
|
|
232
|
+
// ============================================
|
|
233
|
+
export const builtInHooks = {
|
|
234
|
+
/**
|
|
235
|
+
* Example: Validate file paths before write
|
|
236
|
+
*/
|
|
237
|
+
validateWrite: {
|
|
238
|
+
event: "PreToolUse",
|
|
239
|
+
command: `node -e '
|
|
240
|
+
const input = JSON.parse(require("fs").readFileSync(0, "utf8"));
|
|
241
|
+
if (input.tool_name === "Write") {
|
|
242
|
+
const path = input.tool_input.file_path;
|
|
243
|
+
if (path.includes("..") || path.startsWith("/etc/")) {
|
|
244
|
+
console.log(JSON.stringify({ decision: "deny", reason: "Unsafe path" }));
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
console.log(JSON.stringify({ decision: "allow" }));
|
|
249
|
+
'`,
|
|
250
|
+
timeout: 5000,
|
|
251
|
+
enabled: false,
|
|
252
|
+
},
|
|
253
|
+
/**
|
|
254
|
+
* Example: Log all tool uses
|
|
255
|
+
*/
|
|
256
|
+
logToolUse: {
|
|
257
|
+
event: "PostToolUse",
|
|
258
|
+
command: `node -e '
|
|
259
|
+
const input = JSON.parse(require("fs").readFileSync(0, "utf8"));
|
|
260
|
+
console.error(\`[LOG] Tool: \${input.tool_name}\`);
|
|
261
|
+
console.log(JSON.stringify({ decision: "allow" }));
|
|
262
|
+
'`,
|
|
263
|
+
timeout: 5000,
|
|
264
|
+
enabled: false,
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
// ============================================
|
|
268
|
+
// HOOK EVENT DOCUMENTATION
|
|
269
|
+
// ============================================
|
|
270
|
+
export const hookEventDocs = {
|
|
271
|
+
PreToolUse: "Before a tool is executed. Can modify input or deny execution.",
|
|
272
|
+
PostToolUse: "After a tool successfully executes. Can process result.",
|
|
273
|
+
PostToolUseFailure: "After a tool fails. Can handle error or retry.",
|
|
274
|
+
Stop: "When the agent stops (end_turn, max_tokens, error).",
|
|
275
|
+
UserPromptSubmit: "When user submits a prompt. Can modify or reject.",
|
|
276
|
+
SessionStart: "When a new session starts.",
|
|
277
|
+
SessionEnd: "When a session ends.",
|
|
278
|
+
Notification: "When a notification is sent.",
|
|
279
|
+
ConfigChange: "When configuration changes.",
|
|
280
|
+
WorktreeCreate: "When a git worktree is created.",
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* Exit codes for hook commands:
|
|
284
|
+
* 0 = Success, allow execution
|
|
285
|
+
* 1 = Show stderr, deny execution
|
|
286
|
+
* 2 = Block execution silently
|
|
287
|
+
*/
|
|
288
|
+
export const hookExitCodes = {
|
|
289
|
+
ALLOW: 0,
|
|
290
|
+
DENY: 1,
|
|
291
|
+
BLOCK: 2,
|
|
292
|
+
};
|
|
293
|
+
// Re-export prompt evaluator utilities
|
|
294
|
+
export { createPromptEvaluator, createMockPromptEvaluator } from "./prompt-evaluator.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Evaluator - LLM-based hook evaluation
|
|
3
|
+
*
|
|
4
|
+
* Evaluates hook prompts by calling the Claude API to make decisions
|
|
5
|
+
* about tool execution based on natural language rules.
|
|
6
|
+
*/
|
|
7
|
+
import type { PromptEvaluator } from "./index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Options for creating a prompt evaluator
|
|
10
|
+
*/
|
|
11
|
+
export interface PromptEvaluatorOptions {
|
|
12
|
+
/** Anthropic API key */
|
|
13
|
+
apiKey: string;
|
|
14
|
+
/** Model to use for evaluation (default: claude-haiku-4-5 for speed) */
|
|
15
|
+
model?: string;
|
|
16
|
+
/** Max tokens for response (default: 256) */
|
|
17
|
+
maxTokens?: number;
|
|
18
|
+
/** System prompt for the evaluator */
|
|
19
|
+
systemPrompt?: string;
|
|
20
|
+
/** Base URL for API (default: from ANTHROPIC_BASE_URL env or https://api.anthropic.com) */
|
|
21
|
+
baseUrl?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a prompt evaluator that uses the Claude API
|
|
25
|
+
*/
|
|
26
|
+
export declare function createPromptEvaluator(options: PromptEvaluatorOptions): PromptEvaluator;
|
|
27
|
+
/**
|
|
28
|
+
* Create a mock prompt evaluator for testing
|
|
29
|
+
* Returns canned responses based on patterns in the prompt
|
|
30
|
+
*/
|
|
31
|
+
export declare function createMockPromptEvaluator(): PromptEvaluator;
|
|
32
|
+
//# sourceMappingURL=prompt-evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-evaluator.d.ts","sourceRoot":"","sources":["../../../packages/src/ecosystem/hooks/prompt-evaluator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAsMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CAwCtF;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,eAAe,CA4B3D"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Evaluator - LLM-based hook evaluation
|
|
3
|
+
*
|
|
4
|
+
* Evaluates hook prompts by calling the Claude API to make decisions
|
|
5
|
+
* about tool execution based on natural language rules.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Default system prompt for hook evaluation
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_SYSTEM_PROMPT = `You are a hook evaluator for Coder. Your job is to evaluate tool usage against security and best-practice rules.
|
|
11
|
+
|
|
12
|
+
You MUST respond with ONLY a valid JSON object in this exact format:
|
|
13
|
+
{
|
|
14
|
+
"decision": "allow" | "deny" | "block",
|
|
15
|
+
"reason": "Optional explanation for the decision",
|
|
16
|
+
"modified_input": { ... } // Optional: modified tool input if you want to change it
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Rules:
|
|
20
|
+
- "allow": Let the tool execute normally
|
|
21
|
+
- "deny": Prevent execution and show the user the reason
|
|
22
|
+
- "block": Prevent execution silently (no message shown)
|
|
23
|
+
- Only modify input if absolutely necessary and you're certain of the correct format
|
|
24
|
+
|
|
25
|
+
Be concise and make quick decisions. Do not explain your reasoning in prose - only use the JSON format.`;
|
|
26
|
+
/**
|
|
27
|
+
* Interpolate variables in a prompt template
|
|
28
|
+
*/
|
|
29
|
+
function interpolatePrompt(template, input) {
|
|
30
|
+
let result = template;
|
|
31
|
+
// Replace $ARGUMENTS with tool input as JSON
|
|
32
|
+
if (input.tool_input) {
|
|
33
|
+
result = result.replace(/\$ARGUMENTS/g, JSON.stringify(input.tool_input, null, 2));
|
|
34
|
+
}
|
|
35
|
+
// Replace $TOOL_NAME with tool name
|
|
36
|
+
if (input.tool_name) {
|
|
37
|
+
result = result.replace(/\$TOOL_NAME/g, input.tool_name);
|
|
38
|
+
}
|
|
39
|
+
// Replace $EVENT with event name
|
|
40
|
+
result = result.replace(/\$EVENT/g, input.event);
|
|
41
|
+
// Replace $SESSION_ID with session ID
|
|
42
|
+
if (input.session_id) {
|
|
43
|
+
result = result.replace(/\$SESSION_ID/g, input.session_id);
|
|
44
|
+
}
|
|
45
|
+
// Replace $TIMESTAMP with timestamp
|
|
46
|
+
result = result.replace(/\$TIMESTAMP/g, String(input.timestamp));
|
|
47
|
+
// Replace $ERROR with error message if present
|
|
48
|
+
if (input.error) {
|
|
49
|
+
result = result.replace(/\$ERROR/g, input.error);
|
|
50
|
+
}
|
|
51
|
+
// Replace $TOOL_RESULT with tool result if present
|
|
52
|
+
if (input.tool_result) {
|
|
53
|
+
const resultStr = typeof input.tool_result.content === "string"
|
|
54
|
+
? input.tool_result.content
|
|
55
|
+
: JSON.stringify(input.tool_result.content);
|
|
56
|
+
result = result.replace(/\$TOOL_RESULT/g, resultStr);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Parse the LLM response into a HookOutput
|
|
62
|
+
* Supports multiple JSON formats:
|
|
63
|
+
* 1. Standard: { "decision": "allow" | "deny" | "block", "reason": "..." }
|
|
64
|
+
* 2. Standard format: { "continue": true/false, "hookSpecificOutput": {...} }
|
|
65
|
+
*/
|
|
66
|
+
function parseHookOutput(responseText) {
|
|
67
|
+
// Try to extract JSON from the response
|
|
68
|
+
// The model might wrap it in markdown code blocks or add extra text
|
|
69
|
+
let parsed = null;
|
|
70
|
+
// First, try direct parse
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(responseText);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Not valid JSON directly
|
|
76
|
+
}
|
|
77
|
+
// Try to extract JSON from markdown code block
|
|
78
|
+
if (!parsed) {
|
|
79
|
+
const jsonBlockMatch = responseText.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
80
|
+
if (jsonBlockMatch?.[1]) {
|
|
81
|
+
try {
|
|
82
|
+
parsed = JSON.parse(jsonBlockMatch[1].trim());
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Invalid JSON in code block
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Try to find JSON object anywhere in the response
|
|
90
|
+
if (!parsed) {
|
|
91
|
+
const jsonMatch = responseText.match(/\{[\s\S]*?\}/);
|
|
92
|
+
if (jsonMatch) {
|
|
93
|
+
try {
|
|
94
|
+
parsed = JSON.parse(jsonMatch[0]);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Invalid JSON
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!parsed) {
|
|
102
|
+
// If we can't parse JSON, default to allow with a warning
|
|
103
|
+
return {
|
|
104
|
+
decision: "allow",
|
|
105
|
+
reason: "Hook response could not be parsed as JSON, allowing by default",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// Format 1: Standard { decision: "allow" | "deny" | "block" }
|
|
109
|
+
if ("decision" in parsed) {
|
|
110
|
+
return {
|
|
111
|
+
decision: parsed.decision || "allow",
|
|
112
|
+
reason: parsed.reason,
|
|
113
|
+
modified_input: parsed.modified_input,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Format 2: Standard { continue: true/false, hookSpecificOutput: {...} }
|
|
117
|
+
if ("continue" in parsed) {
|
|
118
|
+
const shouldContinue = Boolean(parsed.continue);
|
|
119
|
+
if (shouldContinue) {
|
|
120
|
+
return { decision: "allow" };
|
|
121
|
+
}
|
|
122
|
+
// Extract reason from hookSpecificOutput if present
|
|
123
|
+
const hookOutput = parsed.hookSpecificOutput;
|
|
124
|
+
const reason = hookOutput?.permissionDecisionReason;
|
|
125
|
+
return {
|
|
126
|
+
decision: "deny",
|
|
127
|
+
reason: reason || "Hook denied execution",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Unknown format, default to allow
|
|
131
|
+
return {
|
|
132
|
+
decision: "allow",
|
|
133
|
+
reason: "Unknown hook response format, allowing by default",
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Make a non-streaming API call to Claude
|
|
138
|
+
*/
|
|
139
|
+
async function callClaudeAPI(apiKey, model, maxTokens, systemPrompt, userPrompt, baseUrl = "https://api.anthropic.com") {
|
|
140
|
+
const response = await fetch(`${baseUrl}/v1/messages`, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: {
|
|
143
|
+
"Content-Type": "application/json",
|
|
144
|
+
"x-api-key": apiKey,
|
|
145
|
+
"anthropic-version": "2023-06-01",
|
|
146
|
+
},
|
|
147
|
+
body: JSON.stringify({
|
|
148
|
+
model,
|
|
149
|
+
max_tokens: maxTokens,
|
|
150
|
+
system: systemPrompt,
|
|
151
|
+
messages: [
|
|
152
|
+
{
|
|
153
|
+
role: "user",
|
|
154
|
+
content: userPrompt,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
const errorText = await response.text();
|
|
161
|
+
throw new Error(`API error: ${response.status} - ${errorText}`);
|
|
162
|
+
}
|
|
163
|
+
const data = await response.json();
|
|
164
|
+
// Extract text from response
|
|
165
|
+
const textContent = data.content
|
|
166
|
+
.filter((block) => block.type === "text")
|
|
167
|
+
.map((block) => block.text || "")
|
|
168
|
+
.join("");
|
|
169
|
+
return textContent;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Create a prompt evaluator that uses the Claude API
|
|
173
|
+
*/
|
|
174
|
+
export function createPromptEvaluator(options) {
|
|
175
|
+
const { apiKey, model = "claude-haiku-4-5", // Use Haiku for fast evaluation
|
|
176
|
+
maxTokens = 256, systemPrompt = DEFAULT_SYSTEM_PROMPT, baseUrl = process.env.ANTHROPIC_BASE_URL || "https://api.anthropic.com", } = options;
|
|
177
|
+
return async (promptTemplate, context) => {
|
|
178
|
+
// Interpolate variables in the prompt
|
|
179
|
+
const userPrompt = interpolatePrompt(promptTemplate, context);
|
|
180
|
+
try {
|
|
181
|
+
// Call the API
|
|
182
|
+
const responseText = await callClaudeAPI(apiKey, model, maxTokens, systemPrompt, userPrompt, baseUrl);
|
|
183
|
+
if (!responseText) {
|
|
184
|
+
return { decision: "allow" };
|
|
185
|
+
}
|
|
186
|
+
// Parse the response
|
|
187
|
+
return parseHookOutput(responseText);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
191
|
+
// On error, allow by default but log the issue
|
|
192
|
+
console.error(`[PromptEvaluator] Error evaluating hook: ${errorMessage}`);
|
|
193
|
+
return {
|
|
194
|
+
decision: "allow",
|
|
195
|
+
reason: `Hook evaluation failed: ${errorMessage}`,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Create a mock prompt evaluator for testing
|
|
202
|
+
* Returns canned responses based on patterns in the prompt
|
|
203
|
+
*/
|
|
204
|
+
export function createMockPromptEvaluator() {
|
|
205
|
+
return async (promptTemplate, context) => {
|
|
206
|
+
// Simple mock logic for testing
|
|
207
|
+
const prompt = promptTemplate.toLowerCase();
|
|
208
|
+
const toolInput = context.tool_input;
|
|
209
|
+
// If checking for MCP alternatives and we have a Bash command
|
|
210
|
+
if (prompt.includes("mcp") && toolInput && "command" in toolInput) {
|
|
211
|
+
const command = String(toolInput.command);
|
|
212
|
+
// Check for common patterns that have MCP alternatives
|
|
213
|
+
if (command.includes("git status")) {
|
|
214
|
+
return {
|
|
215
|
+
decision: "deny",
|
|
216
|
+
reason: "Consider using the Git MCP tool instead of running git commands directly",
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (command.includes("gh ")) {
|
|
220
|
+
return {
|
|
221
|
+
decision: "deny",
|
|
222
|
+
reason: "Consider using the GitHub MCP tool instead of gh CLI",
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Default allow
|
|
227
|
+
return { decision: "allow" };
|
|
228
|
+
};
|
|
229
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill System - Custom agent behaviors
|
|
3
|
+
*/
|
|
4
|
+
import type { ClaudeModel } from "../../types/index.js";
|
|
5
|
+
export interface SkillFile {
|
|
6
|
+
path: string;
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
prompt: string;
|
|
10
|
+
tools?: string[];
|
|
11
|
+
model?: ClaudeModel;
|
|
12
|
+
color?: string;
|
|
13
|
+
source: "built-in" | "project" | "user";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse a SKILL.md file with YAML frontmatter
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseSkillFile(path: string, source?: "built-in" | "project" | "user"): SkillFile | null;
|
|
19
|
+
export declare class SkillManager {
|
|
20
|
+
private skills;
|
|
21
|
+
/**
|
|
22
|
+
* Load skills from a directory
|
|
23
|
+
*/
|
|
24
|
+
loadFromDirectory(dir: string, source?: "built-in" | "project" | "user"): number;
|
|
25
|
+
/**
|
|
26
|
+
* Get a skill by name
|
|
27
|
+
*/
|
|
28
|
+
get(name: string): SkillFile | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get all skills
|
|
31
|
+
*/
|
|
32
|
+
getAll(): SkillFile[];
|
|
33
|
+
/**
|
|
34
|
+
* Check if skill exists
|
|
35
|
+
*/
|
|
36
|
+
has(name: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Get skill names
|
|
39
|
+
*/
|
|
40
|
+
getNames(): string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the skill prompt that gets injected into system prompt
|
|
44
|
+
*/
|
|
45
|
+
export declare function buildSkillPrompt(skill: SkillFile): string;
|
|
46
|
+
export declare const builtInSkills: SkillFile[];
|
|
47
|
+
/**
|
|
48
|
+
* Check if a message is a skill invocation
|
|
49
|
+
*/
|
|
50
|
+
export declare function isSkillInvocation(message: string): string | null;
|
|
51
|
+
/**
|
|
52
|
+
* Get skill invocation arguments
|
|
53
|
+
*/
|
|
54
|
+
export declare function getSkillArgs(message: string): string;
|
|
55
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../packages/src/ecosystem/skills/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIzE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;CACzC;AAMD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,UAAU,GAAG,SAAS,GAAG,MAAkB,GAAG,SAAS,GAAG,IAAI,CAoClH;AAkDD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAgC;IAE9C;;OAEG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,UAAU,GAAG,SAAS,GAAG,MAAkB,GAAG,MAAM;IAqB3F;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIxC;;OAEG;IACH,MAAM,IAAI,SAAS,EAAE;IAIrB;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;CAGrB;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CASzD;AAMD,eAAO,MAAM,aAAa,EAAE,SAAS,EAoFpC,CAAC;AAMF;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGpD"}
|