kimaki 0.26.0 → 0.28.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.
- package/dist/agent-model.e2e.test.js +250 -164
- package/dist/anthropic-account-identity.js +9 -1
- package/dist/anthropic-auth-plugin.js +10 -13
- package/dist/anthropic-auth-plugin.test.js +17 -0
- package/dist/anthropic-auth-state.js +1 -0
- package/dist/bash-tool-schema-plugin.js +32 -0
- package/dist/bash-tool-schema-plugin.test.js +49 -0
- package/dist/bin.js +73 -19
- package/dist/cli-commands/maintenance.js +46 -7
- package/dist/cli-commands/project.js +11 -27
- package/dist/cli-commands/send.js +30 -1
- package/dist/cli-commands/session.js +322 -90
- package/dist/cli-commands/task.js +34 -15
- package/dist/cli-parsing.test.js +83 -4
- package/dist/cli-runner.js +44 -8
- package/dist/cli-runner.test.js +27 -0
- package/dist/cli-send-thread.e2e.test.js +9 -9
- package/dist/cli.js +32 -0
- package/dist/commands/abort.js +5 -1
- package/dist/commands/action-buttons.js +2 -1
- package/dist/commands/add-project.js +4 -7
- package/dist/commands/agent.js +164 -32
- package/dist/commands/ask-question.js +23 -33
- package/dist/commands/ask-question.test.js +43 -1
- package/dist/commands/btw.js +28 -6
- package/dist/commands/file-upload.js +2 -1
- package/dist/commands/fork-subagent.js +2 -4
- package/dist/commands/fork.js +4 -4
- package/dist/commands/last-sessions.js +17 -10
- package/dist/commands/login.js +6 -0
- package/dist/commands/merge-worktree.js +47 -14
- package/dist/commands/model-variant.js +8 -1
- package/dist/commands/model.js +16 -9
- package/dist/commands/multioauth.js +1 -0
- package/dist/commands/new-worktree.js +170 -102
- package/dist/commands/queue.js +3 -2
- package/dist/commands/resume.js +4 -4
- package/dist/commands/session.js +78 -63
- package/dist/commands/user-command.js +6 -8
- package/dist/commands/worktrees.js +5 -13
- package/dist/config.js +16 -1
- package/dist/cpu-profiler.js +211 -0
- package/dist/cpu-profiler.test.js +160 -0
- package/dist/database.js +152 -3
- package/dist/db.js +33 -0
- package/dist/db.test.js +267 -1
- package/dist/default-channel-provisioning.test.js +148 -0
- package/dist/discord-bot.js +517 -488
- package/dist/discord-command-registration.js +25 -10
- package/dist/discord-command-registration.test.js +17 -0
- package/dist/discord-utils.js +97 -5
- package/dist/discord-utils.test.js +151 -1
- package/dist/errors.js +10 -0
- package/dist/exec-async.js +17 -5
- package/dist/external-directory-permissions.e2e.test.js +11 -7
- package/dist/external-directory-project-deny.e2e.test.js +5 -3
- package/dist/external-opencode-sync.js +94 -17
- package/dist/external-opencode-sync.test.js +206 -0
- package/dist/extract-sdk-error-message.test.js +13 -0
- package/dist/file-edit-log.js +197 -0
- package/dist/file-edit-log.test.js +258 -0
- package/dist/format-tables.js +52 -0
- package/dist/format-tables.test.js +93 -0
- package/dist/gateway-proxy-reconnect.e2e.test.js +28 -8
- package/dist/gateway-proxy.e2e.test.js +18 -18
- package/dist/git-worktree-core.js +182 -17
- package/dist/interaction-handler.js +416 -398
- package/dist/ipc-tools-plugin.js +68 -3
- package/dist/kimaki-opencode-plugin-loading.e2e.test.js +122 -58
- package/dist/kimaki-opencode-plugin.js +9 -3
- package/dist/kimaki-workspace-adaptor.js +33 -10
- package/dist/logger.js +11 -1
- package/dist/markdown.js +3 -1
- package/dist/markdown.test.js +11 -3
- package/dist/message-formatting.js +181 -51
- package/dist/message-formatting.test.js +529 -22
- package/dist/message-preprocessing.js +105 -1
- package/dist/oauth-rotation-shared.js +10 -0
- package/dist/openai-auth-plugin.js +1 -0
- package/dist/openai-auth-state.js +1 -0
- package/dist/opencode-command.js +28 -0
- package/dist/opencode-command.test.js +109 -1
- package/dist/opencode-interrupt-plugin.js +4 -0
- package/dist/opencode-interrupt-plugin.test.js +24 -0
- package/dist/opencode.js +82 -15
- package/dist/project-add.test.js +62 -0
- package/dist/question-abort-clears-dropdown.e2e.test.js +89 -0
- package/dist/question-abort-retry-text-before-dropdown.e2e.test.js +150 -0
- package/dist/question-text-before-dropdown.e2e.test.js +52 -0
- package/dist/queue-advanced-abort.e2e.test.js +8 -10
- package/dist/queue-advanced-action-buttons.e2e.test.js +8 -8
- package/dist/queue-advanced-e2e-setup.js +78 -5
- package/dist/queue-advanced-footer.e2e.test.js +60 -269
- package/dist/queue-advanced-model-switch.e2e.test.js +9 -11
- package/dist/queue-advanced-permissions-typing.e2e.test.js +15 -15
- package/dist/queue-advanced-question.e2e.test.js +32 -27
- package/dist/queue-advanced-typing-interrupt.e2e.test.js +10 -12
- package/dist/queue-advanced-typing.e2e.test.js +7 -9
- package/dist/queue-delete-message.e2e.test.js +3 -3
- package/dist/queue-drain-after-interactive-ui.e2e.test.js +5 -5
- package/dist/queue-interrupt-drain.e2e.test.js +122 -12
- package/dist/queue-question-select-drain.e2e.test.js +34 -132
- package/dist/runtime-lifecycle.e2e.test.js +21 -51
- package/dist/schema.js +35 -1
- package/dist/session-handler/event-stream-state.js +391 -50
- package/dist/session-handler/event-stream-state.test.js +736 -8
- package/dist/session-handler/model-utils.js +172 -5
- package/dist/session-handler/model-utils.test.js +445 -0
- package/dist/session-handler/opencode-session-event-log.js +30 -1
- package/dist/session-handler/thread-ingress.test.js +41 -0
- package/dist/session-handler/thread-runtime-state.js +2 -0
- package/dist/session-handler/thread-session-runtime-summary.test.js +121 -0
- package/dist/session-handler/thread-session-runtime.js +574 -299
- package/dist/session-search.js +123 -4
- package/dist/session-search.test.js +248 -1
- package/dist/session-sleep.test.js +224 -0
- package/dist/session-title-rename.test.js +37 -39
- package/dist/sleep.e2e.test.js +494 -0
- package/dist/startup-time.e2e.test.js +2 -1
- package/dist/store.js +3 -0
- package/dist/system-message.js +102 -16
- package/dist/system-message.test.js +192 -15
- package/dist/task-runner.js +96 -5
- package/dist/task-schedule.js +87 -1
- package/dist/task-schedule.test.js +149 -1
- package/dist/test-utils.js +17 -9
- package/dist/thinking-utils.js +10 -0
- package/dist/thinking-utils.test.js +35 -0
- package/dist/thread-message-queue.e2e.test.js +65 -213
- package/dist/undo-redo.e2e.test.js +17 -9
- package/dist/voice-attachment.js +23 -1
- package/dist/voice-handler.js +21 -4
- package/dist/voice-message.e2e.test.js +144 -30
- package/dist/voice-routing-input.e2e.test.js +195 -0
- package/dist/voice-routing-question.e2e.test.js +125 -0
- package/dist/voice.js +28 -8
- package/dist/voice.test.js +96 -30
- package/dist/worktree-clone-isolation.e2e.test.js +188 -0
- package/dist/worktree-lifecycle.e2e.test.js +55 -36
- package/dist/worktrees.js +226 -443
- package/dist/worktrees.test.js +435 -58
- package/dist/xai-auth-plugin.js +1 -0
- package/dist/xai-auth-state.js +1 -0
- package/package.json +8 -6
- package/skills/bump-holocron-consumers/SKILL.md +137 -0
- package/skills/critique/SKILL.md +4 -4
- package/skills/errore/SKILL.md +60 -218
- package/skills/goke/SKILL.md +150 -10
- package/skills/holocron/SKILL.md +154 -17
- package/skills/npm-package/SKILL.md +55 -35
- package/skills/profano/SKILL.md +17 -2
- package/skills/spiceflow/SKILL.md +39 -3
- package/skills/strada/SKILL.md +39 -0
- package/skills/zele/SKILL.md +19 -0
- package/src/agent-model.e2e.test.ts +287 -186
- package/src/anthropic-account-identity.ts +20 -1
- package/src/anthropic-auth-plugin.test.ts +19 -0
- package/src/anthropic-auth-plugin.ts +12 -16
- package/src/anthropic-auth-state.ts +1 -0
- package/src/bash-tool-schema-plugin.test.ts +55 -0
- package/src/bash-tool-schema-plugin.ts +46 -0
- package/src/bin.ts +78 -26
- package/src/cli-commands/maintenance.ts +59 -13
- package/src/cli-commands/project.ts +14 -35
- package/src/cli-commands/send.ts +31 -1
- package/src/cli-commands/session.ts +374 -114
- package/src/cli-commands/task.ts +34 -15
- package/src/cli-parsing.test.ts +103 -4
- package/src/cli-runner.test.ts +49 -0
- package/src/cli-runner.ts +44 -7
- package/src/cli-send-thread.e2e.test.ts +9 -11
- package/src/cli.ts +53 -0
- package/src/commands/abort.ts +6 -1
- package/src/commands/action-buttons.ts +2 -1
- package/src/commands/add-project.ts +4 -8
- package/src/commands/agent.ts +205 -29
- package/src/commands/ask-question.test.ts +48 -1
- package/src/commands/ask-question.ts +23 -33
- package/src/commands/btw.ts +40 -5
- package/src/commands/file-upload.ts +2 -1
- package/src/commands/fork-subagent.ts +2 -3
- package/src/commands/fork.ts +4 -3
- package/src/commands/last-sessions.ts +10 -4
- package/src/commands/login.ts +6 -0
- package/src/commands/merge-worktree.ts +54 -16
- package/src/commands/model-variant.ts +9 -1
- package/src/commands/model.ts +20 -9
- package/src/commands/multioauth.ts +1 -0
- package/src/commands/new-worktree.ts +138 -55
- package/src/commands/queue.ts +3 -2
- package/src/commands/resume.ts +4 -3
- package/src/commands/session.ts +94 -70
- package/src/commands/user-command.ts +6 -6
- package/src/commands/worktrees.ts +5 -12
- package/src/config.ts +18 -1
- package/src/cpu-profiler.test.ts +183 -0
- package/src/cpu-profiler.ts +293 -0
- package/src/database.ts +235 -3
- package/src/db.test.ts +293 -0
- package/src/db.ts +38 -0
- package/src/default-channel-provisioning.test.ts +155 -0
- package/src/discord-bot.ts +78 -36
- package/src/discord-command-registration.test.ts +20 -0
- package/src/discord-command-registration.ts +42 -12
- package/src/discord-utils.test.ts +176 -0
- package/src/discord-utils.ts +152 -7
- package/src/errors.ts +12 -0
- package/src/exec-async.ts +20 -11
- package/src/external-directory-permissions.e2e.test.ts +11 -7
- package/src/external-directory-project-deny.e2e.test.ts +5 -3
- package/src/external-opencode-sync.test.ts +248 -0
- package/src/external-opencode-sync.ts +122 -19
- package/src/extract-sdk-error-message.test.ts +18 -0
- package/src/file-edit-log.test.ts +287 -0
- package/src/file-edit-log.ts +283 -0
- package/src/format-tables.test.ts +101 -0
- package/src/format-tables.ts +75 -0
- package/src/gateway-proxy-reconnect.e2e.test.ts +38 -8
- package/src/gateway-proxy.e2e.test.ts +18 -17
- package/src/git-worktree-core.ts +247 -20
- package/src/interaction-handler.ts +36 -13
- package/src/ipc-tools-plugin.ts +82 -5
- package/src/kimaki-opencode-plugin-loading.e2e.test.ts +188 -97
- package/src/kimaki-opencode-plugin.ts +9 -3
- package/src/kimaki-workspace-adaptor.ts +40 -11
- package/src/logger.ts +14 -4
- package/src/markdown.test.ts +13 -3
- package/src/markdown.ts +4 -1
- package/src/message-formatting.test.ts +672 -25
- package/src/message-formatting.ts +242 -53
- package/src/message-preprocessing.ts +116 -1
- package/src/oauth-rotation-shared.ts +10 -0
- package/src/openai-auth-plugin.ts +1 -0
- package/src/openai-auth-state.ts +1 -0
- package/src/opencode-command.test.ts +140 -0
- package/src/opencode-command.ts +38 -0
- package/src/opencode-interrupt-plugin.test.ts +32 -0
- package/src/opencode-interrupt-plugin.ts +3 -0
- package/src/opencode.ts +115 -15
- package/src/project-add.test.ts +80 -0
- package/src/question-abort-clears-dropdown.e2e.test.ts +109 -0
- package/src/question-abort-retry-text-before-dropdown.e2e.test.ts +172 -0
- package/src/question-text-before-dropdown.e2e.test.ts +67 -0
- package/src/queue-advanced-abort.e2e.test.ts +8 -9
- package/src/queue-advanced-action-buttons.e2e.test.ts +8 -8
- package/src/queue-advanced-e2e-setup.ts +83 -4
- package/src/queue-advanced-footer.e2e.test.ts +67 -315
- package/src/queue-advanced-model-switch.e2e.test.ts +9 -10
- package/src/queue-advanced-permissions-typing.e2e.test.ts +15 -15
- package/src/queue-advanced-question.e2e.test.ts +36 -30
- package/src/queue-advanced-typing-interrupt.e2e.test.ts +11 -11
- package/src/queue-advanced-typing.e2e.test.ts +8 -8
- package/src/queue-delete-message.e2e.test.ts +3 -3
- package/src/queue-drain-after-interactive-ui.e2e.test.ts +5 -5
- package/src/queue-interrupt-drain.e2e.test.ts +133 -12
- package/src/queue-question-select-drain.e2e.test.ts +36 -161
- package/src/runtime-lifecycle.e2e.test.ts +21 -54
- package/src/schema.sql +15 -2
- package/src/schema.ts +37 -1
- package/src/session-handler/event-stream-state.test.ts +790 -7
- package/src/session-handler/event-stream-state.ts +568 -53
- package/src/session-handler/model-utils.test.ts +537 -0
- package/src/session-handler/model-utils.ts +281 -5
- package/src/session-handler/opencode-session-event-log.ts +31 -1
- package/src/session-handler/thread-ingress.test.ts +54 -0
- package/src/session-handler/thread-runtime-state.ts +3 -0
- package/src/session-handler/thread-session-runtime-summary.test.ts +169 -0
- package/src/session-handler/thread-session-runtime.ts +712 -358
- package/src/session-search.test.ts +281 -0
- package/src/session-search.ts +241 -7
- package/src/session-sleep.test.ts +294 -0
- package/src/session-title-rename.test.ts +54 -48
- package/src/sleep.e2e.test.ts +565 -0
- package/src/startup-time.e2e.test.ts +5 -1
- package/src/store.ts +22 -0
- package/src/system-message.test.ts +226 -15
- package/src/system-message.ts +130 -16
- package/src/task-runner.ts +138 -3
- package/src/task-schedule.test.ts +170 -0
- package/src/task-schedule.ts +141 -1
- package/src/test-utils.ts +21 -10
- package/src/thinking-utils.test.ts +46 -0
- package/src/thinking-utils.ts +21 -0
- package/src/thread-message-queue.e2e.test.ts +65 -245
- package/src/undo-redo.e2e.test.ts +17 -9
- package/src/voice-attachment.ts +29 -1
- package/src/voice-handler.ts +23 -4
- package/src/voice-message.e2e.test.ts +149 -29
- package/src/voice-routing-input.e2e.test.ts +203 -0
- package/src/voice-routing-question.e2e.test.ts +131 -0
- package/src/voice.test.ts +107 -29
- package/src/voice.ts +34 -6
- package/src/worktree-clone-isolation.e2e.test.ts +213 -0
- package/src/worktree-lifecycle.e2e.test.ts +55 -35
- package/src/worktrees.test.ts +505 -64
- package/src/worktrees.ts +257 -603
- package/src/xai-auth-plugin.ts +1 -0
- package/src/xai-auth-state.ts +1 -0
- package/dist/message-finish-field.e2e.test.js +0 -169
- package/dist/subagent-rate-limit-plugin.js +0 -184
- package/src/message-finish-field.e2e.test.ts +0 -196
- package/src/subagent-rate-limit-plugin.ts +0 -228
package/skills/goke/SKILL.md
CHANGED
|
@@ -5,8 +5,9 @@ description: >
|
|
|
5
5
|
with Standard Schema support (Zod, Valibot, ArkType). Use goke when building CLI
|
|
6
6
|
tools — it handles commands, subcommands, options, type coercion, help generation,
|
|
7
7
|
and more. Schema-based options give you automatic type inference, coercion from
|
|
8
|
-
strings, and help text generation.
|
|
9
|
-
|
|
8
|
+
strings, and help text generation. Pair with `@goke/mcp` to generate CLI
|
|
9
|
+
commands automatically from an MCP server. ALWAYS read this skill when a repo
|
|
10
|
+
uses goke for its CLI.
|
|
10
11
|
version: 0.0.1
|
|
11
12
|
---
|
|
12
13
|
|
|
@@ -30,14 +31,51 @@ npm install goke # or bun, pnpm, etc
|
|
|
30
31
|
|
|
31
32
|
## Quick Notes
|
|
32
33
|
|
|
33
|
-
- Core APIs: `cli.option`, `cli.use`, `cli.version`, `cli.help`, `cli.completions`, `cli.parse`
|
|
34
|
+
- Core APIs: `cli.option`, `cli.use`, `cli.section`, `cli.version`, `cli.help`, `cli.completions`, `cli.parse`
|
|
34
35
|
- Prefer injected `{ fs, console, process }` over globals
|
|
35
36
|
- Use relative paths with injected `fs`; if a helper needs current-cwd semantics, pass injected `process.cwd` into that helper
|
|
36
37
|
- For JustBash compatibility tests, import the existing CLI from app code instead of defining a new CLI inside the test
|
|
37
38
|
- **Never install `picocolors`, `chalk`, `kleur`, or any color library.** Use `import { colors } from 'goke'` instead. It's a vendored picocolors with zero extra dependencies.
|
|
39
|
+
- Use [`@goke/mcp`](https://github.com/remorses/goke/tree/main/mcp) to generate CLI commands from an MCP server. `addMcpCommands({ cli, getMcpUrl, loadCache, saveCache })` discovers tools and registers a typed command for each one.
|
|
38
40
|
|
|
39
41
|
The README is the source of truth for rules, examples, testing patterns, JustBash integration, and API details.
|
|
40
42
|
|
|
43
|
+
## Reporting goke bugs
|
|
44
|
+
|
|
45
|
+
If you find a bug in goke, **always open a GitHub issue with the `gh` CLI**. Do not only mention it in chat.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
gh issue create --repo remorses/goke --title "Short bug title" --body "$(cat <<'EOF'
|
|
49
|
+
**Model:** grok-4.6
|
|
50
|
+
**Harness:** OpenCode / Kimaki
|
|
51
|
+
|
|
52
|
+
**What happened**
|
|
53
|
+
Describe the unexpected behavior.
|
|
54
|
+
|
|
55
|
+
**Relevant goke code**
|
|
56
|
+
Paste the CLI definition or goke API usage from this package that triggered the bug.
|
|
57
|
+
|
|
58
|
+
**Reproduction**
|
|
59
|
+
Minimal example that fails:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { goke } from 'goke'
|
|
63
|
+
|
|
64
|
+
const cli = goke('mycli')
|
|
65
|
+
cli.command('deploy', 'Deploy').action(() => {})
|
|
66
|
+
cli.parse()
|
|
67
|
+
```
|
|
68
|
+
EOF
|
|
69
|
+
)"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Always include in the issue body:
|
|
73
|
+
|
|
74
|
+
- the **model** used (for example `grok-4.6`, `claude-opus-4-6`)
|
|
75
|
+
- the **harness** (for example OpenCode, Claude Code, Cursor, Codex)
|
|
76
|
+
- the **relevant goke code** from this package that hit the bug
|
|
77
|
+
- a **minimal reproduction** example
|
|
78
|
+
|
|
41
79
|
If the README or this skill mentions a `goke` export that is missing from the installed package, upgrade `goke` to latest first before adding workarounds or custom local detection code:
|
|
42
80
|
|
|
43
81
|
```bash
|
|
@@ -72,15 +110,30 @@ if (isAgent) {
|
|
|
72
110
|
}
|
|
73
111
|
```
|
|
74
112
|
|
|
75
|
-
|
|
113
|
+
`isAgent` is for **skipping interactive prompts that have a CLI flag alternative** (e.g. `--env staging` instead of a clack select). Use it to require the flag and fail with a usage hint instead of hanging on stdin:
|
|
76
114
|
|
|
77
115
|
```ts
|
|
78
|
-
if (
|
|
79
|
-
|
|
116
|
+
if (!env) {
|
|
117
|
+
if (isAgent || !process.stdin.isTTY) {
|
|
118
|
+
console.error('Missing --env. Usage: deploy --env staging|production')
|
|
119
|
+
process.exit(1)
|
|
120
|
+
}
|
|
121
|
+
// ... clack prompt fallback
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Never use `isAgent` to block commands that have no flag alternative**, like device-flow login. Those commands don't read stdin at all; they open a browser, print a code, and poll. The only real requirement is a TTY for spinner output. Use `!process.stdin.isTTY` or `!process.stdout.isTTY` alone for those:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
// login command — no flag alternative, agent can run it in tuistory
|
|
129
|
+
if (!process.stdin.isTTY) {
|
|
130
|
+
console.error('Login requires a terminal. Run in tuistory or tmux.')
|
|
80
131
|
process.exit(1)
|
|
81
132
|
}
|
|
82
133
|
```
|
|
83
134
|
|
|
135
|
+
Agents can run login commands in a PTY via tuistory and complete the browser flow with playwriter. Blocking them with `isAgent` makes login impossible from agent contexts.
|
|
136
|
+
|
|
84
137
|
Supported agents: `cursor`, `claude`, `devin`, `replit`, `gemini`, `codex`, `auggie`, `opencode`, `kiro`, `goose`, `pi`. Set `AI_AGENT` env var to override.
|
|
85
138
|
|
|
86
139
|
## Long-Running Interactive Commands
|
|
@@ -96,16 +149,22 @@ cli
|
|
|
96
149
|
.command('login', 'Authenticate with browser login')
|
|
97
150
|
.action(async (options, ctx) => {
|
|
98
151
|
if (ctx.daemon.isDaemon) {
|
|
99
|
-
// ── DAEMON:
|
|
100
|
-
const
|
|
152
|
+
// ── DAEMON: create the URL, hand it to the foreground, then wait ──
|
|
153
|
+
const flow = await startOAuthFlow({ /* ... */ })
|
|
154
|
+
ctx.daemon.publishStartupMessage(`Authorize: ${flow.authorizationUrl}`)
|
|
155
|
+
ctx.daemon.ready()
|
|
156
|
+
const result = await flow.waitForApproval()
|
|
101
157
|
if (result.success) saveAuth(result)
|
|
102
158
|
return // daemon exits, PID file is cleaned up
|
|
103
159
|
}
|
|
104
160
|
|
|
105
161
|
// ── CLIENT: decide foreground vs background ──
|
|
106
162
|
if (isAgent) {
|
|
107
|
-
// Agent mode:
|
|
108
|
-
await ctx.daemon.start({
|
|
163
|
+
// Agent mode: return after the daemon publishes its authorization URL
|
|
164
|
+
await ctx.daemon.start({
|
|
165
|
+
waitForStartup: true,
|
|
166
|
+
timeoutMs: 10 * 60 * 1000,
|
|
167
|
+
})
|
|
109
168
|
ctx.console.log('Login running in background.')
|
|
110
169
|
ctx.console.log('After approving in browser, verify with: mycli me')
|
|
111
170
|
return
|
|
@@ -117,6 +176,8 @@ cli
|
|
|
117
176
|
})
|
|
118
177
|
```
|
|
119
178
|
|
|
179
|
+
Use `waitForStartup: true` when the daemon creates an OAuth URL, device code, or other value that the agent must see before the foreground command returns. Publish ordered messages with `publishStartupMessage(message, { stream: 'stdout' | 'stderr' })`, then call `ready()`. Detached stdio remains ignored. Attached mode still receives the messages directly and waits for the daemon to exit.
|
|
180
|
+
|
|
120
181
|
Add a `me` command (exits 0 if logged in, 1 if not) so agents can poll for completion. Use `ctx.daemon.forCommand('login')` to check the login daemon status from other commands. See the **Background Daemons** section in the goke README for the full pattern, including `env` passthrough and PID file safety.
|
|
121
182
|
|
|
122
183
|
## Shell Completions
|
|
@@ -220,6 +281,17 @@ project remove
|
|
|
220
281
|
|
|
221
282
|
Pick **singular or plural** for the noun and stick with it across the entire CLI. If `project list` exists, don't add `projects add`.
|
|
222
283
|
|
|
284
|
+
**Always group namespaced commands with `.section()`.** Commands that share a parent word (`get pods`, `get services`, `auth login`) must sit under a named heading in root help. Call `cli.section('Get')` before registering that group. Use `.command(...).section('Name')` when one command belongs in a different group.
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
cli.section('Get')
|
|
288
|
+
cli.command('get pods', 'List pods')
|
|
289
|
+
cli.command('get services', 'List services')
|
|
290
|
+
|
|
291
|
+
cli.section('Describe')
|
|
292
|
+
cli.command('describe pod <name>', 'Describe a pod')
|
|
293
|
+
```
|
|
294
|
+
|
|
223
295
|
### Consistent verbs
|
|
224
296
|
|
|
225
297
|
Choose one verb per action and reuse it everywhere:
|
|
@@ -233,6 +305,16 @@ Choose one verb per action and reuse it everywhere:
|
|
|
233
305
|
|
|
234
306
|
Check which verbs the CLI already uses and match them. If existing commands use `add`, every new "create something" command should also use `add`.
|
|
235
307
|
|
|
308
|
+
### Never mix different ID kinds in positionals
|
|
309
|
+
|
|
310
|
+
All positionals of a command must identify the same kind of thing. Never give the first positional a different meaning than the rest (e.g. `events <recordingId> [...eventIds]`): a call like `events 1 4 7` is unreadable because the first number silently refers to a different entity. Move the parent/scoping ID to an optional flag with a sensible default and keep positionals homogeneous:
|
|
311
|
+
|
|
312
|
+
```ts
|
|
313
|
+
cli
|
|
314
|
+
.command('recorder events [...eventIds]', 'Print recorded events')
|
|
315
|
+
.option('-r, --recording <id>', 'Recording ID (defaults to the latest recording)')
|
|
316
|
+
```
|
|
317
|
+
|
|
236
318
|
## Prefer Optional Flags Over Required Flags
|
|
237
319
|
|
|
238
320
|
**Never make a flag required when it can be optional with an interactive fallback.** Required flags force users to read `--help` before they can run anything. Optional flags let them run the bare command and discover options progressively through prompts.
|
|
@@ -301,6 +383,19 @@ if (!options.name) {
|
|
|
301
383
|
}
|
|
302
384
|
```
|
|
303
385
|
|
|
386
|
+
## Error Messages with Recovery Hints
|
|
387
|
+
|
|
388
|
+
**Every error message should include a hint showing how to fix or rerun the command.** When a CLI exits with an error, the user (or agent) should be able to copy-paste a corrected command immediately instead of reading `--help`.
|
|
389
|
+
|
|
390
|
+
```ts
|
|
391
|
+
console.error('Failed to detect local port.')
|
|
392
|
+
console.error('If your server prints the port in an unusual format, specify it explicitly:')
|
|
393
|
+
console.error(` mycli serve -p <port> -- ${shellQuote(args)}`)
|
|
394
|
+
process.exit(1)
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Include the user's original arguments in the suggested command when possible, so the hint is directly copy-pasteable. For timeouts, show how long it waited so the user knows whether to wait longer or try a different approach.
|
|
398
|
+
|
|
304
399
|
## Interactive Prompts with @clack/prompts
|
|
305
400
|
|
|
306
401
|
Use `@clack/prompts` for interactive CLI prompts like `select`, `confirm`, and text input.
|
|
@@ -553,3 +648,48 @@ cli
|
|
|
553
648
|
- Developers can point to `http://localhost:3000` during development without losing their production token
|
|
554
649
|
- Switching servers is just `--api-url` or setting an env var; no re-login needed if the server was used before
|
|
555
650
|
```
|
|
651
|
+
|
|
652
|
+
## MCP CLIs (`@goke/mcp`)
|
|
653
|
+
|
|
654
|
+
Use `addMcpCommands` from `@goke/mcp`. Do not hide `--help` behind a token. Put token steps on a `config` command. Never write `isSetupCmd` or a first-run prompt that blocks no-args.
|
|
655
|
+
|
|
656
|
+
Use `getMcpUrl` plus `getHeaders` for HTTP Bearer tokens. Use `getMcpTransport` for stdio or any custom transport.
|
|
657
|
+
|
|
658
|
+
```ts
|
|
659
|
+
await addMcpCommands({
|
|
660
|
+
cli,
|
|
661
|
+
getMcpUrl: () => MCP_URL,
|
|
662
|
+
getHeaders: () => {
|
|
663
|
+
const token = process.env.TOKEN || loadConfig().token
|
|
664
|
+
if (!token) return
|
|
665
|
+
return { Authorization: `Bearer ${token}` }
|
|
666
|
+
},
|
|
667
|
+
loadCache: () => loadConfig().cache,
|
|
668
|
+
saveCache: (cache) => saveConfig({ cache }),
|
|
669
|
+
})
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
## Writing a Skill for a goke CLI
|
|
673
|
+
|
|
674
|
+
When creating a SKILL.md for a CLI built with goke, keep it **thin**. The skill is a bridge between the agent and the canonical docs, not a copy of them.
|
|
675
|
+
|
|
676
|
+
### Structure
|
|
677
|
+
|
|
678
|
+
1. **Always start with `--help`.** The CLI self-documents commands, options, and examples via goke's help generator. Make agents read it first, in full, every session. Add a "Read the help first" section with `mycli --help` and a rule to never truncate with `head`, `tail`, or `sed -n`.
|
|
679
|
+
|
|
680
|
+
2. **Point at canonical docs.** If the CLI has a docs site with `llms-full.txt` (e.g. built with Holocron), tell agents to `curl -s https://mycli.dev/llms-full.txt` as the single source of truth. For OSS repos without a docs site, curl the raw README from GitHub: `curl -s https://raw.githubusercontent.com/owner/repo/main/README.md`. Add a "never truncate" rule next to the curl command. Optionally list 3-4 individual page URLs for the most common quick lookups.
|
|
681
|
+
|
|
682
|
+
3. **Install and auth.** Just the commands, one per line, minimal prose. Start with `which mycli` so agents check before installing. Then `npm install -g mycli`, `mycli auth check`, `mycli auth login`, and `mycli auth set --key` for CI.
|
|
683
|
+
|
|
684
|
+
4. **Gotchas.** Agent-specific knowledge that is not obvious from `--help` or the docs. Things like browser flows that need user interaction, remote vs local file path restrictions, implicit defaults that cause silent failures, and subscription requirements.
|
|
685
|
+
|
|
686
|
+
5. **MCP alternative.** If the CLI has an MCP server, include the one-liner install command.
|
|
687
|
+
|
|
688
|
+
### What NOT to put in the skill
|
|
689
|
+
|
|
690
|
+
- **Command reference** — already in `--help` output
|
|
691
|
+
- **Workflow examples** — belong in the docs site (quickstart, guides)
|
|
692
|
+
- **Option descriptions** — already in Zod `.describe()` strings that goke renders in help
|
|
693
|
+
- **Output format details** — covered by `--help` and docs
|
|
694
|
+
|
|
695
|
+
If a section in the skill duplicates content from `--help` or the docs, delete it. The agent will fetch the canonical source.
|
package/skills/holocron/SKILL.md
CHANGED
|
@@ -4,7 +4,8 @@ repo: https://github.com/remorses/holocron
|
|
|
4
4
|
description: >
|
|
5
5
|
Holocron is a Mintlify-compatible docs site generator and Vite plugin.
|
|
6
6
|
Use this skill when creating, migrating, customizing, or deploying a
|
|
7
|
-
Holocron documentation site.
|
|
7
|
+
Holocron documentation site. Also load when writing index.mdx, page
|
|
8
|
+
titles, hideTitle, Above heroes, or homepage SEO for Google brand ranking.
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
# Holocron
|
|
@@ -182,6 +183,7 @@ README as the index page:
|
|
|
182
183
|
|
|
183
184
|
```mdx
|
|
184
185
|
---
|
|
186
|
+
$schema: https://holocron.so/frontmatter.json
|
|
185
187
|
title: My Project
|
|
186
188
|
---
|
|
187
189
|
|
|
@@ -304,9 +306,56 @@ title: Quickstart
|
|
|
304
306
|
description: Build and deploy your first Holocron docs site.
|
|
305
307
|
icon: lucide:rocket
|
|
306
308
|
tag: NEW
|
|
309
|
+
prompt: |
|
|
310
|
+
Write the Quickstart from @/cli/src/create.ts.
|
|
311
|
+
---
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Record the generation prompt
|
|
315
|
+
|
|
316
|
+
Every documentation page you create must include a **`prompt`** field that
|
|
317
|
+
records the instruction and sources used to generate that page. When editing an
|
|
318
|
+
older page without one, add it when you can identify the real sources. Write the
|
|
319
|
+
original generation recipe, not a maintenance instruction.
|
|
320
|
+
|
|
321
|
+
Use **`@/path`** for source files and folders from the **repository root**.
|
|
322
|
+
Use `@./path` or `@../path` only when the source sits next to the MDX page.
|
|
323
|
+
Prefix remote sources with **`@https://`**. Bare URLs are not references. Do
|
|
324
|
+
not invent sources, and update the prompt when source locations or page scope
|
|
325
|
+
change.
|
|
326
|
+
|
|
327
|
+
```yaml
|
|
328
|
+
---
|
|
329
|
+
$schema: https://holocron.so/frontmatter.json
|
|
330
|
+
title: Authentication
|
|
331
|
+
prompt: |
|
|
332
|
+
Write the authentication guide from @/src/auth/ and
|
|
333
|
+
@/src/middleware/session.ts.
|
|
334
|
+
Use @https://github.com/example/project/releases for recent behavior.
|
|
335
|
+
|
|
336
|
+
Explain sessions, API keys, and GitHub Actions OIDC.
|
|
337
|
+
Include a complete TypeScript example for every method.
|
|
307
338
|
---
|
|
308
339
|
```
|
|
309
340
|
|
|
341
|
+
Holocron Maintain extracts these references and reruns the generation prompt
|
|
342
|
+
when a source changes. A folder reference matches changes to any tracked file
|
|
343
|
+
inside that folder.
|
|
344
|
+
|
|
345
|
+
### Migrating an existing docs site
|
|
346
|
+
|
|
347
|
+
When moving a docs site to Holocron, write each `prompt` as if the page was
|
|
348
|
+
authored from scratch. Keep it a short summary of what the page documents.
|
|
349
|
+
|
|
350
|
+
Do not mention migration, recreation, or the old docs URL. Do not add
|
|
351
|
+
`@https://old-site/...` references. The source site is going away after the
|
|
352
|
+
move unless the user says otherwise.
|
|
353
|
+
|
|
354
|
+
```yaml
|
|
355
|
+
prompt: |
|
|
356
|
+
Document connecting the first integration, role access, and chat validation.
|
|
357
|
+
```
|
|
358
|
+
|
|
310
359
|
**Title** should be **50-60 characters** max. It appears in the OG image at large
|
|
311
360
|
font size, in the browser tab, and in search results. Keep it concise and
|
|
312
361
|
descriptive.
|
|
@@ -319,6 +368,7 @@ the full title still appears in the page heading, browser tab, and OG image.
|
|
|
319
368
|
|
|
320
369
|
```mdx
|
|
321
370
|
---
|
|
371
|
+
$schema: https://holocron.so/frontmatter.json
|
|
322
372
|
title: Configuring Authentication Providers
|
|
323
373
|
sidebarTitle: Auth Providers
|
|
324
374
|
---
|
|
@@ -328,35 +378,121 @@ sidebarTitle: Auth Providers
|
|
|
328
378
|
below the title and in search engine snippets. Write a single sentence that
|
|
329
379
|
summarizes the page content. Longer descriptions get truncated with an ellipsis.
|
|
330
380
|
|
|
331
|
-
## Page titles (MUST follow)
|
|
381
|
+
## Page titles and SEO (MUST follow)
|
|
382
|
+
|
|
383
|
+
Google title links and snippets come from on-page title, H1, and description.
|
|
384
|
+
See [title links](https://developers.google.com/search/docs/appearance/title-link)
|
|
385
|
+
and [snippets](https://developers.google.com/search/docs/appearance/snippet).
|
|
386
|
+
|
|
387
|
+
Holocron already appends the site name. `buildPageTitle` renders
|
|
388
|
+
`{page title} — {site name}` unless `title` already starts with the site name.
|
|
389
|
+
**Do not put the site name in `title` or in the H1.** That doubles the brand
|
|
390
|
+
(`Kimaki: … — Kimaki`). Write the ranking keywords only. Let Holocron add
|
|
391
|
+
` — {site name}`.
|
|
332
392
|
|
|
333
|
-
|
|
334
|
-
frontmatter fields control what appears where:
|
|
393
|
+
Two frontmatter fields:
|
|
335
394
|
|
|
336
|
-
- **`title`** — browser tab, Google
|
|
337
|
-
- **`sidebarTitle`** — sidebar
|
|
395
|
+
- **`title`** — browser tab, Google title link, OG image, and the injected H1. Write for SEO. Put the keywords this page should rank for.
|
|
396
|
+
- **`sidebarTitle`** — sidebar only. Short label, under 30 characters.
|
|
338
397
|
|
|
339
|
-
**Always set both.** `
|
|
340
|
-
|
|
341
|
-
|
|
398
|
+
**Always set both.** Without `sidebarTitle`, the long SEO title wraps in the 230px sidebar.
|
|
399
|
+
|
|
400
|
+
**Always quote frontmatter strings.** YAML treats `:` as a map. `title: Kimaki: AI agents` is nested YAML. Holocron then drops all frontmatter, and the browser title becomes the first body heading. Quote `title` and `description`. Holocron warns when an unquoted value contains `:`, and when a parsed key contains a space and `:`.
|
|
342
401
|
|
|
343
402
|
```mdx
|
|
344
403
|
---
|
|
345
|
-
|
|
404
|
+
$schema: https://holocron.so/frontmatter.json
|
|
405
|
+
title: "Open-source browser automation"
|
|
346
406
|
sidebarTitle: Home
|
|
347
|
-
description: Automate any browser with a
|
|
407
|
+
description: "Automate any browser with a TypeScript API. Control Chrome from a CLI or agent."
|
|
348
408
|
---
|
|
349
409
|
```
|
|
350
410
|
|
|
351
|
-
Browser tab: `Open-source browser automation
|
|
411
|
+
Browser tab: `Open-source browser automation — Playwriter`
|
|
412
|
+
Injected H1: `Open-source browser automation`
|
|
352
413
|
Sidebar: `Home`
|
|
353
414
|
|
|
354
|
-
**
|
|
415
|
+
On most pages Holocron injects `title` as the only H1, so **title and H1 are the same**. Keep it that way. Do not add another `#` or `<h1>` in the body.
|
|
416
|
+
|
|
417
|
+
**Title rules:**
|
|
418
|
+
|
|
419
|
+
- **Put ranking keywords in `title`.** The homepage title is the most important. Docs pages use the topic keywords (`Subscriptions`, `Worktrees`), not `Introduction` or `Overview`.
|
|
420
|
+
- **Never start `title` with the site name.** Holocron already appends ` — {site name}`.
|
|
421
|
+
- **Never set `title` identical to the site name.** A title of `Playwriter` becomes `Playwriter — Playwriter`.
|
|
422
|
+
- **Every `title` MUST be unique, descriptive, and concise.** Google truncates long titles. Avoid keyword stuffing and boilerplate that only changes one word.
|
|
423
|
+
- **`index.mdx` MUST use `sidebarTitle: Home`** (or `Overview`). See Homepage SEO below.
|
|
424
|
+
|
|
425
|
+
**H1 rules:**
|
|
426
|
+
|
|
427
|
+
- **One H1 per page.** It must contain the same ranking keywords as `title`. Prefer the exact `title` text. Holocron does this automatically when it injects the title.
|
|
428
|
+
- Google uses the first prominent H1 as a title-link source. Extra H1s with the same weight can steal the tab title (`Quick Start — Site`). Heading count is not a ranking penalty. A clear main title is.
|
|
429
|
+
|
|
430
|
+
**Description rules:**
|
|
431
|
+
|
|
432
|
+
`description` becomes `<meta name="description">`. Google may use it as the snippet when it describes the page better than on-page text.
|
|
433
|
+
|
|
434
|
+
- **Unique per page.** Site-wide copy on every page is useless in search results.
|
|
435
|
+
- **Summarize this page**, in one or two sentences. Not a keyword list.
|
|
436
|
+
- **Include ranking keywords naturally.** Do not stuff. Do not repeat the site name just because the title suffix already has it. The homepage may name the product once if that is the summary.
|
|
437
|
+
- **Be specific.** Length has no hard cap. Google truncates to the device width. Aim for a short pitch, about 120 to 160 characters.
|
|
438
|
+
- Quote the YAML string.
|
|
439
|
+
|
|
440
|
+
```yaml
|
|
441
|
+
description: "Run AI coding agents from Discord. Each channel is a project, each thread is a session."
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Homepage SEO
|
|
445
|
+
|
|
446
|
+
The homepage title is the strongest brand query signal. Put the keywords people search in `title` and H1. Let Holocron append the site name.
|
|
447
|
+
|
|
448
|
+
```mdx
|
|
449
|
+
---
|
|
450
|
+
$schema: https://holocron.so/frontmatter.json
|
|
451
|
+
title: "AI coding agents from Discord"
|
|
452
|
+
sidebarTitle: Home
|
|
453
|
+
description: "Run AI coding agents from Discord. Each channel is a project, each thread is a session."
|
|
454
|
+
---
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Browser tab: `AI coding agents from Discord — Kimaki`
|
|
458
|
+
H1: `AI coding agents from Discord`
|
|
355
459
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
460
|
+
**One H1, same keywords as `title`.** Holocron injects that H1 unless the page has `<Above>` or `hideTitle: true`. A custom hero that also renders `<h1>` next to an injected title creates two H1s.
|
|
461
|
+
|
|
462
|
+
**If the page has `<Above>`, that hero owns the H1.** Holocron skips the injected title. Set the hero H1 to the same text as `title`. Do not put the site name in the hero H1. Never write `#` or `<h1>` in the MDX body below it. The first body section must be `##`. Extra H1s are demoted to H2.
|
|
463
|
+
|
|
464
|
+
```mdx
|
|
465
|
+
---
|
|
466
|
+
title: "AI coding agents from Discord"
|
|
467
|
+
sidebarTitle: Home
|
|
468
|
+
description: "Run AI coding agents from Discord. Each channel is a project, each thread is a session."
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
<Above>
|
|
472
|
+
<HeroSection />
|
|
473
|
+
</Above>
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
```tsx
|
|
477
|
+
<h1>
|
|
478
|
+
<span>AI coding agents</span>
|
|
479
|
+
<span>from Discord.</span>
|
|
480
|
+
</h1>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
If there is no custom hero, do **not** set `hideTitle`. Let Holocron inject `title` as the only H1.
|
|
484
|
+
|
|
485
|
+
**Do not make `/` a clone of GitHub.** Importing `README.md` under the hero is fine. The homepage still needs its own title, H1, and description. If `/` is the same text as GitHub, Google prefers GitHub plus a unique inner docs page.
|
|
486
|
+
|
|
487
|
+
A **logo link to `/`** is weak. Fix title, H1, and description first.
|
|
488
|
+
|
|
489
|
+
After deploy, fetch the live HTML and check:
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
curl -sL -A 'Mozilla/5.0 (compatible; Googlebot/2.1)' 'https://example.com/' -o /tmp/home.html
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Confirm **exactly one `<h1>`**, that H1 text matches `title`, and `<title>` is `{title} — {site name}` with the site name only at the end. Rank will not move until Google recrawls.
|
|
360
496
|
|
|
361
497
|
## Page modes — hiding sidebars
|
|
362
498
|
|
|
@@ -369,6 +505,7 @@ In both modes the content can feel too wide. Use **`maxWidth`** to constrain it:
|
|
|
369
505
|
|
|
370
506
|
```yaml
|
|
371
507
|
---
|
|
508
|
+
$schema: https://holocron.so/frontmatter.json
|
|
372
509
|
mode: "custom"
|
|
373
510
|
maxWidth: 700
|
|
374
511
|
---
|
|
@@ -3,8 +3,9 @@ name: npm-package
|
|
|
3
3
|
description: >
|
|
4
4
|
Opinionated TypeScript npm package template for ESM packages. Enforces
|
|
5
5
|
src→dist builds with tsc, strict TypeScript defaults, explicit exports, and
|
|
6
|
-
publish-safe package metadata.
|
|
7
|
-
|
|
6
|
+
publish-safe package metadata. Relative source imports must use .ts or .tsx
|
|
7
|
+
(never .js); tsc rewrites them via rewriteRelativeImportExtensions. Use this
|
|
8
|
+
when creating or updating any npm package in this repo.
|
|
8
9
|
version: 0.0.1
|
|
9
10
|
---
|
|
10
11
|
|
|
@@ -45,19 +46,36 @@ Use this skill when scaffolding or fixing npm packages.
|
|
|
45
46
|
README at the repository root. Package READMEs don't get read by anyone.
|
|
46
47
|
The root README is the single source of truth for the whole project.
|
|
47
48
|
10. `scripts.build` should be `tsc && chmod +x dist/cli.js` (skip the chmod if
|
|
48
|
-
the package has no bin). No bundling.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
the package has no bin). No bundling. Optionally include running scripts
|
|
50
|
+
with `tsx` if needed to generate build artifacts.
|
|
51
|
+
|
|
52
|
+
**Never put `rm -rf`, `rimraf`, or any delete in `build`.** `build` runs on
|
|
53
|
+
every edit, watch loop, and CI test job. Deleting `dist/` there breaks live
|
|
54
|
+
dev servers that hold it in their module graph (Bun fails with `Failed to
|
|
55
|
+
load bundled module '<pkg>/dist/index.js'` until restarted) and throws away
|
|
56
|
+
incremental compilation. A stale file only matters in a published tarball,
|
|
57
|
+
which `prepublishOnly` already handles.
|
|
58
|
+
|
|
59
|
+
11. `prepublishOnly` is the **only** place a delete belongs. It keeps a file
|
|
60
|
+
deleted from `src/` out of the published package:
|
|
54
61
|
```json
|
|
55
62
|
{ "prepublishOnly": "rimraf dist \"*.tsbuildinfo\" && pnpm build" }
|
|
56
63
|
```
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
**Always use `rimraf`, never `rm -rf`.** This holds for every package.json
|
|
65
|
+
script, not just this one. `rm -rf` is not portable to Windows, and with no
|
|
66
|
+
`.tsbuildinfo` present zsh aborts `rm -rf dist *.tsbuildinfo` with `no
|
|
67
|
+
matches found`, so the build after `&&` never runs and you publish a stale
|
|
68
|
+
`dist/`. `sh` and `bash` only survive because `rm -f` ignores the literal
|
|
69
|
+
unmatched name. Install `rimraf` as a devDependency; never rely on
|
|
70
|
+
`npx`/`bunx` at publish time.
|
|
71
|
+
|
|
72
|
+
When the package also has a publish guard, chain it first so the guard
|
|
73
|
+
still runs before anything is deleted:
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"prepublishOnly": "node -e \"if (!process.env.CI) process.exit(1)\" && rimraf dist \"*.tsbuildinfo\" && pnpm build"
|
|
77
|
+
}
|
|
78
|
+
```
|
|
61
79
|
|
|
62
80
|
## bin field
|
|
63
81
|
|
|
@@ -175,33 +193,33 @@ Use Node ESM-compatible compiler settings:
|
|
|
175
193
|
|
|
176
194
|
- Always use "rootDir": "src"
|
|
177
195
|
- Add `"DOM"` to `lib` only when browser globals are needed.
|
|
178
|
-
-
|
|
179
|
-
`.js` in the emitted `dist/` output automatically via
|
|
180
|
-
`rewriteRelativeImportExtensions`. This means source code works directly in
|
|
181
|
-
runtimes like `tsx`, `bun`, and frameworks like Next.js that expect `.ts`
|
|
182
|
-
extensions, while the published `dist/` has correct `.js` imports that Node.js
|
|
183
|
-
and other consumers resolve without issues.
|
|
184
|
-
|
|
185
|
-
```ts
|
|
186
|
-
// source (src/index.ts) — use .ts/.tsx extensions
|
|
187
|
-
import { helper } from "./utils.ts";
|
|
188
|
-
import { Button } from "./button.tsx";
|
|
189
|
-
|
|
190
|
-
// emitted output (dist/index.js) — tsc rewrites to .js
|
|
191
|
-
// import { helper } from './utils.js'
|
|
192
|
-
// import { Button } from './button.js'
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
- Only relative imports are rewritten. Path aliases (`paths` in tsconfig) are
|
|
196
|
-
not supported by `rewriteRelativeImportExtensions` — this is fine since npm
|
|
197
|
-
packages should use relative imports anyway.
|
|
198
|
-
- Requires TypeScript 5.7+.
|
|
196
|
+
- Requires TypeScript 5.7+ (`rewriteRelativeImportExtensions`).
|
|
199
197
|
- Install `@types/node` as a dev dependency whenever Node APIs are used.
|
|
200
198
|
- If generation is required, keep generators in `scripts/*.ts` and invoke them
|
|
201
199
|
from package scripts before build/publish.
|
|
202
200
|
|
|
203
201
|
> IMPORTANT! always use rootDir src. if there are other root level folders that should be type checked you should create other tsconfig.json files inside those folder. DO NOT add other folders inside src or the dist/ will contain dist/src, dist/other-folder. which breaks imports. the tsconfig.json inside these other folders can be minimal, using noEmit true, declaration false. Because usually these folders do not need to be emitted or compiled. just type checked. tests should still be put inside src. other folders can be things like `scripts` or `fixtures`.
|
|
204
202
|
|
|
203
|
+
## Relative imports
|
|
204
|
+
|
|
205
|
+
Always write `.ts` or `.tsx` in relative source imports. Never write `.js`.
|
|
206
|
+
|
|
207
|
+
TypeScript 5.7+ rewrites those extensions to `.js` in `dist/` when
|
|
208
|
+
`rewriteRelativeImportExtensions` is on. Source then runs as-is in `tsx`,
|
|
209
|
+
`bun`, Next.js, and Node type-stripping. Published JS still resolves.
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import { helper } from "./utils.ts";
|
|
213
|
+
import { Button } from "./button.tsx";
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`tsc` emits `./utils.js` and `./button.js`. Only relative paths (`./`, `../`)
|
|
217
|
+
are rewritten. Path aliases, `#` imports, and bare specifiers are not. npm
|
|
218
|
+
packages should use relative imports anyway.
|
|
219
|
+
|
|
220
|
+
Docs: [rewriteRelativeImportExtensions](https://www.typescriptlang.org/tsconfig/#rewriteRelativeImportExtensions),
|
|
221
|
+
[TypeScript 5.7 path rewriting](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-7.html#path-rewriting-for-relative-paths).
|
|
222
|
+
|
|
205
223
|
## Preferred exports template
|
|
206
224
|
|
|
207
225
|
```json
|
|
@@ -355,7 +373,7 @@ Source of truth: [TypeScript Modules Reference — package.json "imports" and se
|
|
|
355
373
|
|
|
356
374
|
## tests location
|
|
357
375
|
|
|
358
|
-
test files should be close with the associated source files. for example if you have an utils.ts file you will create utils.test.ts file next to it. with tests, importing from utils. preferred testing framework is vitest (or bun if project already using `bun test` or depends on bun APIs, rare)
|
|
376
|
+
test files should be close with the associated source files. for example if you have an utils.ts file you will create utils.test.ts file next to it. with tests, importing from `./utils.ts`. preferred testing framework is vitest (or bun if project already using `bun test` or depends on bun APIs, rare)
|
|
359
377
|
|
|
360
378
|
## Agent skill
|
|
361
379
|
|
|
@@ -665,8 +683,10 @@ To make peer dependencies optional, add `peerDependenciesMeta`:
|
|
|
665
683
|
|
|
666
684
|
## common mistakes
|
|
667
685
|
|
|
686
|
+
- never write `.js` in relative source imports. use `.ts` or `.tsx`. tsc rewrites them in `dist/`
|
|
668
687
|
- if you need to use zod always use latest version
|
|
669
688
|
- always install packages as dev dependencies if used only for scripts, testing or types only
|
|
670
|
-
-
|
|
689
|
+
- never use `rm -rf` in a package.json script. always use `rimraf`, installed as a dev dependency. `rm -rf` is not portable to Windows and zsh aborts the whole `&&` chain when a glob matches nothing
|
|
690
|
+
- never delete anything in `build`. deletes belong in `prepublishOnly` only
|
|
671
691
|
- never use em-dashes (—) or dashes as inline separators (like `word - word`) in README or documentation. instead restructure the sentence: use periods to split into two sentences, colons, commas, or parentheses
|
|
672
692
|
- never add badge images (shields.io, etc.) or any images you don't have locally in the repo. don't invent image URLs
|
package/skills/profano/SKILL.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: profano
|
|
3
|
-
|
|
3
|
+
repo: remorses/profano
|
|
4
|
+
description: >
|
|
5
|
+
CLI tool to analyze V8 .cpuprofile files and Chrome Performance traces and
|
|
6
|
+
print top functions by self-time or total-time in the terminal. ALWAYS load
|
|
7
|
+
this skill when CPU profiling JavaScript or TypeScript programs (Node, Vitest,
|
|
8
|
+
Bun, Chrome DevTools exports, Cloudflare Workers startup or request CPU).
|
|
9
|
+
It shows how to generate .cpuprofile files and how to inspect them from the
|
|
10
|
+
terminal without opening Chrome DevTools.
|
|
4
11
|
---
|
|
5
12
|
|
|
6
13
|
# profano
|
|
@@ -13,6 +20,14 @@ Every time you use profano, you MUST fetch the latest README and read it in full
|
|
|
13
20
|
curl -s https://raw.githubusercontent.com/remorses/profano/main/README.md # NEVER pipe to head/tail, read in full
|
|
14
21
|
```
|
|
15
22
|
|
|
16
|
-
The README covers generating `.cpuprofile` files (Node, Vitest, Bun, Chrome Performance traces, browser pages via playwriter, React component profiling), all CLI options, and how to read the output columns.
|
|
23
|
+
The README covers generating `.cpuprofile` files (Node, Vitest, Bun, **Cloudflare Workers** startup and request, Chrome Performance traces, browser pages via playwriter, React component profiling), all CLI options, and how to read the output columns.
|
|
17
24
|
|
|
18
25
|
Chrome Performance **Save profile** writes a trace JSON. Pass it to `profano Trace.json` directly. Do not convert it first.
|
|
26
|
+
|
|
27
|
+
## Cloudflare Workers
|
|
28
|
+
|
|
29
|
+
A Worker needs **two** profiles. Startup is `wrangler check startup`. A request is `wrangler dev --inspector-port 9230` plus `profano workers request <url>`. `wrangler tail` `cpuTime` is only a total. Never paste a one-off CDP script; use the CLI command.
|
|
30
|
+
|
|
31
|
+
Do **not** copy `dist/` to a temp folder unless `wrangler check startup` errors about two wrangler configs with different base paths. That copy is an exception, not the default.
|
|
32
|
+
|
|
33
|
+
Trust the **function mix** in a local profile. Do not treat local milliseconds as Cloudflare CPU.
|