@kosuke-ai/cli 0.0.56 → 1.0.0

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 (251) hide show
  1. package/README.md +31 -448
  2. package/dist/commands/auth.js +117 -0
  3. package/dist/generated/commands/deploy/cancel.js +17 -0
  4. package/dist/generated/commands/deploy/messages.js +17 -0
  5. package/dist/generated/commands/deploy/run.js +60 -0
  6. package/dist/generated/commands/index.js +132 -0
  7. package/dist/generated/commands/preview/get.js +25 -0
  8. package/dist/generated/commands/preview/health.js +25 -0
  9. package/dist/generated/commands/preview/reset.js +27 -0
  10. package/dist/generated/commands/preview/share-create.js +36 -0
  11. package/dist/generated/commands/preview/share-delete.js +26 -0
  12. package/dist/generated/commands/preview/share-get.js +26 -0
  13. package/dist/generated/commands/preview/shared.js +17 -0
  14. package/dist/generated/commands/projects/create.js +37 -0
  15. package/dist/generated/commands/projects/delete.js +17 -0
  16. package/dist/generated/commands/projects/env-vars-add.js +21 -0
  17. package/dist/generated/commands/projects/env-vars-remove.js +21 -0
  18. package/dist/generated/commands/projects/get.js +17 -0
  19. package/dist/generated/commands/projects/list.js +15 -0
  20. package/dist/generated/commands/projects/services-add.js +87 -0
  21. package/dist/generated/commands/projects/services-list.js +18 -0
  22. package/dist/generated/commands/projects/services-remove.js +19 -0
  23. package/dist/generated/commands/projects/services-update.js +81 -0
  24. package/dist/generated/commands/projects/settings-get.js +18 -0
  25. package/dist/generated/commands/projects/settings-import.js +91 -0
  26. package/dist/generated/commands/projects/settings-update.js +77 -0
  27. package/dist/generated/commands/projects/skills.js +35 -0
  28. package/dist/generated/commands/projects/update.js +27 -0
  29. package/dist/generated/commands/sessions/activate.js +18 -0
  30. package/dist/generated/commands/sessions/checklist-generate.js +19 -0
  31. package/dist/generated/commands/sessions/checklist-get.js +19 -0
  32. package/dist/generated/commands/sessions/comments-add.js +63 -0
  33. package/dist/generated/commands/sessions/comments-delete.js +20 -0
  34. package/dist/generated/commands/sessions/comments-list.js +19 -0
  35. package/dist/generated/commands/sessions/comments-update.js +23 -0
  36. package/dist/generated/commands/sessions/create.js +126 -0
  37. package/dist/generated/commands/sessions/delete.js +18 -0
  38. package/dist/generated/commands/sessions/diff-files.js +19 -0
  39. package/dist/generated/commands/sessions/diff-patch.js +86 -0
  40. package/dist/generated/commands/sessions/edit-prompt.js +59 -0
  41. package/dist/generated/commands/sessions/files-get.js +27 -0
  42. package/dist/generated/commands/sessions/files-list.js +19 -0
  43. package/dist/generated/commands/sessions/files-write.js +41 -0
  44. package/dist/generated/commands/sessions/get.js +18 -0
  45. package/dist/generated/commands/sessions/git-commit-message.js +19 -0
  46. package/dist/generated/commands/sessions/git-commit.js +29 -0
  47. package/dist/generated/commands/sessions/git-push.js +19 -0
  48. package/dist/generated/commands/sessions/git-state.js +19 -0
  49. package/dist/generated/commands/sessions/jobs-cancel.js +20 -0
  50. package/dist/generated/commands/sessions/jobs-get.js +20 -0
  51. package/dist/generated/commands/sessions/list.js +81 -0
  52. package/dist/generated/commands/sessions/messages.js +18 -0
  53. package/dist/generated/commands/sessions/search.js +23 -0
  54. package/dist/generated/commands/sessions/send.js +98 -0
  55. package/dist/generated/commands/sessions/update.js +72 -0
  56. package/dist/generated/commands/workspaces/access-status.js +29 -0
  57. package/dist/generated/commands/workspaces/ai-provider-get.js +18 -0
  58. package/dist/generated/commands/workspaces/ai-provider-remove.js +42 -0
  59. package/dist/generated/commands/workspaces/ai-provider-set.js +21 -0
  60. package/dist/generated/commands/workspaces/credits.js +17 -0
  61. package/dist/generated/commands/workspaces/get.js +17 -0
  62. package/dist/generated/commands/workspaces/getting-started-get.js +18 -0
  63. package/dist/generated/commands/workspaces/getting-started-update.js +32 -0
  64. package/dist/generated/commands/workspaces/list.js +15 -0
  65. package/dist/generated/commands/workspaces/members.js +25 -0
  66. package/dist/generated/commands/workspaces/sandbox-limit.js +17 -0
  67. package/dist/generated/commands/workspaces/stop-sandboxes.js +27 -0
  68. package/dist/generated/commands/workspaces/usage.js +32 -0
  69. package/dist/index.js +5 -516
  70. package/dist/program.js +46 -0
  71. package/dist/runtime/attach.js +139 -0
  72. package/dist/runtime/attachments.js +58 -0
  73. package/dist/runtime/client.js +12 -0
  74. package/dist/runtime/config.js +49 -0
  75. package/dist/runtime/credentials.js +24 -0
  76. package/dist/runtime/descriptor.js +7 -0
  77. package/dist/runtime/invoke.js +152 -0
  78. package/dist/runtime/runtime.js +41 -0
  79. package/dist/runtime/version.js +5 -0
  80. package/openapi.json +5222 -0
  81. package/package.json +21 -79
  82. package/LICENSE +0 -21
  83. package/claude.costs.json +0 -34
  84. package/dist/__tests__/utils/file-discovery.test.d.ts +0 -5
  85. package/dist/__tests__/utils/file-discovery.test.d.ts.map +0 -1
  86. package/dist/__tests__/utils/file-discovery.test.js +0 -51
  87. package/dist/__tests__/utils/file-discovery.test.js.map +0 -1
  88. package/dist/__tests__/utils/logger-nologs.test.d.ts +0 -5
  89. package/dist/__tests__/utils/logger-nologs.test.d.ts.map +0 -1
  90. package/dist/__tests__/utils/logger-nologs.test.js +0 -34
  91. package/dist/__tests__/utils/logger-nologs.test.js.map +0 -1
  92. package/dist/__tests__/utils/logger.test.d.ts +0 -5
  93. package/dist/__tests__/utils/logger.test.d.ts.map +0 -1
  94. package/dist/__tests__/utils/logger.test.js +0 -243
  95. package/dist/__tests__/utils/logger.test.js.map +0 -1
  96. package/dist/__tests__/utils/validator.test.d.ts +0 -5
  97. package/dist/__tests__/utils/validator.test.d.ts.map +0 -1
  98. package/dist/__tests__/utils/validator.test.js +0 -206
  99. package/dist/__tests__/utils/validator.test.js.map +0 -1
  100. package/dist/index.d.ts +0 -35
  101. package/dist/index.d.ts.map +0 -1
  102. package/dist/index.js.map +0 -1
  103. package/dist/kosuke/commands/analyse.d.ts +0 -15
  104. package/dist/kosuke/commands/analyse.d.ts.map +0 -1
  105. package/dist/kosuke/commands/analyse.js +0 -273
  106. package/dist/kosuke/commands/analyse.js.map +0 -1
  107. package/dist/kosuke/commands/build.d.ts +0 -35
  108. package/dist/kosuke/commands/build.d.ts.map +0 -1
  109. package/dist/kosuke/commands/build.js +0 -659
  110. package/dist/kosuke/commands/build.js.map +0 -1
  111. package/dist/kosuke/commands/getcode.d.ts +0 -29
  112. package/dist/kosuke/commands/getcode.d.ts.map +0 -1
  113. package/dist/kosuke/commands/getcode.js +0 -221
  114. package/dist/kosuke/commands/getcode.js.map +0 -1
  115. package/dist/kosuke/commands/lint.d.ts +0 -21
  116. package/dist/kosuke/commands/lint.d.ts.map +0 -1
  117. package/dist/kosuke/commands/lint.js +0 -321
  118. package/dist/kosuke/commands/lint.js.map +0 -1
  119. package/dist/kosuke/commands/migrate.d.ts +0 -38
  120. package/dist/kosuke/commands/migrate.d.ts.map +0 -1
  121. package/dist/kosuke/commands/migrate.js +0 -284
  122. package/dist/kosuke/commands/migrate.js.map +0 -1
  123. package/dist/kosuke/commands/plan.d.ts +0 -28
  124. package/dist/kosuke/commands/plan.d.ts.map +0 -1
  125. package/dist/kosuke/commands/plan.js +0 -630
  126. package/dist/kosuke/commands/plan.js.map +0 -1
  127. package/dist/kosuke/commands/requirements.d.ts +0 -52
  128. package/dist/kosuke/commands/requirements.d.ts.map +0 -1
  129. package/dist/kosuke/commands/requirements.js +0 -615
  130. package/dist/kosuke/commands/requirements.js.map +0 -1
  131. package/dist/kosuke/commands/review.d.ts +0 -26
  132. package/dist/kosuke/commands/review.d.ts.map +0 -1
  133. package/dist/kosuke/commands/review.js +0 -303
  134. package/dist/kosuke/commands/review.js.map +0 -1
  135. package/dist/kosuke/commands/serve.d.ts +0 -9
  136. package/dist/kosuke/commands/serve.d.ts.map +0 -1
  137. package/dist/kosuke/commands/serve.js +0 -17
  138. package/dist/kosuke/commands/serve.js.map +0 -1
  139. package/dist/kosuke/commands/ship.d.ts +0 -37
  140. package/dist/kosuke/commands/ship.d.ts.map +0 -1
  141. package/dist/kosuke/commands/ship.js +0 -375
  142. package/dist/kosuke/commands/ship.js.map +0 -1
  143. package/dist/kosuke/commands/sync-rules.d.ts +0 -9
  144. package/dist/kosuke/commands/sync-rules.d.ts.map +0 -1
  145. package/dist/kosuke/commands/sync-rules.js +0 -379
  146. package/dist/kosuke/commands/sync-rules.js.map +0 -1
  147. package/dist/kosuke/commands/test.d.ts +0 -42
  148. package/dist/kosuke/commands/test.d.ts.map +0 -1
  149. package/dist/kosuke/commands/test.js +0 -540
  150. package/dist/kosuke/commands/test.js.map +0 -1
  151. package/dist/kosuke/commands/tickets.d.ts +0 -43
  152. package/dist/kosuke/commands/tickets.d.ts.map +0 -1
  153. package/dist/kosuke/commands/tickets.js +0 -499
  154. package/dist/kosuke/commands/tickets.js.map +0 -1
  155. package/dist/kosuke/serve/middleware/error-handler.d.ts +0 -14
  156. package/dist/kosuke/serve/middleware/error-handler.d.ts.map +0 -1
  157. package/dist/kosuke/serve/middleware/error-handler.js +0 -42
  158. package/dist/kosuke/serve/middleware/error-handler.js.map +0 -1
  159. package/dist/kosuke/serve/middleware/validation.d.ts +0 -13
  160. package/dist/kosuke/serve/middleware/validation.d.ts.map +0 -1
  161. package/dist/kosuke/serve/middleware/validation.js +0 -38
  162. package/dist/kosuke/serve/middleware/validation.js.map +0 -1
  163. package/dist/kosuke/serve/routes/build.d.ts +0 -6
  164. package/dist/kosuke/serve/routes/build.d.ts.map +0 -1
  165. package/dist/kosuke/serve/routes/build.js +0 -226
  166. package/dist/kosuke/serve/routes/build.js.map +0 -1
  167. package/dist/kosuke/serve/routes/health.d.ts +0 -6
  168. package/dist/kosuke/serve/routes/health.d.ts.map +0 -1
  169. package/dist/kosuke/serve/routes/health.js +0 -11
  170. package/dist/kosuke/serve/routes/health.js.map +0 -1
  171. package/dist/kosuke/serve/routes/plan.d.ts +0 -6
  172. package/dist/kosuke/serve/routes/plan.d.ts.map +0 -1
  173. package/dist/kosuke/serve/routes/plan.js +0 -106
  174. package/dist/kosuke/serve/routes/plan.js.map +0 -1
  175. package/dist/kosuke/serve/server.d.ts +0 -16
  176. package/dist/kosuke/serve/server.d.ts.map +0 -1
  177. package/dist/kosuke/serve/server.js +0 -67
  178. package/dist/kosuke/serve/server.js.map +0 -1
  179. package/dist/kosuke/serve/validation/build.d.ts +0 -41
  180. package/dist/kosuke/serve/validation/build.d.ts.map +0 -1
  181. package/dist/kosuke/serve/validation/build.js +0 -20
  182. package/dist/kosuke/serve/validation/build.js.map +0 -1
  183. package/dist/kosuke/serve/validation/plan.d.ts +0 -26
  184. package/dist/kosuke/serve/validation/plan.d.ts.map +0 -1
  185. package/dist/kosuke/serve/validation/plan.js +0 -15
  186. package/dist/kosuke/serve/validation/plan.js.map +0 -1
  187. package/dist/kosuke/types.d.ts +0 -469
  188. package/dist/kosuke/types.d.ts.map +0 -1
  189. package/dist/kosuke/types.js +0 -5
  190. package/dist/kosuke/types.js.map +0 -1
  191. package/dist/kosuke/utils/batch-creator.d.ts +0 -14
  192. package/dist/kosuke/utils/batch-creator.d.ts.map +0 -1
  193. package/dist/kosuke/utils/batch-creator.js +0 -76
  194. package/dist/kosuke/utils/batch-creator.js.map +0 -1
  195. package/dist/kosuke/utils/claude-agent.d.ts +0 -145
  196. package/dist/kosuke/utils/claude-agent.d.ts.map +0 -1
  197. package/dist/kosuke/utils/claude-agent.js +0 -504
  198. package/dist/kosuke/utils/claude-agent.js.map +0 -1
  199. package/dist/kosuke/utils/constants.d.ts +0 -40
  200. package/dist/kosuke/utils/constants.d.ts.map +0 -1
  201. package/dist/kosuke/utils/constants.js +0 -54
  202. package/dist/kosuke/utils/constants.js.map +0 -1
  203. package/dist/kosuke/utils/file-discovery.d.ts +0 -15
  204. package/dist/kosuke/utils/file-discovery.d.ts.map +0 -1
  205. package/dist/kosuke/utils/file-discovery.js +0 -80
  206. package/dist/kosuke/utils/file-discovery.js.map +0 -1
  207. package/dist/kosuke/utils/git.d.ts +0 -41
  208. package/dist/kosuke/utils/git.d.ts.map +0 -1
  209. package/dist/kosuke/utils/git.js +0 -145
  210. package/dist/kosuke/utils/git.js.map +0 -1
  211. package/dist/kosuke/utils/github.d.ts +0 -17
  212. package/dist/kosuke/utils/github.d.ts.map +0 -1
  213. package/dist/kosuke/utils/github.js +0 -22
  214. package/dist/kosuke/utils/github.js.map +0 -1
  215. package/dist/kosuke/utils/interactive-input.d.ts +0 -22
  216. package/dist/kosuke/utils/interactive-input.d.ts.map +0 -1
  217. package/dist/kosuke/utils/interactive-input.js +0 -124
  218. package/dist/kosuke/utils/interactive-input.js.map +0 -1
  219. package/dist/kosuke/utils/logger.d.ts +0 -161
  220. package/dist/kosuke/utils/logger.d.ts.map +0 -1
  221. package/dist/kosuke/utils/logger.js +0 -234
  222. package/dist/kosuke/utils/logger.js.map +0 -1
  223. package/dist/kosuke/utils/playwright-mcp-client.d.ts +0 -46
  224. package/dist/kosuke/utils/playwright-mcp-client.d.ts.map +0 -1
  225. package/dist/kosuke/utils/playwright-mcp-client.js +0 -135
  226. package/dist/kosuke/utils/playwright-mcp-client.js.map +0 -1
  227. package/dist/kosuke/utils/pr-orchestrator.d.ts +0 -49
  228. package/dist/kosuke/utils/pr-orchestrator.d.ts.map +0 -1
  229. package/dist/kosuke/utils/pr-orchestrator.js +0 -154
  230. package/dist/kosuke/utils/pr-orchestrator.js.map +0 -1
  231. package/dist/kosuke/utils/repository-manager.d.ts +0 -13
  232. package/dist/kosuke/utils/repository-manager.d.ts.map +0 -1
  233. package/dist/kosuke/utils/repository-manager.js +0 -94
  234. package/dist/kosuke/utils/repository-manager.js.map +0 -1
  235. package/dist/kosuke/utils/repository-resolver.d.ts +0 -12
  236. package/dist/kosuke/utils/repository-resolver.d.ts.map +0 -1
  237. package/dist/kosuke/utils/repository-resolver.js +0 -186
  238. package/dist/kosuke/utils/repository-resolver.js.map +0 -1
  239. package/dist/kosuke/utils/tickets-manager.d.ts +0 -64
  240. package/dist/kosuke/utils/tickets-manager.d.ts.map +0 -1
  241. package/dist/kosuke/utils/tickets-manager.js +0 -331
  242. package/dist/kosuke/utils/tickets-manager.js.map +0 -1
  243. package/dist/kosuke/utils/validator.d.ts +0 -45
  244. package/dist/kosuke/utils/validator.d.ts.map +0 -1
  245. package/dist/kosuke/utils/validator.js +0 -248
  246. package/dist/kosuke/utils/validator.js.map +0 -1
  247. package/dist/lib.d.ts +0 -96
  248. package/dist/lib.d.ts.map +0 -1
  249. package/dist/lib.js +0 -95
  250. package/dist/lib.js.map +0 -1
  251. package/dist/package.json +0 -99
