@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.
- package/bin.js +2 -0
- package/dist/ai-tool-to-genai.js +233 -0
- package/dist/ai-tool-to-genai.test.js +267 -0
- package/dist/ai-tool.js +6 -0
- package/dist/bin.js +87 -0
- package/dist/bot-token.js +121 -0
- package/dist/bot-token.test.js +134 -0
- package/dist/channel-management.js +101 -0
- package/dist/cli-parsing.test.js +89 -0
- package/dist/cli.js +2529 -0
- package/dist/commands/abort.js +82 -0
- package/dist/commands/action-buttons.js +257 -0
- package/dist/commands/add-project.js +114 -0
- package/dist/commands/agent.js +291 -0
- package/dist/commands/ask-question.js +223 -0
- package/dist/commands/compact.js +120 -0
- package/dist/commands/context-usage.js +140 -0
- package/dist/commands/create-new-project.js +118 -0
- package/dist/commands/diff.js +128 -0
- package/dist/commands/file-upload.js +275 -0
- package/dist/commands/fork.js +217 -0
- package/dist/commands/gemini-apikey.js +70 -0
- package/dist/commands/login.js +490 -0
- package/dist/commands/mention-mode.js +51 -0
- package/dist/commands/merge-worktree.js +124 -0
- package/dist/commands/model.js +694 -0
- package/dist/commands/permissions.js +163 -0
- package/dist/commands/queue.js +217 -0
- package/dist/commands/remove-project.js +115 -0
- package/dist/commands/restart-opencode-server.js +116 -0
- package/dist/commands/resume.js +159 -0
- package/dist/commands/run-command.js +79 -0
- package/dist/commands/session-id.js +78 -0
- package/dist/commands/session.js +192 -0
- package/dist/commands/share.js +80 -0
- package/dist/commands/types.js +2 -0
- package/dist/commands/undo-redo.js +159 -0
- package/dist/commands/unset-model.js +152 -0
- package/dist/commands/upgrade.js +42 -0
- package/dist/commands/user-command.js +148 -0
- package/dist/commands/verbosity.js +60 -0
- package/dist/commands/worktree-settings.js +50 -0
- package/dist/commands/worktree.js +299 -0
- package/dist/condense-memory.js +33 -0
- package/dist/config.js +110 -0
- package/dist/database.js +1050 -0
- package/dist/db.js +159 -0
- package/dist/db.test.js +49 -0
- package/dist/discord-api.js +28 -0
- package/dist/discord-auth.js +231 -0
- package/dist/discord-auth.test.js +80 -0
- package/dist/discord-bot.js +997 -0
- package/dist/discord-utils.js +560 -0
- package/dist/discord-utils.test.js +115 -0
- package/dist/errors.js +167 -0
- package/dist/escape-backticks.test.js +429 -0
- package/dist/format-tables.js +122 -0
- package/dist/format-tables.test.js +199 -0
- package/dist/forum-sync/config.js +79 -0
- package/dist/forum-sync/discord-operations.js +154 -0
- package/dist/forum-sync/index.js +5 -0
- package/dist/forum-sync/markdown.js +117 -0
- package/dist/forum-sync/sync-to-discord.js +417 -0
- package/dist/forum-sync/sync-to-files.js +190 -0
- package/dist/forum-sync/types.js +53 -0
- package/dist/forum-sync/watchers.js +307 -0
- package/dist/gateway-consumer.js +232 -0
- package/dist/gateway-consumer.test.js +18 -0
- package/dist/genai-worker-wrapper.js +111 -0
- package/dist/genai-worker.js +311 -0
- package/dist/genai.js +232 -0
- package/dist/generated/browser.js +17 -0
- package/dist/generated/client.js +35 -0
- package/dist/generated/commonInputTypes.js +10 -0
- package/dist/generated/enums.js +30 -0
- package/dist/generated/internal/class.js +41 -0
- package/dist/generated/internal/prismaNamespace.js +239 -0
- package/dist/generated/internal/prismaNamespaceBrowser.js +209 -0
- package/dist/generated/models/bot_api_keys.js +1 -0
- package/dist/generated/models/bot_tokens.js +1 -0
- package/dist/generated/models/channel_agents.js +1 -0
- package/dist/generated/models/channel_directories.js +1 -0
- package/dist/generated/models/channel_mention_mode.js +1 -0
- package/dist/generated/models/channel_models.js +1 -0
- package/dist/generated/models/channel_verbosity.js +1 -0
- package/dist/generated/models/channel_worktrees.js +1 -0
- package/dist/generated/models/forum_sync_configs.js +1 -0
- package/dist/generated/models/global_models.js +1 -0
- package/dist/generated/models/ipc_requests.js +1 -0
- package/dist/generated/models/part_messages.js +1 -0
- package/dist/generated/models/scheduled_tasks.js +1 -0
- package/dist/generated/models/session_agents.js +1 -0
- package/dist/generated/models/session_models.js +1 -0
- package/dist/generated/models/session_start_sources.js +1 -0
- package/dist/generated/models/thread_sessions.js +1 -0
- package/dist/generated/models/thread_worktrees.js +1 -0
- package/dist/generated/models.js +1 -0
- package/dist/heap-monitor.js +95 -0
- package/dist/hrana-server.js +416 -0
- package/dist/hrana-server.test.js +368 -0
- package/dist/image-utils.js +112 -0
- package/dist/interaction-handler.js +327 -0
- package/dist/ipc-polling.js +251 -0
- package/dist/kimaki-digital-twin.e2e.test.js +165 -0
- package/dist/limit-heading-depth.js +25 -0
- package/dist/limit-heading-depth.test.js +105 -0
- package/dist/logger.js +160 -0
- package/dist/markdown.js +342 -0
- package/dist/markdown.test.js +253 -0
- package/dist/message-formatting.js +433 -0
- package/dist/message-formatting.test.js +73 -0
- package/dist/openai-realtime.js +228 -0
- package/dist/opencode-plugin-loading.e2e.test.js +91 -0
- package/dist/opencode-plugin.js +536 -0
- package/dist/opencode-plugin.test.js +98 -0
- package/dist/opencode.js +409 -0
- package/dist/privacy-sanitizer.js +105 -0
- package/dist/runtime-mode.js +51 -0
- package/dist/runtime-mode.test.js +115 -0
- package/dist/sentry.js +127 -0
- package/dist/session-handler/state.js +151 -0
- package/dist/session-handler.js +1874 -0
- package/dist/session-search.js +100 -0
- package/dist/session-search.test.js +40 -0
- package/dist/startup-service.js +153 -0
- package/dist/system-message.js +499 -0
- package/dist/task-runner.js +282 -0
- package/dist/task-schedule.js +191 -0
- package/dist/task-schedule.test.js +71 -0
- package/dist/thinking-utils.js +35 -0
- package/dist/thread-message-queue.e2e.test.js +781 -0
- package/dist/tools.js +359 -0
- package/dist/unnest-code-blocks.js +136 -0
- package/dist/unnest-code-blocks.test.js +641 -0
- package/dist/upgrade.js +114 -0
- package/dist/utils.js +109 -0
- package/dist/voice-handler.js +606 -0
- package/dist/voice.js +304 -0
- package/dist/voice.test.js +187 -0
- package/dist/wait-session.js +94 -0
- package/dist/worker-types.js +4 -0
- package/dist/worktree-utils.js +727 -0
- package/dist/xml.js +92 -0
- package/dist/xml.test.js +32 -0
- package/package.json +82 -0
- package/schema.prisma +246 -0
- package/skills/batch/SKILL.md +87 -0
- package/skills/critique/SKILL.md +129 -0
- package/skills/errore/SKILL.md +589 -0
- package/skills/goke/.prettierrc +5 -0
- package/skills/goke/CHANGELOG.md +40 -0
- package/skills/goke/LICENSE +21 -0
- package/skills/goke/README.md +666 -0
- package/skills/goke/SKILL.md +458 -0
- package/skills/goke/package.json +43 -0
- package/skills/goke/src/__test__/coerce.test.ts +411 -0
- package/skills/goke/src/__test__/index.test.ts +1798 -0
- package/skills/goke/src/__test__/types.test-d.ts +111 -0
- package/skills/goke/src/coerce.ts +547 -0
- package/skills/goke/src/goke.ts +1362 -0
- package/skills/goke/src/index.ts +16 -0
- package/skills/goke/src/mri.ts +164 -0
- package/skills/goke/tsconfig.json +15 -0
- package/skills/jitter/EDITOR.md +219 -0
- package/skills/jitter/EXPORT-INTERNALS.md +309 -0
- package/skills/jitter/SKILL.md +158 -0
- package/skills/jitter/jitter-clipboard.json +1042 -0
- package/skills/jitter/package.json +14 -0
- package/skills/jitter/tsconfig.json +15 -0
- package/skills/jitter/utils/actions.ts +212 -0
- package/skills/jitter/utils/export.ts +114 -0
- package/skills/jitter/utils/index.ts +141 -0
- package/skills/jitter/utils/snapshot.ts +154 -0
- package/skills/jitter/utils/traverse.ts +246 -0
- package/skills/jitter/utils/types.ts +279 -0
- package/skills/jitter/utils/wait.ts +133 -0
- package/skills/playwriter/SKILL.md +31 -0
- package/skills/security-review/SKILL.md +208 -0
- package/skills/simplify/SKILL.md +58 -0
- package/skills/termcast/SKILL.md +945 -0
- package/skills/tuistory/SKILL.md +250 -0
- package/skills/zustand-centralized-state/SKILL.md +582 -0
- package/src/__snapshots__/compact-session-context-no-system.md +35 -0
- package/src/__snapshots__/compact-session-context.md +41 -0
- package/src/__snapshots__/first-session-no-info.md +17 -0
- package/src/__snapshots__/first-session-with-info.md +23 -0
- package/src/__snapshots__/session-1.md +17 -0
- package/src/__snapshots__/session-2.md +5871 -0
- package/src/__snapshots__/session-3.md +17 -0
- package/src/__snapshots__/session-with-tools.md +5871 -0
- package/src/ai-tool-to-genai.test.ts +296 -0
- package/src/ai-tool-to-genai.ts +282 -0
- package/src/ai-tool.ts +39 -0
- package/src/bin.ts +108 -0
- package/src/bot-token.test.ts +171 -0
- package/src/bot-token.ts +159 -0
- package/src/channel-management.ts +172 -0
- package/src/cli-parsing.test.ts +132 -0
- package/src/cli.ts +3605 -0
- package/src/commands/abort.ts +112 -0
- package/src/commands/action-buttons.ts +376 -0
- package/src/commands/add-project.ts +152 -0
- package/src/commands/agent.ts +404 -0
- package/src/commands/ask-question.ts +330 -0
- package/src/commands/compact.ts +157 -0
- package/src/commands/context-usage.ts +199 -0
- package/src/commands/create-new-project.ts +179 -0
- package/src/commands/diff.ts +165 -0
- package/src/commands/file-upload.ts +389 -0
- package/src/commands/fork.ts +320 -0
- package/src/commands/gemini-apikey.ts +104 -0
- package/src/commands/login.ts +634 -0
- package/src/commands/mention-mode.ts +77 -0
- package/src/commands/merge-worktree.ts +177 -0
- package/src/commands/model.ts +961 -0
- package/src/commands/permissions.ts +261 -0
- package/src/commands/queue.ts +296 -0
- package/src/commands/remove-project.ts +155 -0
- package/src/commands/restart-opencode-server.ts +162 -0
- package/src/commands/resume.ts +242 -0
- package/src/commands/run-command.ts +123 -0
- package/src/commands/session-id.ts +109 -0
- package/src/commands/session.ts +250 -0
- package/src/commands/share.ts +106 -0
- package/src/commands/types.ts +25 -0
- package/src/commands/undo-redo.ts +221 -0
- package/src/commands/unset-model.ts +189 -0
- package/src/commands/upgrade.ts +52 -0
- package/src/commands/user-command.ts +193 -0
- package/src/commands/verbosity.ts +88 -0
- package/src/commands/worktree-settings.ts +79 -0
- package/src/commands/worktree.ts +431 -0
- package/src/condense-memory.ts +36 -0
- package/src/config.ts +148 -0
- package/src/database.ts +1530 -0
- package/src/db.test.ts +60 -0
- package/src/db.ts +190 -0
- package/src/discord-api.ts +35 -0
- package/src/discord-bot.ts +1316 -0
- package/src/discord-utils.test.ts +132 -0
- package/src/discord-utils.ts +767 -0
- package/src/errors.ts +213 -0
- package/src/escape-backticks.test.ts +469 -0
- package/src/format-tables.test.ts +223 -0
- package/src/format-tables.ts +145 -0
- package/src/forum-sync/config.ts +92 -0
- package/src/forum-sync/discord-operations.ts +241 -0
- package/src/forum-sync/index.ts +9 -0
- package/src/forum-sync/markdown.ts +176 -0
- package/src/forum-sync/sync-to-discord.ts +595 -0
- package/src/forum-sync/sync-to-files.ts +294 -0
- package/src/forum-sync/types.ts +175 -0
- package/src/forum-sync/watchers.ts +454 -0
- package/src/genai-worker-wrapper.ts +164 -0
- package/src/genai-worker.ts +386 -0
- package/src/genai.ts +321 -0
- package/src/generated/browser.ts +109 -0
- package/src/generated/client.ts +131 -0
- package/src/generated/commonInputTypes.ts +512 -0
- package/src/generated/enums.ts +46 -0
- package/src/generated/internal/class.ts +362 -0
- package/src/generated/internal/prismaNamespace.ts +2251 -0
- package/src/generated/internal/prismaNamespaceBrowser.ts +308 -0
- package/src/generated/models/bot_api_keys.ts +1288 -0
- package/src/generated/models/bot_tokens.ts +1577 -0
- package/src/generated/models/channel_agents.ts +1256 -0
- package/src/generated/models/channel_directories.ts +2104 -0
- package/src/generated/models/channel_mention_mode.ts +1300 -0
- package/src/generated/models/channel_models.ts +1288 -0
- package/src/generated/models/channel_verbosity.ts +1224 -0
- package/src/generated/models/channel_worktrees.ts +1308 -0
- package/src/generated/models/forum_sync_configs.ts +1452 -0
- package/src/generated/models/global_models.ts +1288 -0
- package/src/generated/models/ipc_requests.ts +1485 -0
- package/src/generated/models/part_messages.ts +1302 -0
- package/src/generated/models/scheduled_tasks.ts +2320 -0
- package/src/generated/models/session_agents.ts +1086 -0
- package/src/generated/models/session_models.ts +1114 -0
- package/src/generated/models/session_start_sources.ts +1408 -0
- package/src/generated/models/thread_sessions.ts +1599 -0
- package/src/generated/models/thread_worktrees.ts +1352 -0
- package/src/generated/models.ts +29 -0
- package/src/heap-monitor.ts +121 -0
- package/src/hrana-server.test.ts +428 -0
- package/src/hrana-server.ts +547 -0
- package/src/image-utils.ts +149 -0
- package/src/interaction-handler.ts +461 -0
- package/src/ipc-polling.ts +325 -0
- package/src/kimaki-digital-twin.e2e.test.ts +201 -0
- package/src/limit-heading-depth.test.ts +116 -0
- package/src/limit-heading-depth.ts +26 -0
- package/src/logger.ts +203 -0
- package/src/markdown.test.ts +360 -0
- package/src/markdown.ts +410 -0
- package/src/message-formatting.test.ts +81 -0
- package/src/message-formatting.ts +549 -0
- package/src/openai-realtime.ts +362 -0
- package/src/opencode-plugin-loading.e2e.test.ts +112 -0
- package/src/opencode-plugin.test.ts +108 -0
- package/src/opencode-plugin.ts +652 -0
- package/src/opencode.ts +554 -0
- package/src/privacy-sanitizer.ts +142 -0
- package/src/schema.sql +158 -0
- package/src/sentry.ts +137 -0
- package/src/session-handler/state.ts +232 -0
- package/src/session-handler.ts +2668 -0
- package/src/session-search.test.ts +50 -0
- package/src/session-search.ts +148 -0
- package/src/startup-service.ts +200 -0
- package/src/system-message.ts +568 -0
- package/src/task-runner.ts +425 -0
- package/src/task-schedule.test.ts +84 -0
- package/src/task-schedule.ts +287 -0
- package/src/thinking-utils.ts +61 -0
- package/src/thread-message-queue.e2e.test.ts +997 -0
- package/src/tools.ts +432 -0
- package/src/unnest-code-blocks.test.ts +679 -0
- package/src/unnest-code-blocks.ts +168 -0
- package/src/upgrade.ts +127 -0
- package/src/utils.ts +145 -0
- package/src/voice-handler.ts +852 -0
- package/src/voice.test.ts +219 -0
- package/src/voice.ts +444 -0
- package/src/wait-session.ts +147 -0
- package/src/worker-types.ts +64 -0
- package/src/worktree-utils.ts +988 -0
- package/src/xml.test.ts +38 -0
- 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
|
+
}
|