@openadapter/koda 1.0.0-beta.10
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/CHANGELOG.md +4448 -0
- package/README.md +97 -0
- package/dist/bun/cli.d.ts +2 -0
- package/dist/bun/cli.js +2 -0
- package/dist/bun/register-bedrock.d.ts +1 -0
- package/dist/bun/register-bedrock.js +1 -0
- package/dist/bun/restore-sandbox-env.d.ts +12 -0
- package/dist/bun/restore-sandbox-env.js +1 -0
- package/dist/cli/args.d.ts +55 -0
- package/dist/cli/args.js +167 -0
- package/dist/cli/config-selector.d.ts +13 -0
- package/dist/cli/config-selector.js +1 -0
- package/dist/cli/file-processor.d.ts +14 -0
- package/dist/cli/file-processor.js +7 -0
- package/dist/cli/import-sessions.d.ts +34 -0
- package/dist/cli/import-sessions.js +6 -0
- package/dist/cli/initial-message.d.ts +17 -0
- package/dist/cli/initial-message.js +1 -0
- package/dist/cli/list-models.d.ts +8 -0
- package/dist/cli/list-models.js +2 -0
- package/dist/cli/openadapter-setup.d.ts +35 -0
- package/dist/cli/openadapter-setup.js +4 -0
- package/dist/cli/session-picker.d.ts +8 -0
- package/dist/cli/session-picker.js +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +2 -0
- package/dist/config.d.ts +92 -0
- package/dist/config.js +1 -0
- package/dist/core/agent-session-runtime.d.ts +116 -0
- package/dist/core/agent-session-runtime.js +1 -0
- package/dist/core/agent-session-services.d.ts +86 -0
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session.d.ts +752 -0
- package/dist/core/agent-session.js +32 -0
- package/dist/core/auth-guidance.d.ts +4 -0
- package/dist/core/auth-guidance.js +8 -0
- package/dist/core/auth-storage.d.ts +140 -0
- package/dist/core/auth-storage.js +1 -0
- package/dist/core/bash-executor.d.ts +31 -0
- package/dist/core/bash-executor.js +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +89 -0
- package/dist/core/compaction/branch-summarization.js +38 -0
- package/dist/core/compaction/compaction.d.ts +120 -0
- package/dist/core/compaction/compaction.js +104 -0
- package/dist/core/compaction/index.d.ts +6 -0
- package/dist/core/compaction/index.js +1 -0
- package/dist/core/compaction/utils.d.ts +37 -0
- package/dist/core/compaction/utils.js +19 -0
- package/dist/core/defaults.d.ts +2 -0
- package/dist/core/defaults.js +1 -0
- package/dist/core/diagnostics.d.ts +14 -0
- package/dist/core/diagnostics.js +0 -0
- package/dist/core/event-bus.d.ts +8 -0
- package/dist/core/event-bus.js +1 -0
- package/dist/core/exec.d.ts +28 -0
- package/dist/core/exec.js +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +21 -0
- package/dist/core/export-html/ansi-to-html.js +1 -0
- package/dist/core/export-html/index.d.ts +36 -0
- package/dist/core/export-html/index.js +2 -0
- package/dist/core/export-html/template.css +1066 -0
- package/dist/core/export-html/template.html +55 -0
- package/dist/core/export-html/template.js +72 -0
- package/dist/core/export-html/tool-renderer.d.ts +33 -0
- package/dist/core/export-html/tool-renderer.js +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +8 -0
- package/dist/core/export-html/vendor/marked.min.js +56 -0
- package/dist/core/extensions/index.d.ts +11 -0
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/loader.d.ts +23 -0
- package/dist/core/extensions/loader.js +1 -0
- package/dist/core/extensions/runner.d.ts +160 -0
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/types.d.ts +1180 -0
- package/dist/core/extensions/types.js +1 -0
- package/dist/core/extensions/wrapper.d.ts +19 -0
- package/dist/core/extensions/wrapper.js +1 -0
- package/dist/core/footer-data-provider.d.ts +53 -0
- package/dist/core/footer-data-provider.js +1 -0
- package/dist/core/http-dispatcher.d.ts +20 -0
- package/dist/core/http-dispatcher.js +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.js +1 -0
- package/dist/core/keybindings.d.ts +352 -0
- package/dist/core/keybindings.js +1 -0
- package/dist/core/messages.d.ts +76 -0
- package/dist/core/messages.js +17 -0
- package/dist/core/model-registry.d.ts +149 -0
- package/dist/core/model-registry.js +9 -0
- package/dist/core/model-resolver.d.ts +109 -0
- package/dist/core/model-resolver.js +1 -0
- package/dist/core/output-guard.d.ts +6 -0
- package/dist/core/output-guard.js +1 -0
- package/dist/core/package-manager.d.ts +203 -0
- package/dist/core/package-manager.js +3 -0
- package/dist/core/prompt-templates.d.ts +51 -0
- package/dist/core/prompt-templates.js +2 -0
- package/dist/core/provider-attribution.d.ts +3 -0
- package/dist/core/provider-attribution.js +1 -0
- package/dist/core/provider-display-names.d.ts +1 -0
- package/dist/core/provider-display-names.js +1 -0
- package/dist/core/resolve-config-value.d.ts +30 -0
- package/dist/core/resolve-config-value.js +1 -0
- package/dist/core/resource-loader.d.ts +193 -0
- package/dist/core/resource-loader.js +1 -0
- package/dist/core/sdk.d.ts +108 -0
- package/dist/core/sdk.js +1 -0
- package/dist/core/session-cwd.d.ts +18 -0
- package/dist/core/session-cwd.js +7 -0
- package/dist/core/session-manager.d.ts +331 -0
- package/dist/core/session-manager.js +11 -0
- package/dist/core/settings-manager.d.ts +265 -0
- package/dist/core/settings-manager.js +1 -0
- package/dist/core/skills.d.ts +59 -0
- package/dist/core/skills.js +4 -0
- package/dist/core/slash-commands.d.ts +13 -0
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/source-info.d.ts +17 -0
- package/dist/core/source-info.js +1 -0
- package/dist/core/system-prompt.d.ts +27 -0
- package/dist/core/system-prompt.js +52 -0
- package/dist/core/telemetry.d.ts +2 -0
- package/dist/core/telemetry.js +1 -0
- package/dist/core/timings.d.ts +7 -0
- package/dist/core/timings.js +3 -0
- package/dist/core/tools/bash.d.ts +67 -0
- package/dist/core/tools/bash.js +18 -0
- package/dist/core/tools/edit-diff.d.ts +86 -0
- package/dist/core/tools/edit-diff.js +16 -0
- package/dist/core/tools/edit.d.ts +50 -0
- package/dist/core/tools/edit.js +2 -0
- package/dist/core/tools/file-mutation-queue.d.ts +5 -0
- package/dist/core/tools/file-mutation-queue.js +1 -0
- package/dist/core/tools/find.d.ts +34 -0
- package/dist/core/tools/find.js +13 -0
- package/dist/core/tools/grep.d.ts +36 -0
- package/dist/core/tools/grep.js +13 -0
- package/dist/core/tools/index.d.ts +39 -0
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/ls.d.ts +36 -0
- package/dist/core/tools/ls.js +9 -0
- package/dist/core/tools/output-accumulator.d.ts +51 -0
- package/dist/core/tools/output-accumulator.js +4 -0
- package/dist/core/tools/path-utils.d.ts +9 -0
- package/dist/core/tools/path-utils.js +1 -0
- package/dist/core/tools/read.d.ts +34 -0
- package/dist/core/tools/read.js +22 -0
- package/dist/core/tools/render-utils.d.ts +23 -0
- package/dist/core/tools/render-utils.js +4 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +13 -0
- package/dist/core/tools/tool-definition-wrapper.js +1 -0
- package/dist/core/tools/truncate.d.ts +69 -0
- package/dist/core/tools/truncate.js +5 -0
- package/dist/core/tools/write.d.ts +25 -0
- package/dist/core/tools/write.js +13 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +1 -0
- package/dist/main.d.ts +11 -0
- package/dist/main.js +1 -0
- package/dist/migrations.d.ts +32 -0
- package/dist/migrations.js +8 -0
- package/dist/modes/index.d.ts +8 -0
- package/dist/modes/index.js +1 -0
- package/dist/modes/interactive/assets/clankolas.png +0 -0
- package/dist/modes/interactive/components/armin.d.ts +33 -0
- package/dist/modes/interactive/components/armin.js +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +19 -0
- package/dist/modes/interactive/components/assistant-message.js +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +33 -0
- package/dist/modes/interactive/components/bash-execution.js +13 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +15 -0
- package/dist/modes/interactive/components/bordered-loader.js +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +15 -0
- package/dist/modes/interactive/components/branch-summary-message.js +3 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +15 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +3 -0
- package/dist/modes/interactive/components/config-selector.d.ts +70 -0
- package/dist/modes/interactive/components/config-selector.js +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +13 -0
- package/dist/modes/interactive/components/countdown-timer.js +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +20 -0
- package/dist/modes/interactive/components/custom-editor.js +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +19 -0
- package/dist/modes/interactive/components/custom-message.js +2 -0
- package/dist/modes/interactive/components/daxnuts.d.ts +22 -0
- package/dist/modes/interactive/components/daxnuts.js +1 -0
- package/dist/modes/interactive/components/diff.d.ts +11 -0
- package/dist/modes/interactive/components/diff.js +3 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +14 -0
- package/dist/modes/interactive/components/dynamic-border.js +1 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts +4 -0
- package/dist/modes/interactive/components/earendil-announcement.js +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +19 -0
- package/dist/modes/interactive/components/extension-editor.js +3 -0
- package/dist/modes/interactive/components/extension-input.d.ts +22 -0
- package/dist/modes/interactive/components/extension-input.js +2 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +25 -0
- package/dist/modes/interactive/components/extension-selector.js +2 -0
- package/dist/modes/interactive/components/footer.d.ts +27 -0
- package/dist/modes/interactive/components/footer.js +1 -0
- package/dist/modes/interactive/components/index.d.ts +31 -0
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +12 -0
- package/dist/modes/interactive/components/keybinding-hints.js +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +51 -0
- package/dist/modes/interactive/components/login-dialog.js +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +46 -0
- package/dist/modes/interactive/components/model-selector.js +2 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +30 -0
- package/dist/modes/interactive/components/oauth-selector.js +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +41 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +22 -0
- package/dist/modes/interactive/components/session-selector-search.js +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +95 -0
- package/dist/modes/interactive/components/session-selector.js +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +69 -0
- package/dist/modes/interactive/components/settings-selector.js +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +9 -0
- package/dist/modes/interactive/components/show-images-selector.js +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +16 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +3 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +10 -0
- package/dist/modes/interactive/components/theme-selector.js +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +10 -0
- package/dist/modes/interactive/components/thinking-selector.js +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +62 -0
- package/dist/modes/interactive/components/tool-execution.js +4 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +88 -0
- package/dist/modes/interactive/components/tree-selector.js +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +29 -0
- package/dist/modes/interactive/components/user-message-selector.js +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +9 -0
- package/dist/modes/interactive/components/user-message.js +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +23 -0
- package/dist/modes/interactive/components/visual-truncate.js +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +420 -0
- package/dist/modes/interactive/interactive-mode.js +116 -0
- package/dist/modes/interactive/theme/dark.json +86 -0
- package/dist/modes/interactive/theme/light.json +85 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.d.ts +101 -0
- package/dist/modes/interactive/theme/theme.js +18 -0
- package/dist/modes/print-mode.d.ts +27 -0
- package/dist/modes/print-mode.js +4 -0
- package/dist/modes/rpc/jsonl.d.ts +16 -0
- package/dist/modes/rpc/jsonl.js +3 -0
- package/dist/modes/rpc/rpc-client.d.ts +226 -0
- package/dist/modes/rpc/rpc-client.js +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +19 -0
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +419 -0
- package/dist/modes/rpc/rpc-types.js +0 -0
- package/dist/package-manager-cli.d.ts +3 -0
- package/dist/package-manager-cli.js +49 -0
- package/dist/utils/ansi.d.ts +1 -0
- package/dist/utils/ansi.js +1 -0
- package/dist/utils/auto-update.d.ts +13 -0
- package/dist/utils/auto-update.js +1 -0
- package/dist/utils/changelog.d.ts +20 -0
- package/dist/utils/changelog.js +4 -0
- package/dist/utils/child-process.d.ts +14 -0
- package/dist/utils/child-process.js +1 -0
- package/dist/utils/clipboard-image.d.ts +10 -0
- package/dist/utils/clipboard-image.js +1 -0
- package/dist/utils/clipboard-native.d.ts +9 -0
- package/dist/utils/clipboard-native.js +1 -0
- package/dist/utils/clipboard.d.ts +1 -0
- package/dist/utils/clipboard.js +1 -0
- package/dist/utils/deprecation.d.ts +3 -0
- package/dist/utils/deprecation.js +1 -0
- package/dist/utils/exif-orientation.d.ts +4 -0
- package/dist/utils/exif-orientation.js +1 -0
- package/dist/utils/frontmatter.d.ts +7 -0
- package/dist/utils/frontmatter.js +4 -0
- package/dist/utils/fs-watch.d.ts +4 -0
- package/dist/utils/fs-watch.js +1 -0
- package/dist/utils/git.d.ts +25 -0
- package/dist/utils/git.js +1 -0
- package/dist/utils/html.d.ts +6 -0
- package/dist/utils/html.js +1 -0
- package/dist/utils/image-convert.d.ts +8 -0
- package/dist/utils/image-convert.js +1 -0
- package/dist/utils/image-resize-core.d.ts +29 -0
- package/dist/utils/image-resize-core.js +1 -0
- package/dist/utils/image-resize-worker.d.ts +1 -0
- package/dist/utils/image-resize-worker.js +1 -0
- package/dist/utils/image-resize.d.ts +15 -0
- package/dist/utils/image-resize.js +1 -0
- package/dist/utils/json.d.ts +2 -0
- package/dist/utils/json.js +1 -0
- package/dist/utils/koda-user-agent.d.ts +1 -0
- package/dist/utils/koda-user-agent.js +1 -0
- package/dist/utils/mime.d.ts +2 -0
- package/dist/utils/mime.js +1 -0
- package/dist/utils/paths.d.ts +30 -0
- package/dist/utils/paths.js +1 -0
- package/dist/utils/photon.d.ts +20 -0
- package/dist/utils/photon.js +1 -0
- package/dist/utils/shell.d.ts +29 -0
- package/dist/utils/shell.js +8 -0
- package/dist/utils/sleep.d.ts +4 -0
- package/dist/utils/sleep.js +1 -0
- package/dist/utils/syntax-highlight.d.ts +11 -0
- package/dist/utils/syntax-highlight.js +2 -0
- package/dist/utils/tools-manager.d.ts +2 -0
- package/dist/utils/tools-manager.js +1 -0
- package/dist/utils/version-check.d.ts +14 -0
- package/dist/utils/version-check.js +1 -0
- package/dist/utils/windows-self-update.d.ts +2 -0
- package/dist/utils/windows-self-update.js +1 -0
- package/docs/compaction.md +394 -0
- package/docs/custom-provider.md +736 -0
- package/docs/development.md +71 -0
- package/docs/docs.json +148 -0
- package/docs/extensions.md +2626 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +80 -0
- package/docs/json.md +82 -0
- package/docs/keybindings.md +197 -0
- package/docs/models.md +493 -0
- package/docs/packages.md +226 -0
- package/docs/prompt-templates.md +88 -0
- package/docs/providers.md +253 -0
- package/docs/quickstart.md +165 -0
- package/docs/rpc.md +1408 -0
- package/docs/sdk.md +1137 -0
- package/docs/session-format.md +412 -0
- package/docs/sessions.md +145 -0
- package/docs/settings.md +281 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +231 -0
- package/docs/terminal-setup.md +114 -0
- package/docs/termux.md +127 -0
- package/docs/themes.md +295 -0
- package/docs/tmux.md +61 -0
- package/docs/tui.md +927 -0
- package/docs/usage.md +288 -0
- package/docs/windows.md +17 -0
- package/npm-shrinkwrap.json +1792 -0
- package/openadapter/extensions/koda-ask.js +12 -0
- package/openadapter/extensions/koda-bg.js +14 -0
- package/openadapter/extensions/koda-commands.mjs +15 -0
- package/openadapter/extensions/koda-help.js +8 -0
- package/openadapter/extensions/koda-memory.js +16 -0
- package/openadapter/extensions/koda-status.js +1 -0
- package/openadapter/extensions/koda-todo.js +4 -0
- package/openadapter/extensions/koda-vision.js +4 -0
- package/openadapter/extensions/koda-web.js +7 -0
- package/openadapter/setup.mjs +175 -0
- package/openadapter/skills/code-review/SKILL.md +22 -0
- package/openadapter/skills/debugging/SKILL.md +28 -0
- package/openadapter/skills/frontend/SKILL.md +38 -0
- package/package.json +108 -0
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<h1 align="center">Koda</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center"><strong>The coding agent that makes affordable models actually finish the job.</strong></p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@openadapter/koda"><img alt="npm" src="https://img.shields.io/npm/v/@openadapter/koda/beta?style=flat-square&label=beta" /></a>
|
|
7
|
+
<a href="https://openadapter.in"><img alt="OpenAdapter" src="https://img.shields.io/badge/built%20for-OpenAdapter-7c3aed?style=flat-square" /></a>
|
|
8
|
+
<img alt="license" src="https://img.shields.io/badge/license-MIT-green?style=flat-square" />
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
**Koda** is a terminal coding agent built for [OpenAdapter](https://openadapter.in). One key gives you many models — and Koda wraps a **reliability layer** around them so cheaper, faster models still ship working code: it never idles on rate limits, fails over when a model stalls, verifies its own work, and steps up to a stronger model only when it has to.
|
|
14
|
+
|
|
15
|
+
It runs in your terminal like the coding CLIs you already know — just harder to break, and tuned end-to-end for OpenAdapter.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i -g @openadapter/koda@beta
|
|
21
|
+
koda
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
First launch runs a one-time setup: paste your OpenAdapter API key (`sk-cv-…` from your [dashboard](https://openadapter.in)) and Koda wires up the models, tools, and skills. That's it.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
koda # start (or resume) in the current folder
|
|
28
|
+
koda --continue # reopen the latest session here
|
|
29
|
+
koda --resume # pick a past session
|
|
30
|
+
koda setup # re-run setup any time
|
|
31
|
+
koda import # pull in past sessions from other CLIs (see below)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## What makes Koda different
|
|
35
|
+
|
|
36
|
+
**One key, many models — tiered.** Point Koda at any OpenAdapter model (max / pro / lite). Koda reads live health/latency signals to route well, and you stay on *your* pick.
|
|
37
|
+
|
|
38
|
+
**Reliability that keeps cheap models honest:**
|
|
39
|
+
|
|
40
|
+
- **Never idle on a rate limit** — `/zenitsu` speed mode instantly reroutes a 429 to a healthy, faster model (no waiting), then snaps back to your preferred one the moment it's free.
|
|
41
|
+
- **Failover, not failure** — provider/model hiccups are retried and routed around; a request rarely dies from a single flake.
|
|
42
|
+
- **Run-it verification** — when code changed, Koda runs your build/tests/lint and treats the **exit code as ground truth**, not the model's opinion.
|
|
43
|
+
- **Overseer + escalation** — a stronger model double-checks "done" on smaller models and, if it's stuck, Koda climbs the tier ladder — capped, then sticks.
|
|
44
|
+
- **Heal, don't crash** — loop/state errors recover instead of killing your session; repetition/garbage output is detected and replaced.
|
|
45
|
+
|
|
46
|
+
**Features that respect your time:**
|
|
47
|
+
|
|
48
|
+
- **Ask & suggest** — on open-ended requests Koda proposes an approach and asks the decisions that matter (framework, storage…) with a clean multiple-choice card, instead of guessing wrong.
|
|
49
|
+
- **Vision on any model** — paste a screenshot even on a non-vision model; Koda reads it with a vision model and passes the details along.
|
|
50
|
+
- **Bring your history** — `koda import` (and a first-run prompt) imports past sessions from **Claude Code** and **OpenCode** into Koda, organized by project. Nothing left behind.
|
|
51
|
+
- **Memory, web, background tasks** — remember/recall with semantic search, web search + fetch, and long-running servers via `run_background`.
|
|
52
|
+
- **Skills & modes** — drop-in Agent Skills (frontend, debugging, code-review), `/plan` and `/build` modes.
|
|
53
|
+
- **Stays current** — checks for updates and updates itself in the background; the model list auto-refreshes daily so you always have the newest models.
|
|
54
|
+
- **Calm, useful UX** — live working indicator, an end-of-task recap, a session-resume hint when you reopen a folder, and contextual tips that surface the right feature exactly when it helps.
|
|
55
|
+
|
|
56
|
+
## Common commands
|
|
57
|
+
|
|
58
|
+
| Command | What it does |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `/zenitsu` | Toggle speed mode (never wait on a rate limit) |
|
|
61
|
+
| `/goal` | Set a session goal Koda tracks to completion |
|
|
62
|
+
| `/plan` · `/build` | Switch between plan and build modes |
|
|
63
|
+
| `/resume` · `/continue` | Open a past session |
|
|
64
|
+
| `/memory` · `/todos` | Memory and task list |
|
|
65
|
+
| `/use <skill>` | Keep a skill active for the session |
|
|
66
|
+
| `/trace` | What the harness did (failover / verify / escalate …) |
|
|
67
|
+
| `/settings` | Settings (incl. "Import past sessions") |
|
|
68
|
+
| `/help` | Full help |
|
|
69
|
+
|
|
70
|
+
## Configuration (env flags)
|
|
71
|
+
|
|
72
|
+
| Flag | Effect |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `KODA_ZENITSU=1` | Start in speed mode |
|
|
75
|
+
| `KODA_NO_AUTO_UPDATE=1` | Notify about updates but don't auto-install |
|
|
76
|
+
| `KODA_NO_MODEL_REFRESH=1` | Don't auto-refresh the model list |
|
|
77
|
+
| `KODA_NO_RESUME_HINT=1` | Hide the "past sessions in this folder" hint |
|
|
78
|
+
| `KODA_TIPS=0` | Disable contextual feature tips |
|
|
79
|
+
| `KODA_OFFLINE=1` | No network calls (version check, model refresh, tool downloads) |
|
|
80
|
+
|
|
81
|
+
## Built on Pi — credit where it's due
|
|
82
|
+
|
|
83
|
+
Koda stands on **[Pi](https://github.com/earendil-works/pi)**, the excellent open-source terminal coding harness by **Mario Zechner** ([@badlogic](https://github.com/badlogic)). A huge amount of what makes Koda pleasant to use is Pi's, and we're grateful for it.
|
|
84
|
+
|
|
85
|
+
**Pi provides the foundation** — the interactive TUI + editor, sessions & branching, context compaction, the extension / skill / prompt-template / theme system, prompt-template and package management, and the interactive / print / RPC / SDK run modes.
|
|
86
|
+
|
|
87
|
+
**Koda adds, on top of Pi:**
|
|
88
|
+
- OpenAdapter integration (one key → many tiered models) and the first-run setup.
|
|
89
|
+
- The reliability layer — zenitsu never-idle rerouting, model failover, run-it verification, the overseer + escalation, heal-don't-crash, poison guard.
|
|
90
|
+
- Ask & suggest, the vision bridge, session import from Claude Code & OpenCode.
|
|
91
|
+
- Auto-update + daily model refresh, the resume hint, contextual tips, recap, and the live status UX.
|
|
92
|
+
|
|
93
|
+
Thank you to the Pi project and its contributors.
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT — see [LICENSE](../../LICENSE). Copyright © Mario Zechner (original "pi" project) and OpenAdapter (the "Koda" fork).
|
package/dist/bun/cli.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{setBedrockProviderModule as o}from"@openadapter/koda-ai";import{bedrockProviderModule as r}from"@openadapter/koda-ai/bedrock-provider";o(r);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workaround for https://github.com/oven-sh/bun/issues/27802
|
|
3
|
+
*
|
|
4
|
+
* Bun compiled binaries have an empty `process.env` when running inside
|
|
5
|
+
* sandbox environments (e.g. nono on Linux/macOS). On Linux we can recover
|
|
6
|
+
* the environment from `/proc/self/environ`.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Restore environment variables from `/proc/self/environ` when running
|
|
10
|
+
* inside a sandbox where Bun's `process.env` is empty.
|
|
11
|
+
*/
|
|
12
|
+
export declare function restoreSandboxEnv(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var s=Object.defineProperty;var o=(n,e)=>s(n,"name",{value:e,configurable:!0});import{readFileSync as t}from"node:fs";function f(){if(process.versions?.bun&&!(Object.keys(process.env).length>0))try{const n=t("/proc/self/environ","utf-8");for(const e of n.split("\0")){const r=e.indexOf("=");r>0&&(process.env[e.slice(0,r)]=e.slice(r+1))}}catch{}}o(f,"restoreSandboxEnv");export{f as restoreSandboxEnv};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI argument parsing and help display
|
|
3
|
+
*/
|
|
4
|
+
import type { ThinkingLevel } from "@openadapter/koda-agent-core";
|
|
5
|
+
import type { ExtensionFlag } from "../core/extensions/types.ts";
|
|
6
|
+
export type Mode = "text" | "json" | "rpc";
|
|
7
|
+
export interface Args {
|
|
8
|
+
provider?: string;
|
|
9
|
+
model?: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
systemPrompt?: string;
|
|
12
|
+
appendSystemPrompt?: string[];
|
|
13
|
+
thinking?: ThinkingLevel;
|
|
14
|
+
continue?: boolean;
|
|
15
|
+
resume?: boolean;
|
|
16
|
+
help?: boolean;
|
|
17
|
+
version?: boolean;
|
|
18
|
+
mode?: Mode;
|
|
19
|
+
name?: string;
|
|
20
|
+
noSession?: boolean;
|
|
21
|
+
session?: string;
|
|
22
|
+
sessionId?: string;
|
|
23
|
+
fork?: string;
|
|
24
|
+
sessionDir?: string;
|
|
25
|
+
models?: string[];
|
|
26
|
+
tools?: string[];
|
|
27
|
+
excludeTools?: string[];
|
|
28
|
+
noTools?: boolean;
|
|
29
|
+
noBuiltinTools?: boolean;
|
|
30
|
+
extensions?: string[];
|
|
31
|
+
noExtensions?: boolean;
|
|
32
|
+
print?: boolean;
|
|
33
|
+
export?: string;
|
|
34
|
+
noSkills?: boolean;
|
|
35
|
+
skills?: string[];
|
|
36
|
+
promptTemplates?: string[];
|
|
37
|
+
noPromptTemplates?: boolean;
|
|
38
|
+
themes?: string[];
|
|
39
|
+
noThemes?: boolean;
|
|
40
|
+
noContextFiles?: boolean;
|
|
41
|
+
listModels?: string | true;
|
|
42
|
+
offline?: boolean;
|
|
43
|
+
verbose?: boolean;
|
|
44
|
+
messages: string[];
|
|
45
|
+
fileArgs: string[];
|
|
46
|
+
/** Unknown flags (potentially extension flags) - map of flag name to value */
|
|
47
|
+
unknownFlags: Map<string, boolean | string>;
|
|
48
|
+
diagnostics: Array<{
|
|
49
|
+
type: "warning" | "error";
|
|
50
|
+
message: string;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
export declare function isValidThinkingLevel(level: string): level is ThinkingLevel;
|
|
54
|
+
export declare function parseArgs(args: string[]): Args;
|
|
55
|
+
export declare function printHelp(extensionFlags?: ExtensionFlag[]): void;
|
package/dist/cli/args.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
var c=Object.defineProperty;var a=(o,t)=>c(o,"name",{value:t,configurable:!0});import l from"chalk";import{APP_NAME as n,CONFIG_DIR_NAME as d,ENV_AGENT_DIR as u,ENV_SESSION_DIR as A}from"../config.js";const m=["off","minimal","low","medium","high","xhigh"];function f(o){return m.includes(o)}a(f,"isValidThinkingLevel");function _(o){const t={messages:[],fileArgs:[],unknownFlags:new Map,diagnostics:[]};for(let s=0;s<o.length;s++){const e=o[s];if(e==="--help"||e==="-h")t.help=!0;else if(e==="--version"||e==="-v")t.version=!0;else if(e==="--mode"&&s+1<o.length){const i=o[++s];(i==="text"||i==="json"||i==="rpc")&&(t.mode=i)}else if(e==="--continue"||e==="-c")t.continue=!0;else if(e==="--resume"||e==="-r")t.resume=!0;else if(e==="--provider"&&s+1<o.length)t.provider=o[++s];else if(e==="--model"&&s+1<o.length)t.model=o[++s];else if(e==="--api-key"&&s+1<o.length)t.apiKey=o[++s];else if(e==="--system-prompt"&&s+1<o.length)t.systemPrompt=o[++s];else if(e==="--append-system-prompt"&&s+1<o.length)t.appendSystemPrompt=t.appendSystemPrompt??[],t.appendSystemPrompt.push(o[++s]);else if(e==="--name"||e==="-n")s+1<o.length?t.name=o[++s]:t.diagnostics.push({type:"error",message:"--name requires a value"});else if(e==="--no-session")t.noSession=!0;else if(e==="--session"&&s+1<o.length)t.session=o[++s];else if(e==="--session-id"&&s+1<o.length)t.sessionId=o[++s];else if(e==="--fork"&&s+1<o.length)t.fork=o[++s];else if(e==="--session-dir"&&s+1<o.length)t.sessionDir=o[++s];else if(e==="--models"&&s+1<o.length)t.models=o[++s].split(",").map(i=>i.trim());else if(e==="--no-tools"||e==="-nt")t.noTools=!0;else if(e==="--no-builtin-tools"||e==="-nbt")t.noBuiltinTools=!0;else if((e==="--tools"||e==="-t")&&s+1<o.length)t.tools=o[++s].split(",").map(i=>i.trim()).filter(i=>i.length>0);else if((e==="--exclude-tools"||e==="-xt")&&s+1<o.length)t.excludeTools=o[++s].split(",").map(i=>i.trim()).filter(i=>i.length>0);else if(e==="--thinking"&&s+1<o.length){const i=o[++s];f(i)?t.thinking=i:t.diagnostics.push({type:"warning",message:`Invalid thinking level "${i}". Valid values: ${m.join(", ")}`})}else if(e==="--print"||e==="-p"){t.print=!0;const i=o[s+1];i!==void 0&&!i.startsWith("@")&&(!i.startsWith("-")||i.startsWith("---"))&&(t.messages.push(i),s++)}else if(e==="--export"&&s+1<o.length)t.export=o[++s];else if((e==="--extension"||e==="-e")&&s+1<o.length)t.extensions=t.extensions??[],t.extensions.push(o[++s]);else if(e==="--no-extensions"||e==="-ne")t.noExtensions=!0;else if(e==="--skill"&&s+1<o.length)t.skills=t.skills??[],t.skills.push(o[++s]);else if(e==="--prompt-template"&&s+1<o.length)t.promptTemplates=t.promptTemplates??[],t.promptTemplates.push(o[++s]);else if(e==="--theme"&&s+1<o.length)t.themes=t.themes??[],t.themes.push(o[++s]);else if(e==="--no-skills"||e==="-ns")t.noSkills=!0;else if(e==="--no-prompt-templates"||e==="-np")t.noPromptTemplates=!0;else if(e==="--no-themes")t.noThemes=!0;else if(e==="--no-context-files"||e==="-nc")t.noContextFiles=!0;else if(e==="--list-models")s+1<o.length&&!o[s+1].startsWith("-")&&!o[s+1].startsWith("@")?t.listModels=o[++s]:t.listModels=!0;else if(e==="--verbose")t.verbose=!0;else if(e==="--offline")t.offline=!0;else if(e.startsWith("@"))t.fileArgs.push(e.slice(1));else if(e.startsWith("--")){const i=e.indexOf("=");if(i!==-1)t.unknownFlags.set(e.slice(2,i),e.slice(i+1));else{const p=e.slice(2),r=o[s+1];r!==void 0&&!r.startsWith("-")&&!r.startsWith("@")?(t.unknownFlags.set(p,r),s++):t.unknownFlags.set(p,!0)}}else e.startsWith("-")&&!e.startsWith("--")?t.diagnostics.push({type:"error",message:`Unknown option: ${e}`}):e.startsWith("-")||t.messages.push(e)}return t}a(_,"parseArgs");function k(o){const t=o&&o.length>0?`
|
|
2
|
+
${l.bold("Extension CLI Flags:")}
|
|
3
|
+
${o.map(s=>{const e=s.type==="string"?" <value>":"",i=s.description??`Registered by ${s.extensionPath}`;return` --${s.name}${e}`.padEnd(30)+i}).join(`
|
|
4
|
+
`)}
|
|
5
|
+
`:"";console.log(`${l.bold(n)} - AI coding assistant with read, bash, edit, write tools
|
|
6
|
+
|
|
7
|
+
${l.bold("Usage:")}
|
|
8
|
+
${n} [options] [@files...] [messages...]
|
|
9
|
+
|
|
10
|
+
${l.bold("Commands:")}
|
|
11
|
+
${n} install <source> [-l] Install extension source and add to settings
|
|
12
|
+
${n} remove <source> [-l] Remove extension source from settings
|
|
13
|
+
${n} uninstall <source> [-l] Alias for remove
|
|
14
|
+
${n} update [source|self|koda] Update koda and installed extensions
|
|
15
|
+
${n} list List installed extensions from settings
|
|
16
|
+
${n} config Open TUI to enable/disable package resources
|
|
17
|
+
${n} <command> --help Show help for install/remove/uninstall/update/list
|
|
18
|
+
|
|
19
|
+
${l.bold("Options:")}
|
|
20
|
+
--provider <name> Provider name (default: google)
|
|
21
|
+
--model <pattern> Model pattern or ID (supports "provider/id" and optional ":<thinking>")
|
|
22
|
+
--api-key <key> API key (defaults to env vars)
|
|
23
|
+
--system-prompt <text> System prompt (default: coding assistant prompt)
|
|
24
|
+
--append-system-prompt <text> Append text or file contents to the system prompt (can be used multiple times)
|
|
25
|
+
--mode <mode> Output mode: text (default), json, or rpc
|
|
26
|
+
--print, -p Non-interactive mode: process prompt and exit
|
|
27
|
+
--continue, -c Continue previous session
|
|
28
|
+
--resume, -r Select a session to resume
|
|
29
|
+
--session <path|id> Use specific session file or partial UUID
|
|
30
|
+
--session-id <id> Use exact project session ID, creating it if missing
|
|
31
|
+
--fork <path|id> Fork specific session file or partial UUID into a new session
|
|
32
|
+
--session-dir <dir> Directory for session storage and lookup
|
|
33
|
+
--no-session Don't save session (ephemeral)
|
|
34
|
+
--name, -n <name> Set session display name
|
|
35
|
+
--models <patterns> Comma-separated model patterns for Ctrl+P cycling
|
|
36
|
+
Supports globs (anthropic/*, *sonnet*) and fuzzy matching
|
|
37
|
+
--no-tools, -nt Disable all tools by default (built-in and extension)
|
|
38
|
+
--no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled
|
|
39
|
+
--tools, -t <tools> Comma-separated allowlist of tool names to enable
|
|
40
|
+
Applies to built-in, extension, and custom tools
|
|
41
|
+
--exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable
|
|
42
|
+
Applies to built-in, extension, and custom tools
|
|
43
|
+
--thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh
|
|
44
|
+
--extension, -e <path> Load an extension file (can be used multiple times)
|
|
45
|
+
--no-extensions, -ne Disable extension discovery (explicit -e paths still work)
|
|
46
|
+
--skill <path> Load a skill file or directory (can be used multiple times)
|
|
47
|
+
--no-skills, -ns Disable skills discovery and loading
|
|
48
|
+
--prompt-template <path> Load a prompt template file or directory (can be used multiple times)
|
|
49
|
+
--no-prompt-templates, -np Disable prompt template discovery and loading
|
|
50
|
+
--theme <path> Load a theme file or directory (can be used multiple times)
|
|
51
|
+
--no-themes Disable theme discovery and loading
|
|
52
|
+
--no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading
|
|
53
|
+
--export <file> Export session file to HTML and exit
|
|
54
|
+
--list-models [search] List available models (with optional fuzzy search)
|
|
55
|
+
--verbose Force verbose startup (overrides quietStartup setting)
|
|
56
|
+
--offline Disable startup network operations (same as KODA_OFFLINE=1)
|
|
57
|
+
--help, -h Show this help
|
|
58
|
+
--version, -v Show version number
|
|
59
|
+
|
|
60
|
+
Extensions can register additional flags (e.g., --plan from plan-mode extension).${t}
|
|
61
|
+
|
|
62
|
+
${l.bold("Examples:")}
|
|
63
|
+
# Interactive mode
|
|
64
|
+
${n}
|
|
65
|
+
|
|
66
|
+
# Interactive mode with initial prompt
|
|
67
|
+
${n} "List all .ts files in src/"
|
|
68
|
+
|
|
69
|
+
# Include files in initial message
|
|
70
|
+
${n} @prompt.md @image.png "What color is the sky?"
|
|
71
|
+
|
|
72
|
+
# Non-interactive mode (process and exit)
|
|
73
|
+
${n} -p "List all .ts files in src/"
|
|
74
|
+
|
|
75
|
+
# Multiple messages (interactive)
|
|
76
|
+
${n} "Read package.json" "What dependencies do we have?"
|
|
77
|
+
|
|
78
|
+
# Continue previous session
|
|
79
|
+
${n} --continue "What did we discuss?"
|
|
80
|
+
|
|
81
|
+
# Start a named session
|
|
82
|
+
${n} --name "Refactor auth module"
|
|
83
|
+
|
|
84
|
+
# Use different model
|
|
85
|
+
${n} --provider openai --model gpt-4o-mini "Help me refactor this code"
|
|
86
|
+
|
|
87
|
+
# Use model with provider prefix (no --provider needed)
|
|
88
|
+
${n} --model openai/gpt-4o "Help me refactor this code"
|
|
89
|
+
|
|
90
|
+
# Use model with thinking level shorthand
|
|
91
|
+
${n} --model sonnet:high "Solve this complex problem"
|
|
92
|
+
|
|
93
|
+
# Limit model cycling to specific models
|
|
94
|
+
${n} --models claude-sonnet,claude-haiku,gpt-4o
|
|
95
|
+
|
|
96
|
+
# Limit to a specific provider with glob pattern
|
|
97
|
+
${n} --models "github-copilot/*"
|
|
98
|
+
|
|
99
|
+
# Cycle models with fixed thinking levels
|
|
100
|
+
${n} --models sonnet:high,haiku:low
|
|
101
|
+
|
|
102
|
+
# Start with a specific thinking level
|
|
103
|
+
${n} --thinking high "Solve this complex problem"
|
|
104
|
+
|
|
105
|
+
# Read-only mode (no file modifications possible)
|
|
106
|
+
${n} --tools read,grep,find,ls -p "Review the code in src/"
|
|
107
|
+
|
|
108
|
+
# Disable one tool while keeping the rest available
|
|
109
|
+
${n} --exclude-tools ask_question
|
|
110
|
+
|
|
111
|
+
# Export a session file to HTML
|
|
112
|
+
${n} --export ~/${d}/agent/sessions/--path--/session.jsonl
|
|
113
|
+
${n} --export session.jsonl output.html
|
|
114
|
+
|
|
115
|
+
${l.bold("Environment Variables:")}
|
|
116
|
+
ANTHROPIC_API_KEY - Anthropic Claude API key
|
|
117
|
+
ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)
|
|
118
|
+
OPENAI_API_KEY - OpenAI GPT API key
|
|
119
|
+
AZURE_OPENAI_API_KEY - Azure OpenAI API key
|
|
120
|
+
AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)
|
|
121
|
+
AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)
|
|
122
|
+
AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)
|
|
123
|
+
AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)
|
|
124
|
+
DEEPSEEK_API_KEY - DeepSeek API key
|
|
125
|
+
NVIDIA_API_KEY - NVIDIA NIM API key
|
|
126
|
+
GEMINI_API_KEY - Google Gemini API key
|
|
127
|
+
GROQ_API_KEY - Groq API key
|
|
128
|
+
CEREBRAS_API_KEY - Cerebras API key
|
|
129
|
+
XAI_API_KEY - xAI Grok API key
|
|
130
|
+
FIREWORKS_API_KEY - Fireworks API key
|
|
131
|
+
TOGETHER_API_KEY - Together AI API key
|
|
132
|
+
OPENROUTER_API_KEY - OpenRouter API key
|
|
133
|
+
AI_GATEWAY_API_KEY - Vercel AI Gateway API key
|
|
134
|
+
ZAI_API_KEY - ZAI API key
|
|
135
|
+
MISTRAL_API_KEY - Mistral API key
|
|
136
|
+
MINIMAX_API_KEY - MiniMax API key
|
|
137
|
+
MOONSHOT_API_KEY - Moonshot AI API key
|
|
138
|
+
OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key
|
|
139
|
+
KIMI_API_KEY - Kimi For Coding API key
|
|
140
|
+
CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)
|
|
141
|
+
CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)
|
|
142
|
+
CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)
|
|
143
|
+
XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)
|
|
144
|
+
XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)
|
|
145
|
+
XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)
|
|
146
|
+
XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)
|
|
147
|
+
AWS_PROFILE - AWS profile for Amazon Bedrock
|
|
148
|
+
AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock
|
|
149
|
+
AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock
|
|
150
|
+
AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)
|
|
151
|
+
AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)
|
|
152
|
+
${u.padEnd(32)} - Config directory (default: ~/${d}/agent)
|
|
153
|
+
${A.padEnd(32)} - Session storage directory (overridden by --session-dir)
|
|
154
|
+
KODA_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)
|
|
155
|
+
KODA_OFFLINE - Disable startup network operations when set to 1/true/yes
|
|
156
|
+
KODA_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no
|
|
157
|
+
KODA_SHARE_VIEWER_URL - Base URL for /share command (default: https://openadapter.in/session/)
|
|
158
|
+
|
|
159
|
+
${l.bold("Built-in Tool Names:")}
|
|
160
|
+
read - Read file contents
|
|
161
|
+
bash - Execute bash commands
|
|
162
|
+
edit - Edit files with find/replace
|
|
163
|
+
write - Write files (creates/overwrites)
|
|
164
|
+
grep - Search file contents (read-only, off by default)
|
|
165
|
+
find - Find files by glob pattern (read-only, off by default)
|
|
166
|
+
ls - List directory contents (read-only, off by default)
|
|
167
|
+
`)}a(k,"printHelp");export{f as isValidThinkingLevel,_ as parseArgs,k as printHelp};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI config selector for `pi config` command
|
|
3
|
+
*/
|
|
4
|
+
import type { ResolvedPaths } from "../core/package-manager.ts";
|
|
5
|
+
import type { SettingsManager } from "../core/settings-manager.ts";
|
|
6
|
+
export interface ConfigSelectorOptions {
|
|
7
|
+
resolvedPaths: ResolvedPaths;
|
|
8
|
+
settingsManager: SettingsManager;
|
|
9
|
+
cwd: string;
|
|
10
|
+
agentDir: string;
|
|
11
|
+
}
|
|
12
|
+
/** Show TUI config selector and return when closed */
|
|
13
|
+
export declare function selectConfig(options: ConfigSelectorOptions): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=Object.defineProperty;var o=(e,r)=>a(e,"name",{value:r,configurable:!0});import{ProcessTerminal as c,TUI as m}from"@openadapter/koda-tui";import{ConfigSelectorComponent as l}from"../modes/interactive/components/config-selector.js";import{initTheme as g,stopThemeWatcher as i}from"../modes/interactive/theme/theme.js";async function w(e){return g(e.settingsManager.getTheme(),!0),new Promise(r=>{const t=new m(new c);let s=!1;const n=new l(e.resolvedPaths,e.settingsManager,e.cwd,e.agentDir,()=>{s||(s=!0,t.stop(),i(),r())},()=>{t.stop(),i(),process.exit(0)},()=>t.requestRender(),t.terminal.rows);t.addChild(n),t.setFocus(n.getResourceList()),t.start()})}o(w,"selectConfig");export{w as selectConfig};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process @file CLI arguments into text content and image attachments
|
|
3
|
+
*/
|
|
4
|
+
import type { ImageContent } from "@openadapter/koda-ai";
|
|
5
|
+
export interface ProcessedFiles {
|
|
6
|
+
text: string;
|
|
7
|
+
images: ImageContent[];
|
|
8
|
+
}
|
|
9
|
+
export interface ProcessFileOptions {
|
|
10
|
+
/** Whether to auto-resize images to 2000x2000 max. Default: true */
|
|
11
|
+
autoResizeImages?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Process @file arguments into text content and image attachments */
|
|
14
|
+
export declare function processFileArguments(fileArgs: string[], options?: ProcessFileOptions): Promise<ProcessedFiles>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var u=Object.defineProperty;var l=(a,s)=>u(a,"name",{value:s,configurable:!0});import{access as y,readFile as f,stat as $}from"node:fs/promises";import p from"chalk";import{resolve as h}from"path";import{resolveReadPath as w}from"../core/tools/path-utils.js";import{formatDimensionNote as z,resizeImage as F}from"../utils/image-resize.js";import{detectSupportedImageMimeTypeFromFile as I}from"../utils/mime.js";async function N(a,s){const d=s?.autoResizeImages??!0;let o="";const c=[];for(const g of a){const e=h(w(g,process.cwd()));try{await y(e)}catch{console.error(p.red(`Error: File not found: ${e}`)),process.exit(1)}if((await $(e)).size===0)continue;const n=await I(e);if(n){const t=await f(e);let i,m;if(d){const r=await F(t,n);if(!r){o+=`<file name="${e}">[Image omitted: could not be resized below the inline image size limit.]</file>
|
|
2
|
+
`;continue}m=z(r),i={type:"image",mimeType:r.mimeType,data:r.data}}else i={type:"image",mimeType:n,data:t.toString("base64")};c.push(i),m?o+=`<file name="${e}">${m}</file>
|
|
3
|
+
`:o+=`<file name="${e}"></file>
|
|
4
|
+
`}else try{const t=await f(e,"utf-8");o+=`<file name="${e}">
|
|
5
|
+
${t}
|
|
6
|
+
</file>
|
|
7
|
+
`}catch(t){const i=t instanceof Error?t.message:String(t);console.error(p.red(`Error: Could not read file ${e}: ${i}`)),process.exit(1)}}return{text:o,images:c}}l(N,"processFileArguments");export{N as processFileArguments};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import past sessions from other coding CLIs into Koda's own session store, so
|
|
3
|
+
* nothing is left behind when you switch. Currently supports:
|
|
4
|
+
* - Claude Code (~/.claude/projects/<cwd>/<uuid>.jsonl)
|
|
5
|
+
* - OpenCode (~/.local/share/opencode/opencode.db — SQLite)
|
|
6
|
+
*
|
|
7
|
+
* Each external session is converted to a Koda session (one per source session),
|
|
8
|
+
* organized under the session's own project cwd so it shows up in `koda --resume`.
|
|
9
|
+
* Conversion is "text + tool summaries": the full user/assistant conversation as
|
|
10
|
+
* text, with tool actions noted compactly (e.g. "[tool: edit src/foo.ts]"). It is
|
|
11
|
+
* idempotent — a small registry tracks imported source ids and skips them on re-run.
|
|
12
|
+
*
|
|
13
|
+
* Entry points: `koda import` (CLI) and the first-run setup prompt.
|
|
14
|
+
*/
|
|
15
|
+
export interface ImportCounts {
|
|
16
|
+
claude: number;
|
|
17
|
+
opencode: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ImportResult {
|
|
20
|
+
imported: number;
|
|
21
|
+
skipped: number;
|
|
22
|
+
perSource: {
|
|
23
|
+
claude: number;
|
|
24
|
+
opencode: number;
|
|
25
|
+
};
|
|
26
|
+
errors: number;
|
|
27
|
+
}
|
|
28
|
+
/** Count importable (not-yet-imported) sessions per source. */
|
|
29
|
+
export declare function detectImportable(currentCwdOnly?: string): Promise<ImportCounts>;
|
|
30
|
+
/** Convert + write all not-yet-imported sessions. */
|
|
31
|
+
export declare function importExternalSessions(opts?: {
|
|
32
|
+
currentCwdOnly?: string;
|
|
33
|
+
onProgress?: (done: number, total: number) => void;
|
|
34
|
+
}): Promise<ImportResult>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
var _=Object.defineProperty;var a=(t,e)=>_(t,"name",{value:e,configurable:!0});import{existsSync as h,readdirSync as y,readFileSync as S,writeFileSync as b}from"node:fs";import{homedir as m}from"node:os";import{join as f}from"node:path";import{getAgentDir as x}from"../config.js";import{SessionManager as A}from"../core/session-manager.js";const I={input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}};function w(t,e){return{role:"user",content:t,timestamp:e}}a(w,"userMsg");function D(t,e,r){return{role:"assistant",content:[{type:"text",text:t}],api:"openai-completions",provider:"openadapter",model:e||"imported",usage:I,stopReason:"stop",timestamp:r}}a(D,"asstMsg");function W(){return f(m(),".claude","projects")}a(W,"claudeProjectsDir");function C(){return f(m(),".local","share","opencode","opencode.db")}a(C,"openCodeDbPath");function E(t){return f(t,".koda-import.json")}a(E,"registryPath");function $(t){try{return JSON.parse(S(E(t),"utf-8"))}catch{return{}}}a($,"loadRegistry");function P(t,e){try{b(E(t),`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,"utf-8")}catch{}}a(P,"saveRegistry");const M=a((t,e=120)=>t.length>e?`${t.slice(0,e)}\u2026`:t,"trunc");function j(t,e){const r=e?.file_path||e?.path||e?.command||e?.pattern||e?.url||"";return`[tool: ${t}${r?` ${M(String(r),80)}`:""}]`}a(j,"summarizeTool");function R(){const t=W();if(!h(t))return[];const e=[];for(const r of y(t)){const o=f(t,r);let s;try{s=y(o).filter(n=>n.endsWith(".jsonl"))}catch{continue}for(const n of s)try{const c=F(f(o,n),n.replace(/\.jsonl$/,""),r);c?.turns.length&&e.push(c)}catch{}}return e}a(R,"readClaudeSessions");function F(t,e,r){const o=S(t,"utf-8").split(`
|
|
3
|
+
`).filter(Boolean),s=[];let n="",c=e,p=0;for(const u of o){let i;try{i=JSON.parse(u)}catch{continue}if(i?.cwd&&!n&&(n=i.cwd),i?.sessionId&&(c=i.sessionId),i?.timestamp&&!p&&(p=Date.parse(i.timestamp)||0),i?.isSidechain)continue;const d=i?.timestamp&&Date.parse(i.timestamp)||Date.now();if(i?.type==="user"&&i.message){const l=N(i.message.content);l.trim()&&s.push({role:"user",text:l,ts:d})}else if(i?.type==="assistant"&&i.message){const l=T(i.message.content);l.trim()&&s.push({role:"assistant",text:l,model:i.message.model,ts:d})}}return n||(n=J(r)),{source:"claude",sourceId:c,cwd:n,createdMs:p||Date.now(),turns:s}}a(F,"readClaudeFile");function N(t){if(typeof t=="string")return t;if(!Array.isArray(t))return"";const e=[];for(const r of t)if(r?.type==="text"&&r.text)e.push(r.text);else if(r?.type==="tool_result"){const o=typeof r.content=="string"?r.content:Array.isArray(r.content)?r.content.map(s=>s?.text||"").join(" "):"";e.push(`[tool result: ${M(String(o).replace(/\s+/g," "))}]`)}return e.join(`
|
|
4
|
+
`)}a(N,"extractClaudeUser");function T(t){if(typeof t=="string")return t;if(!Array.isArray(t))return"";const e=[];for(const r of t)r?.type==="text"&&r.text?e.push(r.text):r?.type==="tool_use"&&e.push(j(r.name||"call",r.input));return e.join(`
|
|
5
|
+
`)}a(T,"extractClaudeAssistant");function J(t){return t.startsWith("-")?t.replace(/-/g,"/"):t}a(J,"decodeProjectDir");async function O(){const t=C();if(!h(t))return[];const e=process.emitWarning;process.emitWarning=()=>{};let r;try{({DatabaseSync:r}=await import("node:sqlite"))}catch{return[]}finally{process.emitWarning=e}const o=[];let s;try{s=new r(t,{readOnly:!0});const n=s.prepare("SELECT id, title, path, time_created, model FROM session").all(),c=s.prepare("SELECT id, data, time_created FROM message WHERE session_id = ? ORDER BY time_created, id"),p=s.prepare("SELECT data FROM part WHERE message_id = ? ORDER BY time_created, id");for(const u of n)try{const i=[];for(const d of c.all(u.id)){let l;try{l=JSON.parse(d.data)?.role}catch{continue}if(l!=="user"&&l!=="assistant")continue;const g=k(p.all(d.id));g.trim()&&i.push({role:l,text:g,model:u.model,ts:d.time_created||Date.now()})}i.length&&o.push({source:"opencode",sourceId:u.id,cwd:u.path||m(),title:u.title,createdMs:u.time_created||Date.now(),turns:i})}catch{}}catch{return o}finally{try{s?.close()}catch{}}return o}a(O,"readOpenCodeSessions");function k(t){const e=[];for(const r of t){let o;try{o=JSON.parse(r.data)}catch{continue}const s=o?.type;if(s==="text"&&o.text)e.push(o.text);else if(typeof s=="string"&&s.startsWith("tool")){const n=o.tool||o.name||o.toolName||"call";e.push(j(n,o.state?.input||o.input))}}return e.join(`
|
|
6
|
+
`)}a(k,"extractOpenCodeParts");async function K(t){const e=x(),r=$(e),o=R().filter(n=>!r[`claude:${n.sourceId}`]&&(!t||n.cwd===t)).length,s=(await O()).filter(n=>!r[`opencode:${n.sourceId}`]&&(!t||n.cwd===t)).length;return{claude:o,opencode:s}}a(K,"detectImportable");async function q(t){const e=x(),r=$(e),o=[...R(),...await O()].filter(c=>!r[`${c.source}:${c.sourceId}`]&&(!t?.currentCwdOnly||c.cwd===t.currentCwdOnly)),s={imported:0,skipped:0,perSource:{claude:0,opencode:0},errors:0};let n=0;for(const c of o){try{const p=B(c);r[`${c.source}:${c.sourceId}`]=p,s.imported++,s.perSource[c.source]++}catch{s.errors++}t?.onProgress?.(++n,o.length)}return P(e,r),s}a(q,"importExternalSessions");function B(t){const e=A.create(t.cwd),r=t.title?.trim()?`${t.title.trim()} `:"";e.appendMessage(w(`${r}[imported from ${t.source}]`,t.createdMs));let o=!1;for(const s of t.turns){const n=s.role==="user"?w(s.text,s.ts):D(s.text,s.model,s.ts);s.role==="assistant"&&(o=!0),e.appendMessage(n)}return o||e.appendMessage(D("[no assistant response was recorded in the original session]",void 0,t.createdMs)),e.getSessionFile()??""}a(B,"writeKodaSession");export{K as detectImportable,q as importExternalSessions};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ImageContent } from "@openadapter/koda-ai";
|
|
2
|
+
import type { Args } from "./args.ts";
|
|
3
|
+
export interface InitialMessageInput {
|
|
4
|
+
parsed: Args;
|
|
5
|
+
fileText?: string;
|
|
6
|
+
fileImages?: ImageContent[];
|
|
7
|
+
stdinContent?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface InitialMessageResult {
|
|
10
|
+
initialMessage?: string;
|
|
11
|
+
initialImages?: ImageContent[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Combine stdin content, @file text, and the first CLI message into a single
|
|
15
|
+
* initial prompt for non-interactive mode.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildInitialMessage({ parsed, fileText, fileImages, stdinContent }: InitialMessageInput): InitialMessageResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var g=Object.defineProperty;var t=(s,n)=>g(s,"name",{value:n,configurable:!0});function a({parsed:s,fileText:n,fileImages:e,stdinContent:u}){const i=[];return u!==void 0&&i.push(u),n&&i.push(n),s.messages.length>0&&(i.push(s.messages[0]),s.messages.shift()),{initialMessage:i.length>0?i.join(""):void 0,initialImages:e&&e.length>0?e:void 0}}t(a,"buildInitialMessage");export{a as buildInitialMessage};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List available models with optional fuzzy search
|
|
3
|
+
*/
|
|
4
|
+
import type { ModelRegistry } from "../core/model-registry.ts";
|
|
5
|
+
/**
|
|
6
|
+
* List available models, optionally filtered by search pattern
|
|
7
|
+
*/
|
|
8
|
+
export declare function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var x=Object.defineProperty;var m=(i,e)=>x(i,"name",{value:e,configurable:!0});import{fuzzyFilter as c}from"@openadapter/koda-tui";import u from"chalk";import{formatNoModelsAvailableMessage as f}from"../core/auth-guidance.js";function p(i){if(i>=1e6){const e=i/1e6;return e%1===0?`${e}M`:`${e.toFixed(1)}M`}if(i>=1e3){const e=i/1e3;return e%1===0?`${e}K`:`${e.toFixed(1)}K`}return i.toString()}m(p,"formatTokenCount");async function O(i,e){const s=i.getError();s&&console.error(u.yellow(`Warning: errors loading models.json:
|
|
2
|
+
${s}`));const l=i.getAvailable();if(l.length===0){console.log(f());return}let a=l;if(e&&(a=c(l,e,o=>`${o.provider} ${o.id}`)),a.length===0){console.log(`No models matching "${e}"`);return}a.sort((o,d)=>{const g=o.provider.localeCompare(d.provider);return g!==0?g:o.id.localeCompare(d.id)});const r=a.map(o=>({provider:o.provider,model:o.id,context:p(o.contextWindow),maxOut:p(o.maxTokens),thinking:o.reasoning?"yes":"no",images:o.input.includes("image")?"yes":"no"})),n={provider:"provider",model:"model",context:"context",maxOut:"max-out",thinking:"thinking",images:"images"},t={provider:Math.max(n.provider.length,...r.map(o=>o.provider.length)),model:Math.max(n.model.length,...r.map(o=>o.model.length)),context:Math.max(n.context.length,...r.map(o=>o.context.length)),maxOut:Math.max(n.maxOut.length,...r.map(o=>o.maxOut.length)),thinking:Math.max(n.thinking.length,...r.map(o=>o.thinking.length)),images:Math.max(n.images.length,...r.map(o=>o.images.length))},h=[n.provider.padEnd(t.provider),n.model.padEnd(t.model),n.context.padEnd(t.context),n.maxOut.padEnd(t.maxOut),n.thinking.padEnd(t.thinking),n.images.padEnd(t.images)].join(" ");console.log(h);for(const o of r){const d=[o.provider.padEnd(t.provider),o.model.padEnd(t.model),o.context.padEnd(t.context),o.maxOut.padEnd(t.maxOut),o.thinking.padEnd(t.thinking),o.images.padEnd(t.images)].join(" ");console.log(d)}}m(O,"listModels");export{O as listModels};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAdapter first-run setup for Koda.
|
|
3
|
+
*
|
|
4
|
+
* Koda ships an OpenAdapter layer (provider config + extensions + skills) that a
|
|
5
|
+
* fresh install needs wired up. This runs the bundled `setup.mjs` wizard, which
|
|
6
|
+
* prompts for the user's own sk-cv key, fetches the model list, registers the
|
|
7
|
+
* extensions, and copies the skills.
|
|
8
|
+
*
|
|
9
|
+
* koda setup → re-run the wizard any time
|
|
10
|
+
* first launch with no → auto-run once (interactive only)
|
|
11
|
+
* OpenAdapter provider
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Offer to import past sessions from Claude Code + OpenCode so nothing is left
|
|
15
|
+
* behind. `auto` = called from first-run (skip silently if there's nothing).
|
|
16
|
+
*/
|
|
17
|
+
export declare function runInteractiveImport(opts?: {
|
|
18
|
+
auto?: boolean;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Once a day, refresh the OpenAdapter model list from the gateway so users
|
|
22
|
+
* automatically get newly-added models without re-running setup. Best-effort and
|
|
23
|
+
* throttled (24h); KODA_NO_MODEL_REFRESH=1 or KODA_OFFLINE disables.
|
|
24
|
+
*/
|
|
25
|
+
export declare function maybeRefreshOpenAdapterModels(agentDir: string): Promise<void>;
|
|
26
|
+
/** `koda import` — import sessions from other CLIs any time. */
|
|
27
|
+
export declare function handleImportCommand(args: string[]): Promise<boolean>;
|
|
28
|
+
/** Run the bundled wizard interactively. Returns true on success. */
|
|
29
|
+
export declare function runOpenAdapterSetup(extraArgs?: string[]): boolean;
|
|
30
|
+
/** `koda setup [sk-cv-...]` — explicit (re)configuration. */
|
|
31
|
+
export declare function handleSetupCommand(args: string[]): Promise<boolean>;
|
|
32
|
+
/** True when no OpenAdapter provider is configured yet (a fresh install). */
|
|
33
|
+
export declare function needsOpenAdapterSetup(agentDir: string): boolean;
|
|
34
|
+
/** On the first interactive launch with no OpenAdapter config, run the wizard. */
|
|
35
|
+
export declare function maybeFirstRunSetup(agentDir: string): Promise<void>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var y=Object.defineProperty;var n=(t,e)=>y(t,"name",{value:e,configurable:!0});import{spawnSync as h}from"node:child_process";import{existsSync as S,readFileSync as p,writeFileSync as g}from"node:fs";import{dirname as w,join as i}from"node:path";import{createInterface as O}from"node:readline/promises";import{fileURLToPath as $}from"node:url";import u from"chalk";import{getPackageDir as x}from"../config.js";import{detectImportable as A,importExternalSessions as C}from"./import-sessions.js";async function b(t,e=!0){const r=O({input:process.stdin,output:process.stdout});try{const o=(await r.question(`${t} ${e?"[Y/n]":"[y/N]"} `)).trim().toLowerCase();return o?o==="y"||o==="yes":e}finally{r.close()}}n(b,"askYesNo");async function f(t){let e;try{e=await A()}catch{return}if(e.claude+e.opencode===0){t?.auto||console.log("No new sessions to import from Claude Code or OpenCode.");return}const o=[e.claude?`${e.claude} from Claude Code`:"",e.opencode?`${e.opencode} from OpenCode`:""].filter(Boolean).join(" and ");if(!await b(u.bold(`Import ${o} into Koda so all your history is here?`)))return;process.stdout.write("Importing\u2026 ");const s=await C({onProgress:n((l,c)=>{process.stdout.write(`\rImporting\u2026 ${l}/${c} `)},"onProgress")});process.stdout.write("\r"),console.log(`\u2713 Imported ${s.imported} session(s) (${s.perSource.claude} Claude Code, ${s.perSource.opencode} OpenCode)${s.errors?`, ${s.errors} skipped`:""}. Find them with \`koda --resume\`.`)}n(f,"runInteractiveImport");async function E(t){if(process.env.KODA_NO_MODEL_REFRESH==="1"||process.env.KODA_OFFLINE)return;const e=i(t,"models.json");let r;try{r=JSON.parse(p(e,"utf-8"))}catch{return}const o=r?.providers?.openadapter;if(!o?.apiKey||!o?.baseUrl)return;const d=typeof o.modelsRefreshedAt=="number"?o.modelsRefreshedAt:0;if(!(Date.now()-d<1440*60*1e3))try{const s=await fetch(`${String(o.baseUrl).replace(/\/$/,"")}/models`,{headers:{Authorization:`Bearer ${o.apiKey}`},signal:AbortSignal.timeout(5e3)});if(!s.ok)return;const c=((await s.json()).data??[]).filter(a=>(a.endpoint_format||a.model_type)==="chat");if(c.length===0)return;o.models=c.map(a=>({id:a.id,name:a.id,input:a.supports_vision?["text","image"]:["text"],maxTokens:16e3})),o.modelsRefreshedAt=Date.now(),g(e,`${JSON.stringify(r,null,2)}
|
|
2
|
+
`,"utf-8")}catch{}}n(E,"maybeRefreshOpenAdapterModels");async function J(t){return t[0]!=="import"?!1:(await f(),!0)}n(J,"handleImportCommand");function I(){const t=w($(import.meta.url)),e=[i(x(),"openadapter","setup.mjs"),i(t,"..","..","openadapter","setup.mjs"),i(t,"..","..","..","..","scripts","setup-openadapter.mjs")];for(const r of e)if(S(r))return r;return null}n(I,"findSetupScript");function m(t=[]){const e=I();return e?h(process.execPath,[e,...t],{stdio:"inherit"}).status===0:(console.error(u.red("Koda setup script not found in this install.")),!1)}n(m,"runOpenAdapterSetup");async function L(t){if(t[0]!=="setup")return!1;const e=t.slice(1).find(r=>r.startsWith("sk-"));return m(e?[e]:[]),!0}n(L,"handleSetupCommand");function K(t){try{if(JSON.parse(p(i(t,"settings.json"),"utf-8"))?.defaultProvider==="openadapter")return!1}catch{}try{if(JSON.parse(p(i(t,"models.json"),"utf-8"))?.providers?.openadapter?.apiKey)return!1}catch{}return!0}n(K,"needsOpenAdapterSetup");async function U(t){if(process.env.KODA_SKIP_SETUP!=="1"&&K(t)){console.log(u.bold(`
|
|
3
|
+
Welcome to Koda \u2014 let's connect it to OpenAdapter (one-time).
|
|
4
|
+
`)),m([]),console.log("");try{await f({auto:!0})}catch{}}}n(U,"maybeFirstRunSetup");export{J as handleImportCommand,L as handleSetupCommand,U as maybeFirstRunSetup,E as maybeRefreshOpenAdapterModels,K as needsOpenAdapterSetup,f as runInteractiveImport,m as runOpenAdapterSetup};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI session selector for --resume flag
|
|
3
|
+
*/
|
|
4
|
+
import type { SessionInfo, SessionListProgress } from "../core/session-manager.ts";
|
|
5
|
+
type SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;
|
|
6
|
+
/** Show TUI session selector and return selected session path or null if cancelled */
|
|
7
|
+
export declare function selectSession(currentSessionsLoader: SessionsLoader, allSessionsLoader: SessionsLoader): Promise<string | null>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var l=Object.defineProperty;var c=(t,n)=>l(t,"name",{value:n,configurable:!0});import{ProcessTerminal as m,setKeybindings as p,TUI as d}from"@openadapter/koda-tui";import{KeybindingsManager as f}from"../core/keybindings.js";import{SessionSelectorComponent as u}from"../modes/interactive/components/session-selector.js";async function b(t,n){return new Promise(o=>{const e=new d(new m),i=f.create();p(i);let s=!1;const r=new u(t,n,a=>{s||(s=!0,e.stop(),o(a))},()=>{s||(s=!0,e.stop(),o(null))},()=>{e.stop(),process.exit(0)},()=>e.requestRender(),{showRenameHint:!1,keybindings:i});e.addChild(r),e.setFocus(r.getSessionList()),e.start()})}c(b,"selectSession");export{b as selectSession};
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED