@yeshwanthyk/coding-agent 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/adapters/acp/index.d.ts +10 -0
- package/dist/adapters/acp/index.d.ts.map +1 -0
- package/dist/adapters/acp/index.js +250 -0
- package/dist/adapters/acp/index.js.map +1 -0
- package/dist/adapters/acp/protocol.d.ts +171 -0
- package/dist/adapters/acp/protocol.d.ts.map +1 -0
- package/dist/adapters/acp/protocol.js +25 -0
- package/dist/adapters/acp/protocol.js.map +1 -0
- package/dist/adapters/acp/session.d.ts +33 -0
- package/dist/adapters/acp/session.d.ts.map +1 -0
- package/dist/adapters/acp/session.js +216 -0
- package/dist/adapters/acp/session.js.map +1 -0
- package/dist/adapters/acp/updates.d.ts +17 -0
- package/dist/adapters/acp/updates.d.ts.map +1 -0
- package/dist/adapters/acp/updates.js +62 -0
- package/dist/adapters/acp/updates.js.map +1 -0
- package/dist/adapters/cli/headless.d.ts +7 -0
- package/dist/adapters/cli/headless.d.ts.map +1 -0
- package/dist/adapters/cli/headless.js +93 -0
- package/dist/adapters/cli/headless.js.map +1 -0
- package/dist/adapters/cli/validate.d.ts +3 -0
- package/dist/adapters/cli/validate.d.ts.map +1 -0
- package/dist/adapters/cli/validate.js +40 -0
- package/dist/adapters/cli/validate.js.map +1 -0
- package/dist/adapters/tui/app.d.ts +8 -0
- package/dist/adapters/tui/app.d.ts.map +1 -0
- package/dist/adapters/tui/app.jsx +25 -0
- package/dist/adapters/tui/app.jsx.map +1 -0
- package/dist/agent-events.d.ts +63 -0
- package/dist/agent-events.d.ts.map +1 -0
- package/dist/agent-events.js +510 -0
- package/dist/agent-events.js.map +1 -0
- package/dist/args.d.ts +18 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +87 -0
- package/dist/args.js.map +1 -0
- package/dist/autocomplete-commands.d.ts +26 -0
- package/dist/autocomplete-commands.d.ts.map +1 -0
- package/dist/autocomplete-commands.js +82 -0
- package/dist/autocomplete-commands.js.map +1 -0
- package/dist/commands.d.ts +10 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +17 -0
- package/dist/commands.js.map +1 -0
- package/dist/compact-handler.d.ts +42 -0
- package/dist/compact-handler.d.ts.map +1 -0
- package/dist/compact-handler.js +211 -0
- package/dist/compact-handler.js.map +1 -0
- package/dist/components/Footer.d.ts +9 -0
- package/dist/components/Footer.d.ts.map +1 -0
- package/dist/components/Footer.jsx +36 -0
- package/dist/components/Footer.jsx.map +1 -0
- package/dist/components/Header.d.ts +23 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.jsx +174 -0
- package/dist/components/Header.jsx.map +1 -0
- package/dist/components/MessageList.d.ts +19 -0
- package/dist/components/MessageList.d.ts.map +1 -0
- package/dist/components/MessageList.jsx +237 -0
- package/dist/components/MessageList.jsx.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/domain/commands/builtin/clear.d.ts +3 -0
- package/dist/domain/commands/builtin/clear.d.ts.map +1 -0
- package/dist/domain/commands/builtin/clear.js +13 -0
- package/dist/domain/commands/builtin/clear.js.map +1 -0
- package/dist/domain/commands/builtin/compact.d.ts +3 -0
- package/dist/domain/commands/builtin/compact.d.ts.map +1 -0
- package/dist/domain/commands/builtin/compact.js +84 -0
- package/dist/domain/commands/builtin/compact.js.map +1 -0
- package/dist/domain/commands/builtin/conceal.d.ts +3 -0
- package/dist/domain/commands/builtin/conceal.d.ts.map +1 -0
- package/dist/domain/commands/builtin/conceal.js +8 -0
- package/dist/domain/commands/builtin/conceal.js.map +1 -0
- package/dist/domain/commands/builtin/diffwrap.d.ts +3 -0
- package/dist/domain/commands/builtin/diffwrap.d.ts.map +1 -0
- package/dist/domain/commands/builtin/diffwrap.js +8 -0
- package/dist/domain/commands/builtin/diffwrap.js.map +1 -0
- package/dist/domain/commands/builtin/editor.d.ts +3 -0
- package/dist/domain/commands/builtin/editor.d.ts.map +1 -0
- package/dist/domain/commands/builtin/editor.js +22 -0
- package/dist/domain/commands/builtin/editor.js.map +1 -0
- package/dist/domain/commands/builtin/exit.d.ts +3 -0
- package/dist/domain/commands/builtin/exit.d.ts.map +1 -0
- package/dist/domain/commands/builtin/exit.js +14 -0
- package/dist/domain/commands/builtin/exit.js.map +1 -0
- package/dist/domain/commands/builtin/followup.d.ts +3 -0
- package/dist/domain/commands/builtin/followup.d.ts.map +1 -0
- package/dist/domain/commands/builtin/followup.js +20 -0
- package/dist/domain/commands/builtin/followup.js.map +1 -0
- package/dist/domain/commands/builtin/index.d.ts +2 -0
- package/dist/domain/commands/builtin/index.d.ts.map +1 -0
- package/dist/domain/commands/builtin/index.js +29 -0
- package/dist/domain/commands/builtin/index.js.map +1 -0
- package/dist/domain/commands/builtin/login.d.ts +3 -0
- package/dist/domain/commands/builtin/login.d.ts.map +1 -0
- package/dist/domain/commands/builtin/login.js +92 -0
- package/dist/domain/commands/builtin/login.js.map +1 -0
- package/dist/domain/commands/builtin/model.d.ts +3 -0
- package/dist/domain/commands/builtin/model.d.ts.map +1 -0
- package/dist/domain/commands/builtin/model.js +53 -0
- package/dist/domain/commands/builtin/model.js.map +1 -0
- package/dist/domain/commands/builtin/status.d.ts +3 -0
- package/dist/domain/commands/builtin/status.d.ts.map +1 -0
- package/dist/domain/commands/builtin/status.js +30 -0
- package/dist/domain/commands/builtin/status.js.map +1 -0
- package/dist/domain/commands/builtin/steer.d.ts +3 -0
- package/dist/domain/commands/builtin/steer.d.ts.map +1 -0
- package/dist/domain/commands/builtin/steer.js +20 -0
- package/dist/domain/commands/builtin/steer.js.map +1 -0
- package/dist/domain/commands/builtin/theme.d.ts +3 -0
- package/dist/domain/commands/builtin/theme.d.ts.map +1 -0
- package/dist/domain/commands/builtin/theme.js +19 -0
- package/dist/domain/commands/builtin/theme.js.map +1 -0
- package/dist/domain/commands/builtin/thinking.d.ts +3 -0
- package/dist/domain/commands/builtin/thinking.d.ts.map +1 -0
- package/dist/domain/commands/builtin/thinking.js +16 -0
- package/dist/domain/commands/builtin/thinking.js.map +1 -0
- package/dist/domain/commands/helpers.d.ts +7 -0
- package/dist/domain/commands/helpers.d.ts.map +1 -0
- package/dist/domain/commands/helpers.js +34 -0
- package/dist/domain/commands/helpers.js.map +1 -0
- package/dist/domain/commands/registry.d.ts +10 -0
- package/dist/domain/commands/registry.d.ts.map +1 -0
- package/dist/domain/commands/registry.js +36 -0
- package/dist/domain/commands/registry.js.map +1 -0
- package/dist/domain/commands/types.d.ts +62 -0
- package/dist/domain/commands/types.d.ts.map +1 -0
- package/dist/domain/commands/types.js +2 -0
- package/dist/domain/commands/types.js.map +1 -0
- package/dist/domain/messaging/content.d.ts +37 -0
- package/dist/domain/messaging/content.d.ts.map +1 -0
- package/dist/domain/messaging/content.js +103 -0
- package/dist/domain/messaging/content.js.map +1 -0
- package/dist/editor.d.ts +26 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +81 -0
- package/dist/editor.js.map +1 -0
- package/dist/extensibility/schema.d.ts +2 -0
- package/dist/extensibility/schema.d.ts.map +1 -0
- package/{src/extensibility/schema.ts → dist/extensibility/schema.js} +2 -1
- package/dist/extensibility/schema.js.map +1 -0
- package/dist/extensibility/validation.d.ts +2 -0
- package/dist/extensibility/validation.d.ts.map +1 -0
- package/{src/extensibility/validation.ts → dist/extensibility/validation.js} +2 -1
- package/dist/extensibility/validation.js.map +1 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useAgentEvents.d.ts +8 -0
- package/dist/hooks/useAgentEvents.d.ts.map +1 -0
- package/dist/hooks/useAgentEvents.js +22 -0
- package/dist/hooks/useAgentEvents.js.map +1 -0
- package/dist/hooks/useEditorBridge.d.ts +20 -0
- package/dist/hooks/useEditorBridge.d.ts.map +1 -0
- package/dist/hooks/useEditorBridge.js +80 -0
- package/dist/hooks/useEditorBridge.js.map +1 -0
- package/dist/hooks/useGitStatus.d.ts +2 -0
- package/dist/hooks/useGitStatus.d.ts.map +1 -0
- package/dist/hooks/useGitStatus.js +26 -0
- package/dist/hooks/useGitStatus.js.map +1 -0
- package/dist/hooks/usePromptQueue.d.ts +2 -0
- package/dist/hooks/usePromptQueue.d.ts.map +1 -0
- package/dist/hooks/usePromptQueue.js +2 -0
- package/dist/hooks/usePromptQueue.js.map +1 -0
- package/dist/hooks/useSessionController.d.ts +2 -0
- package/dist/hooks/useSessionController.d.ts.map +1 -0
- package/dist/hooks/useSessionController.js +2 -0
- package/dist/hooks/useSessionController.js.map +1 -0
- package/dist/hooks/useSpinner.d.ts +4 -0
- package/dist/hooks/useSpinner.d.ts.map +1 -0
- package/dist/hooks/useSpinner.js +25 -0
- package/dist/hooks/useSpinner.js.map +1 -0
- package/dist/hooks/useToastManager.d.ts +6 -0
- package/dist/hooks/useToastManager.d.ts.map +1 -0
- package/dist/hooks/useToastManager.js +22 -0
- package/dist/hooks/useToastManager.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +156 -0
- package/dist/index.js.map +1 -0
- package/dist/keyboard-handler.d.ts +30 -0
- package/dist/keyboard-handler.d.ts.map +1 -0
- package/dist/keyboard-handler.js +96 -0
- package/dist/keyboard-handler.js.map +1 -0
- package/dist/profiler.d.ts +2 -0
- package/dist/profiler.d.ts.map +1 -0
- package/dist/profiler.js +41 -0
- package/dist/profiler.js.map +1 -0
- package/dist/runtime/context.d.ts +8 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/context.jsx +11 -0
- package/dist/runtime/context.jsx.map +1 -0
- package/dist/runtime/factory.d.ts +12 -0
- package/dist/runtime/factory.d.ts.map +1 -0
- package/dist/runtime/factory.js +37 -0
- package/dist/runtime/factory.js.map +1 -0
- package/dist/runtime/git/git-info.d.ts +3 -0
- package/dist/runtime/git/git-info.d.ts.map +1 -0
- package/dist/runtime/git/git-info.js +29 -0
- package/dist/runtime/git/git-info.js.map +1 -0
- package/dist/runtime/session/session-controller.d.ts +48 -0
- package/dist/runtime/session/session-controller.d.ts.map +1 -0
- package/dist/runtime/session/session-controller.js +159 -0
- package/dist/runtime/session/session-controller.js.map +1 -0
- package/dist/session-manager.d.ts +2 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +2 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/session-picker.d.ts +6 -0
- package/dist/session-picker.d.ts.map +1 -0
- package/dist/session-picker.jsx +96 -0
- package/dist/session-picker.jsx.map +1 -0
- package/dist/shell-runner.d.ts +21 -0
- package/dist/shell-runner.d.ts.map +1 -0
- package/dist/shell-runner.js +106 -0
- package/dist/shell-runner.js.map +1 -0
- package/dist/syntax-highlighting.d.ts +4 -0
- package/dist/syntax-highlighting.d.ts.map +1 -0
- package/dist/syntax-highlighting.js +108 -0
- package/dist/syntax-highlighting.js.map +1 -0
- package/dist/theme-names.d.ts +7 -0
- package/dist/theme-names.d.ts.map +1 -0
- package/dist/theme-names.js +38 -0
- package/dist/theme-names.js.map +1 -0
- package/dist/tool-ui-contracts.d.ts +30 -0
- package/dist/tool-ui-contracts.d.ts.map +1 -0
- package/dist/tool-ui-contracts.js +53 -0
- package/dist/tool-ui-contracts.js.map +1 -0
- package/dist/tui-open-rendering.d.ts +37 -0
- package/dist/tui-open-rendering.d.ts.map +1 -0
- package/dist/tui-open-rendering.jsx +462 -0
- package/dist/tui-open-rendering.jsx.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/app-shell/TuiApp.d.ts +6 -0
- package/dist/ui/app-shell/TuiApp.d.ts.map +1 -0
- package/dist/ui/app-shell/TuiApp.jsx +480 -0
- package/dist/ui/app-shell/TuiApp.jsx.map +1 -0
- package/dist/ui/clipboard/osc52.d.ts +2 -0
- package/dist/ui/clipboard/osc52.d.ts.map +1 -0
- package/dist/ui/clipboard/osc52.js +19 -0
- package/dist/ui/clipboard/osc52.js.map +1 -0
- package/dist/ui/components/modals/ConfirmModal.d.ts +8 -0
- package/dist/ui/components/modals/ConfirmModal.d.ts.map +1 -0
- package/dist/ui/components/modals/ConfirmModal.jsx +39 -0
- package/dist/ui/components/modals/ConfirmModal.jsx.map +1 -0
- package/dist/ui/components/modals/EditorModal.d.ts +8 -0
- package/dist/ui/components/modals/EditorModal.d.ts.map +1 -0
- package/dist/ui/components/modals/EditorModal.jsx +23 -0
- package/dist/ui/components/modals/EditorModal.jsx.map +1 -0
- package/dist/ui/components/modals/InputModal.d.ts +8 -0
- package/dist/ui/components/modals/InputModal.d.ts.map +1 -0
- package/dist/ui/components/modals/InputModal.jsx +15 -0
- package/dist/ui/components/modals/InputModal.jsx.map +1 -0
- package/dist/ui/components/modals/ModalContainer.d.ts +8 -0
- package/dist/ui/components/modals/ModalContainer.d.ts.map +1 -0
- package/dist/ui/components/modals/ModalContainer.jsx +34 -0
- package/dist/ui/components/modals/ModalContainer.jsx.map +1 -0
- package/dist/ui/components/modals/SelectModal.d.ts +8 -0
- package/dist/ui/components/modals/SelectModal.d.ts.map +1 -0
- package/dist/ui/components/modals/SelectModal.jsx +32 -0
- package/dist/ui/components/modals/SelectModal.jsx.map +1 -0
- package/{src/ui/components/modals/index.ts → dist/ui/components/modals/index.d.ts} +5 -4
- package/dist/ui/components/modals/index.d.ts.map +1 -0
- package/dist/ui/components/modals/index.js +5 -0
- package/dist/ui/components/modals/index.js.map +1 -0
- package/dist/ui/features/composer/Composer.d.ts +16 -0
- package/dist/ui/features/composer/Composer.d.ts.map +1 -0
- package/dist/ui/features/composer/Composer.jsx +39 -0
- package/dist/ui/features/composer/Composer.jsx.map +1 -0
- package/dist/ui/features/composer/SlashCommandHandler.d.ts +14 -0
- package/dist/ui/features/composer/SlashCommandHandler.d.ts.map +1 -0
- package/dist/ui/features/composer/SlashCommandHandler.js +43 -0
- package/dist/ui/features/composer/SlashCommandHandler.js.map +1 -0
- package/dist/ui/features/composer/keyboard.d.ts +3 -0
- package/dist/ui/features/composer/keyboard.d.ts.map +1 -0
- package/dist/ui/features/composer/keyboard.js +3 -0
- package/dist/ui/features/composer/keyboard.js.map +1 -0
- package/dist/ui/features/main-view/MainView.d.ts +52 -0
- package/dist/ui/features/main-view/MainView.d.ts.map +1 -0
- package/dist/ui/features/main-view/MainView.jsx +269 -0
- package/dist/ui/features/main-view/MainView.jsx.map +1 -0
- package/dist/ui/features/message-pane/MessagePane.d.ts +15 -0
- package/dist/ui/features/message-pane/MessagePane.d.ts.map +1 -0
- package/dist/ui/features/message-pane/MessagePane.jsx +7 -0
- package/dist/ui/features/message-pane/MessagePane.jsx.map +1 -0
- package/dist/ui/hooks/useModals.d.ts +35 -0
- package/dist/ui/hooks/useModals.d.ts.map +1 -0
- package/dist/ui/hooks/useModals.js +36 -0
- package/dist/ui/hooks/useModals.js.map +1 -0
- package/dist/ui/state/app-store.d.ts +42 -0
- package/dist/ui/state/app-store.d.ts.map +1 -0
- package/dist/ui/state/app-store.js +28 -0
- package/dist/ui/state/app-store.js.map +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +3 -0
- package/dist/utils.js.map +1 -0
- package/package.json +19 -6
- package/src/adapters/acp/index.ts +0 -305
- package/src/adapters/acp/protocol.ts +0 -191
- package/src/adapters/acp/session.ts +0 -289
- package/src/adapters/acp/updates.ts +0 -96
- package/src/adapters/cli/headless.ts +0 -112
- package/src/adapters/cli/validate.ts +0 -50
- package/src/adapters/tui/app.tsx +0 -39
- package/src/agent-events.ts +0 -671
- package/src/args.ts +0 -102
- package/src/autocomplete-commands.ts +0 -102
- package/src/commands.ts +0 -23
- package/src/compact-handler.ts +0 -272
- package/src/components/Footer.tsx +0 -49
- package/src/components/Header.tsx +0 -218
- package/src/components/MessageList.tsx +0 -380
- package/src/config.ts +0 -1
- package/src/domain/commands/builtin/clear.ts +0 -14
- package/src/domain/commands/builtin/compact.ts +0 -96
- package/src/domain/commands/builtin/conceal.ts +0 -9
- package/src/domain/commands/builtin/diffwrap.ts +0 -9
- package/src/domain/commands/builtin/editor.ts +0 -24
- package/src/domain/commands/builtin/exit.ts +0 -14
- package/src/domain/commands/builtin/followup.ts +0 -24
- package/src/domain/commands/builtin/index.ts +0 -29
- package/src/domain/commands/builtin/login.ts +0 -118
- package/src/domain/commands/builtin/model.ts +0 -66
- package/src/domain/commands/builtin/status.ts +0 -32
- package/src/domain/commands/builtin/steer.ts +0 -24
- package/src/domain/commands/builtin/theme.ts +0 -23
- package/src/domain/commands/builtin/thinking.ts +0 -16
- package/src/domain/commands/helpers.ts +0 -41
- package/src/domain/commands/registry.ts +0 -42
- package/src/domain/commands/types.ts +0 -69
- package/src/domain/messaging/content.ts +0 -117
- package/src/editor.ts +0 -103
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useAgentEvents.ts +0 -28
- package/src/hooks/useEditorBridge.ts +0 -101
- package/src/hooks/useGitStatus.ts +0 -28
- package/src/hooks/usePromptQueue.ts +0 -7
- package/src/hooks/useSessionController.ts +0 -5
- package/src/hooks/useSpinner.ts +0 -28
- package/src/hooks/useToastManager.ts +0 -26
- package/src/index.ts +0 -188
- package/src/keyboard-handler.ts +0 -134
- package/src/profiler.ts +0 -40
- package/src/runtime/context.tsx +0 -16
- package/src/runtime/factory.ts +0 -63
- package/src/runtime/git/git-info.ts +0 -25
- package/src/runtime/session/session-controller.ts +0 -208
- package/src/session-manager.ts +0 -1
- package/src/session-picker.tsx +0 -134
- package/src/shell-runner.ts +0 -134
- package/src/syntax-highlighting.ts +0 -114
- package/src/theme-names.ts +0 -37
- package/src/tool-ui-contracts.ts +0 -77
- package/src/tui-open-rendering.tsx +0 -565
- package/src/types.ts +0 -89
- package/src/ui/app-shell/TuiApp.tsx +0 -586
- package/src/ui/clipboard/osc52.ts +0 -18
- package/src/ui/components/modals/ConfirmModal.tsx +0 -52
- package/src/ui/components/modals/EditorModal.tsx +0 -39
- package/src/ui/components/modals/InputModal.tsx +0 -30
- package/src/ui/components/modals/ModalContainer.tsx +0 -67
- package/src/ui/components/modals/SelectModal.tsx +0 -48
- package/src/ui/features/composer/Composer.tsx +0 -73
- package/src/ui/features/composer/SlashCommandHandler.ts +0 -58
- package/src/ui/features/composer/keyboard.ts +0 -3
- package/src/ui/features/main-view/MainView.tsx +0 -367
- package/src/ui/features/message-pane/MessagePane.tsx +0 -34
- package/src/ui/hooks/useModals.ts +0 -74
- package/src/ui/state/app-store.ts +0 -67
- package/src/utils.ts +0 -14
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
export const MESSAGE_CAP = 75
|
|
2
|
-
|
|
3
|
-
export const appendWithCap = <T,>(arr: T[], item: T, cap = MESSAGE_CAP): T[] => {
|
|
4
|
-
const next = [...arr, item]
|
|
5
|
-
return next.length > cap ? next.slice(-cap) : next
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export const getToolText = (result: unknown): string => {
|
|
9
|
-
if (!result || typeof result !== "object") return String(result)
|
|
10
|
-
const maybe = result as { content?: unknown }
|
|
11
|
-
const content = Array.isArray(maybe.content) ? maybe.content : []
|
|
12
|
-
const parts: string[] = []
|
|
13
|
-
for (const block of content) {
|
|
14
|
-
if (typeof block === "object" && block !== null && (block as Record<string, unknown>).type === "text") {
|
|
15
|
-
parts.push((block as Record<string, string>).text)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return parts.join("")
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const getEditDiffText = (result: unknown): string | null => {
|
|
22
|
-
if (!result || typeof result !== "object") return null
|
|
23
|
-
const maybe = result as { details?: { diff?: string } }
|
|
24
|
-
return maybe.details?.diff || null
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const extractText = (content: unknown[]): string => {
|
|
28
|
-
let text = ""
|
|
29
|
-
for (const block of content) {
|
|
30
|
-
if (typeof block !== "object" || block === null) continue
|
|
31
|
-
const b = block as Record<string, unknown>
|
|
32
|
-
if (b.type === "text" && typeof b.text === "string") {
|
|
33
|
-
text += b.text
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return text
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const THINKING_SUMMARY_MAX = 80
|
|
40
|
-
const THINKING_PREVIEW_MAX = 50
|
|
41
|
-
|
|
42
|
-
export const buildThinkingSummary = (full: string): { summary: string; preview: string } => {
|
|
43
|
-
const trimmed = full.trim()
|
|
44
|
-
const lines = trimmed.split("\n").filter((l) => l.trim().length > 20)
|
|
45
|
-
const base = (lines[0]?.trim() || trimmed).slice(0, THINKING_SUMMARY_MAX)
|
|
46
|
-
const summary = base.length >= THINKING_SUMMARY_MAX ? base + "..." : base
|
|
47
|
-
const previewSource = summary || trimmed
|
|
48
|
-
const firstLine = previewSource.split("\n")[0] || ""
|
|
49
|
-
const preview = firstLine.length <= THINKING_PREVIEW_MAX
|
|
50
|
-
? firstLine
|
|
51
|
-
: firstLine.slice(0, THINKING_PREVIEW_MAX - 3) + "..."
|
|
52
|
-
return { summary, preview }
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const extractThinking = (content: unknown[]): { summary: string; preview: string; full: string } | null => {
|
|
56
|
-
for (const block of content) {
|
|
57
|
-
if (typeof block !== "object" || block === null) continue
|
|
58
|
-
const b = block as Record<string, unknown>
|
|
59
|
-
if (b.type === "thinking" && typeof b.thinking === "string") {
|
|
60
|
-
const full = b.thinking
|
|
61
|
-
const { summary, preview } = buildThinkingSummary(full)
|
|
62
|
-
return { summary, preview, full }
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return null
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface ExtractedToolCall {
|
|
69
|
-
id: string
|
|
70
|
-
name: string
|
|
71
|
-
args: unknown
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export const extractToolCalls = (content: unknown[]): ExtractedToolCall[] => {
|
|
75
|
-
const toolCalls: ExtractedToolCall[] = []
|
|
76
|
-
for (const block of content) {
|
|
77
|
-
if (typeof block !== "object" || block === null) continue
|
|
78
|
-
const b = block as Record<string, unknown>
|
|
79
|
-
if (b.type === "toolCall" && typeof b.id === "string" && typeof b.name === "string") {
|
|
80
|
-
toolCalls.push({ id: b.id, name: b.name, args: b.arguments ?? {} })
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return toolCalls
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export type OrderedBlock =
|
|
87
|
-
| { type: "thinking"; id: string; summary: string; preview: string; full: string }
|
|
88
|
-
| { type: "text"; text: string }
|
|
89
|
-
| { type: "toolCall"; id: string; name: string; args: unknown }
|
|
90
|
-
|
|
91
|
-
export const extractOrderedBlocks = (content: unknown[]): OrderedBlock[] => {
|
|
92
|
-
const blocks: OrderedBlock[] = []
|
|
93
|
-
let thinkingCounter = 0
|
|
94
|
-
|
|
95
|
-
for (const block of content) {
|
|
96
|
-
if (typeof block !== "object" || block === null) continue
|
|
97
|
-
const b = block as Record<string, unknown>
|
|
98
|
-
|
|
99
|
-
if (b.type === "thinking" && typeof b.thinking === "string") {
|
|
100
|
-
const full = b.thinking
|
|
101
|
-
const { summary, preview } = buildThinkingSummary(full)
|
|
102
|
-
blocks.push({
|
|
103
|
-
type: "thinking",
|
|
104
|
-
id: `thinking-${thinkingCounter++}`,
|
|
105
|
-
summary,
|
|
106
|
-
preview,
|
|
107
|
-
full,
|
|
108
|
-
})
|
|
109
|
-
} else if (b.type === "text" && typeof b.text === "string") {
|
|
110
|
-
blocks.push({ type: "text", text: b.text })
|
|
111
|
-
} else if (b.type === "toolCall" && typeof b.id === "string" && typeof b.name === "string") {
|
|
112
|
-
blocks.push({ type: "toolCall", id: b.id, name: b.name, args: b.arguments ?? {} })
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return blocks
|
|
117
|
-
}
|
package/src/editor.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"
|
|
2
|
-
import { tmpdir } from "node:os"
|
|
3
|
-
import * as path from "node:path"
|
|
4
|
-
import { spawn } from "node:child_process"
|
|
5
|
-
import type { CliRenderer } from "@yeshwanthyk/open-tui"
|
|
6
|
-
import type { EditorConfig } from "./config.js"
|
|
7
|
-
|
|
8
|
-
const CWD_PLACEHOLDER = "{cwd}"
|
|
9
|
-
const LINE_JUMP_EDITORS = new Set([
|
|
10
|
-
"vi",
|
|
11
|
-
"vim",
|
|
12
|
-
"nvim",
|
|
13
|
-
"emacs",
|
|
14
|
-
"emacsclient",
|
|
15
|
-
"nano",
|
|
16
|
-
"hx",
|
|
17
|
-
"helix",
|
|
18
|
-
"micro",
|
|
19
|
-
"kak",
|
|
20
|
-
"kakoune",
|
|
21
|
-
])
|
|
22
|
-
|
|
23
|
-
const supportsLineJump = (command: string): boolean => {
|
|
24
|
-
const baseName = path.basename(command).toLowerCase()
|
|
25
|
-
return LINE_JUMP_EDITORS.has(baseName)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const buildEditorInvocation = (
|
|
29
|
-
editor: EditorConfig,
|
|
30
|
-
cwd: string,
|
|
31
|
-
options?: { appendCwd?: boolean },
|
|
32
|
-
): { command: string; args: string[] } => {
|
|
33
|
-
const usesCwd = editor.command.includes(CWD_PLACEHOLDER) || editor.args.some((arg) => arg.includes(CWD_PLACEHOLDER))
|
|
34
|
-
const command = editor.command.replaceAll(CWD_PLACEHOLDER, cwd)
|
|
35
|
-
const args = editor.args.map((arg) => arg.replaceAll(CWD_PLACEHOLDER, cwd))
|
|
36
|
-
if (options?.appendCwd !== false && !usesCwd) args.push(cwd)
|
|
37
|
-
return { command, args }
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const runEditor = async (command: string, args: string[], cwd: string): Promise<void> => {
|
|
41
|
-
await new Promise<void>((resolve, reject) => {
|
|
42
|
-
const proc = spawn(command, args, { cwd, stdio: "inherit" })
|
|
43
|
-
proc.once("error", (err) => reject(err))
|
|
44
|
-
proc.once("exit", () => resolve())
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export const openExternalEditor = async (opts: {
|
|
49
|
-
editor: EditorConfig
|
|
50
|
-
cwd: string
|
|
51
|
-
renderer: CliRenderer
|
|
52
|
-
initialValue: string
|
|
53
|
-
}): Promise<string | undefined> => {
|
|
54
|
-
const { command, args } = buildEditorInvocation(opts.editor, opts.cwd, { appendCwd: false })
|
|
55
|
-
const dir = await mkdtemp(path.join(tmpdir(), "marvin-editor-"))
|
|
56
|
-
const filePath = path.join(dir, "prompt.md")
|
|
57
|
-
let suspended = false
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
await writeFile(filePath, opts.initialValue, "utf8")
|
|
61
|
-
opts.renderer.suspend()
|
|
62
|
-
suspended = true
|
|
63
|
-
opts.renderer.currentRenderBuffer.clear()
|
|
64
|
-
await runEditor(command, [...args, filePath], opts.cwd)
|
|
65
|
-
const content = await readFile(filePath, "utf8")
|
|
66
|
-
return content.length > 0 ? content : undefined
|
|
67
|
-
} finally {
|
|
68
|
-
if (suspended) {
|
|
69
|
-
opts.renderer.currentRenderBuffer.clear()
|
|
70
|
-
opts.renderer.resume()
|
|
71
|
-
opts.renderer.requestRender()
|
|
72
|
-
}
|
|
73
|
-
await rm(dir, { recursive: true, force: true })
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Open an existing file in the user's editor.
|
|
79
|
-
* Unlike openExternalEditor, this opens the file directly without creating a temp copy.
|
|
80
|
-
*/
|
|
81
|
-
export const openFileInEditor = async (opts: {
|
|
82
|
-
editor: EditorConfig
|
|
83
|
-
filePath: string
|
|
84
|
-
line?: number
|
|
85
|
-
cwd: string
|
|
86
|
-
renderer: CliRenderer
|
|
87
|
-
}): Promise<void> => {
|
|
88
|
-
const { command, args } = buildEditorInvocation(opts.editor, opts.cwd, { appendCwd: false })
|
|
89
|
-
const lineArg = typeof opts.line === "number" && Number.isFinite(opts.line) && opts.line > 0 && supportsLineJump(command)
|
|
90
|
-
? [`+${opts.line}`]
|
|
91
|
-
: []
|
|
92
|
-
|
|
93
|
-
opts.renderer.suspend()
|
|
94
|
-
opts.renderer.currentRenderBuffer.clear()
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
await runEditor(command, [...args, ...lineArg, opts.filePath], opts.cwd)
|
|
98
|
-
} finally {
|
|
99
|
-
opts.renderer.currentRenderBuffer.clear()
|
|
100
|
-
opts.renderer.resume()
|
|
101
|
-
opts.renderer.requestRender()
|
|
102
|
-
}
|
|
103
|
-
}
|
package/src/hooks/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "@yeshwanthyk/runtime-effect/hooks/index.js"
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { createEffect, onCleanup } from "solid-js"
|
|
2
|
-
import type { Agent, AgentEvent } from "@yeshwanthyk/agent-core"
|
|
3
|
-
import { createAgentEventHandler, type EventHandlerContext } from "../agent-events.js"
|
|
4
|
-
|
|
5
|
-
export interface AgentEventsOptions {
|
|
6
|
-
agent: Agent
|
|
7
|
-
context: EventHandlerContext
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function useAgentEvents(options: AgentEventsOptions): void {
|
|
11
|
-
const handler = createAgentEventHandler(options.context)
|
|
12
|
-
|
|
13
|
-
createEffect(() => {
|
|
14
|
-
const unsubscribe = options.agent.subscribe((event: AgentEvent) => {
|
|
15
|
-
try {
|
|
16
|
-
handler(event)
|
|
17
|
-
} catch (err) {
|
|
18
|
-
if (process.env.NODE_ENV !== "production") {
|
|
19
|
-
console.error("Agent event handler error", err)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
onCleanup(() => {
|
|
24
|
-
unsubscribe()
|
|
25
|
-
handler.dispose()
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { createPatch } from "diff"
|
|
2
|
-
import type { CliRenderer } from "@yeshwanthyk/open-tui"
|
|
3
|
-
import { openExternalEditor, openFileInEditor } from "../editor.js"
|
|
4
|
-
import type { EditorConfig } from "../config.js"
|
|
5
|
-
|
|
6
|
-
interface ToastOptions {
|
|
7
|
-
title: string
|
|
8
|
-
message?: string
|
|
9
|
-
variant?: "success" | "warning" | "error" | "info"
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface EditorBridgeOptions {
|
|
13
|
-
editor?: EditorConfig
|
|
14
|
-
renderer: CliRenderer
|
|
15
|
-
pushToast: (toast: ToastOptions, ttlMs?: number) => void
|
|
16
|
-
isResponding: () => boolean
|
|
17
|
-
onSubmit: (text: string) => void
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const DEFAULT_EDITOR: EditorConfig = { command: "nvim", args: [] }
|
|
21
|
-
|
|
22
|
-
export function useEditorBridge(options: EditorBridgeOptions) {
|
|
23
|
-
const getEditor = (): EditorConfig => options.editor ?? DEFAULT_EDITOR
|
|
24
|
-
|
|
25
|
-
const openBuffer = async (initialValue = "") => {
|
|
26
|
-
try {
|
|
27
|
-
return await openExternalEditor({
|
|
28
|
-
editor: getEditor(),
|
|
29
|
-
cwd: process.cwd(),
|
|
30
|
-
renderer: options.renderer,
|
|
31
|
-
initialValue,
|
|
32
|
-
})
|
|
33
|
-
} catch (err) {
|
|
34
|
-
options.pushToast({
|
|
35
|
-
title: "Editor failed",
|
|
36
|
-
message: err instanceof Error ? err.message : String(err),
|
|
37
|
-
variant: "error",
|
|
38
|
-
}, 4000)
|
|
39
|
-
return undefined
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const editFile = async (filePath: string, line?: number) => {
|
|
44
|
-
if (options.isResponding()) return
|
|
45
|
-
|
|
46
|
-
let beforeContent: string
|
|
47
|
-
try {
|
|
48
|
-
beforeContent = await Bun.file(filePath).text()
|
|
49
|
-
} catch (err) {
|
|
50
|
-
options.pushToast({
|
|
51
|
-
title: `Cannot read file: ${filePath}`,
|
|
52
|
-
message: err instanceof Error ? err.message : String(err),
|
|
53
|
-
variant: "error",
|
|
54
|
-
}, 3000)
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
await openFileInEditor({
|
|
60
|
-
editor: getEditor(),
|
|
61
|
-
filePath,
|
|
62
|
-
line,
|
|
63
|
-
cwd: process.cwd(),
|
|
64
|
-
renderer: options.renderer,
|
|
65
|
-
})
|
|
66
|
-
} catch (err) {
|
|
67
|
-
options.pushToast({
|
|
68
|
-
title: err instanceof Error ? err.message : String(err),
|
|
69
|
-
variant: "error",
|
|
70
|
-
}, 3000)
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
let afterContent: string
|
|
75
|
-
try {
|
|
76
|
-
afterContent = await Bun.file(filePath).text()
|
|
77
|
-
} catch (err) {
|
|
78
|
-
options.pushToast({
|
|
79
|
-
title: `Cannot read file after edit: ${filePath}`,
|
|
80
|
-
message: err instanceof Error ? err.message : String(err),
|
|
81
|
-
variant: "error",
|
|
82
|
-
}, 3000)
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (beforeContent === afterContent) {
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const diff = createPatch(filePath, beforeContent, afterContent)
|
|
91
|
-
const lines = diff.split("\n")
|
|
92
|
-
const hunkStart = lines.findIndex((line) => line.startsWith("@@"))
|
|
93
|
-
const diffBody = hunkStart >= 0 ? lines.slice(hunkStart).join("\n") : diff
|
|
94
|
-
|
|
95
|
-
const message = `Modified ${filePath}:\n${diffBody}`
|
|
96
|
-
options.onSubmit(message)
|
|
97
|
-
options.pushToast({ title: "Edit recorded", variant: "success" }, 1500)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return { openBuffer, editFile }
|
|
101
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { createSignal, onCleanup, onMount } from "solid-js"
|
|
2
|
-
import { watch, type FSWatcher } from "fs"
|
|
3
|
-
import { findGitHeadPath, getCurrentBranch } from "@runtime/git/git-info.js"
|
|
4
|
-
|
|
5
|
-
export function useGitStatus(): () => string | null {
|
|
6
|
-
const [branch, setBranch] = createSignal<string | null>(getCurrentBranch())
|
|
7
|
-
let watcher: FSWatcher | null = null
|
|
8
|
-
|
|
9
|
-
onMount(() => {
|
|
10
|
-
const gitHeadPath = findGitHeadPath()
|
|
11
|
-
if (gitHeadPath) {
|
|
12
|
-
try {
|
|
13
|
-
watcher = watch(gitHeadPath, () => setBranch(getCurrentBranch()))
|
|
14
|
-
} catch {
|
|
15
|
-
// ignore watcher errors
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
onCleanup(() => {
|
|
21
|
-
if (watcher) {
|
|
22
|
-
watcher.close()
|
|
23
|
-
watcher = null
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
return branch
|
|
28
|
-
}
|
package/src/hooks/useSpinner.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { createSignal, createEffect, onCleanup, type Accessor } from "solid-js"
|
|
2
|
-
import type { ActivityState } from "../types.js"
|
|
3
|
-
|
|
4
|
-
export function useSpinner(activityState: Accessor<ActivityState>): () => number {
|
|
5
|
-
const [spinnerFrame, setSpinnerFrame] = createSignal(0)
|
|
6
|
-
let spinnerInterval: ReturnType<typeof setInterval> | null = null
|
|
7
|
-
|
|
8
|
-
createEffect(() => {
|
|
9
|
-
if (activityState() !== "idle") {
|
|
10
|
-
if (!spinnerInterval) {
|
|
11
|
-
spinnerInterval = setInterval(() => setSpinnerFrame((frame) => (frame + 1) % 8), 200)
|
|
12
|
-
}
|
|
13
|
-
} else if (spinnerInterval) {
|
|
14
|
-
clearInterval(spinnerInterval)
|
|
15
|
-
spinnerInterval = null
|
|
16
|
-
setSpinnerFrame(0)
|
|
17
|
-
}
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
onCleanup(() => {
|
|
21
|
-
if (spinnerInterval) {
|
|
22
|
-
clearInterval(spinnerInterval)
|
|
23
|
-
spinnerInterval = null
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
return spinnerFrame
|
|
28
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { createSignal, onCleanup } from "solid-js"
|
|
2
|
-
import type { ToastItem } from "@yeshwanthyk/open-tui"
|
|
3
|
-
|
|
4
|
-
export function useToastManager(limit = 3) {
|
|
5
|
-
const [toasts, setToasts] = createSignal<ToastItem[]>([])
|
|
6
|
-
const timeouts = new Set<ReturnType<typeof setTimeout>>()
|
|
7
|
-
|
|
8
|
-
onCleanup(() => {
|
|
9
|
-
for (const timeout of timeouts) {
|
|
10
|
-
clearTimeout(timeout)
|
|
11
|
-
}
|
|
12
|
-
timeouts.clear()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
const pushToast = (toast: Omit<ToastItem, "id">, ttlMs = 2000) => {
|
|
16
|
-
const id = crypto.randomUUID()
|
|
17
|
-
setToasts((prev) => [{ id, ...toast }, ...prev].slice(0, limit))
|
|
18
|
-
const timeout = setTimeout(() => {
|
|
19
|
-
timeouts.delete(timeout)
|
|
20
|
-
setToasts((prev) => prev.filter((t) => t.id !== id))
|
|
21
|
-
}, ttlMs)
|
|
22
|
-
timeouts.add(timeout)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return { toasts, pushToast }
|
|
26
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import pkg from '../package.json';
|
|
4
|
-
import { existsSync } from 'node:fs';
|
|
5
|
-
import { createRequire } from 'node:module';
|
|
6
|
-
import { dirname, join } from 'node:path';
|
|
7
|
-
import { fileURLToPath } from 'node:url';
|
|
8
|
-
import { parseArgs } from './args.js';
|
|
9
|
-
import { runHeadless } from './adapters/cli/headless.js';
|
|
10
|
-
import { runValidate } from './adapters/cli/validate.js';
|
|
11
|
-
import { runAcp } from './adapters/acp/index.js';
|
|
12
|
-
import type { ThinkingLevel } from '@yeshwanthyk/agent-core';
|
|
13
|
-
|
|
14
|
-
declare const OTUI_TREE_SITTER_WORKER_PATH: string | undefined;
|
|
15
|
-
|
|
16
|
-
const ensureTreeSitterWorkerPath = (): void => {
|
|
17
|
-
if (
|
|
18
|
-
process.env.OTUI_TREE_SITTER_WORKER_PATH ||
|
|
19
|
-
typeof OTUI_TREE_SITTER_WORKER_PATH !== 'undefined'
|
|
20
|
-
) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const candidates: string[] = [];
|
|
25
|
-
|
|
26
|
-
const execDir = dirname(process.execPath);
|
|
27
|
-
candidates.push(join(execDir, 'parser.worker.js'));
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
31
|
-
candidates.push(join(moduleDir, 'parser.worker.js'));
|
|
32
|
-
} catch {
|
|
33
|
-
// Ignore non-file URLs (e.g. bundled snapshot)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
const require = createRequire(import.meta.url);
|
|
38
|
-
// Use dynamic string to prevent static analysis by bundler
|
|
39
|
-
const modulePath = ['@opentui', 'core', 'parser.worker.js'].join('/');
|
|
40
|
-
candidates.push(require.resolve(modulePath));
|
|
41
|
-
} catch {
|
|
42
|
-
// Ignore missing module resolution in minimal installs
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
for (const candidate of candidates) {
|
|
46
|
-
if (candidate && existsSync(candidate)) {
|
|
47
|
-
process.env.OTUI_TREE_SITTER_WORKER_PATH = candidate;
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
ensureTreeSitterWorkerPath();
|
|
54
|
-
|
|
55
|
-
// Dynamic import for TUI (requires solid plugin for TSX)
|
|
56
|
-
const runTui = async (args: {
|
|
57
|
-
configDir?: string;
|
|
58
|
-
configPath?: string;
|
|
59
|
-
provider?: string;
|
|
60
|
-
model?: string;
|
|
61
|
-
thinking?: ThinkingLevel;
|
|
62
|
-
continueSession?: boolean;
|
|
63
|
-
resumeSession?: boolean;
|
|
64
|
-
}) => {
|
|
65
|
-
const solidPlugin = (await import("@opentui/solid/bun-plugin")).default;
|
|
66
|
-
Bun.plugin(solidPlugin);
|
|
67
|
-
|
|
68
|
-
// Initialize tree-sitter parsers for code syntax highlighting
|
|
69
|
-
const { addDefaultParsers } = await import("@opentui/core");
|
|
70
|
-
const { parsersConfig } = await import("@yeshwanthyk/open-tui");
|
|
71
|
-
addDefaultParsers(parsersConfig.parsers);
|
|
72
|
-
|
|
73
|
-
const { runTuiOpen } = await import('./adapters/tui/app.js');
|
|
74
|
-
return runTuiOpen(args);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const printHelp = () => {
|
|
78
|
-
process.stdout.write(
|
|
79
|
-
[
|
|
80
|
-
'Usage:',
|
|
81
|
-
' marvin [options] [prompt...]',
|
|
82
|
-
' marvin validate [options]',
|
|
83
|
-
'',
|
|
84
|
-
'Options:',
|
|
85
|
-
' --provider <name> Provider (e.g. openai, anthropic, codex)',
|
|
86
|
-
' --model <id> Model id or comma-separated list (Ctrl+P to cycle)',
|
|
87
|
-
' --thinking <level> off|minimal|low|medium|high|xhigh',
|
|
88
|
-
' --config-dir <dir> Config directory (default: ~/.config/marvin)',
|
|
89
|
-
' --config <path> Config file path (default: <config-dir>/config.json)',
|
|
90
|
-
' -c, --continue Resume most recent session for current directory',
|
|
91
|
-
' -r, --resume Pick from recent sessions to resume',
|
|
92
|
-
' --headless Run without TUI; reads prompt from args or stdin',
|
|
93
|
-
' --acp Run as ACP server for Zed integration',
|
|
94
|
-
' -h, --help Show help',
|
|
95
|
-
' -v, --version Print version',
|
|
96
|
-
'',
|
|
97
|
-
'Keybinds:',
|
|
98
|
-
' Ctrl+P Cycle through --models list',
|
|
99
|
-
' Shift+Tab Cycle thinking level',
|
|
100
|
-
' Ctrl+C Clear input / double to exit',
|
|
101
|
-
' Esc Abort current request',
|
|
102
|
-
'',
|
|
103
|
-
'Custom Commands:',
|
|
104
|
-
' Place .md files in ~/.config/marvin/commands/',
|
|
105
|
-
' Use /<name> [args] to expand the template.',
|
|
106
|
-
' $ARGUMENTS in the template is replaced with args.',
|
|
107
|
-
'',
|
|
108
|
-
'Lifecycle Hooks:',
|
|
109
|
-
' Place .ts files in ~/.config/marvin/hooks/',
|
|
110
|
-
' Export default function(marvin) { marvin.on(event, handler) }',
|
|
111
|
-
' Events: app.start, session.start/resume/clear, agent.start/end,',
|
|
112
|
-
' turn.start/end, tool.execute.before/after',
|
|
113
|
-
' Use marvin.send(text) to inject messages into conversation',
|
|
114
|
-
'',
|
|
115
|
-
'Custom Tools:',
|
|
116
|
-
' Place .ts files in ~/.config/marvin/tools/',
|
|
117
|
-
' Export default function(api) returning AgentTool or AgentTool[]',
|
|
118
|
-
' api.cwd: current working directory',
|
|
119
|
-
' api.exec(cmd, args, opts): run commands',
|
|
120
|
-
'',
|
|
121
|
-
'Validation:',
|
|
122
|
-
' Run "marvin validate --config-dir <dir>" to check custom hooks/tools/commands',
|
|
123
|
-
'',
|
|
124
|
-
'Environment:',
|
|
125
|
-
' OPENAI_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEY / ...',
|
|
126
|
-
'',
|
|
127
|
-
].join('\n')
|
|
128
|
-
);
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const main = async () => {
|
|
132
|
-
const argv = process.argv.slice(2);
|
|
133
|
-
const args = parseArgs(argv);
|
|
134
|
-
|
|
135
|
-
if (args.version) {
|
|
136
|
-
process.stdout.write(`${pkg.name} ${pkg.version}\n`);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (args.help) {
|
|
141
|
-
printHelp();
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (args.command === 'validate') {
|
|
146
|
-
await runValidate({
|
|
147
|
-
configDir: args.configDir,
|
|
148
|
-
configPath: args.configPath,
|
|
149
|
-
provider: args.provider,
|
|
150
|
-
model: args.model,
|
|
151
|
-
thinking: args.thinking,
|
|
152
|
-
});
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (args.acp) {
|
|
157
|
-
await runAcp({
|
|
158
|
-
configDir: args.configDir,
|
|
159
|
-
configPath: args.configPath,
|
|
160
|
-
model: args.model,
|
|
161
|
-
});
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (args.headless) {
|
|
166
|
-
await runHeadless({
|
|
167
|
-
prompt: args.prompt,
|
|
168
|
-
configDir: args.configDir,
|
|
169
|
-
configPath: args.configPath,
|
|
170
|
-
provider: args.provider,
|
|
171
|
-
model: args.model,
|
|
172
|
-
thinking: args.thinking,
|
|
173
|
-
});
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
await runTui({
|
|
178
|
-
configDir: args.configDir,
|
|
179
|
-
configPath: args.configPath,
|
|
180
|
-
provider: args.provider,
|
|
181
|
-
model: args.model,
|
|
182
|
-
thinking: args.thinking,
|
|
183
|
-
continueSession: args.continue,
|
|
184
|
-
resumeSession: args.resume,
|
|
185
|
-
});
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
await main();
|