@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,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console Suppression Utilities
|
|
3
|
+
* Manages console output suppression during TUI mode
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Store original console methods for restoration
|
|
8
|
+
*/
|
|
9
|
+
const originalConsole = {
|
|
10
|
+
log: console.log,
|
|
11
|
+
error: console.error,
|
|
12
|
+
warn: console.warn,
|
|
13
|
+
info: console.info,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Suppress all console output during TUI mode
|
|
18
|
+
* Prevents TUI corruption from stray console output
|
|
19
|
+
*/
|
|
20
|
+
export function suppressConsole(): void {
|
|
21
|
+
console.log = () => {};
|
|
22
|
+
console.error = () => {};
|
|
23
|
+
console.warn = () => {};
|
|
24
|
+
console.info = () => {};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Restore original console methods
|
|
29
|
+
* Call when exiting TUI mode
|
|
30
|
+
*/
|
|
31
|
+
export function restoreConsole(): void {
|
|
32
|
+
console.log = originalConsole.log;
|
|
33
|
+
console.error = originalConsole.error;
|
|
34
|
+
console.warn = originalConsole.warn;
|
|
35
|
+
console.info = originalConsole.info;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Execute a function with console suppressed
|
|
40
|
+
* Automatically restores console after execution
|
|
41
|
+
*/
|
|
42
|
+
export async function withSuppressedConsole<T>(fn: () => Promise<T>): Promise<T> {
|
|
43
|
+
suppressConsole();
|
|
44
|
+
try {
|
|
45
|
+
return await fn();
|
|
46
|
+
} finally {
|
|
47
|
+
restoreConsole();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI Module Exports
|
|
3
|
+
* Re-exports all components and utilities from the modular TUI package
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Types
|
|
7
|
+
export type {
|
|
8
|
+
InteractiveTUIProps,
|
|
9
|
+
SessionStore,
|
|
10
|
+
MessageAreaProps,
|
|
11
|
+
StatusBarProps,
|
|
12
|
+
InputFieldProps,
|
|
13
|
+
TerminalLayout,
|
|
14
|
+
CommandContext,
|
|
15
|
+
ContextInfo,
|
|
16
|
+
} from "./types.js";
|
|
17
|
+
|
|
18
|
+
// Console utilities
|
|
19
|
+
export { suppressConsole, restoreConsole, withSuppressedConsole } from "./console.js";
|
|
20
|
+
|
|
21
|
+
// Spinner utilities
|
|
22
|
+
export {
|
|
23
|
+
spinnerFrames,
|
|
24
|
+
dotSpinnerFrames,
|
|
25
|
+
asciiSpinnerFrames,
|
|
26
|
+
arrowSpinnerFrames,
|
|
27
|
+
simpleDotFrames,
|
|
28
|
+
nextFrame,
|
|
29
|
+
getFrame,
|
|
30
|
+
createSpinnerIterator,
|
|
31
|
+
} from "./spinner.js";
|
|
32
|
+
|
|
33
|
+
// Components
|
|
34
|
+
export { MessageArea } from "./MessageArea.js";
|
|
35
|
+
export { StatusBar } from "./StatusBar.js";
|
|
36
|
+
export { InputField } from "./InputField.js";
|
|
37
|
+
|
|
38
|
+
// Hooks
|
|
39
|
+
export { useInputHandler as useInputFieldHandler, useExitHandler } from "./useInputHandler.js";
|
|
40
|
+
|
|
41
|
+
// Commands
|
|
42
|
+
export { handleCommand, getHelpText } from "./commands.js";
|
|
43
|
+
|
|
44
|
+
// Main component and entry point
|
|
45
|
+
export { default as InteractiveTUI } from "./InteractiveTUI.js";
|
|
46
|
+
export { runInteractiveTUI } from "./run.js";
|
|
47
|
+
|
|
48
|
+
// TUI App (Ink-based)
|
|
49
|
+
export {
|
|
50
|
+
createTUIApp,
|
|
51
|
+
type TUIAppProps,
|
|
52
|
+
type TUIAppHandle,
|
|
53
|
+
type Message as TUIMessage,
|
|
54
|
+
} from "./tui-app.js";
|
|
55
|
+
export { default as TUIApp } from "./tui-app.js";
|
|
56
|
+
|
|
57
|
+
// TUI Footer
|
|
58
|
+
export {
|
|
59
|
+
TUIFooter,
|
|
60
|
+
getTUIFooter,
|
|
61
|
+
enableTUIFooter,
|
|
62
|
+
disableTUIFooter,
|
|
63
|
+
renderTUIFooter,
|
|
64
|
+
clearTUIFooter,
|
|
65
|
+
ANSI,
|
|
66
|
+
type TUIFooterOptions,
|
|
67
|
+
type TUIFooterState,
|
|
68
|
+
} from "./tui-footer.js";
|
|
69
|
+
|
|
70
|
+
// Input Context (centralized keyboard input management)
|
|
71
|
+
export {
|
|
72
|
+
InputProvider,
|
|
73
|
+
useInputContext,
|
|
74
|
+
useInputHandler,
|
|
75
|
+
useInputFocus,
|
|
76
|
+
useInputBlock,
|
|
77
|
+
InputPriority,
|
|
78
|
+
type InputHandler,
|
|
79
|
+
type InputHandlerOptions,
|
|
80
|
+
type InputContextValue,
|
|
81
|
+
} from "./InputContext.js";
|
|
82
|
+
|
|
83
|
+
// Message Store (centralized message state management)
|
|
84
|
+
export {
|
|
85
|
+
MessageStoreProvider,
|
|
86
|
+
useMessageStore,
|
|
87
|
+
type UIMessage,
|
|
88
|
+
type MessageSubType,
|
|
89
|
+
type MessageStoreValue,
|
|
90
|
+
} from "./MessageStore.js";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI Entry Point
|
|
3
|
+
* Renders and runs the InteractiveTUI
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: Ink manages terminal state (raw mode, stdin).
|
|
6
|
+
* The native input hook reads events without managing raw mode.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React from "react";
|
|
10
|
+
import { render } from "ink";
|
|
11
|
+
import InteractiveTUI from "./InteractiveTUI.js";
|
|
12
|
+
import { suppressConsole, restoreConsole } from "./console.js";
|
|
13
|
+
import type { InteractiveTUIProps } from "./types.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Run the interactive TUI
|
|
17
|
+
*/
|
|
18
|
+
export async function runInteractiveTUI(
|
|
19
|
+
options: InteractiveTUIProps
|
|
20
|
+
): Promise<void> {
|
|
21
|
+
// Suppress console output to prevent TUI corruption
|
|
22
|
+
suppressConsole();
|
|
23
|
+
|
|
24
|
+
// Ink manages raw mode and stdin
|
|
25
|
+
// Native input reads events without touching raw mode
|
|
26
|
+
const { unmount, waitUntilExit } = render(
|
|
27
|
+
<InteractiveTUI {...options} />,
|
|
28
|
+
{
|
|
29
|
+
exitOnCtrlC: false,
|
|
30
|
+
// Ensure Ink uses stdin properly
|
|
31
|
+
stdin: process.stdin,
|
|
32
|
+
stdout: process.stdout,
|
|
33
|
+
stderr: process.stderr,
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
await waitUntilExit();
|
|
38
|
+
unmount();
|
|
39
|
+
|
|
40
|
+
// Restore console output
|
|
41
|
+
restoreConsole();
|
|
42
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spinner Animation
|
|
3
|
+
* Provides animated spinner frames for loading indicators
|
|
4
|
+
*
|
|
5
|
+
* This is the single source of truth for all spinner frames in Coder.
|
|
6
|
+
* Other modules should import from here rather than defining their own.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ============================================
|
|
10
|
+
// SPINNER FRAME DEFINITIONS
|
|
11
|
+
// ============================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Standard braille spinner frames (default)
|
|
15
|
+
* Used by: ora spinner, TUI footer, Ink components
|
|
16
|
+
*/
|
|
17
|
+
export const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"] as const;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Alternative dot spinner frames
|
|
21
|
+
* Rising dots pattern
|
|
22
|
+
*/
|
|
23
|
+
export const dotSpinnerFrames = ["⠁", "⠂", "⠄", "⡀", "⢀", "⠠", "⠐", "⠈"] as const;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Simple ASCII spinner frames
|
|
27
|
+
* Fallback for limited terminal support
|
|
28
|
+
*/
|
|
29
|
+
export const asciiSpinnerFrames = ["|", "/", "-", "\\"] as const;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Arrow spinner frames
|
|
33
|
+
* Used for tool execution indicators
|
|
34
|
+
*/
|
|
35
|
+
export const arrowSpinnerFrames = ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"] as const;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Simple dots for minimal display
|
|
39
|
+
*/
|
|
40
|
+
export const simpleDotFrames = [". ", ".. ", "...", " "] as const;
|
|
41
|
+
|
|
42
|
+
// ============================================
|
|
43
|
+
// FRAME ITERATION UTILITIES
|
|
44
|
+
// ============================================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get the next spinner frame index
|
|
48
|
+
*/
|
|
49
|
+
export function nextFrame(currentIndex: number, frames: readonly string[] = spinnerFrames): number {
|
|
50
|
+
return (currentIndex + 1) % frames.length;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get a spinner frame by index (with wraparound)
|
|
55
|
+
*/
|
|
56
|
+
export function getFrame(index: number, frames: readonly string[] = spinnerFrames): string {
|
|
57
|
+
return frames[index % frames.length] ?? frames[0] ?? "";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Create a spinner iterator
|
|
62
|
+
*/
|
|
63
|
+
export function* createSpinnerIterator(frames: readonly string[] = spinnerFrames): Generator<string, never, unknown> {
|
|
64
|
+
let index = 0;
|
|
65
|
+
while (true) {
|
|
66
|
+
yield getFrame(index, frames);
|
|
67
|
+
index = nextFrame(index, frames);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI App Component for Coder CLI
|
|
3
|
+
* Full Ink-based TUI with message area, status bar, and input field
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { useState, useEffect, useCallback, useRef } from "react";
|
|
7
|
+
import { render, Box, Text, useInput, useApp, useStdout } from "ink";
|
|
8
|
+
import type { Key } from "ink";
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
import type { PermissionMode } from "../../../../types/index.js";
|
|
11
|
+
import {
|
|
12
|
+
calculateContextInfo,
|
|
13
|
+
getPermissionModeDisplay,
|
|
14
|
+
} from "../shared/status-line.js";
|
|
15
|
+
import { spinnerFrames } from "./spinner.js";
|
|
16
|
+
|
|
17
|
+
// ============================================
|
|
18
|
+
// TYPES
|
|
19
|
+
// ============================================
|
|
20
|
+
|
|
21
|
+
export interface Message {
|
|
22
|
+
id: string;
|
|
23
|
+
role: "user" | "assistant" | "system";
|
|
24
|
+
content: string;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface TUIAppProps {
|
|
29
|
+
permissionMode: PermissionMode;
|
|
30
|
+
tokensUsed: number;
|
|
31
|
+
model: string;
|
|
32
|
+
messages: Message[];
|
|
33
|
+
isLoading?: boolean;
|
|
34
|
+
onSubmit: (value: string) => Promise<void>;
|
|
35
|
+
onExit?: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ============================================
|
|
39
|
+
// MESSAGE AREA COMPONENT
|
|
40
|
+
// ============================================
|
|
41
|
+
|
|
42
|
+
interface MessageAreaProps {
|
|
43
|
+
messages: Message[];
|
|
44
|
+
isLoading?: boolean;
|
|
45
|
+
height: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function MessageArea({ messages, isLoading, height }: MessageAreaProps) {
|
|
49
|
+
const visibleMessages = messages.slice(-height + 2); // Reserve 2 lines for padding
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<Box flexDirection="column" height={height} overflow="hidden">
|
|
53
|
+
{visibleMessages.map((msg) => (
|
|
54
|
+
<Box key={msg.id} flexDirection="column" marginBottom={1}>
|
|
55
|
+
<Text bold color={msg.role === "user" ? "cyan" : "magenta"}>
|
|
56
|
+
{msg.role === "user" ? "You:" : "Claude:"}
|
|
57
|
+
</Text>
|
|
58
|
+
<Text dimColor={msg.role === "system"}>{msg.content}</Text>
|
|
59
|
+
</Box>
|
|
60
|
+
))}
|
|
61
|
+
{isLoading && (
|
|
62
|
+
<Box>
|
|
63
|
+
<Text dimColor>Thinking...</Text>
|
|
64
|
+
</Box>
|
|
65
|
+
)}
|
|
66
|
+
</Box>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ============================================
|
|
71
|
+
// STATUS BAR COMPONENT
|
|
72
|
+
// ============================================
|
|
73
|
+
|
|
74
|
+
interface StatusBarProps {
|
|
75
|
+
permissionMode: PermissionMode;
|
|
76
|
+
tokensUsed: number;
|
|
77
|
+
model: string;
|
|
78
|
+
isLoading?: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function StatusBar({
|
|
82
|
+
permissionMode,
|
|
83
|
+
tokensUsed,
|
|
84
|
+
model,
|
|
85
|
+
isLoading,
|
|
86
|
+
}: StatusBarProps) {
|
|
87
|
+
const [frame, setFrame] = useState(0);
|
|
88
|
+
const contextInfo = calculateContextInfo(tokensUsed, model);
|
|
89
|
+
const permDisplay = getPermissionModeDisplay(permissionMode);
|
|
90
|
+
|
|
91
|
+
// Spinner animation
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (!isLoading) return;
|
|
94
|
+
|
|
95
|
+
const interval = setInterval(() => {
|
|
96
|
+
setFrame((f) => (f + 1) % spinnerFrames.length);
|
|
97
|
+
}, 80);
|
|
98
|
+
|
|
99
|
+
return () => clearInterval(interval);
|
|
100
|
+
}, [isLoading]);
|
|
101
|
+
|
|
102
|
+
// Build status line
|
|
103
|
+
const parts: string[] = [];
|
|
104
|
+
|
|
105
|
+
// Loading spinner
|
|
106
|
+
if (isLoading) {
|
|
107
|
+
parts.push(chalk.cyan(spinnerFrames[frame]));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Context percentage
|
|
111
|
+
const contextValue = contextInfo.isCritical
|
|
112
|
+
? chalk.red(`${contextInfo.percentRemaining.toFixed(0)}%`)
|
|
113
|
+
: contextInfo.isLow
|
|
114
|
+
? chalk.yellow(`${contextInfo.percentRemaining.toFixed(0)}%`)
|
|
115
|
+
: `${contextInfo.percentRemaining.toFixed(0)}%`;
|
|
116
|
+
parts.push(`Context: ${contextValue}`);
|
|
117
|
+
|
|
118
|
+
// Permission mode
|
|
119
|
+
const permColor = permDisplay.color as "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white" | "gray";
|
|
120
|
+
const colorFn = chalk[permColor]?.bind(chalk) ?? chalk.gray;
|
|
121
|
+
parts.push(`${colorFn(permDisplay.symbol)} ${permDisplay.label}`);
|
|
122
|
+
|
|
123
|
+
const statusText = parts.join(" | ");
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<Box width="100%" paddingX={1}>
|
|
127
|
+
<Text dimColor>{statusText}</Text>
|
|
128
|
+
</Box>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ============================================
|
|
133
|
+
// INPUT FIELD COMPONENT
|
|
134
|
+
// ============================================
|
|
135
|
+
|
|
136
|
+
interface InputFieldProps {
|
|
137
|
+
value: string;
|
|
138
|
+
onChange: (value: string) => void;
|
|
139
|
+
onSubmit: (value: string) => void;
|
|
140
|
+
placeholder?: string;
|
|
141
|
+
isActive?: boolean;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function InputField({
|
|
145
|
+
value,
|
|
146
|
+
onChange,
|
|
147
|
+
onSubmit,
|
|
148
|
+
placeholder = "Type your message... (/help for commands)",
|
|
149
|
+
isActive = true,
|
|
150
|
+
}: InputFieldProps) {
|
|
151
|
+
const [cursorPos, setCursorPos] = useState(0);
|
|
152
|
+
|
|
153
|
+
useInput(
|
|
154
|
+
(input, key) => {
|
|
155
|
+
if (!isActive) return;
|
|
156
|
+
|
|
157
|
+
if (key.return) {
|
|
158
|
+
if (value.trim()) {
|
|
159
|
+
onSubmit(value);
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (key.backspace || key.delete) {
|
|
165
|
+
if (cursorPos > 0) {
|
|
166
|
+
onChange(value.slice(0, cursorPos - 1) + value.slice(cursorPos));
|
|
167
|
+
setCursorPos(cursorPos - 1);
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (key.leftArrow) {
|
|
173
|
+
setCursorPos(Math.max(0, cursorPos - 1));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (key.rightArrow) {
|
|
178
|
+
setCursorPos(Math.min(value.length, cursorPos + 1));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (key.upArrow || key.downArrow) {
|
|
183
|
+
// Ignore up/down for now (could be used for history)
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Regular character input
|
|
188
|
+
if (input && !key.ctrl && !key.meta) {
|
|
189
|
+
onChange(value.slice(0, cursorPos) + input + value.slice(cursorPos));
|
|
190
|
+
setCursorPos(cursorPos + input.length);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
{ isActive }
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
// Display value with cursor
|
|
197
|
+
const displayValue = value.length > 0 ? value : chalk.dim(placeholder);
|
|
198
|
+
const cursorChar = value.length > 0 ? "▋" : chalk.dim("▋");
|
|
199
|
+
|
|
200
|
+
// Calculate where cursor should appear
|
|
201
|
+
const beforeCursor = value.slice(0, cursorPos);
|
|
202
|
+
const afterCursor = value.slice(cursorPos);
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<Box borderStyle="round" borderColor="cyan" paddingX={1} width="100%">
|
|
206
|
+
<Text bold color="cyan">
|
|
207
|
+
You:{" "}
|
|
208
|
+
</Text>
|
|
209
|
+
{value.length > 0 ? (
|
|
210
|
+
<Text>
|
|
211
|
+
{beforeCursor}
|
|
212
|
+
{cursorChar}
|
|
213
|
+
{afterCursor}
|
|
214
|
+
</Text>
|
|
215
|
+
) : (
|
|
216
|
+
<Text dimColor>{placeholder}</Text>
|
|
217
|
+
)}
|
|
218
|
+
</Box>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ============================================
|
|
223
|
+
// MAIN TUI APP COMPONENT
|
|
224
|
+
// ============================================
|
|
225
|
+
|
|
226
|
+
function TUIApp({
|
|
227
|
+
permissionMode,
|
|
228
|
+
tokensUsed,
|
|
229
|
+
model,
|
|
230
|
+
messages,
|
|
231
|
+
isLoading = false,
|
|
232
|
+
onSubmit,
|
|
233
|
+
onExit,
|
|
234
|
+
}: TUIAppProps) {
|
|
235
|
+
const [inputValue, setInputValue] = useState("");
|
|
236
|
+
const { exit } = useApp();
|
|
237
|
+
const { stdout } = useStdout();
|
|
238
|
+
|
|
239
|
+
// Calculate heights
|
|
240
|
+
const terminalHeight = stdout.rows || 24;
|
|
241
|
+
const inputHeight = 3; // Input field with border
|
|
242
|
+
const statusHeight = 1; // Status bar
|
|
243
|
+
const messageHeight = Math.max(5, terminalHeight - inputHeight - statusHeight - 2);
|
|
244
|
+
|
|
245
|
+
// Handle global keybindings
|
|
246
|
+
useInput(
|
|
247
|
+
(input, key) => {
|
|
248
|
+
// Ctrl+C to exit
|
|
249
|
+
if (key.ctrl && input === "c") {
|
|
250
|
+
if (onExit) onExit();
|
|
251
|
+
exit();
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
{ isActive: true }
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
// Handle submit
|
|
258
|
+
const handleSubmit = useCallback(
|
|
259
|
+
async (value: string) => {
|
|
260
|
+
if (!value.trim()) return;
|
|
261
|
+
|
|
262
|
+
// Clear input
|
|
263
|
+
setInputValue("");
|
|
264
|
+
|
|
265
|
+
// Call onSubmit
|
|
266
|
+
await onSubmit(value);
|
|
267
|
+
},
|
|
268
|
+
[onSubmit]
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
return (
|
|
272
|
+
<Box flexDirection="column" height={terminalHeight} width="100%">
|
|
273
|
+
{/* Message area (scrollable) */}
|
|
274
|
+
<Box flexGrow={1} flexDirection="column" overflow="hidden">
|
|
275
|
+
<MessageArea
|
|
276
|
+
messages={messages}
|
|
277
|
+
isLoading={isLoading}
|
|
278
|
+
height={messageHeight}
|
|
279
|
+
/>
|
|
280
|
+
</Box>
|
|
281
|
+
|
|
282
|
+
{/* Status bar */}
|
|
283
|
+
<StatusBar
|
|
284
|
+
permissionMode={permissionMode}
|
|
285
|
+
tokensUsed={tokensUsed}
|
|
286
|
+
model={model}
|
|
287
|
+
isLoading={isLoading}
|
|
288
|
+
/>
|
|
289
|
+
|
|
290
|
+
{/* Input field */}
|
|
291
|
+
<InputField
|
|
292
|
+
value={inputValue}
|
|
293
|
+
onChange={setInputValue}
|
|
294
|
+
onSubmit={handleSubmit}
|
|
295
|
+
isActive={!isLoading}
|
|
296
|
+
/>
|
|
297
|
+
</Box>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// ============================================
|
|
302
|
+
// RENDER FUNCTION
|
|
303
|
+
// ============================================
|
|
304
|
+
|
|
305
|
+
export interface TUIAppHandle {
|
|
306
|
+
rerender: (props: Partial<TUIAppProps>) => void;
|
|
307
|
+
unmount: () => void;
|
|
308
|
+
waitUntilExit: () => Promise<void>;
|
|
309
|
+
addMessage: (message: Omit<Message, "id" | "timestamp">) => void;
|
|
310
|
+
setMessages: (messages: Message[]) => void;
|
|
311
|
+
setLoading: (isLoading: boolean) => void;
|
|
312
|
+
setTokensUsed: (tokens: number) => void;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Create and render the TUI app
|
|
317
|
+
*/
|
|
318
|
+
export function createTUIApp(
|
|
319
|
+
initialProps: Omit<TUIAppProps, "messages"> & { messages?: Message[] }
|
|
320
|
+
): TUIAppHandle {
|
|
321
|
+
let currentProps: TUIAppProps = {
|
|
322
|
+
...initialProps,
|
|
323
|
+
messages: initialProps.messages || [],
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
let rerenderFn: ((node: React.ReactNode) => void) | null = null;
|
|
327
|
+
let unmountFn: (() => void) | null = null;
|
|
328
|
+
let waitUntilExitFn: (() => Promise<void>) | null = null;
|
|
329
|
+
|
|
330
|
+
// Create the app
|
|
331
|
+
const { rerender, unmount, waitUntilExit } = render(
|
|
332
|
+
<TUIApp {...currentProps} />,
|
|
333
|
+
{
|
|
334
|
+
exitOnCtrlC: false,
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
rerenderFn = rerender;
|
|
339
|
+
unmountFn = unmount;
|
|
340
|
+
waitUntilExitFn = waitUntilExit;
|
|
341
|
+
|
|
342
|
+
return {
|
|
343
|
+
rerender: (newProps) => {
|
|
344
|
+
currentProps = { ...currentProps, ...newProps };
|
|
345
|
+
rerenderFn?.(<TUIApp {...currentProps} />);
|
|
346
|
+
},
|
|
347
|
+
|
|
348
|
+
unmount: () => {
|
|
349
|
+
unmountFn?.();
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
waitUntilExit: () => {
|
|
353
|
+
return waitUntilExitFn?.() || Promise.resolve();
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
addMessage: (message) => {
|
|
357
|
+
const newMessage: Message = {
|
|
358
|
+
...message,
|
|
359
|
+
id: `msg-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
360
|
+
timestamp: Date.now(),
|
|
361
|
+
};
|
|
362
|
+
currentProps = {
|
|
363
|
+
...currentProps,
|
|
364
|
+
messages: [...currentProps.messages, newMessage],
|
|
365
|
+
};
|
|
366
|
+
rerenderFn?.(<TUIApp {...currentProps} />);
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
setMessages: (messages) => {
|
|
370
|
+
currentProps = { ...currentProps, messages };
|
|
371
|
+
rerenderFn?.(<TUIApp {...currentProps} />);
|
|
372
|
+
},
|
|
373
|
+
|
|
374
|
+
setLoading: (isLoading) => {
|
|
375
|
+
currentProps = { ...currentProps, isLoading };
|
|
376
|
+
rerenderFn?.(<TUIApp {...currentProps} />);
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
setTokensUsed: (tokensUsed) => {
|
|
380
|
+
currentProps = { ...currentProps, tokensUsed };
|
|
381
|
+
rerenderFn?.(<TUIApp {...currentProps} />);
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// ============================================
|
|
387
|
+
// EXPORTS
|
|
388
|
+
// ============================================
|
|
389
|
+
|
|
390
|
+
export default TUIApp;
|