@kata-sh/cli 0.1.0 → 0.1.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.
Files changed (199) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/dist/app-paths.d.ts +4 -0
  4. package/dist/app-paths.js +6 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +56 -0
  7. package/dist/loader.d.ts +2 -0
  8. package/dist/loader.js +95 -0
  9. package/dist/resource-loader.d.ts +18 -0
  10. package/dist/resource-loader.js +50 -0
  11. package/dist/wizard.d.ts +15 -0
  12. package/dist/wizard.js +159 -0
  13. package/package.json +50 -21
  14. package/pkg/dist/modes/interactive/theme/dark.json +85 -0
  15. package/pkg/dist/modes/interactive/theme/light.json +84 -0
  16. package/pkg/dist/modes/interactive/theme/theme-schema.json +335 -0
  17. package/pkg/dist/modes/interactive/theme/theme.d.ts +78 -0
  18. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  19. package/pkg/dist/modes/interactive/theme/theme.js +949 -0
  20. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -0
  21. package/pkg/package.json +8 -0
  22. package/scripts/postinstall.js +45 -0
  23. package/src/resources/AGENTS.md +108 -0
  24. package/src/resources/KATA-WORKFLOW.md +661 -0
  25. package/src/resources/agents/researcher.md +29 -0
  26. package/src/resources/agents/scout.md +56 -0
  27. package/src/resources/agents/worker.md +31 -0
  28. package/src/resources/extensions/ask-user-questions.ts +200 -0
  29. package/src/resources/extensions/bg-shell/index.ts +2758 -0
  30. package/src/resources/extensions/browser-tools/BROWSER-TOOLS-V2-PROPOSAL.md +1277 -0
  31. package/src/resources/extensions/browser-tools/core.js +1057 -0
  32. package/src/resources/extensions/browser-tools/index.ts +4916 -0
  33. package/src/resources/extensions/browser-tools/package.json +20 -0
  34. package/src/resources/extensions/context7/index.ts +428 -0
  35. package/src/resources/extensions/context7/package.json +11 -0
  36. package/src/resources/extensions/get-secrets-from-user.ts +352 -0
  37. package/src/resources/extensions/github/formatters.ts +207 -0
  38. package/src/resources/extensions/github/gh-api.ts +537 -0
  39. package/src/resources/extensions/github/index.ts +778 -0
  40. package/src/resources/extensions/kata/activity-log.ts +88 -0
  41. package/src/resources/extensions/kata/auto.ts +2786 -0
  42. package/src/resources/extensions/kata/commands.ts +355 -0
  43. package/src/resources/extensions/kata/crash-recovery.ts +85 -0
  44. package/src/resources/extensions/kata/dashboard-overlay.ts +516 -0
  45. package/src/resources/extensions/kata/docs/preferences-reference.md +103 -0
  46. package/src/resources/extensions/kata/doctor.ts +683 -0
  47. package/src/resources/extensions/kata/files.ts +730 -0
  48. package/src/resources/extensions/kata/gitignore.ts +165 -0
  49. package/src/resources/extensions/kata/guided-flow.ts +976 -0
  50. package/src/resources/extensions/kata/index.ts +556 -0
  51. package/src/resources/extensions/kata/metrics.ts +397 -0
  52. package/src/resources/extensions/kata/observability-validator.ts +408 -0
  53. package/src/resources/extensions/kata/package.json +11 -0
  54. package/src/resources/extensions/kata/paths.ts +346 -0
  55. package/src/resources/extensions/kata/preferences.ts +695 -0
  56. package/src/resources/extensions/kata/prompt-loader.ts +50 -0
  57. package/src/resources/extensions/kata/prompts/complete-milestone.md +25 -0
  58. package/src/resources/extensions/kata/prompts/complete-slice.md +27 -0
  59. package/src/resources/extensions/kata/prompts/discuss.md +151 -0
  60. package/src/resources/extensions/kata/prompts/doctor-heal.md +29 -0
  61. package/src/resources/extensions/kata/prompts/execute-task.md +64 -0
  62. package/src/resources/extensions/kata/prompts/guided-complete-slice.md +1 -0
  63. package/src/resources/extensions/kata/prompts/guided-discuss-milestone.md +3 -0
  64. package/src/resources/extensions/kata/prompts/guided-discuss-slice.md +59 -0
  65. package/src/resources/extensions/kata/prompts/guided-execute-task.md +1 -0
  66. package/src/resources/extensions/kata/prompts/guided-plan-milestone.md +23 -0
  67. package/src/resources/extensions/kata/prompts/guided-plan-slice.md +1 -0
  68. package/src/resources/extensions/kata/prompts/guided-research-slice.md +11 -0
  69. package/src/resources/extensions/kata/prompts/guided-resume-task.md +1 -0
  70. package/src/resources/extensions/kata/prompts/plan-milestone.md +47 -0
  71. package/src/resources/extensions/kata/prompts/plan-slice.md +63 -0
  72. package/src/resources/extensions/kata/prompts/queue.md +85 -0
  73. package/src/resources/extensions/kata/prompts/reassess-roadmap.md +48 -0
  74. package/src/resources/extensions/kata/prompts/replan-slice.md +39 -0
  75. package/src/resources/extensions/kata/prompts/research-milestone.md +37 -0
  76. package/src/resources/extensions/kata/prompts/research-slice.md +28 -0
  77. package/src/resources/extensions/kata/prompts/run-uat.md +109 -0
  78. package/src/resources/extensions/kata/prompts/system.md +341 -0
  79. package/src/resources/extensions/kata/session-forensics.ts +550 -0
  80. package/src/resources/extensions/kata/skill-discovery.ts +137 -0
  81. package/src/resources/extensions/kata/state.ts +509 -0
  82. package/src/resources/extensions/kata/templates/context.md +76 -0
  83. package/src/resources/extensions/kata/templates/decisions.md +8 -0
  84. package/src/resources/extensions/kata/templates/milestone-summary.md +73 -0
  85. package/src/resources/extensions/kata/templates/plan.md +133 -0
  86. package/src/resources/extensions/kata/templates/preferences.md +15 -0
  87. package/src/resources/extensions/kata/templates/project.md +31 -0
  88. package/src/resources/extensions/kata/templates/reassessment.md +28 -0
  89. package/src/resources/extensions/kata/templates/requirements.md +81 -0
  90. package/src/resources/extensions/kata/templates/research.md +46 -0
  91. package/src/resources/extensions/kata/templates/roadmap.md +118 -0
  92. package/src/resources/extensions/kata/templates/slice-context.md +58 -0
  93. package/src/resources/extensions/kata/templates/slice-summary.md +99 -0
  94. package/src/resources/extensions/kata/templates/state.md +19 -0
  95. package/src/resources/extensions/kata/templates/task-plan.md +52 -0
  96. package/src/resources/extensions/kata/templates/task-summary.md +57 -0
  97. package/src/resources/extensions/kata/templates/uat.md +54 -0
  98. package/src/resources/extensions/kata/tests/activity-log-prune.test.ts +327 -0
  99. package/src/resources/extensions/kata/tests/auto-preflight.test.ts +97 -0
  100. package/src/resources/extensions/kata/tests/auto-supervisor.test.mjs +53 -0
  101. package/src/resources/extensions/kata/tests/complete-milestone.test.ts +317 -0
  102. package/src/resources/extensions/kata/tests/cost-projection.test.ts +160 -0
  103. package/src/resources/extensions/kata/tests/derive-state-deps.test.ts +477 -0
  104. package/src/resources/extensions/kata/tests/derive-state.test.ts +1013 -0
  105. package/src/resources/extensions/kata/tests/doctor.test.ts +718 -0
  106. package/src/resources/extensions/kata/tests/idle-recovery.test.ts +490 -0
  107. package/src/resources/extensions/kata/tests/metrics-io.test.ts +254 -0
  108. package/src/resources/extensions/kata/tests/metrics.test.ts +217 -0
  109. package/src/resources/extensions/kata/tests/must-have-parser.test.ts +309 -0
  110. package/src/resources/extensions/kata/tests/parsers.test.ts +1257 -0
  111. package/src/resources/extensions/kata/tests/plan-milestone.test.ts +185 -0
  112. package/src/resources/extensions/kata/tests/plan-quality-validator.test.ts +386 -0
  113. package/src/resources/extensions/kata/tests/reassess-prompt.test.ts +208 -0
  114. package/src/resources/extensions/kata/tests/replan-slice.test.ts +686 -0
  115. package/src/resources/extensions/kata/tests/requirements.test.ts +151 -0
  116. package/src/resources/extensions/kata/tests/resolve-ts-hooks.mjs +17 -0
  117. package/src/resources/extensions/kata/tests/resolve-ts.mjs +11 -0
  118. package/src/resources/extensions/kata/tests/run-uat.test.ts +383 -0
  119. package/src/resources/extensions/kata/tests/unit-runtime.test.ts +388 -0
  120. package/src/resources/extensions/kata/tests/workspace-index.test.ts +118 -0
  121. package/src/resources/extensions/kata/tests/worktree.test.ts +222 -0
  122. package/src/resources/extensions/kata/types.ts +159 -0
  123. package/src/resources/extensions/kata/unit-runtime.ts +163 -0
  124. package/src/resources/extensions/kata/workspace-index.ts +203 -0
  125. package/src/resources/extensions/kata/worktree.ts +182 -0
  126. package/src/resources/extensions/mac-tools/index.ts +852 -0
  127. package/src/resources/extensions/mac-tools/swift-cli/Package.swift +22 -0
  128. package/src/resources/extensions/mac-tools/swift-cli/Sources/main.swift +1318 -0
  129. package/src/resources/extensions/search-the-web/cache.ts +78 -0
  130. package/src/resources/extensions/search-the-web/format.ts +258 -0
  131. package/src/resources/extensions/search-the-web/http.ts +238 -0
  132. package/src/resources/extensions/search-the-web/index.ts +68 -0
  133. package/src/resources/extensions/search-the-web/tool-fetch-page.ts +519 -0
  134. package/src/resources/extensions/search-the-web/tool-llm-context.ts +404 -0
  135. package/src/resources/extensions/search-the-web/tool-search.ts +503 -0
  136. package/src/resources/extensions/search-the-web/url-utils.ts +91 -0
  137. package/src/resources/extensions/shared/confirm-ui.ts +126 -0
  138. package/src/resources/extensions/shared/interview-ui.ts +822 -0
  139. package/src/resources/extensions/shared/next-action-ui.ts +235 -0
  140. package/src/resources/extensions/shared/progress-widget.ts +282 -0
  141. package/src/resources/extensions/shared/thinking-widget.ts +107 -0
  142. package/src/resources/extensions/shared/ui.ts +400 -0
  143. package/src/resources/extensions/shared/wizard-ui.ts +551 -0
  144. package/src/resources/extensions/slash-commands/audit.ts +92 -0
  145. package/src/resources/extensions/slash-commands/create-extension.ts +375 -0
  146. package/src/resources/extensions/slash-commands/create-slash-command.ts +280 -0
  147. package/src/resources/extensions/slash-commands/index.ts +12 -0
  148. package/src/resources/extensions/slash-commands/kata-run.ts +34 -0
  149. package/src/resources/extensions/subagent/agents.ts +126 -0
  150. package/src/resources/extensions/subagent/index.ts +1293 -0
  151. package/src/resources/skills/debug-like-expert/SKILL.md +231 -0
  152. package/src/resources/skills/debug-like-expert/references/debugging-mindset.md +253 -0
  153. package/src/resources/skills/debug-like-expert/references/hypothesis-testing.md +373 -0
  154. package/src/resources/skills/debug-like-expert/references/investigation-techniques.md +337 -0
  155. package/src/resources/skills/debug-like-expert/references/verification-patterns.md +425 -0
  156. package/src/resources/skills/debug-like-expert/references/when-to-research.md +361 -0
  157. package/src/resources/skills/frontend-design/SKILL.md +45 -0
  158. package/src/resources/skills/swiftui/SKILL.md +208 -0
  159. package/src/resources/skills/swiftui/references/animations.md +921 -0
  160. package/src/resources/skills/swiftui/references/architecture.md +1561 -0
  161. package/src/resources/skills/swiftui/references/layout-system.md +1186 -0
  162. package/src/resources/skills/swiftui/references/navigation.md +1492 -0
  163. package/src/resources/skills/swiftui/references/networking-async.md +214 -0
  164. package/src/resources/skills/swiftui/references/performance.md +1706 -0
  165. package/src/resources/skills/swiftui/references/platform-integration.md +204 -0
  166. package/src/resources/skills/swiftui/references/state-management.md +1443 -0
  167. package/src/resources/skills/swiftui/references/swiftdata.md +297 -0
  168. package/src/resources/skills/swiftui/references/testing-debugging.md +247 -0
  169. package/src/resources/skills/swiftui/references/uikit-appkit-interop.md +218 -0
  170. package/src/resources/skills/swiftui/workflows/add-feature.md +191 -0
  171. package/src/resources/skills/swiftui/workflows/build-new-app.md +311 -0
  172. package/src/resources/skills/swiftui/workflows/debug-swiftui.md +192 -0
  173. package/src/resources/skills/swiftui/workflows/optimize-performance.md +197 -0
  174. package/src/resources/skills/swiftui/workflows/ship-app.md +203 -0
  175. package/src/resources/skills/swiftui/workflows/write-tests.md +235 -0
  176. package/dist/commands/task.d.ts +0 -9
  177. package/dist/commands/task.d.ts.map +0 -1
  178. package/dist/commands/task.js +0 -129
  179. package/dist/commands/task.js.map +0 -1
  180. package/dist/commands/task.test.d.ts +0 -2
  181. package/dist/commands/task.test.d.ts.map +0 -1
  182. package/dist/commands/task.test.js +0 -169
  183. package/dist/commands/task.test.js.map +0 -1
  184. package/dist/e2e/task-e2e.test.d.ts +0 -2
  185. package/dist/e2e/task-e2e.test.d.ts.map +0 -1
  186. package/dist/e2e/task-e2e.test.js +0 -173
  187. package/dist/e2e/task-e2e.test.js.map +0 -1
  188. package/dist/index.d.ts +0 -3
  189. package/dist/index.d.ts.map +0 -1
  190. package/dist/index.js +0 -93
  191. package/dist/index.js.map +0 -1
  192. package/dist/slug.d.ts +0 -2
  193. package/dist/slug.d.ts.map +0 -1
  194. package/dist/slug.js +0 -12
  195. package/dist/slug.js.map +0 -1
  196. package/dist/slug.test.d.ts +0 -2
  197. package/dist/slug.test.d.ts.map +0 -1
  198. package/dist/slug.test.js +0 -32
  199. package/dist/slug.test.js.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lex Christopherson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # Kata CLI
