@brianli/kimaki 0.4.72-brianli.1

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 (328) hide show
  1. package/bin.js +2 -0
  2. package/dist/ai-tool-to-genai.js +233 -0
  3. package/dist/ai-tool-to-genai.test.js +267 -0
  4. package/dist/ai-tool.js +6 -0
  5. package/dist/bin.js +87 -0
  6. package/dist/bot-token.js +121 -0
  7. package/dist/bot-token.test.js +134 -0
  8. package/dist/channel-management.js +101 -0
  9. package/dist/cli-parsing.test.js +89 -0
  10. package/dist/cli.js +2529 -0
  11. package/dist/commands/abort.js +82 -0
  12. package/dist/commands/action-buttons.js +257 -0
  13. package/dist/commands/add-project.js +114 -0
  14. package/dist/commands/agent.js +291 -0
  15. package/dist/commands/ask-question.js +223 -0
  16. package/dist/commands/compact.js +120 -0
  17. package/dist/commands/context-usage.js +140 -0
  18. package/dist/commands/create-new-project.js +118 -0
  19. package/dist/commands/diff.js +128 -0
  20. package/dist/commands/file-upload.js +275 -0
  21. package/dist/commands/fork.js +217 -0
  22. package/dist/commands/gemini-apikey.js +70 -0
  23. package/dist/commands/login.js +490 -0
  24. package/dist/commands/mention-mode.js +51 -0
  25. package/dist/commands/merge-worktree.js +124 -0
  26. package/dist/commands/model.js +694 -0
  27. package/dist/commands/permissions.js +163 -0
  28. package/dist/commands/queue.js +217 -0
  29. package/dist/commands/remove-project.js +115 -0
  30. package/dist/commands/restart-opencode-server.js +116 -0
  31. package/dist/commands/resume.js +159 -0
  32. package/dist/commands/run-command.js +79 -0
  33. package/dist/commands/session-id.js +78 -0
  34. package/dist/commands/session.js +192 -0
  35. package/dist/commands/share.js +80 -0
  36. package/dist/commands/types.js +2 -0
  37. package/dist/commands/undo-redo.js +159 -0
  38. package/dist/commands/unset-model.js +152 -0
  39. package/dist/commands/upgrade.js +42 -0
  40. package/dist/commands/user-command.js +148 -0
  41. package/dist/commands/verbosity.js +60 -0
  42. package/dist/commands/worktree-settings.js +50 -0
  43. package/dist/commands/worktree.js +299 -0
  44. package/dist/condense-memory.js +33 -0
  45. package/dist/config.js +110 -0
  46. package/dist/database.js +1050 -0
  47. package/dist/db.js +159 -0
  48. package/dist/db.test.js +49 -0
  49. package/dist/discord-api.js +28 -0
  50. package/dist/discord-auth.js +231 -0
  51. package/dist/discord-auth.test.js +80 -0
  52. package/dist/discord-bot.js +997 -0
  53. package/dist/discord-utils.js +560 -0
  54. package/dist/discord-utils.test.js +115 -0
  55. package/dist/errors.js +167 -0
  56. package/dist/escape-backticks.test.js +429 -0
  57. package/dist/format-tables.js +122 -0
  58. package/dist/format-tables.test.js +199 -0
  59. package/dist/forum-sync/config.js +79 -0
  60. package/dist/forum-sync/discord-operations.js +154 -0
  61. package/dist/forum-sync/index.js +5 -0
  62. package/dist/forum-sync/markdown.js +117 -0
  63. package/dist/forum-sync/sync-to-discord.js +417 -0
  64. package/dist/forum-sync/sync-to-files.js +190 -0
  65. package/dist/forum-sync/types.js +53 -0
  66. package/dist/forum-sync/watchers.js +307 -0
  67. package/dist/gateway-consumer.js +232 -0
  68. package/dist/gateway-consumer.test.js +18 -0
  69. package/dist/genai-worker-wrapper.js +111 -0
  70. package/dist/genai-worker.js +311 -0
  71. package/dist/genai.js +232 -0
  72. package/dist/generated/browser.js +17 -0
  73. package/dist/generated/client.js +35 -0
  74. package/dist/generated/commonInputTypes.js +10 -0
  75. package/dist/generated/enums.js +30 -0
  76. package/dist/generated/internal/class.js +41 -0
  77. package/dist/generated/internal/prismaNamespace.js +239 -0
  78. package/dist/generated/internal/prismaNamespaceBrowser.js +209 -0
  79. package/dist/generated/models/bot_api_keys.js +1 -0
  80. package/dist/generated/models/bot_tokens.js +1 -0
  81. package/dist/generated/models/channel_agents.js +1 -0
  82. package/dist/generated/models/channel_directories.js +1 -0
  83. package/dist/generated/models/channel_mention_mode.js +1 -0
  84. package/dist/generated/models/channel_models.js +1 -0
  85. package/dist/generated/models/channel_verbosity.js +1 -0
  86. package/dist/generated/models/channel_worktrees.js +1 -0
  87. package/dist/generated/models/forum_sync_configs.js +1 -0
  88. package/dist/generated/models/global_models.js +1 -0
  89. package/dist/generated/models/ipc_requests.js +1 -0
  90. package/dist/generated/models/part_messages.js +1 -0
  91. package/dist/generated/models/scheduled_tasks.js +1 -0
  92. package/dist/generated/models/session_agents.js +1 -0
  93. package/dist/generated/models/session_models.js +1 -0
  94. package/dist/generated/models/session_start_sources.js +1 -0
  95. package/dist/generated/models/thread_sessions.js +1 -0
  96. package/dist/generated/models/thread_worktrees.js +1 -0
  97. package/dist/generated/models.js +1 -0
  98. package/dist/heap-monitor.js +95 -0
  99. package/dist/hrana-server.js +416 -0
  100. package/dist/hrana-server.test.js +368 -0
  101. package/dist/image-utils.js +112 -0
  102. package/dist/interaction-handler.js +327 -0
  103. package/dist/ipc-polling.js +251 -0
  104. package/dist/kimaki-digital-twin.e2e.test.js +165 -0
  105. package/dist/limit-heading-depth.js +25 -0
  106. package/dist/limit-heading-depth.test.js +105 -0
  107. package/dist/logger.js +160 -0
  108. package/dist/markdown.js +342 -0
  109. package/dist/markdown.test.js +253 -0
  110. package/dist/message-formatting.js +433 -0
  111. package/dist/message-formatting.test.js +73 -0
  112. package/dist/openai-realtime.js +228 -0
  113. package/dist/opencode-plugin-loading.e2e.test.js +91 -0
  114. package/dist/opencode-plugin.js +536 -0
  115. package/dist/opencode-plugin.test.js +98 -0
  116. package/dist/opencode.js +409 -0
  117. package/dist/privacy-sanitizer.js +105 -0
  118. package/dist/runtime-mode.js +51 -0
  119. package/dist/runtime-mode.test.js +115 -0
  120. package/dist/sentry.js +127 -0
  121. package/dist/session-handler/state.js +151 -0
  122. package/dist/session-handler.js +1874 -0
  123. package/dist/session-search.js +100 -0
  124. package/dist/session-search.test.js +40 -0
  125. package/dist/startup-service.js +153 -0
  126. package/dist/system-message.js +499 -0
  127. package/dist/task-runner.js +282 -0
  128. package/dist/task-schedule.js +191 -0
  129. package/dist/task-schedule.test.js +71 -0
  130. package/dist/thinking-utils.js +35 -0
  131. package/dist/thread-message-queue.e2e.test.js +781 -0
  132. package/dist/tools.js +359 -0
  133. package/dist/unnest-code-blocks.js +136 -0
  134. package/dist/unnest-code-blocks.test.js +641 -0
  135. package/dist/upgrade.js +114 -0
  136. package/dist/utils.js +109 -0
  137. package/dist/voice-handler.js +606 -0
  138. package/dist/voice.js +304 -0
  139. package/dist/voice.test.js +187 -0
  140. package/dist/wait-session.js +94 -0
  141. package/dist/worker-types.js +4 -0
  142. package/dist/worktree-utils.js +727 -0
  143. package/dist/xml.js +92 -0
  144. package/dist/xml.test.js +32 -0
  145. package/package.json +82 -0
  146. package/schema.prisma +246 -0
  147. package/skills/batch/SKILL.md +87 -0
  148. package/skills/critique/SKILL.md +129 -0
  149. package/skills/errore/SKILL.md +589 -0
  150. package/skills/goke/.prettierrc +5 -0
  151. package/skills/goke/CHANGELOG.md +40 -0
  152. package/skills/goke/LICENSE +21 -0
  153. package/skills/goke/README.md +666 -0
  154. package/skills/goke/SKILL.md +458 -0
  155. package/skills/goke/package.json +43 -0
  156. package/skills/goke/src/__test__/coerce.test.ts +411 -0
  157. package/skills/goke/src/__test__/index.test.ts +1798 -0
  158. package/skills/goke/src/__test__/types.test-d.ts +111 -0
  159. package/skills/goke/src/coerce.ts +547 -0
  160. package/skills/goke/src/goke.ts +1362 -0
  161. package/skills/goke/src/index.ts +16 -0
  162. package/skills/goke/src/mri.ts +164 -0
  163. package/skills/goke/tsconfig.json +15 -0
  164. package/skills/jitter/EDITOR.md +219 -0
  165. package/skills/jitter/EXPORT-INTERNALS.md +309 -0
  166. package/skills/jitter/SKILL.md +158 -0
  167. package/skills/jitter/jitter-clipboard.json +1042 -0
  168. package/skills/jitter/package.json +14 -0
  169. package/skills/jitter/tsconfig.json +15 -0
  170. package/skills/jitter/utils/actions.ts +212 -0
  171. package/skills/jitter/utils/export.ts +114 -0
  172. package/skills/jitter/utils/index.ts +141 -0
  173. package/skills/jitter/utils/snapshot.ts +154 -0
  174. package/skills/jitter/utils/traverse.ts +246 -0
  175. package/skills/jitter/utils/types.ts +279 -0
  176. package/skills/jitter/utils/wait.ts +133 -0
  177. package/skills/playwriter/SKILL.md +31 -0
  178. package/skills/security-review/SKILL.md +208 -0
  179. package/skills/simplify/SKILL.md +58 -0
  180. package/skills/termcast/SKILL.md +945 -0
  181. package/skills/tuistory/SKILL.md +250 -0
  182. package/skills/zustand-centralized-state/SKILL.md +582 -0
  183. package/src/__snapshots__/compact-session-context-no-system.md +35 -0
  184. package/src/__snapshots__/compact-session-context.md +41 -0
  185. package/src/__snapshots__/first-session-no-info.md +17 -0
  186. package/src/__snapshots__/first-session-with-info.md +23 -0
  187. package/src/__snapshots__/session-1.md +17 -0
  188. package/src/__snapshots__/session-2.md +5871 -0
  189. package/src/__snapshots__/session-3.md +17 -0
  190. package/src/__snapshots__/session-with-tools.md +5871 -0
  191. package/src/ai-tool-to-genai.test.ts +296 -0
  192. package/src/ai-tool-to-genai.ts +282 -0
  193. package/src/ai-tool.ts +39 -0
  194. package/src/bin.ts +108 -0
  195. package/src/bot-token.test.ts +171 -0
  196. package/src/bot-token.ts +159 -0
  197. package/src/channel-management.ts +172 -0
  198. package/src/cli-parsing.test.ts +132 -0
  199. package/src/cli.ts +3605 -0
  200. package/src/commands/abort.ts +112 -0
  201. package/src/commands/action-buttons.ts +376 -0
  202. package/src/commands/add-project.ts +152 -0
  203. package/src/commands/agent.ts +404 -0
  204. package/src/commands/ask-question.ts +330 -0
  205. package/src/commands/compact.ts +157 -0
  206. package/src/commands/context-usage.ts +199 -0
  207. package/src/commands/create-new-project.ts +179 -0
  208. package/src/commands/diff.ts +165 -0
  209. package/src/commands/file-upload.ts +389 -0
  210. package/src/commands/fork.ts +320 -0
  211. package/src/commands/gemini-apikey.ts +104 -0
  212. package/src/commands/login.ts +634 -0
  213. package/src/commands/mention-mode.ts +77 -0
  214. package/src/commands/merge-worktree.ts +177 -0
  215. package/src/commands/model.ts +961 -0
  216. package/src/commands/permissions.ts +261 -0
  217. package/src/commands/queue.ts +296 -0
  218. package/src/commands/remove-project.ts +155 -0
  219. package/src/commands/restart-opencode-server.ts +162 -0
  220. package/src/commands/resume.ts +242 -0
  221. package/src/commands/run-command.ts +123 -0
  222. package/src/commands/session-id.ts +109 -0
  223. package/src/commands/session.ts +250 -0
  224. package/src/commands/share.ts +106 -0
  225. package/src/commands/types.ts +25 -0
  226. package/src/commands/undo-redo.ts +221 -0
  227. package/src/commands/unset-model.ts +189 -0
  228. package/src/commands/upgrade.ts +52 -0
  229. package/src/commands/user-command.ts +193 -0
  230. package/src/commands/verbosity.ts +88 -0
  231. package/src/commands/worktree-settings.ts +79 -0
  232. package/src/commands/worktree.ts +431 -0
  233. package/src/condense-memory.ts +36 -0
  234. package/src/config.ts +148 -0
  235. package/src/database.ts +1530 -0
  236. package/src/db.test.ts +60 -0
  237. package/src/db.ts +190 -0
  238. package/src/discord-api.ts +35 -0
  239. package/src/discord-bot.ts +1316 -0
  240. package/src/discord-utils.test.ts +132 -0
  241. package/src/discord-utils.ts +767 -0
  242. package/src/errors.ts +213 -0
  243. package/src/escape-backticks.test.ts +469 -0
  244. package/src/format-tables.test.ts +223 -0
  245. package/src/format-tables.ts +145 -0
  246. package/src/forum-sync/config.ts +92 -0
  247. package/src/forum-sync/discord-operations.ts +241 -0
  248. package/src/forum-sync/index.ts +9 -0
  249. package/src/forum-sync/markdown.ts +176 -0
  250. package/src/forum-sync/sync-to-discord.ts +595 -0
  251. package/src/forum-sync/sync-to-files.ts +294 -0
  252. package/src/forum-sync/types.ts +175 -0
  253. package/src/forum-sync/watchers.ts +454 -0
  254. package/src/genai-worker-wrapper.ts +164 -0
  255. package/src/genai-worker.ts +386 -0
  256. package/src/genai.ts +321 -0
  257. package/src/generated/browser.ts +109 -0
  258. package/src/generated/client.ts +131 -0
  259. package/src/generated/commonInputTypes.ts +512 -0
  260. package/src/generated/enums.ts +46 -0
  261. package/src/generated/internal/class.ts +362 -0
  262. package/src/generated/internal/prismaNamespace.ts +2251 -0
  263. package/src/generated/internal/prismaNamespaceBrowser.ts +308 -0
  264. package/src/generated/models/bot_api_keys.ts +1288 -0
  265. package/src/generated/models/bot_tokens.ts +1577 -0
  266. package/src/generated/models/channel_agents.ts +1256 -0
  267. package/src/generated/models/channel_directories.ts +2104 -0
  268. package/src/generated/models/channel_mention_mode.ts +1300 -0
  269. package/src/generated/models/channel_models.ts +1288 -0
  270. package/src/generated/models/channel_verbosity.ts +1224 -0
  271. package/src/generated/models/channel_worktrees.ts +1308 -0
  272. package/src/generated/models/forum_sync_configs.ts +1452 -0
  273. package/src/generated/models/global_models.ts +1288 -0
  274. package/src/generated/models/ipc_requests.ts +1485 -0
  275. package/src/generated/models/part_messages.ts +1302 -0
  276. package/src/generated/models/scheduled_tasks.ts +2320 -0
  277. package/src/generated/models/session_agents.ts +1086 -0
  278. package/src/generated/models/session_models.ts +1114 -0
  279. package/src/generated/models/session_start_sources.ts +1408 -0
  280. package/src/generated/models/thread_sessions.ts +1599 -0
  281. package/src/generated/models/thread_worktrees.ts +1352 -0
  282. package/src/generated/models.ts +29 -0
  283. package/src/heap-monitor.ts +121 -0
  284. package/src/hrana-server.test.ts +428 -0
  285. package/src/hrana-server.ts +547 -0
  286. package/src/image-utils.ts +149 -0
  287. package/src/interaction-handler.ts +461 -0
  288. package/src/ipc-polling.ts +325 -0
  289. package/src/kimaki-digital-twin.e2e.test.ts +201 -0
  290. package/src/limit-heading-depth.test.ts +116 -0
  291. package/src/limit-heading-depth.ts +26 -0
  292. package/src/logger.ts +203 -0
  293. package/src/markdown.test.ts +360 -0
  294. package/src/markdown.ts +410 -0
  295. package/src/message-formatting.test.ts +81 -0
  296. package/src/message-formatting.ts +549 -0
  297. package/src/openai-realtime.ts +362 -0
  298. package/src/opencode-plugin-loading.e2e.test.ts +112 -0
  299. package/src/opencode-plugin.test.ts +108 -0
  300. package/src/opencode-plugin.ts +652 -0
  301. package/src/opencode.ts +554 -0
  302. package/src/privacy-sanitizer.ts +142 -0
  303. package/src/schema.sql +158 -0
  304. package/src/sentry.ts +137 -0
  305. package/src/session-handler/state.ts +232 -0
  306. package/src/session-handler.ts +2668 -0
  307. package/src/session-search.test.ts +50 -0
  308. package/src/session-search.ts +148 -0
  309. package/src/startup-service.ts +200 -0
  310. package/src/system-message.ts +568 -0
  311. package/src/task-runner.ts +425 -0
  312. package/src/task-schedule.test.ts +84 -0
  313. package/src/task-schedule.ts +287 -0
  314. package/src/thinking-utils.ts +61 -0
  315. package/src/thread-message-queue.e2e.test.ts +997 -0
  316. package/src/tools.ts +432 -0
  317. package/src/unnest-code-blocks.test.ts +679 -0
  318. package/src/unnest-code-blocks.ts +168 -0
  319. package/src/upgrade.ts +127 -0
  320. package/src/utils.ts +145 -0
  321. package/src/voice-handler.ts +852 -0
  322. package/src/voice.test.ts +219 -0
  323. package/src/voice.ts +444 -0
  324. package/src/wait-session.ts +147 -0
  325. package/src/worker-types.ts +64 -0
  326. package/src/worktree-utils.ts +988 -0
  327. package/src/xml.test.ts +38 -0
  328. package/src/xml.ts +121 -0