package/README.md CHANGED
@@ -1,451 +1,34 @@
1
- # Kosuke CLI
1
+ # @kosuke-ai/cli
2
2
 
3
- Development automation tool for syncing rules and analyzing code quality with Claude AI.
3
+ The Kosuke platform CLI: `kosuke`, the client you install on your own machine to
4
+ drive [app.kosuke.ai](https://app.kosuke.ai). Not the agent that runs inside a
5
+ Kosuke sandbox; that one lives in `sandbox/kosuke-cli` and is never installed
6
+ by hand.
4
7
 
5
- ## Installation
6
-
7
- Install globally via npm:
8
-
9
- ```bash
8
+ ```sh
10
9
  npm install -g @kosuke-ai/cli
11
- ```
12
-
13
- Or use with npx (no installation required):
14
-
15
- ```bash
16
- npx @kosuke-ai/cli <command>
17
- ```
18
-
19
- ### Use as Library in TypeScript Projects
20
-
21
- Install as a project dependency:
22
-
23
- ```bash
24
- npm install @kosuke-ai/cli
25
- ```
26
-
27
- Then import and use programmatically:
28
-
29
- ```typescript
30
- import {
31
- analyseCommand,
32
- lintCommand,
33
- syncRulesCommand,
34
- requirementsCommand,
35
- planCoreStream,
36
- discoverFiles,
37
- createBatches,
38
- runLint,
39
- runTypecheck,
40
- } from '@kosuke-ai/cli';
41
-
42
- // Run commands programmatically
43
- await analyseCommand({
44
- scope: 'src/components',
45
- pr: false,
46
- });
47
-
48
- await lintCommand({ pr: false });
49
-
50
- // Use utilities
51
- const files = await discoverFiles({
52
- types: ['ts', 'tsx'],
53
- scope: 'lib',
54
- });
55
-
56
- const batches = createBatches(files, {
57
- maxSize: 10,
58
- groupBy: 'directory',
59
- });
60
-
61
- const lintResult = await runLint();
62
- if (!lintResult.success) {
63
- console.error('Linting failed:', lintResult.error);
64
- }
65
-
66
- // Stream plan command (for real-time updates)
67
- const stream = planCoreStream({
68
- prompt: 'Add dark mode',
69
- directory: './my-project',
70
- });
71
-
72
- for await (const event of stream) {
73
- if (event.type === 'message') {
74
- console.log('Claude:', event.data.text);
75
- } else if (event.type === 'done') {
76
- console.log('Result:', event.data);
77
- }
78
- }
79
- ```
80
-
81
- #### Local Development with npm link
82
-
83
- To develop against a local version of kosuke-cli:
84
-
85
- ```bash
86
- # In kosuke-cli directory
87
- npm run dev:link # Builds, links, and watches for changes
88
-
89
- # In your project directory
90
- npm link @kosuke-ai/cli
91
- ```
92
-
93
- Now your project will use the local kosuke-cli, and changes will be reflected automatically.
94
-
95
- ## Prerequisites
96
-
97
- Set up the required environment variables:
98
-
99
- ```bash
100
- # Required for Claude API access
101
- export ANTHROPIC_API_KEY="your-api-key-here"
102
-
103
- # Optional: Specify Claude model (default: claude-haiku-4-5-20251001)
104
- export ANTHROPIC_MODEL="claude-haiku-4-5-20251001"
105
-
106
- # Optional: Only required when using --pr flag
107
- export GITHUB_TOKEN="your-github-token-here"
108
- ```
109
-
110
- You can also create a `.env` file in your project root:
111
-
112
- ```env
113
- ANTHROPIC_API_KEY=your-api-key-here
114
- ANTHROPIC_MODEL=claude-haiku-4-5-20251001
115
- GITHUB_TOKEN=your-github-token-here
116
- ```
117
-
118
- **Available Models:**
119
-
120
- - `claude-haiku-4-5-20251001` - Fast and cost-effective (default)
121
- - `claude-sonnet-4-5-20250929` - Balanced performance and quality
122
- - `claude-opus-4-5-20251101` - Highest quality, slower
123
-
124
- Model pricing is configured in `claude.costs.json` (per million tokens).
125
-
126
- ### CLI Logging (Optional)
127
-
128
- Kosuke CLI can automatically log command executions to kosuke-core for analytics, cost monitoring, and debugging. This feature is optional and requires additional configuration.
129
-
130
- **Environment Variables:**
131
-
132
- ```bash
133
- # Optional: Enable logging to kosuke-core
134
- export KOSUKE_BASE_URL="https://your-kosuke-core.com"
135
- export KOSUKE_API_KEY="your-cli-api-key"
136
- export KOSUKE_PROJECT_ID="your-project-uuid"
137
- ```
138
-
139
- Or add to your `.env` file:
140
-
141
- ```env
142
- KOSUKE_BASE_URL=https://your-kosuke-core.com
143
- KOSUKE_API_KEY=your-cli-api-key
144
- KOSUKE_PROJECT_ID=xxx-xxx-xxx-xxx-xxx
145
- ```
146
-
147
- **What gets logged:**
148
-
149
- When configured, Kosuke CLI automatically logs:
150
-
151
- - Command execution (ship, test, review, getcode, tickets)
152
- - Token usage (input, output, cache creation, cache read)
153
- - Cost breakdown (calculated from token usage)
154
- - Execution time and performance metrics
155
- - Command-specific metrics (fixes applied, tests run, etc.)
156
- - Success/error status
157
-
158
- **Privacy:**
159
-
160
- - Logging is non-blocking and will not interrupt commands if it fails
161
- - No sensitive data (API keys, tokens, passwords) is logged
162
- - File paths are logged, but not file contents
163
- - Logging is automatically enabled when all three environment variables are set
164
- - Logging can be safely omitted if not using kosuke-core
165
-
166
- ## Workflow
167
-
168
- By default, all commands apply changes **locally** without git operations. This allows you to:
169
-
170
- - Review changes before committing
171
- - Test fixes in your local environment
172
- - Iterate quickly without creating PRs
173
-
174
- Use the `--pr` flag to automatically create a pull request with the changes.
175
-
176
- ## Commands
177
-
178
- ### `kosuke serve`
179
-
180
- Start an HTTP server that exposes Kosuke CLI commands via REST API with Server-Sent Events (SSE) for real-time streaming.
181
-
182
- **Options:**
183
-
184
- - `--port=<number>` - Port to listen on (default: 3000)
185
-
186
- **Examples:**
187
-
188
- ```bash
189
- # Start server on default port 3000
190
- kosuke serve
191
-
192
- # Start server on custom port
193
- kosuke serve --port=8080
194
- ```
195
-
196
- **API Endpoints:**
197
-
198
- - `GET /health` - Health check endpoint
199
- - `POST /api/plan` - Plan command with SSE streaming
200
- - `POST /api/build` - Build command with SSE streaming
201
-
202
- **Example API Usage:**
203
-
204
- ```bash
205
- # Health check
206
- curl http://localhost:3000/health
207
-
208
- # Plan command with SSE
209
- curl -N -X POST http://localhost:3000/api/plan \
210
- -H "Content-Type: application/json" \
211
- -d '{
212
- "query": "Add dark mode toggle",
213
- "cwd": "/path/to/project",
214
- "noTest": false
215
- }'
216
-
217
- # Build command with SSE
218
- curl -N -X POST http://localhost:3000/api/build \
219
- -H "Content-Type: application/json" \
220
- -d '{
221
- "cwd": "/path/to/project",
222
- "review": true,
223
- "url": "http://localhost:3000"
224
- }'
225
- ```
226
-
227
- **SSE Event Types:**
228
-
229
- The API returns Server-Sent Events (SSE) with the following event types:
230
-
231
- - `tool_call` - Tool execution events (file reads, bash commands, etc.)
232
- - `message` - Assistant text messages (Claude's reasoning and updates)
233
- - `done` - Final result with statistics, tokens used, and cost
234
-
235
- **Request Validation:**
236
-
237
- All API requests are validated using Zod schemas:
238
-
239
- - `/api/plan` requires: `{ query: string, cwd: string, noTest?: boolean, resume?: string }`
240
- - `/api/build` requires: `{ cwd: string, ticketsFile?: string, reset?: boolean, review?: boolean }`
241
-
242
- Invalid requests return 400 with detailed error messages.
243
-
244
- ### `kosuke sync-rules`
245
-
246
- Sync rules and documentation from kosuke-template repository.
247
-
248
- **Options:**
249
-
250
- - `--force` - Compare files regardless of recent commit history
251
- - `--pr` - Create a pull request with the changes
252
- - `--base-branch=<name>` - Base branch for PR (default: current branch)
253
-
254
- **Examples:**
255
-
256
- ```bash
257
- # Sync locally
258
- kosuke sync-rules
259
-
260
- # Force comparison and sync locally
261
- kosuke sync-rules --force
262
-
263
- # Create PR with synced changes
264
- kosuke sync-rules --pr
265
-
266
- # Create PR with custom base branch
267
- kosuke sync-rules --pr --base-branch=develop
268
- ```
269
-
270
- ### `kosuke analyse`
271
-
272
- Analyze and fix code quality issues against CLAUDE.md rules. Applies fixes locally by default.
273
-
274
- **Options:**
275
-
276
- - `--pr` - Create a pull request with fixes
277
- - `--base-branch=<name>` - Base branch for PR (default: current branch)
278
- - `--scope=<dirs>` - Analyze specific directories (comma-separated)
279
- - `--types=<exts>` - Analyze specific file types (comma-separated)
280
-
281
- **Examples:**
282
-
283
- ```bash
284
- # Analyze and fix locally
285
- kosuke analyse
286
-
287
- # Analyze specific directories
288
- kosuke analyse --scope=hooks,lib/trpc
289
-
290
- # Analyze specific file types
291
- kosuke analyse --types=ts,tsx
292
-
293
- # Create PR with fixes
294
- kosuke analyse --pr
295
-
296
- # Create PR with custom base branch
297
- kosuke analyse --pr --base-branch=main
298
- ```
299
-
300
- ### `kosuke lint`
301
-
302
- Use Claude AI to automatically fix linting errors. Applies fixes locally by default.
303
-
304
- **Options:**
305
-
306
- - `--pr` - Create a pull request with fixes
307
- - `--base-branch=<name>` - Base branch for PR (default: current branch)
308
-
309
- **Examples:**
310
-
311
- ```bash
312
- # Fix linting errors locally
313
- kosuke lint
314
-
315
- # Create PR with fixes
316
- kosuke lint --pr
317
-
318
- # Create PR with custom base branch
319
- kosuke lint --pr --base-branch=main
320
- ```
321
-
322
- **Requirements:**
323
-
324
- - Your `package.json` must have a `lint` script (e.g., `"lint": "eslint ."`)
325
- - The lint script should support the `--fix` flag for auto-fixing
326
-
327
- ### `kosuke requirements`
328
-
329
- Interactive requirements gathering tool powered by Claude AI. Creates a comprehensive `docs.md` file through a conversational workflow.
330
-
331
- **How it works:**
332
-
333
- 1. You describe your web application
334
- 2. Claude analyzes and extracts core functionalities
335
- 3. Claude asks clarification questions
336
- 4. You answer iteratively until requirements are clear
337
- 5. Claude generates a detailed `docs.md` with:
338
- - Product Overview
339
- - Core Functionalities
340
- - Technical Architecture
341
- - User Flows
342
- - Database Schema
343
- - API Endpoints
344
- - Implementation Notes
345
-
346
- **Example:**
347
-
348
- ```bash
349
- kosuke requirements
350
- ```
351
-
352
- **Features:**
353
-
354
- - ✨ Fully interactive conversation workflow
355
- - 💰 Real-time cost tracking (shows token usage)
356
- - 🔄 Iterative refinement until requirements are comprehensive
357
- - 📝 Structured markdown output in `docs.md`
358
- - 🌐 Optimized for web application projects
359
-
360
- ## Configuration
361
-
362
- ### `.kosukeignore`
363
-
364
- Create a `.kosukeignore` file in your project root to exclude files and directories from analysis. Uses the same syntax as `.gitignore`.
365
-
366
- Example:
367
-
368
- ```gitignore
369
- # Ignore build outputs
370
- dist/
371
- build/
372
-
373
- # Ignore specific files
374
- *.test.ts
375
- **/*.spec.ts
376
-
377
- # Ignore directories
378
- node_modules/
379
- .git/
380
- ```
381
-
382
- ## Development
383
-
384
- ### Local Development
385
-
386
- If you want to contribute or run from source:
387
-
388
- ```bash
389
- # Clone the repository
390
- git clone https://github.com/Kosuke-Org/kosuke-cli.git
391
- cd kosuke-cli
392
-
393
- # Install dependencies
394
- npm install
395
-
396
- # Build the project
397
- npm run build
398
-
399
- # Run in development mode
400
- npm run dev <command>
401
-
402
- # Link for local testing
403
- npm link
404
- kosuke <command>
405
- ```
406
-
407
- ### Docker Development
408
-
409
- Run kosuke-cli inside Docker for an isolated development environment:
410
-
411
- **Prerequisites:**
412
-
413
- - Docker installed and running
414
- - `kosuke_network` Docker network created (if you want to connect to other services)
415
-
416
- **Quick Start:**
417
-
418
- ```bash
419
- # Create .env file with your credentials
420
- cat > .env << EOF
421
- ANTHROPIC_API_KEY=your-api-key
422
- GITHUB_TOKEN=your-github-token
423
- EOF
424
-
425
- # Run the development container
426
- ./docker-dev.sh
427
- ```
428
-
429
- The script will:
430
-
431
- - Build the Docker image
432
- - Mount your current directory into the container
433
- - Connect to `kosuke_network` for inter-service communication
434
- - Load environment variables from `.env`
435
- - Drop you into an interactive bash shell
436
-
437
- **Inside the container:**
438
-
439
- ```bash
440
- # Run any kosuke command
441
- kosuke sync-rules
442
- kosuke analyse
443
- kosuke lint
444
-
445
- # The workspace is mounted, so changes are reflected immediately
446
- npm run build
447
- kosuke <command>
448
-
449
- # Exit the container
450
- exit
451
- ```
10
+ kosuke auth login # paste an auth token from Settings
11
+ kosuke projects list | jq '.data[] | {id, name}'
12
+ kosuke sessions create <projectId> --title "Fix the login form" \
13
+ --content "See the screenshot" --status backlog --attach shot.png
14
+ ```
15
+
16
+ Every command prints the platform's JSON response as is, so it pipes into `jq`.
17
+ Path params are positional, request fields are flags (`--exclude-archived`,
18
+ `--start-line-number 12`), and any body can be passed whole with `--body '{…}'`,
19
+ `--body-file path` or `--body-file -` for stdin. `kosuke <group> --help` lists
20
+ the operations; each one's help is the API's own description.
21
+
22
+ The token comes from `--api-key`, then `KOSUKE_API_KEY`, then the file
23
+ `kosuke auth login` writes (mode 0600, under `~/.config/kosuke`, or
24
+ `KOSUKE_CONFIG_DIR`). `--api-url` / `KOSUKE_API_URL` point it at another
25
+ deployment.
26
+
27
+ ## Generated from the API
28
+
29
+ `openapi.json` is the platform's own `GET /api/openapi.json`, snapshotted by
30
+ `bun run openapi:snapshot` at the repository root. `npm run generate` turns it
31
+ into `src/generated/`: request types (openapi-typescript) and one descriptor per
32
+ operation, which the hand-written runtime turns into commands. `npm run check`
33
+ regenerates and fails on any difference, so the tree is only ever what the
34
+ document says.
@@ -0,0 +1,117 @@
1
+ import { createApiClient } from '../runtime/client.js';
2
+ import { credentialsPath, DEFAULT_API_URL, deleteCredentials, writeCredentials, } from '../runtime/config.js';
3
+ export function attachAuthCommands(root, runtime, deps = {}) {
4
+ const { env = process.env, fetch, prompt = promptHidden, stdout = (line) => process.stdout.write(line + '\n'), stderr = (line) => process.stderr.write(line + '\n'), exit = (code) => {
5
+ process.exitCode = code;
6
+ }, } = deps;
7
+ const auth = root.command('auth').description('Manage the auth token this machine uses.');
8
+ auth
9
+ .command('login')
10
+ .description('Store an auth token, after checking it works. Takes the global --api-key when ' +
11
+ 'given, and prompts otherwise. Create one in Settings.')
12
+ .action(async () => {
13
+ // The global --api-key is the one flag: commander reads a program option
14
+ // wherever it appears, so a second `--api-key` on this subcommand would
15
+ // never receive the value. Only that flag counts as the token to store:
16
+ // logging in is an explicit act, and a stale KOSUKE_API_KEY left in the
17
+ // shell is exactly what someone running this may be trying to replace.
18
+ const resolved = runtime.credentials();
19
+ const apiUrl = resolved.apiUrl;
20
+ const apiKey = resolved.apiKeySource === 'flag' ? resolved.apiKey : (await prompt('Auth token: ')).trim();
21
+ if (!apiKey) {
22
+ stderr('No token given.');
23
+ exit(1);
24
+ return;
25
+ }
26
+ const who = await verify(apiUrl, apiKey, fetch);
27
+ if (!who.ok) {
28
+ stderr(`The token was refused by ${apiUrl} (HTTP ${who.status}). Nothing saved.`);
29
+ exit(1);
30
+ return;
31
+ }
32
+ const path = writeCredentials({ apiKey, ...(apiUrl !== DEFAULT_API_URL ? { apiUrl } : {}) }, env);
33
+ stdout(`Logged in to ${apiUrl}; member of ${who.workspaces} workspace${who.workspaces === 1 ? '' : 's'}. Token saved to ${path}.`);
34
+ });
35
+ auth
36
+ .command('status')
37
+ .description('Show where the token comes from and whether the platform accepts it.')
38
+ .action(async () => {
39
+ const { apiKey, apiKeySource, apiUrl, apiUrlSource } = runtime.credentials();
40
+ const result = {
41
+ apiUrl,
42
+ apiUrlSource,
43
+ apiKeySource,
44
+ credentialsFile: credentialsPath(env),
45
+ };
46
+ if (apiKey) {
47
+ const who = await verify(apiUrl, apiKey, fetch);
48
+ result.tokenPrefix = apiKey.slice(0, 12);
49
+ result.accepted = who.ok;
50
+ if (who.ok)
51
+ result.workspaces = who.workspaces;
52
+ else
53
+ result.status = who.status;
54
+ }
55
+ else {
56
+ result.accepted = false;
57
+ }
58
+ stdout(JSON.stringify(result, null, 2));
59
+ if (!result.accepted)
60
+ exit(1);
61
+ });
62
+ auth
63
+ .command('logout')
64
+ .description('Delete the stored token. Tokens from the environment or flags are untouched.')
65
+ .action(() => {
66
+ const path = credentialsPath(env);
67
+ stdout(deleteCredentials(env) ? `Removed ${path}.` : `Nothing stored at ${path}.`);
68
+ });
69
+ }
70
+ /** The cheapest call a token must be able to make: the workspaces it belongs to. */
71
+ async function verify(apiUrl, apiKey, fetch) {
72
+ const client = createApiClient({ apiUrl, apiKey, fetch });
73
+ const { data, response } = await client.GET('/api/organizations');
74
+ if (!response.ok)
75
+ return { ok: false, status: response.status };
76
+ const list = data?.data;
77
+ return { ok: true, workspaces: Array.isArray(list) ? list.length : 0 };
78
+ }
79
+ /** Read a line without echoing it, when stdin is a terminal. */
80
+ async function promptHidden(question) {
81
+ const { stdin, stdout } = process;
82
+ stdout.write(question);
83
+ if (!stdin.isTTY) {
84
+ const { createInterface } = await import('node:readline/promises');
85
+ const rl = createInterface({ input: stdin, terminal: false });
86
+ const answer = await rl.question('');
87
+ rl.close();
88
+ return answer;
89
+ }
90
+ return new Promise((resolve) => {
91
+ let answer = '';
92
+ stdin.setRawMode(true);
93
+ stdin.resume();
94
+ stdin.setEncoding('utf8');
95
+ const onData = (chunk) => {
96
+ for (const char of chunk) {
97
+ if (char === '\n' || char === '\r' || char === '\u0004') {
98
+ stdin.setRawMode(false);
99
+ stdin.pause();
100
+ stdin.off('data', onData);
101
+ stdout.write('\n');
102
+ resolve(answer);
103
+ return;
104
+ }
105
+ if (char === '\u0003') {
106
+ stdin.setRawMode(false);
107
+ process.exit(130);
108
+ }
109
+ if (char === '\u007f' || char === '\b')
110
+ answer = answer.slice(0, -1);
111
+ else
112
+ answer += char;
113
+ }
114
+ };
115
+ stdin.on('data', onData);
116
+ });
117
+ }
@@ -0,0 +1,17 @@
1
+ export const operation = {
2
+ "method": "post",
3
+ "path": "/api/projects/{projectId}/settings/agentic-deploy/cancel",
4
+ "command": [
5
+ "deploy",
6
+ "cancel"
7
+ ],
8
+ "summary": "Stop the running deploy. Steers queued behind it are discarded and listed.",
9
+ "pathParams": [
10
+ "projectId"
11
+ ],
12
+ "query": [],
13
+ "body": null,
14
+ "multipart": null,
15
+ "attachments": false,
16
+ "anonymous": false
17
+ };
@@ -0,0 +1,17 @@
1
+ export const operation = {
2
+ "method": "get",
3
+ "path": "/api/projects/{projectId}/deploy-messages",
4
+ "command": [
5
+ "deploy",
6
+ "messages"
7
+ ],
8
+ "summary": "Read the deploy conversation and the current deploy status.",
9
+ "pathParams": [
10
+ "projectId"
11
+ ],
12
+ "query": [],
13
+ "body": null,
14
+ "multipart": null,
15
+ "attachments": false,
16
+ "anonymous": false
17
+ };
@@ -0,0 +1,60 @@
1
+ export const operation = {
2
+ "method": "post",
3
+ "path": "/api/projects/{projectId}/settings/agentic-deploy",
4
+ "command": [
5
+ "deploy",
6
+ "run"
7
+ ],
8
+ "summary": "Start a deploy (empty JSON body), continue the current one with userResponse, or steer a running one with steerTargetDeployJobId. Attachments ride along as multipart, where the message is called content.",
9
+ "pathParams": [
10
+ "projectId"
11
+ ],
12
+ "query": [],
13
+ "body": {
14
+ "fields": [
15
+ {
16
+ "name": "userResponse",
17
+ "flag": "user-response",
18
+ "kind": "string",
19
+ "required": false
20
+ },
21
+ {
22
+ "name": "steerTargetDeployJobId",
23
+ "flag": "steer-target-deploy-job-id",
24
+ "kind": "string",
25
+ "required": false
26
+ },
27
+ {
28
+ "name": "freshDeploy",
29
+ "flag": "fresh-deploy",
30
+ "kind": "boolean",
31
+ "required": false
32
+ }
33
+ ],
34
+ "required": false
35
+ },
36
+ "multipart": [
37
+ {
38
+ "name": "content",
39
+ "flag": "content",
40
+ "kind": "string",
41
+ "required": true,
42
+ "description": "The message for the deploy agent."
43
+ },
44
+ {
45
+ "name": "freshDeploy",
46
+ "flag": "fresh-deploy",
47
+ "kind": "boolean",
48
+ "required": false,
49
+ "description": "Sent as the string 'true'."
50
+ },
51
+ {
52
+ "name": "steerTargetDeployJobId",
53
+ "flag": "steer-target-deploy-job-id",
54
+ "kind": "string",
55
+ "required": false
56
+ }
57
+ ],
58
+ "attachments": true,
59
+ "anonymous": false
60
+ };