2
+
3
+ A terminal coding agent built on [pi](https://github.com/badlogic/pi-mono) (`@mariozechner/pi-coding-agent`). Kata CLI bundles a curated set of extensions for structured planning, browser automation, web search, subagent orchestration, and more.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # From the monorepo root
9
+ bun install
10
+ cd apps/cli
11
+ npx tsc
12
+ npm run copy-themes
13
+ node dist/loader.js
14
+ ```
15
+
16
+ Authenticate with an API key:
17
+
18
+ ```bash
19
+ export ANTHROPIC_API_KEY=sk-ant-...
20
+ node dist/loader.js
21
+ ```
22
+
23
+ ## Architecture
24
+
25
+ Kata CLI is a thin wrapper around pi-coding-agent. It does not fork pi — it consumes it as an npm dependency and layers on branding, config, and bundled extensions.
26
+
27
+ ```
28
+ apps/cli/
29
+ src/
30
+ loader.ts — Entry point: sets KATA_* env vars, imports cli.ts
31
+ cli.ts — Calls pi-coding-agent's main()
32
+ app-paths.ts — ~/.kata-cli/ path constants
33
+ resource-loader.ts — Syncs bundled resources to ~/.kata-cli/agent/
34
+ wizard.ts — First-run setup, env key hydration
35
+ resources/
36
+ KATA-WORKFLOW.md — The Kata planning methodology
37
+ AGENTS.md — System prompt instructions (synced to agent dir)
38
+ agents/ — Agent templates (worker, scout, researcher)
39
+ extensions/ — Bundled extensions (see below)
40
+ skills/ — Bundled skills
41
+ pkg/
42
+ package.json — piConfig shim (name: "kata", configDir: ".kata-cli")
43
+ dist/ — Theme assets copied from pi-coding-agent
44
+ ```
45
+
46
+ ### How It Works
47
+
48
+ 1. `loader.ts` sets `PI_PACKAGE_DIR` to `pkg/` so pi reads Kata's branding config
49
+ 2. `loader.ts` sets `KATA_CODING_AGENT_DIR` so pi uses `~/.kata-cli/agent/` instead of `~/.pi/agent/`
50
+ 3. `resource-loader.ts` syncs bundled extensions, agents, skills, and `AGENTS.md` to `~/.kata-cli/agent/` on every launch
51
+ 4. `cli.ts` calls pi-coding-agent's `main()` — pi handles everything from there
52
+
53
+ ## Bundled Extensions
54
+
55
+ | Extension | Description |
56
+ |-----------|-------------|
57
+ | `kata/` | Main extension: `/kata` command, auto-mode, planning, state management |
58
+ | `browser-tools/` | Playwright-based browser automation |
59
+ | `subagent/` | Spawns child Kata processes for parallel work |
60
+ | `slash-commands/` | `/kata-run` and other slash commands |
61
+ | `bg-shell/` | Background shell execution |
62
+ | `context7/` | Context7 library documentation lookup |
63
+ | `search-the-web/` | Web search via Brave API |
64
+ | `mac-tools/` | macOS-specific utilities |
65
+ | `shared/` | Shared UI components (library, not an entry point) |
66
+
67
+ ## The /kata Command
68
+
69
+ The main extension registers `/kata` with subcommands:
70
+
71
+ | Command | Description |
72
+ |---------|-------------|
73
+ | `/kata` | Contextual wizard — smart entry point based on project state |
74
+ | `/kata auto` | Start auto-mode (loops fresh sessions until milestone complete) |
75
+ | `/kata stop` | Stop auto-mode gracefully |
76
+ | `/kata status` | Progress dashboard |
77
+ | `/kata queue` | View/manage work queue |
78
+ | `/kata discuss` | Discuss gray areas before planning |
79
+ | `/kata prefs` | Manage preferences (global/project/status) |
80
+ | `/kata doctor` | Diagnose and fix project state |
81
+
82
+ ### Project State
83
+
84
+ Kata stores planning state in `.kata/` at the project root:
85
+
86
+ ```
87
+ .kata/
88
+ STATE.md — Dashboard (read first)
89
+ DECISIONS.md — Append-only decisions register
90
+ PROJECT.md — Project description
91
+ REQUIREMENTS.md — Requirements tracking
92
+ milestones/
93
+ M001/
94
+ M001-ROADMAP.md — Milestone plan with slices
95
+ slices/
96
+ S01/
97
+ S01-PLAN.md — Task decomposition
98
+ tasks/
99
+ T01-PLAN.md
100
+ T01-SUMMARY.md
101
+ ```
102
+
103
+ ## Config Directory
104
+
105
+ Kata uses `~/.kata-cli/` (not `~/.kata/`) to avoid collision with other Kata apps (desktop, etc.):
106
+
107
+ ```
108
+ ~/.kata-cli/
109
+ agent/
110
+ extensions/ — Synced from src/resources/extensions/
111
+ agents/ — Synced from src/resources/agents/
112
+ skills/ — Synced from src/resources/skills/
113
+ AGENTS.md — Synced from src/resources/AGENTS.md
114
+ auth.json — API keys
115
+ settings.json — User settings
116
+ models.json — Custom model definitions
117
+ sessions/ — Session history
118
+ preferences.md — Global Kata preferences
119
+ ```
120
+
121
+ ## Environment Variables
122
+
123
+ Set by `loader.ts` before pi starts:
124
+
125
+ | Variable | Purpose |
126
+ |----------|---------|
127
+ | `PI_PACKAGE_DIR` | Points to `pkg/` for Kata's piConfig |
128
+ | `KATA_CODING_AGENT_DIR` | Tells pi to use `~/.kata-cli/agent/` |
129
+ | `KATA_VERSION` | Package version for display |
130
+ | `KATA_BIN_PATH` | Absolute path to loader, used by subagent |
131
+ | `KATA_WORKFLOW_PATH` | Absolute path to bundled KATA-WORKFLOW.md |
132
+ | `KATA_BUNDLED_EXTENSION_PATHS` | Colon-joined extension entry points for subagent |
133
+
134
+ ## Development
135
+
136
+ ```bash
137
+ # Build
138
+ npx tsc
139
+
140
+ # Copy theme assets (required once, or after pi-coding-agent updates)
141
+ npm run copy-themes
142
+
143
+ # Run
144
+ node dist/loader.js
145
+
146
+ # Test
147
+ npm test
148
+ ```
149
+
150
+ ### Key Dependency
151
+
152
+ `@mariozechner/pi-coding-agent` is consumed via npm (hoisted to monorepo root `node_modules/`). Never fork — run `npm update` to pick up upstream changes.
153
+
154
+ ## License
155
+
156
+ MIT
@@ -0,0 +1,4 @@
1
+ export declare const appRoot: string;
2
+ export declare const agentDir: string;
3
+ export declare const sessionsDir: string;
4
+ export declare const authFilePath: string;
@@ -0,0 +1,6 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+ export const appRoot = join(homedir(), '.kata-cli');
4
+ export const agentDir = join(appRoot, 'agent');
5
+ export const sessionsDir = join(appRoot, 'sessions');
6
+ export const authFilePath = join(agentDir, 'auth.json');
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,56 @@
1
+ import { AuthStorage, ModelRegistry, SettingsManager, SessionManager, createAgentSession, InteractiveMode, } from '@mariozechner/pi-coding-agent';
2
+ import { agentDir, sessionsDir, authFilePath } from './app-paths.js';
3
+ import { buildResourceLoader, initResources } from './resource-loader.js';
4
+ import { loadStoredEnvKeys, runWizardIfNeeded } from './wizard.js';
5
+ const authStorage = AuthStorage.create(authFilePath);
6
+ loadStoredEnvKeys(authStorage);
7
+ await runWizardIfNeeded(authStorage);
8
+ const modelRegistry = new ModelRegistry(authStorage);
9
+ const settingsManager = SettingsManager.create(agentDir);
10
+ // Always ensure defaults: anthropic/claude-sonnet-4-6, thinking off.
11
+ // Validates on every startup — catches stale settings from prior installs
12
+ // (e.g. grok-2 which no longer exists) and fresh installs with no settings.
13
+ const configuredProvider = settingsManager.getDefaultProvider();
14
+ const configuredModel = settingsManager.getDefaultModel();
15
+ const allModels = modelRegistry.getAll();
16
+ const configuredExists = configuredProvider && configuredModel &&
17
+ allModels.some((m) => m.provider === configuredProvider && m.id === configuredModel);
18
+ if (!configuredModel || !configuredExists) {
19
+ // Preferred default: anthropic/claude-sonnet-4-6
20
+ const preferred = allModels.find((m) => m.provider === 'anthropic' && m.id === 'claude-sonnet-4-6') ||
21
+ allModels.find((m) => m.provider === 'anthropic' && m.id.includes('sonnet')) ||
22
+ allModels.find((m) => m.provider === 'anthropic');
23
+ if (preferred) {
24
+ settingsManager.setDefaultModelAndProvider(preferred.provider, preferred.id);
25
+ }
26
+ }
27
+ // Default thinking level: off (always reset if not explicitly set)
28
+ if (settingsManager.getDefaultThinkingLevel() !== 'off' && !configuredExists) {
29
+ settingsManager.setDefaultThinkingLevel('off');
30
+ }
31
+ // Quiet startup — the kata extension renders its own branded header
32
+ if (!settingsManager.getQuietStartup()) {
33
+ settingsManager.setQuietStartup(true);
34
+ }
35
+ // Collapse changelog by default — avoid wall of text on updates
36
+ if (!settingsManager.getCollapseChangelog()) {
37
+ settingsManager.setCollapseChangelog(true);
38
+ }
39
+ const sessionManager = SessionManager.create(process.cwd(), sessionsDir);
40
+ initResources(agentDir);
41
+ const resourceLoader = buildResourceLoader(agentDir);
42
+ await resourceLoader.reload();
43
+ const { session, extensionsResult } = await createAgentSession({
44
+ authStorage,
45
+ modelRegistry,
46
+ settingsManager,
47
+ sessionManager,
48
+ resourceLoader,
49
+ });
50
+ if (extensionsResult.errors.length > 0) {
51
+ for (const err of extensionsResult.errors) {
52
+ process.stderr.write(`[kata] Extension load error: ${err.error}\n`);
53
+ }
54
+ }
55
+ const interactiveMode = new InteractiveMode(session);
56
+ await interactiveMode.run();
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/loader.js ADDED
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ import { fileURLToPath } from "url";
3
+ import { dirname, resolve, join } from "path";
4
+ import { existsSync, readFileSync } from "fs";
5
+ import { agentDir, appRoot } from "./app-paths.js";
6
+ // pkg/ is a shim directory: contains kata's piConfig (package.json) and pi's
7
+ // theme assets (dist/modes/interactive/theme/) without a src/ directory.
8
+ // This allows config.js to:
9
+ // 1. Read piConfig.name → "kata" (branding)
10
+ // 2. Resolve themes via dist/ (no src/ present → uses dist path)
11
+ const pkgDir = resolve(dirname(fileURLToPath(import.meta.url)), "..", "pkg");
12
+ // MUST be set before any dynamic import of pi SDK fires — this is what config.js
13
+ // reads to determine APP_NAME and CONFIG_DIR_NAME
14
+ process.env.PI_PACKAGE_DIR = pkgDir;
15
+ process.env.PI_SKIP_VERSION_CHECK = "1";
16
+ process.title = "kata";
17
+ // Print branded banner on first launch (before ~/.kata-cli/ exists)
18
+ if (!existsSync(appRoot)) {
19
+ const cyan = "\x1b[36m";
20
+ const green = "\x1b[32m";
21
+ const dim = "\x1b[2m";
22
+ const reset = "\x1b[0m";
23
+ let version = "";
24
+ try {
25
+ const pkgJson = JSON.parse(readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf-8"));
26
+ version = pkgJson.version ?? "";
27
+ }
28
+ catch {
29
+ /* ignore */
30
+ }
31
+ process.stderr.write("\n" +
32
+ cyan +
33
+ " ██╗ ██╗ █████╗ ████████╗ █████╗ \n" +
34
+ " ██║ ██╔╝██╔══██╗╚══██╔══╝██╔══██╗\n" +
35
+ " █████╔╝ ███████║ ██║ ███████║\n" +
36
+ " ██╔═██╗ ██╔══██║ ██║ ██╔══██║\n" +
37
+ " ██║ ██╗██║ ██║ ██║ ██║ ██║\n" +
38
+ " ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝" +
39
+ reset +
40
+ "\n\n" +
41
+ ` Kata CLI ${dim}v${version}${reset}\n` +
42
+ ` ${green}Welcome.${reset} Setting up your environment...\n\n`);
43
+ }
44
+ // KATA_CODING_AGENT_DIR — tells pi's getAgentDir() to return ~/.kata-cli/agent/
45
+ process.env.KATA_CODING_AGENT_DIR = agentDir;
46
+ // NODE_PATH — make kata's own node_modules available to extensions loaded via jiti.
47
+ // Without this, extensions (e.g. browser-tools) can't resolve dependencies like
48
+ // `playwright` because jiti resolves modules from pi-coding-agent's location, not kata's.
49
+ const kataRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
50
+ const kataNodeModules = join(kataRoot, "node_modules");
51
+ process.env.NODE_PATH = process.env.NODE_PATH
52
+ ? `${kataNodeModules}:${process.env.NODE_PATH}`
53
+ : kataNodeModules;
54
+ // Force Node to re-evaluate module search paths with the updated NODE_PATH.
55
+ // Must happen synchronously before cli.js imports → extension loading.
56
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
57
+ const { Module } = await import("module");
58
+ Module._initPaths?.();
59
+ // KATA_VERSION — expose package version so extensions can display it
60
+ try {
61
+ const kataPkg = JSON.parse(readFileSync(join(kataRoot, "package.json"), "utf-8"));
62
+ process.env.KATA_VERSION = kataPkg.version || "0.0.0";
63
+ }
64
+ catch {
65
+ process.env.KATA_VERSION = "0.0.0";
66
+ }
67
+ // KATA_BIN_PATH — absolute path to this loader (dist/loader.js), used by subagent
68
+ // to spawn kata instead of pi when dispatching workflow tasks
69
+ process.env.KATA_BIN_PATH = process.argv[1];
70
+ // KATA_WORKFLOW_PATH — absolute path to bundled KATA-WORKFLOW.md
71
+ // when dispatching workflow prompts
72
+ const resourcesDir = resolve(dirname(fileURLToPath(import.meta.url)), "..", "src", "resources");
73
+ process.env.KATA_WORKFLOW_PATH = join(resourcesDir, "KATA-WORKFLOW.md");
74
+ // KATA_BUNDLED_EXTENSION_PATHS — colon-joined list of all bundled extension entry point absolute
75
+ // paths, used by subagent to pass --extension <path> to spawned processes.
76
+ // IMPORTANT: paths point to agentDir (~/.kata-cli/agent/extensions/) NOT src/resources/extensions/.
77
+ // initResources() syncs bundled extensions to agentDir before any extension loading occurs,
78
+ // so these paths are always valid at runtime. Using agentDir paths matches what buildResourceLoader
79
+ // discovers (it scans agentDir), so pi's deduplication works correctly and extensions are not
80
+ // double-loaded in subagent child processes.
81
+ // Note: shared/ is NOT included — it's a library imported by kata and ask-user-questions, not an entry point.
82
+ process.env.KATA_BUNDLED_EXTENSION_PATHS = [
83
+ join(agentDir, "extensions", "kata", "index.ts"),
84
+ join(agentDir, "extensions", "bg-shell", "index.ts"),
85
+ join(agentDir, "extensions", "browser-tools", "index.ts"),
86
+ join(agentDir, "extensions", "context7", "index.ts"),
87
+ join(agentDir, "extensions", "search-the-web", "index.ts"),
88
+ join(agentDir, "extensions", "slash-commands", "index.ts"),
89
+ join(agentDir, "extensions", "subagent", "index.ts"),
90
+ join(agentDir, "extensions", "mac-tools", "index.ts"),
91
+ join(agentDir, "extensions", "ask-user-questions.ts"),
92
+ join(agentDir, "extensions", "get-secrets-from-user.ts"),
93
+ ].join(":");
94
+ // Dynamic import defers ESM evaluation — config.js will see PI_PACKAGE_DIR above
95
+ await import("./cli.js");
@@ -0,0 +1,18 @@
1
+ import { DefaultResourceLoader } from '@mariozechner/pi-coding-agent';
2
+ /**
3
+ * Syncs all bundled resources to agentDir (~/.kata-cli/agent/) on every launch.
4
+ *
5
+ * - extensions/ → ~/.kata-cli/agent/extensions/ (always overwrite)
6
+ * - agents/ → ~/.kata-cli/agent/agents/ (always overwrite)
7
+ * - AGENTS.md → ~/.kata-cli/agent/AGENTS.md (always overwrite)
8
+ * - KATA-WORKFLOW.md is read directly from bundled path via KATA_WORKFLOW_PATH env var
9
+ *
10
+ * Always-overwrite ensures updates take effect immediately.
11
+ */
12
+ export declare function initResources(agentDir: string): void;
13
+ /**
14
+ * Constructs a DefaultResourceLoader with no additionalExtensionPaths.
15
+ * Extensions are synced to agentDir by initResources() and pi auto-discovers
16
+ * them from ~/.kata-cli/agent/extensions/ via its normal agentDir scan.
17
+ */
18
+ export declare function buildResourceLoader(agentDir: string): DefaultResourceLoader;
@@ -0,0 +1,50 @@
1
+ import { DefaultResourceLoader } from '@mariozechner/pi-coding-agent';
2
+ import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { dirname, join, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ // Resolves to the bundled src/resources/ inside the npm package at runtime:
6
+ // dist/resource-loader.js → .. → package root → src/resources/
7
+ const resourcesDir = resolve(dirname(fileURLToPath(import.meta.url)), '..', 'src', 'resources');
8
+ const bundledExtensionsDir = join(resourcesDir, 'extensions');
9
+ /**
10
+ * Syncs all bundled resources to agentDir (~/.kata-cli/agent/) on every launch.
11
+ *
12
+ * - extensions/ → ~/.kata-cli/agent/extensions/ (always overwrite)
13
+ * - agents/ → ~/.kata-cli/agent/agents/ (always overwrite)
14
+ * - AGENTS.md → ~/.kata-cli/agent/AGENTS.md (always overwrite)
15
+ * - KATA-WORKFLOW.md is read directly from bundled path via KATA_WORKFLOW_PATH env var
16
+ *
17
+ * Always-overwrite ensures updates take effect immediately.
18
+ */
19
+ export function initResources(agentDir) {
20
+ mkdirSync(agentDir, { recursive: true });
21
+ // Sync extensions — always overwrite so updates land on next launch
22
+ const destExtensions = join(agentDir, 'extensions');
23
+ cpSync(bundledExtensionsDir, destExtensions, { recursive: true, force: true });
24
+ // Sync agents
25
+ const destAgents = join(agentDir, 'agents');
26
+ const srcAgents = join(resourcesDir, 'agents');
27
+ if (existsSync(srcAgents)) {
28
+ cpSync(srcAgents, destAgents, { recursive: true, force: true });
29
+ }
30
+ // Sync skills — always overwrite so updates land on next launch
31
+ const destSkills = join(agentDir, 'skills');
32
+ const srcSkills = join(resourcesDir, 'skills');
33
+ if (existsSync(srcSkills)) {
34
+ cpSync(srcSkills, destSkills, { recursive: true, force: true });
35
+ }
36
+ // Sync AGENTS.md
37
+ const srcAgentsMd = join(resourcesDir, 'AGENTS.md');
38
+ const destAgentsMd = join(agentDir, 'AGENTS.md');
39
+ if (existsSync(srcAgentsMd)) {
40
+ writeFileSync(destAgentsMd, readFileSync(srcAgentsMd));
41
+ }
42
+ }
43
+ /**
44
+ * Constructs a DefaultResourceLoader with no additionalExtensionPaths.
45
+ * Extensions are synced to agentDir by initResources() and pi auto-discovers
46
+ * them from ~/.kata-cli/agent/extensions/ via its normal agentDir scan.
47
+ */
48
+ export function buildResourceLoader(agentDir) {
49
+ return new DefaultResourceLoader({ agentDir });
50
+ }
@@ -0,0 +1,15 @@
1
+ import type { AuthStorage } from '@mariozechner/pi-coding-agent';
2
+ /**
3
+ * Hydrate process.env from stored auth.json credentials for optional tool keys.
4
+ * Runs on every launch so extensions see Brave/Context7/Jina keys stored via the
5
+ * wizard on prior launches.
6
+ */
7
+ export declare function loadStoredEnvKeys(authStorage: AuthStorage): void;
8
+ /**
9
+ * Check for missing optional tool API keys and prompt for them if on a TTY.
10
+ *
11
+ * Anthropic auth is handled by pi's own OAuth/API key flow — we don't touch it.
12
+ * This wizard only collects Brave Search, Context7, and Jina keys which are needed
13
+ * for web search and documentation tools.
14
+ */
15
+ export declare function runWizardIfNeeded(authStorage: AuthStorage): Promise<void>;
package/dist/wizard.js ADDED
@@ -0,0 +1,159 @@
1
+ import { createInterface } from 'readline';
2
+ // ─── Colors ──────────────────────────────────────────────────────────────────
3
+ const cyan = '\x1b[36m';
4
+ const green = '\x1b[32m';
5
+ const yellow = '\x1b[33m';
6
+ const dim = '\x1b[2m';
7
+ const bold = '\x1b[1m';
8
+ const reset = '\x1b[0m';
9
+ // ─── Masked input ─────────────────────────────────────────────────────────────
10
+ /**
11
+ * Prompt for masked input using raw mode stdin.
12
+ * Handles backspace, Ctrl+C, and Enter.
13
+ * Falls back to plain readline if setRawMode is unavailable (e.g. some SSH contexts).
14
+ */
15
+ async function promptMasked(label, hint) {
16
+ return new Promise((resolve) => {
17
+ const question = ` ${cyan}›${reset} ${label} ${dim}${hint}${reset}\n `;
18
+ try {
19
+ process.stdout.write(question);
20
+ process.stdin.setRawMode(true);
21
+ process.stdin.resume();
22
+ process.stdin.setEncoding('utf8');
23
+ let value = '';
24
+ const handler = (ch) => {
25
+ if (ch === '\r' || ch === '\n') {
26
+ process.stdin.setRawMode(false);
27
+ process.stdin.pause();
28
+ process.stdin.off('data', handler);
29
+ process.stdout.write('\n');
30
+ resolve(value);
31
+ }
32
+ else if (ch === '\u0003') {
33
+ process.stdin.setRawMode(false);
34
+ process.stdout.write('\n');
35
+ process.exit(0);
36
+ }
37
+ else if (ch === '\u007f') {
38
+ if (value.length > 0) {
39
+ value = value.slice(0, -1);
40
+ }
41
+ process.stdout.clearLine(0);
42
+ process.stdout.cursorTo(0);
43
+ process.stdout.write(' ' + '*'.repeat(value.length));
44
+ }
45
+ else {
46
+ value += ch;
47
+ process.stdout.write('*');
48
+ }
49
+ };
50
+ process.stdin.on('data', handler);
51
+ }
52
+ catch (_err) {
53
+ process.stdout.write(` ${dim}(input will be visible)${reset}\n `);
54
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
55
+ rl.question('', (answer) => {
56
+ rl.close();
57
+ resolve(answer);
58
+ });
59
+ }
60
+ });
61
+ }
62
+ // ─── Env hydration ────────────────────────────────────────────────────────────
63
+ /**
64
+ * Hydrate process.env from stored auth.json credentials for optional tool keys.
65
+ * Runs on every launch so extensions see Brave/Context7/Jina keys stored via the
66
+ * wizard on prior launches.
67
+ */
68
+ export function loadStoredEnvKeys(authStorage) {
69
+ const providers = [
70
+ ['brave', 'BRAVE_API_KEY'],
71
+ ['brave_answers', 'BRAVE_ANSWERS_KEY'],
72
+ ['context7', 'CONTEXT7_API_KEY'],
73
+ ['jina', 'JINA_API_KEY'],
74
+ ];
75
+ for (const [provider, envVar] of providers) {
76
+ if (!process.env[envVar]) {
77
+ const cred = authStorage.get(provider);
78
+ if (cred?.type === 'api_key') {
79
+ process.env[envVar] = cred.key;
80
+ }
81
+ }
82
+ }
83
+ }
84
+ const API_KEYS = [
85
+ {
86
+ provider: 'brave',
87
+ envVar: 'BRAVE_API_KEY',
88
+ label: 'Brave Search',
89
+ hint: '(search-the-web + search_and_read tools)',
90
+ description: 'Web search and page extraction',
91
+ },
92
+ {
93
+ provider: 'brave_answers',
94
+ envVar: 'BRAVE_ANSWERS_KEY',
95
+ label: 'Brave Answers',
96
+ hint: '(AI-summarised search answers)',
97
+ description: 'AI-generated search summaries',
98
+ },
99
+ {
100
+ provider: 'context7',
101
+ envVar: 'CONTEXT7_API_KEY',
102
+ label: 'Context7',
103
+ hint: '(up-to-date library docs)',
104
+ description: 'Live library and framework documentation',
105
+ },
106
+ {
107
+ provider: 'jina',
108
+ envVar: 'JINA_API_KEY',
109
+ label: 'Jina AI',
110
+ hint: '(clean page extraction)',
111
+ description: 'High-quality web page content extraction',
112
+ },
113
+ ];
114
+ /**
115
+ * Check for missing optional tool API keys and prompt for them if on a TTY.
116
+ *
117
+ * Anthropic auth is handled by pi's own OAuth/API key flow — we don't touch it.
118
+ * This wizard only collects Brave Search, Context7, and Jina keys which are needed
119
+ * for web search and documentation tools.
120
+ */
121
+ export async function runWizardIfNeeded(authStorage) {
122
+ const missing = API_KEYS.filter(k => !authStorage.has(k.provider) && !process.env[k.envVar]);
123
+ if (missing.length === 0)
124
+ return;
125
+ // Non-TTY: warn and continue
126
+ if (!process.stdin.isTTY) {
127
+ const names = missing.map(k => k.label).join(', ');
128
+ process.stderr.write(`[kata] Warning: optional tool API keys not configured (${names}). Some tools may not work.\n`);
129
+ return;
130
+ }
131
+ // ── Header ──────────────────────────────────────────────────────────────────
132
+ process.stdout.write(`\n ${bold}Optional API keys${reset}\n` +
133
+ ` ${dim}─────────────────────────────────────────────${reset}\n` +
134
+ ` These unlock additional tools. All optional — press ${cyan}Enter${reset} to skip any.\n\n`);
135
+ // ── Prompts ─────────────────────────────────────────────────────────────────
136
+ let savedCount = 0;
137
+ for (const key of missing) {
138
+ const value = await promptMasked(key.label, key.hint);
139
+ if (value.trim()) {
140
+ authStorage.set(key.provider, { type: 'api_key', key: value.trim() });
141
+ process.env[key.envVar] = value.trim();
142
+ process.stdout.write(` ${green}✓${reset} ${key.label} saved\n\n`);
143
+ savedCount++;
144
+ }
145
+ else {
146
+ process.stdout.write(` ${dim}↷ ${key.label} skipped${reset}\n\n`);
147
+ }
148
+ }
149
+ // ── Footer ───────────────────────────────────────────────────────────────────
150
+ process.stdout.write(` ${dim}─────────────────────────────────────────────${reset}\n`);
151
+ if (savedCount > 0) {
152
+ process.stdout.write(` ${green}✓${reset} ${savedCount} key${savedCount > 1 ? 's' : ''} saved to ${dim}~/.kata-cli/agent/auth.json${reset}\n` +
153
+ ` ${dim}Run ${reset}${cyan}/login${reset}${dim} inside kata to connect your LLM provider.${reset}\n\n`);
154
+ }
155
+ else {
156
+ process.stdout.write(` ${yellow}↷${reset} All keys skipped — you can add them later via ${dim}~/.kata-cli/agent/auth.json${reset}\n` +
157
+ ` ${dim}Run ${reset}${cyan}/login${reset}${dim} inside kata to connect your LLM provider.${reset}\n\n`);
158
+ }
159
+ }