@@ -0,0 +1,458 @@
1
+ ---
2
+ name: goke
3
+ description: >
4
+ goke is a zero-dependency, type-safe CLI framework for TypeScript. CAC replacement
5
+ with Standard Schema support (Zod, Valibot, ArkType). Use goke when building CLI
6
+ tools — it handles commands, subcommands, options, type coercion, help generation,
7
+ and more. Schema-based options give you automatic type inference, coercion from
8
+ strings, and help text generation. ALWAYS read this skill when a repo uses goke
9
+ for its CLI.
10
+ version: 0.0.1
11
+ ---
12
+
13
+ # goke
14
+
15
+ Zero-dependency, type-safe CLI framework for TypeScript. A CAC replacement with Standard Schema support.
16
+
17
+ 4 core APIs: `cli.option`, `cli.version`, `cli.help`, `cli.parse`.
18
+
19
+ ```ts
20
+ import { goke } from 'goke'
21
+ import { z } from 'zod'
22
+
23
+ const cli = goke('mycli')
24
+
25
+ cli
26
+ .command('serve', 'Start the dev server')
27
+ .option('--port <port>', z.number().default(3000).describe('Port to listen on'))
28
+ .option('--host [host]', z.string().default('localhost').describe('Hostname to bind'))
29
+ .option('--open', 'Open browser on start')
30
+ .action((options) => {
31
+ // options.port: number, options.host: string, options.open: boolean
32
+ console.log(options)
33
+ })
34
+
35
+ cli.help()
36
+ cli.version('1.0.0')
37
+ cli.parse()
38
+ ```
39
+
40
+ ## Version
41
+
42
+ Import `package.json` with `type: 'json'` and use the `version` field:
43
+
44
+ ```ts
45
+ import pkg from './package.json' with { type: 'json' }
46
+
47
+ cli.version(pkg.version)
48
+ ```
49
+
50
+ This works in Node.js and keeps the version in sync with `package.json` automatically.
51
+
52
+ ## Rules
53
+
54
+ 1. Always use schema-based options (Zod, Valibot, etc.) for typed values — without a schema, all values are raw strings
55
+ 2. **Never add `(default: X)` in the description string** when using `.default()` — goke extracts the default from the schema and appends it to help output automatically. Adding it in the description shows the default twice
56
+ 3. Don't manually type `action` callback arguments — goke infers argument and option types automatically from the command signature and option schemas
57
+ 4. Use `<angle brackets>` for required values, `[square brackets]` for optional values — this applies to both command arguments and option values
58
+ 5. Use `z.array()` for options that can be passed multiple times (repeatable flags)
59
+ 6. Use `z.enum()` for options constrained to a fixed set of values
60
+ 7. Write very detailed descriptions for commands and options — agents and users rely on `--help` output as documentation. Include what the option does, when to use it, and examples if relevant
61
+ 8. Add `.example()` to commands to show usage patterns in help output — use a `#` comment as the first line to explain the scenario
62
+ 9. Options without brackets are boolean flags (`--verbose` → `true`/`false`)
63
+ 10. Kebab-case options are auto-camelCased in the parsed result (`--max-retries` → `options.maxRetries`)
64
+
65
+ ## Schema-based options
66
+
67
+ Pass a Standard Schema (Zod, Valibot, ArkType) as the second argument to `.option()` for automatic type coercion. Description, default, and deprecated flag are extracted from the schema.
68
+
69
+ ### Typed values
70
+
71
+ ```ts
72
+ // number — string "3000" coerced to number 3000
73
+ .option('--port <port>', z.number().describe('Port number'))
74
+
75
+ // integer — rejects decimals like "3.14"
76
+ .option('--workers <n>', z.int().describe('Number of worker threads'))
77
+
78
+ // string — preserves value as-is (no auto-conversion)
79
+ .option('--name <name>', z.string().describe('Project name'))
80
+
81
+ // boolean value option — accepts "true" or "false" strings
82
+ .option('--flag <flag>', z.boolean().describe('Enable feature'))
83
+ ```
84
+
85
+ ### Default values
86
+
87
+ Use `.default()` on the schema. The default is shown in help output automatically.
88
+
89
+ ```ts
90
+ // Port defaults to 3000 if not passed
91
+ .option('--port [port]', z.number().default(3000).describe('Port to listen on'))
92
+
93
+ // Host defaults to "localhost"
94
+ .option('--host [host]', z.string().default('localhost').describe('Hostname to bind'))
95
+ ```
96
+
97
+ **Important:** use `[optional]` brackets when the option has a default — `<required>` brackets throw an error when the value is missing, even if a default exists.
98
+
99
+ Help output for the above:
100
+
101
+ ```
102
+ --port [port] Port to listen on (default: 3000)
103
+ --host [host] Hostname to bind (default: localhost)
104
+ ```
105
+
106
+ The `(default: 3000)` is appended automatically. Never write `.default(3000).describe('Port to listen on (default: 3000)')` — this would display the default twice.
107
+
108
+ ### Enum options (constrained values)
109
+
110
+ Use `z.enum()` for options that only accept specific values:
111
+
112
+ ```ts
113
+ .option('--format <format>', z.enum(['json', 'yaml', 'csv']).describe('Output format'))
114
+ .option('--env <env>', z.enum(['dev', 'staging', 'production']).describe('Target environment'))
115
+ ```
116
+
117
+ Invalid values throw a clear error: `expected one of "json", "yaml", "csv", got "xml"`.
118
+
119
+ ### Repeatable options (arrays)
120
+
121
+ Use `z.array()` to allow passing the same flag multiple times:
122
+
123
+ ```ts
124
+ // Pass --tag multiple times: --tag foo --tag bar → ["foo", "bar"]
125
+ .option('--tag <tag>', z.array(z.string()).describe('Tags (repeatable)'))
126
+
127
+ // Typed array items: --id 1 --id 2 → [1, 2] (numbers, not strings)
128
+ .option('--id <id>', z.array(z.number()).describe('IDs (repeatable)'))
129
+ ```
130
+
131
+ The optimal way for users to pass array values is repeating the flag:
132
+
133
+ ```bash
134
+ mycli deploy --tag v2.1.0 --tag latest --tag rollback
135
+ # → tags: ["v2.1.0", "latest", "rollback"]
136
+ ```
137
+
138
+ A single value is automatically wrapped: `--tag foo` → `["foo"]`.
139
+
140
+ JSON array strings also work but are less ergonomic: `--ids '[1,2,3]'` → `[1, 2, 3]`.
141
+
142
+ **Non-array schemas reject repeated flags.** If a user passes `--port 3000 --port 4000` with a `z.number()` schema, goke throws `does not accept multiple values`.
143
+
144
+ ### Nullable options
145
+
146
+ ```ts
147
+ // Pass empty string "" to get null, or a number
148
+ .option('--timeout <timeout>', z.nullable(z.number()).describe('Timeout in ms, empty for none'))
149
+ ```
150
+
151
+ ### Union types
152
+
153
+ ```ts
154
+ // Tries number first, falls back to string
155
+ .option('--val <val>', z.union([z.number(), z.string()]).describe('A number or string value'))
156
+ ```
157
+
158
+ ### Deprecated options (hidden from help)
159
+
160
+ Use `.meta({ deprecated: true })` to hide options from `--help` while still parsing them:
161
+
162
+ ```ts
163
+ .option('--old-port <port>', z.number().meta({ deprecated: true, description: 'Use --port instead' }))
164
+ .option('--port <port>', z.number().describe('Port number'))
165
+ ```
166
+
167
+ ### No schema = raw strings
168
+
169
+ Without a schema, all values stay as strings. `--port 3000` → `"3000"` (string, not number). Use schemas for type safety.
170
+
171
+ ## Brackets
172
+
173
+ | Syntax | Meaning |
174
+ |--------|---------|
175
+ | `<name>` in command | Required argument |
176
+ | `[name]` in command | Optional argument |
177
+ | `[...files]` in command | Variadic (collects remaining args into array) |
178
+ | `<value>` in option | Required value (error if missing) |
179
+ | `[value]` in option | Optional value (`true` if flag present without value) |
180
+ | no brackets in option | Boolean flag (`--verbose` → `true`) |
181
+
182
+ ## Commands
183
+
184
+ ### Basic commands with arguments
185
+
186
+ ```ts
187
+ cli
188
+ .command('deploy <env>', 'Deploy to an environment')
189
+ .option('--dry-run', 'Preview without deploying')
190
+ .action((env, options) => {
191
+ // env: string, options.dryRun: boolean
192
+ })
193
+ ```
194
+
195
+ ### Root command (runs when no subcommand given)
196
+
197
+ Use empty string `''` as the command name:
198
+
199
+ ```ts
200
+ // `mycli` runs the root command, `mycli status` runs the subcommand
201
+ cli
202
+ .command('', 'Deploy the current project')
203
+ .option('--env <env>', z.string().default('production').describe('Target environment'))
204
+ .action((options) => {})
205
+
206
+ cli.command('status', 'Show deployment status').action(() => {})
207
+ ```
208
+
209
+ ### Space-separated subcommands
210
+
211
+ For git-like nested commands:
212
+
213
+ ```ts
214
+ cli.command('mcp login <url>', 'Login to MCP server').action((url) => {})
215
+ cli.command('mcp logout', 'Logout from MCP server').action(() => {})
216
+ cli.command('git remote add <name> <url>', 'Add a git remote').action((name, url) => {})
217
+ ```
218
+
219
+ Greedy matching: `mcp login` matches before `mcp` when both exist.
220
+
221
+ ### Variadic arguments
222
+
223
+ The last argument can be variadic with `...` prefix:
224
+
225
+ ```ts
226
+ cli
227
+ .command('build <entry> [...otherFiles]', 'Build your app')
228
+ .action((entry, otherFiles, options) => {
229
+ // entry: string, otherFiles: string[]
230
+ })
231
+ ```
232
+
233
+ ### Command aliases
234
+
235
+ ```ts
236
+ cli.command('install', 'Install packages').alias('i').action(() => {})
237
+ // Now both `mycli install` and `mycli i` work
238
+ ```
239
+
240
+ ## Writing detailed help text
241
+
242
+ Agents and users rely on `--help` as the primary documentation for a CLI. Write descriptions that are thorough and actionable.
243
+
244
+ ### Detailed command descriptions
245
+
246
+ Use `string-dedent` for multi-line descriptions:
247
+
248
+ ```ts
249
+ import dedent from 'string-dedent'
250
+
251
+ cli
252
+ .command(
253
+ 'release <version>',
254
+ dedent`
255
+ Publish a versioned release to distribution channels.
256
+
257
+ - Validates release metadata and changelog before publishing.
258
+ - Builds production artifacts with reproducible settings.
259
+ - Tags git history using semantic version format.
260
+ - Publishes to npm and creates release notes.
261
+
262
+ > Recommended: run with --dry-run first in CI to verify output.
263
+ `,
264
+ )
265
+ .option('--channel <name>', z.enum(['stable', 'beta', 'alpha']).describe('Target release channel'))
266
+ .option('--dry-run', 'Preview every step without publishing')
267
+ .action((version, options) => {})
268
+ ```
269
+
270
+ ### Detailed option descriptions
271
+
272
+ Write descriptions that tell the user exactly what the option does:
273
+
274
+ ```ts
275
+ // Bad — too terse
276
+ .option('--limit [limit]', z.number().default(10).describe('Limit'))
277
+
278
+ // Good — tells what it does, what values are valid
279
+ .option('--limit [limit]', z.number().default(10).describe('Maximum number of results to return'))
280
+ ```
281
+
282
+ ### Examples in help output
283
+
284
+ Add `.example()` to commands. Use `#` comments to explain the scenario:
285
+
286
+ ```ts
287
+ cli
288
+ .command('deploy', 'Deploy current app')
289
+ .option('--env <env>', z.enum(['staging', 'production']).describe('Target environment'))
290
+ .example('# Deploy to staging first')
291
+ .example('mycli deploy --env staging')
292
+ .example('# Then deploy to production')
293
+ .example('mycli deploy --env production')
294
+ .action(() => {})
295
+ ```
296
+
297
+ Root-level examples:
298
+
299
+ ```ts
300
+ cli.example((bin) => `${bin} deploy --env production`)
301
+ ```
302
+
303
+ ## Boolean flags
304
+
305
+ Options without brackets are boolean flags:
306
+
307
+ ```ts
308
+ .option('--verbose', 'Enable verbose output') // --verbose → true
309
+ .option('--no-cache', 'Disable caching') // --no-cache → true (negated option)
310
+ ```
311
+
312
+ ## Dot-nested options
313
+
314
+ ```ts
315
+ cli.option('--env <env>', 'Set envs')
316
+ // --env.API_SECRET xxx → options.env = { API_SECRET: 'xxx' }
317
+ ```
318
+
319
+ ## Short aliases
320
+
321
+ ```ts
322
+ .option('-p, --port <port>', z.number().describe('Port number'))
323
+ // -p 3000 and --port 3000 both work
324
+ // options.port and options.p both equal 3000
325
+ ```
326
+
327
+ ## Injectable I/O (testing)
328
+
329
+ Override stdout, stderr, argv, and exit for testing:
330
+
331
+ ```ts
332
+ import goke, { createConsole } from 'goke'
333
+
334
+ const stdout = { lines: [], write(data) { this.lines.push(data) } }
335
+ const cli = goke('mycli', {
336
+ stdout,
337
+ stderr: process.stderr,
338
+ exit: () => {}, // prevent process.exit in tests
339
+ })
340
+ ```
341
+
342
+ ## @goke/mcp — turn MCP servers into CLIs
343
+
344
+ `@goke/mcp` auto-discovers tools from an MCP server and registers them as CLI commands with typed options from JSON Schema:
345
+
346
+ ```ts
347
+ import { goke } from 'goke'
348
+ import { addMcpCommands } from '@goke/mcp'
349
+
350
+ const cli = goke('mycli')
351
+
352
+ await addMcpCommands({
353
+ cli,
354
+ getMcpUrl: () => 'https://your-mcp-server.com/mcp',
355
+ oauth: {
356
+ clientName: 'My CLI',
357
+ load: () => loadConfig().oauthState,
358
+ save: (state) => saveConfig({ oauthState: state }),
359
+ },
360
+ loadCache: () => loadConfig().cache,
361
+ saveCache: (cache) => saveConfig({ cache }),
362
+ })
363
+
364
+ cli.help()
365
+ cli.parse()
366
+ ```
367
+
368
+ Tools are cached for 1 hour. OAuth is lazy — triggered only on 401 errors.
369
+
370
+ ## Complete example
371
+
372
+ ```ts
373
+ import { goke } from 'goke'
374
+ import { z } from 'zod'
375
+ import dedent from 'string-dedent'
376
+
377
+ const cli = goke('acme')
378
+
379
+ cli
380
+ .command('', 'Run the default workflow')
381
+ .option('--env [env]', z.string().default('development').describe('Target environment'))
382
+ .action((options) => {
383
+ console.log(`Running in ${options.env}`)
384
+ })
385
+
386
+ cli
387
+ .command(
388
+ 'deploy <target>',
389
+ dedent`
390
+ Deploy the application to a target environment.
391
+
392
+ - Builds optimized production bundle.
393
+ - Uploads artifacts to the target.
394
+ - Runs post-deploy health checks.
395
+
396
+ > Always deploy to staging first before production.
397
+ `,
398
+ )
399
+ .option('--env <env>', z.enum(['staging', 'production']).describe('Deployment environment'))
400
+ .option('--tag <tag>', z.array(z.string()).describe('Docker image tags to deploy (repeatable)'))
401
+ .option('--workers <n>', z.int().default(4).describe('Number of parallel upload workers'))
402
+ .option('--timeout [ms]', z.number().default(30000).describe('Deployment timeout in milliseconds'))
403
+ .option('--dry-run', 'Preview the deployment plan without executing')
404
+ .option('--verbose', 'Enable detailed deployment logging')
405
+ .example('# Deploy to staging with custom tags')
406
+ .example('acme deploy web --env staging --tag v2.1.0 --tag latest')
407
+ .example('# Dry-run production deploy')
408
+ .example('acme deploy api --env production --dry-run --verbose')
409
+ .action((target, options) => {
410
+ console.log('deploying', target, options)
411
+ })
412
+
413
+ cli
414
+ .command('db migrate', 'Apply pending database migrations in sequence')
415
+ .option('--target <migration>', z.string().describe('Apply up to a specific migration ID'))
416
+ .option('--dry-run', 'Print SQL plan without executing')
417
+ .option('--verbose', 'Show each executed SQL statement')
418
+ .action((options) => {
419
+ console.log('migrating', options)
420
+ })
421
+
422
+ cli
423
+ .command('config set <key> <value>', 'Set a configuration value')
424
+ .action((key, value) => {
425
+ console.log('setting', key, value)
426
+ })
427
+
428
+ cli.help()
429
+ cli.version('1.0.0')
430
+ cli.parse()
431
+ ```
432
+
433
+ ## Exposing your CLI as a skill
434
+
435
+ When you build a CLI with goke, the optimal way to create a skill for it is a minimal SKILL.md that tells agents to run `--help` before using the CLI. This way descriptions, examples, and usage patterns live in the CLI code (collocated with the implementation) instead of a separate markdown file that can go stale.
436
+
437
+ Example SKILL.md for a CLI built with goke:
438
+
439
+ ````markdown
440
+ ---
441
+ name: acme
442
+ description: >
443
+ acme is a deployment CLI. Always run `acme --help` before using it
444
+ to discover available commands, options, and usage examples.
445
+ ---
446
+
447
+ # acme
448
+
449
+ Always run `acme --help` before using this CLI. The help output contains
450
+ all commands, options, defaults, and usage examples.
451
+
452
+ For subcommand details: `acme <command> --help`
453
+ ````
454
+
455
+ This is the recommended pattern because:
456
+ - Descriptions and examples are defined once in `.option()` and `.example()` calls
457
+ - Help output always matches the actual CLI behavior
458
+ - No separate documentation to maintain or keep in sync
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "goke",
3
+ "version": "6.1.3",
4
+ "type": "module",
5
+ "description": "Simple yet powerful framework for building command-line apps. Inspired by cac.",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/remorses/goke"
9
+ },
10
+ "main": "dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "src"
22
+ ],
23
+ "scripts": {
24
+ "clean": "rm -rf dist",
25
+ "build": "pnpm clean && tsc",
26
+ "test": "vitest --run",
27
+ "prepublishOnly": "pnpm build"
28
+ },
29
+ "dependencies": {
30
+ "picocolors": "^1.1.1"
31
+ },
32
+ "author": "remorses, egoist <0x142857@gmail.com>",
33
+ "license": "MIT",
34
+ "devDependencies": {
35
+ "@types/node": "^25.2.2",
36
+ "typescript": "^5.9.3",
37
+ "vitest": "^3.1.0",
38
+ "zod": "^4.3.6"
39
+ },
40
+ "engines": {
41
+ "node": ">=18"
42
+ }
43
+ }