kimaki 0.26.0 → 0.27.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 +25 -122
- package/dist/anthropic-account-identity.js +1 -0
- package/dist/anthropic-auth-plugin.js +1 -0
- package/dist/anthropic-auth-state.js +1 -0
- package/dist/bin.js +73 -19
- package/dist/cli-commands/maintenance.js +46 -7
- package/dist/cli-commands/send.js +24 -0
- package/dist/cli-commands/session.js +183 -8
- package/dist/cli-commands/task.js +13 -1
- package/dist/cli-parsing.test.js +59 -3
- package/dist/cli-runner.js +28 -4
- package/dist/cli-runner.test.js +27 -0
- package/dist/cli-send-thread.e2e.test.js +1 -1
- package/dist/cli.js +32 -0
- package/dist/commands/abort.js +5 -1
- package/dist/commands/agent.js +6 -8
- package/dist/commands/ask-question.js +21 -32
- package/dist/commands/ask-question.test.js +43 -1
- package/dist/commands/login.js +6 -0
- package/dist/commands/merge-worktree.js +36 -10
- package/dist/commands/model-variant.js +7 -1
- package/dist/commands/model.js +14 -8
- package/dist/commands/multioauth.js +1 -0
- package/dist/commands/new-worktree.js +170 -102
- package/dist/commands/user-command.js +6 -8
- package/dist/commands/worktrees.js +5 -13
- package/dist/config.js +16 -1
- package/dist/database.js +124 -3
- package/dist/db.js +22 -0
- package/dist/db.test.js +167 -1
- package/dist/discord-bot.js +34 -32
- package/dist/discord-command-registration.js +9 -1
- package/dist/discord-utils.js +13 -5
- package/dist/discord-utils.test.js +17 -1
- package/dist/errors.js +5 -0
- package/dist/exec-async.js +17 -5
- package/dist/external-directory-permissions.e2e.test.js +2 -2
- 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 +5 -5
- package/dist/git-worktree-core.js +182 -17
- package/dist/ipc-tools-plugin.js +63 -3
- package/dist/kimaki-opencode-plugin-loading.e2e.test.js +122 -58
- package/dist/kimaki-opencode-plugin.js +7 -3
- package/dist/kimaki-workspace-adaptor.js +33 -10
- package/dist/logger.js +10 -1
- package/dist/markdown.js +3 -1
- package/dist/markdown.test.js +11 -3
- package/dist/message-formatting.js +18 -7
- package/dist/message-formatting.test.js +56 -9
- 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.test.js +60 -0
- package/dist/opencode.js +53 -12
- package/dist/question-abort-clears-dropdown.e2e.test.js +89 -0
- package/dist/question-text-before-dropdown.e2e.test.js +52 -0
- package/dist/queue-advanced-abort.e2e.test.js +1 -1
- package/dist/queue-advanced-action-buttons.e2e.test.js +3 -3
- package/dist/queue-advanced-e2e-setup.js +78 -5
- package/dist/queue-advanced-footer.e2e.test.js +40 -246
- package/dist/queue-advanced-model-switch.e2e.test.js +2 -2
- package/dist/queue-advanced-permissions-typing.e2e.test.js +7 -9
- package/dist/queue-advanced-question.e2e.test.js +31 -26
- package/dist/queue-advanced-typing-interrupt.e2e.test.js +2 -2
- package/dist/queue-delete-message.e2e.test.js +1 -1
- package/dist/queue-drain-after-interactive-ui.e2e.test.js +2 -2
- package/dist/queue-interrupt-drain.e2e.test.js +112 -2
- package/dist/queue-question-select-drain.e2e.test.js +30 -128
- package/dist/runtime-lifecycle.e2e.test.js +10 -37
- package/dist/schema.js +34 -0
- package/dist/session-handler/event-stream-state.js +267 -50
- package/dist/session-handler/event-stream-state.test.js +415 -8
- package/dist/session-handler/model-utils.js +159 -5
- package/dist/session-handler/model-utils.test.js +345 -0
- package/dist/session-handler/thread-session-runtime.js +252 -182
- package/dist/session-sleep.test.js +224 -0
- package/dist/session-title-rename.test.js +7 -39
- package/dist/sleep.e2e.test.js +491 -0
- package/dist/startup-time.e2e.test.js +2 -1
- package/dist/store.js +3 -0
- package/dist/system-message.js +59 -6
- package/dist/system-message.test.js +76 -6
- package/dist/task-runner.js +94 -4
- package/dist/task-schedule.js +56 -0
- package/dist/task-schedule.test.js +71 -1
- package/dist/thread-message-queue.e2e.test.js +10 -169
- package/dist/undo-redo.e2e.test.js +2 -2
- package/dist/voice-attachment.js +23 -1
- package/dist/voice-message.e2e.test.js +10 -10
- package/dist/voice.test.js +55 -29
- package/dist/worktree-clone-isolation.e2e.test.js +188 -0
- package/dist/worktree-lifecycle.e2e.test.js +29 -10
- 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/errore/SKILL.md +18 -0
- package/skills/goke/SKILL.md +150 -10
- package/skills/holocron/SKILL.md +37 -0
- 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 +25 -151
- package/src/anthropic-account-identity.ts +1 -0
- package/src/anthropic-auth-plugin.ts +1 -0
- package/src/anthropic-auth-state.ts +1 -0
- package/src/bin.ts +78 -26
- package/src/cli-commands/maintenance.ts +59 -13
- package/src/cli-commands/send.ts +25 -0
- package/src/cli-commands/session.ts +203 -9
- package/src/cli-commands/task.ts +13 -1
- package/src/cli-parsing.test.ts +69 -3
- package/src/cli-runner.test.ts +49 -0
- package/src/cli-runner.ts +28 -4
- package/src/cli-send-thread.e2e.test.ts +1 -1
- package/src/cli.ts +53 -0
- package/src/commands/abort.ts +6 -1
- package/src/commands/agent.ts +6 -6
- package/src/commands/ask-question.test.ts +48 -1
- package/src/commands/ask-question.ts +21 -32
- package/src/commands/login.ts +6 -0
- package/src/commands/merge-worktree.ts +43 -12
- package/src/commands/model-variant.ts +8 -1
- package/src/commands/model.ts +18 -8
- package/src/commands/multioauth.ts +1 -0
- package/src/commands/new-worktree.ts +138 -55
- package/src/commands/user-command.ts +6 -6
- package/src/commands/worktrees.ts +5 -12
- package/src/config.ts +18 -1
- package/src/database.ts +195 -3
- package/src/db.test.ts +188 -0
- package/src/db.ts +26 -0
- package/src/discord-bot.ts +35 -29
- package/src/discord-command-registration.ts +15 -1
- package/src/discord-utils.test.ts +19 -0
- package/src/discord-utils.ts +21 -6
- package/src/errors.ts +5 -0
- package/src/exec-async.ts +20 -11
- package/src/external-directory-permissions.e2e.test.ts +2 -2
- 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 +5 -5
- package/src/git-worktree-core.ts +247 -20
- package/src/ipc-tools-plugin.ts +75 -5
- package/src/kimaki-opencode-plugin-loading.e2e.test.ts +188 -97
- package/src/kimaki-opencode-plugin.ts +7 -3
- package/src/kimaki-workspace-adaptor.ts +40 -11
- package/src/logger.ts +13 -4
- package/src/markdown.test.ts +13 -3
- package/src/markdown.ts +4 -1
- package/src/message-formatting.test.ts +86 -12
- package/src/message-formatting.ts +19 -7
- 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 +81 -0
- package/src/opencode.ts +71 -11
- package/src/question-abort-clears-dropdown.e2e.test.ts +109 -0
- package/src/question-text-before-dropdown.e2e.test.ts +67 -0
- package/src/queue-advanced-abort.e2e.test.ts +1 -1
- package/src/queue-advanced-action-buttons.e2e.test.ts +3 -3
- package/src/queue-advanced-e2e-setup.ts +83 -4
- package/src/queue-advanced-footer.e2e.test.ts +47 -294
- package/src/queue-advanced-model-switch.e2e.test.ts +2 -2
- package/src/queue-advanced-permissions-typing.e2e.test.ts +7 -9
- package/src/queue-advanced-question.e2e.test.ts +35 -29
- package/src/queue-advanced-typing-interrupt.e2e.test.ts +2 -2
- package/src/queue-delete-message.e2e.test.ts +1 -1
- package/src/queue-drain-after-interactive-ui.e2e.test.ts +2 -2
- package/src/queue-interrupt-drain.e2e.test.ts +123 -2
- package/src/queue-question-select-drain.e2e.test.ts +32 -157
- package/src/runtime-lifecycle.e2e.test.ts +10 -41
- package/src/schema.sql +14 -1
- package/src/schema.ts +36 -0
- package/src/session-handler/event-stream-state.test.ts +437 -7
- package/src/session-handler/event-stream-state.ts +389 -53
- package/src/session-handler/model-utils.test.ts +415 -0
- package/src/session-handler/model-utils.ts +249 -5
- package/src/session-handler/thread-session-runtime.ts +300 -215
- package/src/session-sleep.test.ts +294 -0
- package/src/session-title-rename.test.ts +9 -48
- package/src/sleep.e2e.test.ts +562 -0
- package/src/startup-time.e2e.test.ts +5 -1
- package/src/store.ts +21 -0
- package/src/system-message.test.ts +86 -6
- package/src/system-message.ts +66 -7
- package/src/task-runner.ts +136 -2
- package/src/task-schedule.test.ts +76 -0
- package/src/task-schedule.ts +95 -0
- package/src/thread-message-queue.e2e.test.ts +10 -202
- package/src/undo-redo.e2e.test.ts +2 -2
- package/src/voice-attachment.ts +29 -1
- package/src/voice-message.e2e.test.ts +10 -10
- package/src/voice.test.ts +63 -29
- package/src/worktree-clone-isolation.e2e.test.ts +213 -0
- package/src/worktree-lifecycle.e2e.test.ts +29 -9
- 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
|
@@ -182,6 +182,7 @@ README as the index page:
|
|
|
182
182
|
|
|
183
183
|
```mdx
|
|
184
184
|
---
|
|
185
|
+
$schema: https://holocron.so/frontmatter.json
|
|
185
186
|
title: My Project
|
|
186
187
|
---
|
|
187
188
|
|
|
@@ -304,9 +305,42 @@ title: Quickstart
|
|
|
304
305
|
description: Build and deploy your first Holocron docs site.
|
|
305
306
|
icon: lucide:rocket
|
|
306
307
|
tag: NEW
|
|
308
|
+
prompt: |
|
|
309
|
+
Write the Quickstart from @/cli/src/create.ts.
|
|
310
|
+
---
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Record the generation prompt
|
|
314
|
+
|
|
315
|
+
Every documentation page you create must include a **`prompt`** field that
|
|
316
|
+
records the instruction and sources used to generate that page. When editing an
|
|
317
|
+
older page without one, add it when you can identify the real sources. Write the
|
|
318
|
+
original generation recipe, not a maintenance instruction.
|
|
319
|
+
|
|
320
|
+
Use **`@/path`** for source files and folders from the **repository root**.
|
|
321
|
+
Use `@./path` or `@../path` only when the source sits next to the MDX page.
|
|
322
|
+
Prefix remote sources with **`@https://`**. Bare URLs are not references. Do
|
|
323
|
+
not invent sources, and update the prompt when source locations or page scope
|
|
324
|
+
change.
|
|
325
|
+
|
|
326
|
+
```yaml
|
|
327
|
+
---
|
|
328
|
+
$schema: https://holocron.so/frontmatter.json
|
|
329
|
+
title: Authentication
|
|
330
|
+
prompt: |
|
|
331
|
+
Write the authentication guide from @/src/auth/ and
|
|
332
|
+
@/src/middleware/session.ts.
|
|
333
|
+
Use @https://github.com/example/project/releases for recent behavior.
|
|
334
|
+
|
|
335
|
+
Explain sessions, API keys, and GitHub Actions OIDC.
|
|
336
|
+
Include a complete TypeScript example for every method.
|
|
307
337
|
---
|
|
308
338
|
```
|
|
309
339
|
|
|
340
|
+
Holocron Maintain extracts these references and reruns the generation prompt
|
|
341
|
+
when a source changes. A folder reference matches changes to any tracked file
|
|
342
|
+
inside that folder.
|
|
343
|
+
|
|
310
344
|
**Title** should be **50-60 characters** max. It appears in the OG image at large
|
|
311
345
|
font size, in the browser tab, and in search results. Keep it concise and
|
|
312
346
|
descriptive.
|
|
@@ -319,6 +353,7 @@ the full title still appears in the page heading, browser tab, and OG image.
|
|
|
319
353
|
|
|
320
354
|
```mdx
|
|
321
355
|
---
|
|
356
|
+
$schema: https://holocron.so/frontmatter.json
|
|
322
357
|
title: Configuring Authentication Providers
|
|
323
358
|
sidebarTitle: Auth Providers
|
|
324
359
|
---
|
|
@@ -342,6 +377,7 @@ sidebar and often wraps or looks verbose.
|
|
|
342
377
|
|
|
343
378
|
```mdx
|
|
344
379
|
---
|
|
380
|
+
$schema: https://holocron.so/frontmatter.json
|
|
345
381
|
title: Open-source browser automation for AI agents
|
|
346
382
|
sidebarTitle: Home
|
|
347
383
|
description: Automate any browser with a simple TypeScript API.
|
|
@@ -369,6 +405,7 @@ In both modes the content can feel too wide. Use **`maxWidth`** to constrain it:
|
|
|
369
405
|
|
|
370
406
|
```yaml
|
|
371
407
|
---
|
|
408
|
+
$schema: https://holocron.so/frontmatter.json
|
|
372
409
|
mode: "custom"
|
|
373
410
|
maxWidth: 700
|
|
374
411
|
---
|
|
@@ -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.
|
|
@@ -64,6 +64,28 @@ Always import and use `Link` from `spiceflow/react` for navigational links in Sp
|
|
|
64
64
|
|
|
65
65
|
**`Link` auto-prepends the Vite `base` path.** Never manually prepend the base path to `Link` href values. `<Link href="/dashboard" />` automatically renders as `<a href="/my-app/dashboard">` when the Vite base is `/my-app/`. Manually prepending causes double-prefixing. This only applies to `Link`; raw `fetch()` calls, `Response.redirect()`, and other non-Link URL construction still need manual base path handling.
|
|
66
66
|
|
|
67
|
+
## `<Head>` is server-only
|
|
68
|
+
|
|
69
|
+
`<Head>` renders nothing. It records its children during the RSC render, and spiceflow reads them back to build the document head. A `'use client'` module never runs in that render, so a `<Head>` inside one contributes nothing at all.
|
|
70
|
+
|
|
71
|
+
Always put `<Head>` in the `.page()` or `.layout()` handler, never in a `'use client'` component:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
.page('/', async () => {
|
|
75
|
+
return (
|
|
76
|
+
<>
|
|
77
|
+
<Head>
|
|
78
|
+
<Head.Title>Dashboard | My App</Head.Title>
|
|
79
|
+
<Head.Meta name="description" content="Your account overview." />
|
|
80
|
+
</Head>
|
|
81
|
+
<InteractiveDashboard />
|
|
82
|
+
</>
|
|
83
|
+
)
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Importing `Head` into a `'use client'` module fails the build, and rendering one throws. To change the title from the browser after load, set `document.title` in an effect instead.
|
|
88
|
+
|
|
67
89
|
## OpenTelemetry instrumentation
|
|
68
90
|
|
|
69
91
|
Spiceflow supports automatic route instrumentation when you pass an OpenTelemetry-compatible tracer to the constructor:
|
|
@@ -150,14 +172,28 @@ export async function deleteProject(id: string) {
|
|
|
150
172
|
|
|
151
173
|
Never assume a server action is only reachable through your own UI. Treat every server action like a public API endpoint.
|
|
152
174
|
|
|
175
|
+
## Always `throw redirect(...)`, never `return redirect(...)`
|
|
176
|
+
|
|
177
|
+
Both work at runtime, but `throw` is safer: it prevents the redirect from contributing to the handler's inferred return type, avoiding circular TS7022 errors with `SpiceflowRegister`. It also short-circuits the handler immediately, making control flow explicit. This applies to `.page()`, `.layout()`, `.loader()`, `.get()`, `.post()`, server actions, and middleware.
|
|
178
|
+
|
|
153
179
|
## Never `router.refresh()` after server actions
|
|
154
180
|
|
|
155
181
|
Successful server actions re-run matching loaders and reconcile the current page. Do not call `router.refresh()` afterward. Use it only when data changes outside a server action.
|
|
156
182
|
|
|
157
183
|
`router.refresh()` is fire-and-forget. Do not await a custom refresh or navigation commit helper inside a React form action because the transition can deadlock.
|
|
158
184
|
|
|
159
|
-
##
|
|
185
|
+
## Circular types in app entry handlers
|
|
186
|
+
|
|
187
|
+
Circular TypeScript errors (TS7022) happen when any API that reads from `SpiceflowRegister` (i.e. `typeof app`) appears in a handler's **return value**. This affects `router.href()`, `router.getLoaderData()`, `createSpiceflowFetch()`, `useLoaderData()`, `Link`, and any future API typed against the registered app.
|
|
188
|
+
|
|
189
|
+
**Safe** (no circular):
|
|
190
|
+
- Any registered API in **JSX children, attributes, or event handlers** (`.page()`, `.layout()`)
|
|
191
|
+
- `throw` expressions: `throw redirect(router.href(...))` in any handler
|
|
192
|
+
- Any registered API in **client components, server components, and separate files**
|
|
160
193
|
|
|
161
|
-
|
|
194
|
+
**Circular** (causes TS7022):
|
|
195
|
+
- Any registered API in a `.loader()` **return value**
|
|
196
|
+
- Any registered API in a `.get()` or `.post()` **return value**
|
|
197
|
+
- `return redirect(router.href(...))` inside `.page()` on paths **with loaders**
|
|
162
198
|
|
|
163
|
-
|
|
199
|
+
The rule: circular happens when a `RegisteredApp`-typed expression reaches a **return value** that feeds `typeof app` inference. JSX, `throw`, and event handler callbacks don't feed return types. See `spiceflow/src/type-repros/registered-app-circular.test.ts` for the exact boundaries.
|
package/skills/strada/SKILL.md
CHANGED
|
@@ -98,6 +98,16 @@ Rules to never break:
|
|
|
98
98
|
- **Browser project id needs a public prefix** or the bundler will strip it.
|
|
99
99
|
- In **RSC / server-rendered** apps, run browser `initStrada()` from a side-effect-only `"use client"` module rendered once in the root layout (a component that returns `null`). A bare `import` runs on the server and gets tree-shaken from the client bundle. See `website/src/docs/quickstart.mdx` for the pattern.
|
|
100
100
|
- If the framework exposes an OTel tracer hook (e.g. Spiceflow `new Spiceflow({ tracer })`), pass `trace.getTracer("my-app")` from the SDK so request spans flow to the same project.
|
|
101
|
+
- In **Cloudflare Workers**, import `env` from `cloudflare:workers` and call
|
|
102
|
+
`initStrada()` at module scope. Never initialize in per-request middleware.
|
|
103
|
+
See the Cloudflare Workers section of `website/src/sdk/README.mdx`.
|
|
104
|
+
- **Email and user id belong on errors, logs, and product events.** That is how
|
|
105
|
+
you open an issue and see who hit it. Use `strataBetterAuth()` (default
|
|
106
|
+
`includeUserDetails: true`), `identifyUser()`, or `tags` / event properties
|
|
107
|
+
with `user.id` and `user.email`. Do not strip them.
|
|
108
|
+
- Never attach API keys, prompts, or raw user content (the text they typed)
|
|
109
|
+
to tags or events. Use stable route, handler, service, and environment
|
|
110
|
+
identifiers for those.
|
|
101
111
|
|
|
102
112
|
## Terminal UI
|
|
103
113
|
|
|
@@ -233,4 +243,33 @@ FROM otel_traces
|
|
|
233
243
|
WHERE Duration > 1000000000
|
|
234
244
|
ORDER BY Duration DESC
|
|
235
245
|
LIMIT 20
|
|
246
|
+
|
|
247
|
+
-- HTTP route performance: top routes by RPS and latency
|
|
248
|
+
-- ParentSpanId = '' filters to root spans (one per HTTP request)
|
|
249
|
+
-- Duration is nanoseconds, divide by 1e6 for milliseconds
|
|
250
|
+
SELECT
|
|
251
|
+
SpanName AS path,
|
|
252
|
+
count() AS total_requests,
|
|
253
|
+
round(count() / 3600, 2) AS rps,
|
|
254
|
+
round(avg(Duration) / 1e6, 1) AS avg_ms,
|
|
255
|
+
round(quantile(0.95)(Duration) / 1e6, 1) AS p95_ms,
|
|
256
|
+
round(max(Duration) / 1e6, 1) AS max_ms
|
|
257
|
+
FROM otel_traces
|
|
258
|
+
WHERE Timestamp >= now() - INTERVAL 1 HOUR
|
|
259
|
+
AND ParentSpanId = ''
|
|
260
|
+
GROUP BY path
|
|
261
|
+
ORDER BY total_requests DESC
|
|
262
|
+
LIMIT 30
|
|
263
|
+
|
|
264
|
+
-- Per-minute traffic pattern for a specific route
|
|
265
|
+
SELECT
|
|
266
|
+
toStartOfMinute(Timestamp) AS minute,
|
|
267
|
+
count() AS requests
|
|
268
|
+
FROM otel_traces
|
|
269
|
+
WHERE Timestamp >= now() - INTERVAL 1 HOUR
|
|
270
|
+
AND ParentSpanId = ''
|
|
271
|
+
AND SpanName = 'POST /api/my-route'
|
|
272
|
+
GROUP BY minute
|
|
273
|
+
ORDER BY minute DESC
|
|
274
|
+
LIMIT 60
|
|
236
275
|
```
|
package/skills/zele/SKILL.md
CHANGED
|
@@ -60,3 +60,22 @@ The README and `zele --help` output are the source of truth for commands, option
|
|
|
60
60
|
zele mail watch --filter "is:unread from:bob@example.com subject:Re:Question" --timeout 600
|
|
61
61
|
```
|
|
62
62
|
If the matched email wasn't the expected one, call `zele mail watch` again with a more specific filter. Exit code 0 means a match was found, exit code 1 means timeout.
|
|
63
|
+
8. **Check reply recipients before sending** with `zele mail reply <thread-id> --dry-run`. Recipients are inferred from the thread, not from the sender of the last message, so a thread whose last message you sent still replies to the other person. If a reply would only reach the account's own address, zele refuses to send:
|
|
64
|
+
```bash
|
|
65
|
+
# see to / cc / subject / In-Reply-To without sending
|
|
66
|
+
zele mail reply <thread-id> --dry-run
|
|
67
|
+
|
|
68
|
+
# override the inferred recipient
|
|
69
|
+
zele mail reply <thread-id> --to paul@acme.com --body "..."
|
|
70
|
+
|
|
71
|
+
# deliberately reply to yourself (normally refused)
|
|
72
|
+
zele mail reply <thread-id> --allow-self --body "..."
|
|
73
|
+
```
|
|
74
|
+
Never work around a `SelfRecipientError` by switching to `zele mail send`; pass `--to` to `zele mail reply` instead, so threading headers stay correct.
|
|
75
|
+
9. **Read a thread before replying.** `zele mail reply` and `zele mail send --thread-id` fail with `UnseenLatestError` unless `zele mail read <thread-id>` already showed the live last message. `mail watch` and `mail list` do **not** count. If a new reply arrives after you read, read again before sending:
|
|
76
|
+
```bash
|
|
77
|
+
zele mail read <thread-id>
|
|
78
|
+
zele mail reply <thread-id> --body "..."
|
|
79
|
+
```
|
|
80
|
+
Never pass `--force` to skip this unless the user explicitly asks to send without reading.
|
|
81
|
+
10. **Send into an existing thread** with `zele mail send --thread-id <thread-id>` when you need full control of recipients and subject but still want correct `In-Reply-To`/`References` headers. Recipients and subject are inferred from the thread when omitted. The same read-before-reply rule applies.
|