kimaki 0.20.1 → 0.22.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 +6 -4
- package/dist/cli-commands/project.js +148 -24
- package/dist/cli-commands/send.js +48 -3
- package/dist/cli-runner.js +86 -7
- package/dist/cli-runner.test.js +28 -1
- package/dist/commands/btw.js +7 -3
- package/dist/commands/new-worktree.js +14 -2
- package/dist/commands/session.js +66 -13
- package/dist/commands/tasks.js +104 -19
- package/dist/commands/user-command.js +3 -2
- package/dist/database.js +14 -0
- package/dist/db.js +1 -0
- package/dist/discord-bot.js +65 -9
- package/dist/interaction-handler.js +6 -15
- package/dist/message-preprocessing.js +9 -2
- package/dist/queue-advanced-e2e-setup.js +22 -0
- package/dist/queue-delete-message.e2e.test.js +75 -0
- package/dist/schema.js +3 -0
- package/dist/session-handler/thread-runtime-state.js +9 -0
- package/dist/session-handler/thread-session-runtime.js +49 -1
- package/dist/system-message.js +50 -63
- package/dist/system-message.test.js +65 -61
- package/dist/task-runner.js +18 -3
- package/dist/task-schedule.js +4 -0
- package/dist/thread-message-queue.e2e.test.js +4 -4
- package/dist/voice-message.e2e.test.js +1 -1
- package/dist/worktree-lifecycle.e2e.test.js +70 -1
- package/dist/worktrees.js +63 -0
- package/package.json +11 -4
- package/skills/egaki/SKILL.md +26 -80
- package/skills/goke/SKILL.md +27 -20
- package/skills/holocron/SKILL.md +72 -8
- package/skills/new-skill/SKILL.md +87 -0
- package/skills/playwriter/SKILL.md +4 -4
- package/skills/spiceflow/SKILL.md +2 -0
- package/src/agent-model.e2e.test.ts +10 -4
- package/src/cli-commands/project.ts +183 -26
- package/src/cli-commands/send.ts +64 -5
- package/src/cli-runner.test.ts +39 -1
- package/src/cli-runner.ts +115 -6
- package/src/commands/btw.ts +9 -2
- package/src/commands/new-worktree.ts +14 -1
- package/src/commands/session.ts +79 -17
- package/src/commands/tasks.ts +119 -19
- package/src/commands/user-command.ts +3 -2
- package/src/database.ts +24 -0
- package/src/db.ts +1 -0
- package/src/discord-bot.ts +80 -8
- package/src/interaction-handler.ts +7 -19
- package/src/message-preprocessing.ts +11 -2
- package/src/queue-advanced-e2e-setup.ts +23 -0
- package/src/queue-delete-message.e2e.test.ts +102 -0
- package/src/schema.sql +1 -0
- package/src/schema.ts +3 -0
- package/src/session-handler/thread-runtime-state.ts +19 -0
- package/src/session-handler/thread-session-runtime.ts +75 -0
- package/src/system-message.test.ts +73 -61
- package/src/system-message.ts +63 -62
- package/src/task-runner.ts +34 -3
- package/src/task-schedule.ts +6 -0
- package/src/thread-message-queue.e2e.test.ts +4 -4
- package/src/voice-message.e2e.test.ts +1 -1
- package/src/worktree-lifecycle.e2e.test.ts +88 -1
- package/src/worktrees.ts +74 -0
package/skills/egaki/SKILL.md
CHANGED
|
@@ -1,43 +1,45 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: egaki
|
|
3
|
+
repo: remorses/egaki
|
|
3
4
|
description: >
|
|
4
|
-
AI image and video generation CLI
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
AI image and video generation CLI and MDX-to-video framework built on Remotion.
|
|
6
|
+
Use this skill to install egaki, configure auth, generate images/videos, create
|
|
7
|
+
MDX video projects with animation primitives (Opacity, Scale, TranslateX, Blur),
|
|
8
|
+
easing presets (EASE, springFromDuration, dspring, cubicBezier), LayoutTransition,
|
|
9
|
+
captions, voice cloning, TTS, Server components, and media components. ALWAYS load
|
|
10
|
+
this skill when the user mentions egaki, runs egaki commands, edits egaki MDX video
|
|
11
|
+
files, or works in a project with an egaki vite plugin.
|
|
7
12
|
---
|
|
8
13
|
|
|
9
14
|
# egaki
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
Use this for text-to-image, image editing, mask-based edits, text-to-video,
|
|
13
|
-
image-to-video, and model discovery.
|
|
14
|
-
|
|
15
|
-
## Install
|
|
16
|
+
Every time you work with egaki, you MUST fetch the latest README:
|
|
16
17
|
|
|
17
18
|
```bash
|
|
18
|
-
|
|
19
|
+
curl -s https://raw.githubusercontent.com/remorses/egaki/main/README.md # NEVER pipe to head/tail, read the full output
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
The README is the single source of truth for all user-facing docs: CLI usage,
|
|
23
|
+
MDX video syntax, animation primitives, easing presets, LayoutTransition,
|
|
24
|
+
captions, voice cloning, media components, CSS rules, and project setup.
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
## Always check help first
|
|
24
27
|
|
|
25
28
|
```bash
|
|
26
|
-
egaki --help
|
|
29
|
+
egaki --help # NEVER pipe to head/tail, read the full output
|
|
27
30
|
```
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
For subcommand details: `egaki <command> --help` (e.g. `egaki image --help`, `egaki video --help`, `egaki login --help`)
|
|
32
|
+
For subcommand details: `egaki <command> --help` (e.g. `egaki image --help`,
|
|
33
|
+
`egaki video --help`, `egaki login --help`)
|
|
32
34
|
|
|
33
35
|
## Auth options
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
Two authentication modes:
|
|
36
38
|
|
|
37
|
-
1. Egaki subscription key (recommended
|
|
38
|
-
2. Provider API keys (Google, OpenAI, Fal,
|
|
39
|
+
1. **Egaki subscription key** (recommended, all models, one key)
|
|
40
|
+
2. **Provider API keys** (Google, OpenAI, Fal, xAI, etc.) via `egaki login`
|
|
39
41
|
|
|
40
|
-
If using Egaki subscription, set it up
|
|
42
|
+
If using Egaki subscription, set it up with `egaki subscribe`, then store
|
|
41
43
|
the key with `egaki login --provider egaki --key egaki_...`.
|
|
42
44
|
|
|
43
45
|
## Login behavior for remote agents
|
|
@@ -49,78 +51,22 @@ to the user so they can complete auth interactively.
|
|
|
49
51
|
|
|
50
52
|
The `--model` / `-m` flag is **optional** on both `egaki image` and `egaki video`.
|
|
51
53
|
|
|
52
|
-
- **Interactive (TTY):** omitting `--model` shows a picker
|
|
53
|
-
- **Non-interactive (piped/scripted):**
|
|
54
|
+
- **Interactive (TTY):** omitting `--model` shows a picker
|
|
55
|
+
- **Non-interactive (piped/scripted):** uses a sensible default
|
|
54
56
|
|
|
55
57
|
Agents should always pass `-m` explicitly to avoid the interactive picker.
|
|
56
58
|
|
|
57
59
|
### Preferred image models
|
|
58
60
|
|
|
59
|
-
When the user does not specify a model, prefer these in order:
|
|
60
|
-
|
|
61
61
|
1. **`gpt-image-1`** (or `gpt-image-2` / `chatgpt-image-latest` if available)
|
|
62
62
|
2. **`grok-imagine-image`** (xAI Grok)
|
|
63
63
|
3. **`nano-banana-pro-preview`**
|
|
64
64
|
|
|
65
|
-
Always try the first available model. Fall back to the next if auth is missing
|
|
66
|
-
for the preferred one.
|
|
67
|
-
|
|
68
65
|
### Preferred video models
|
|
69
66
|
|
|
70
|
-
When the user does not specify a video model, prefer:
|
|
71
|
-
|
|
72
67
|
1. **`grok-imagine-video-1.5`** (xAI Grok)
|
|
73
68
|
|
|
74
|
-
##
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
# configure key interactively
|
|
78
|
-
egaki login
|
|
79
|
-
|
|
80
|
-
# show login status
|
|
81
|
-
egaki login --show
|
|
82
|
-
|
|
83
|
-
# subscribe to Egaki for all supported models
|
|
84
|
-
egaki subscribe
|
|
85
|
-
|
|
86
|
-
# check subscription usage
|
|
87
|
-
egaki usage
|
|
88
|
-
|
|
89
|
-
# generate an image (interactive model picker if TTY)
|
|
90
|
-
egaki image "a watercolor fox reading a map" -o fox.png
|
|
91
|
-
|
|
92
|
-
# select a model explicitly
|
|
93
|
-
egaki image "isometric floating city, soft colors" -m imagen-4.0-generate-001 -o city.png
|
|
94
|
-
|
|
95
|
-
# edit an existing image (local file or URL)
|
|
96
|
-
egaki image "add a red scarf and make it winter" --input portrait.jpg -o portrait-winter.png
|
|
97
|
-
egaki image "turn this into a manga panel" --input https://example.com/photo.jpg -o manga.png
|
|
98
|
-
|
|
99
|
-
# inpainting with a mask
|
|
100
|
-
egaki image "replace the sky with a dramatic sunset" --input scene.png --mask mask.png -o scene-sunset.png
|
|
101
|
-
|
|
102
|
-
# generate a video — use a 5 minute timeout, video generation is slow
|
|
103
|
-
egaki video "a paper boat drifting on a calm lake at sunrise" -o boat.mp4
|
|
104
|
-
|
|
105
|
-
# generate a video with a specific model
|
|
106
|
-
egaki video "timelapse of a stormy sea, cinematic" -m google/veo-3.1-fast-generate-001 --duration 6 -o storm.mp4
|
|
107
|
-
|
|
108
|
-
# cheap video model
|
|
109
|
-
egaki video "a cat walking on a rooftop at night" -m klingai/kling-v2.5-turbo-t2v --duration 5 -o cat.mp4
|
|
110
|
-
|
|
111
|
-
# image-to-video (model must support i2v)
|
|
112
|
-
egaki video "slowly animate the clouds" --input photo.jpg -m klingai/kling-v2.6-i2v -o animated.mp4
|
|
113
|
-
|
|
114
|
-
# discover all models (image + video)
|
|
115
|
-
egaki models
|
|
116
|
-
|
|
117
|
-
# filter by type
|
|
118
|
-
egaki models --type video
|
|
119
|
-
egaki models --type image
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Video generation note for agents
|
|
69
|
+
## Video generation note
|
|
123
70
|
|
|
124
|
-
Video generation can be very slow
|
|
125
|
-
|
|
126
|
-
from automation or agent workflows.
|
|
71
|
+
Video generation can be very slow (1-3 minutes per request). Always use a
|
|
72
|
+
command timeout of **at least 5 minutes** from automation or agent workflows.
|
package/skills/goke/SKILL.md
CHANGED
|
@@ -85,34 +85,39 @@ Supported agents: `cursor`, `claude`, `devin`, `replit`, `gemini`, `codex`, `aug
|
|
|
85
85
|
|
|
86
86
|
## Long-Running Interactive Commands
|
|
87
87
|
|
|
88
|
-
Commands that start a browser/device login flow
|
|
88
|
+
Commands that start a browser/device login flow need to work for both interactive users and AI agents. goke's built-in **daemon** pattern (`ctx.daemon`) handles this: the command forks itself into a background process that waits for browser approval, while the foreground returns immediately so agents aren't blocked.
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
Use `isAgent` to branch between agent mode (start daemon, return immediately) and interactive mode (block until login completes). Do not fail in non-TTY shells; use the daemon instead.
|
|
91
91
|
|
|
92
92
|
```ts
|
|
93
|
-
import
|
|
94
|
-
import { goke } from 'goke'
|
|
95
|
-
|
|
96
|
-
cli.command('login', 'Authenticate with browser login').action((options, { console, process }) => {
|
|
97
|
-
if (!process.stdout.isTTY) {
|
|
98
|
-
console.error(dedent`
|
|
99
|
-
mycli login needs an interactive terminal and must stay alive while you approve the browser login.
|
|
100
|
-
|
|
101
|
-
Run it in a background terminal session like tuistory or tmux, then wait for the URL/code:
|
|
93
|
+
import { goke, isAgent, openInBrowser } from 'goke'
|
|
102
94
|
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
cli
|
|
96
|
+
.command('login', 'Authenticate with browser login')
|
|
97
|
+
.action(async (options, ctx) => {
|
|
98
|
+
if (ctx.daemon.isDaemon) {
|
|
99
|
+
// ── DAEMON: run the long-running flow in background ──
|
|
100
|
+
const result = await startOAuthFlow({ /* ... */ })
|
|
101
|
+
if (result.success) saveAuth(result)
|
|
102
|
+
return // daemon exits, PID file is cleaned up
|
|
103
|
+
}
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
// ── CLIENT: decide foreground vs background ──
|
|
106
|
+
if (isAgent) {
|
|
107
|
+
// Agent mode: start daemon and return immediately
|
|
108
|
+
await ctx.daemon.start({ timeoutMs: 10 * 60 * 1000 })
|
|
109
|
+
ctx.console.log('Login running in background.')
|
|
110
|
+
ctx.console.log('After approving in browser, verify with: mycli me')
|
|
111
|
+
return
|
|
112
|
+
}
|
|
110
113
|
|
|
111
|
-
|
|
112
|
-
})
|
|
114
|
+
// Interactive mode: attach to daemon, see all its logs and errors in real time
|
|
115
|
+
await ctx.daemon.start({ attach: true, timeoutMs: 10 * 60 * 1000 })
|
|
116
|
+
ctx.console.log('Login successful!')
|
|
117
|
+
})
|
|
113
118
|
```
|
|
114
119
|
|
|
115
|
-
|
|
120
|
+
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.
|
|
116
121
|
|
|
117
122
|
## Shell Completions
|
|
118
123
|
|
|
@@ -398,6 +403,8 @@ cli
|
|
|
398
403
|
|
|
399
404
|
CLIs that talk to a remote server must support multiple server URLs so users can self-host, use a preview/staging environment, or point to localhost during development. Auth tokens and other per-server state live in a JSON config file keyed by API URL.
|
|
400
405
|
|
|
406
|
+
**Never log config file paths** (like `~/.myapp/config.json` or `~/.myapp/auth.json`) in CLI output. Agents read CLI output and will try to `cat` or parse these files directly, bypassing the CLI's own commands. Log success/failure messages without revealing internal storage paths.
|
|
407
|
+
|
|
401
408
|
### Config file location
|
|
402
409
|
|
|
403
410
|
Store config at `~/.cliname/config.json`. The directory is named after the CLI binary. Use `os.homedir()` to resolve `~`.
|
package/skills/holocron/SKILL.md
CHANGED
|
@@ -44,6 +44,7 @@ When the user asks about a specific workflow, fetch the matching page directly:
|
|
|
44
44
|
- **Holocron deploy**: https://holocron.so/docs/deploy/holocron.md
|
|
45
45
|
- **AI assistant docs**: https://holocron.so/docs/ai/assistant.md
|
|
46
46
|
- **Bleed**: https://holocron.so/docs/customize/bleed.md
|
|
47
|
+
- **Layout and page modes**: https://holocron.so/docs/customize/layout.md
|
|
47
48
|
|
|
48
49
|
```bash
|
|
49
50
|
curl -fsSL https://holocron.so/docs/quickstart.md
|
|
@@ -55,7 +56,7 @@ curl -fsSL https://holocron.so/docs/organize/docs-json.md
|
|
|
55
56
|
Use the CLI to create a new docs site with a working template:
|
|
56
57
|
|
|
57
58
|
```bash
|
|
58
|
-
npx -y @holocron.so/cli create --name "My Docs" my-docs --skip-auth
|
|
59
|
+
npx -y "@holocron.so/cli" create --name "My Docs" my-docs --skip-auth
|
|
59
60
|
```
|
|
60
61
|
|
|
61
62
|
The `--skip-auth` flag skips cloud setup & AI chat setup (suitable for agents and local-only
|
|
@@ -357,6 +358,22 @@ Sidebar: `Home`
|
|
|
357
358
|
- **Every `title` MUST be unique across the site.**
|
|
358
359
|
- **`index.mdx` MUST use `sidebarTitle: Home`** (or `Overview`) and a descriptive `title`.
|
|
359
360
|
|
|
361
|
+
## Page modes — hiding sidebars
|
|
362
|
+
|
|
363
|
+
Set **`mode`** in frontmatter to hide sidebars. Use for landing pages, tool pages, or pages that should not show left nav or AI chat. See https://holocron.so/docs/customize/layout.md for details.
|
|
364
|
+
|
|
365
|
+
- **`center`** — hides the left nav, centers content. Right aside still works.
|
|
366
|
+
- **`custom`** — hides both sidebars and the editorial grid. Only navbar, tab bar, and footer remain. See `example/src/landing.mdx` for a full example.
|
|
367
|
+
|
|
368
|
+
In both modes the content can feel too wide. Use **`maxWidth`** to constrain it:
|
|
369
|
+
|
|
370
|
+
```yaml
|
|
371
|
+
---
|
|
372
|
+
mode: "custom"
|
|
373
|
+
maxWidth: 700
|
|
374
|
+
---
|
|
375
|
+
```
|
|
376
|
+
|
|
360
377
|
## Custom entry (mounting docs inside a Spiceflow app)
|
|
361
378
|
|
|
362
379
|
When the site mounts Holocron inside an existing **Spiceflow** app (the `entry`
|
|
@@ -402,6 +419,23 @@ the **`knownPaths`** field in `docs.json` to tell Holocron these paths are valid
|
|
|
402
419
|
Wildcards only work as a trailing `/*` suffix. Glob patterns like `/api/*/users`
|
|
403
420
|
are not supported.
|
|
404
421
|
|
|
422
|
+
## Vertical spacing inside wrappers
|
|
423
|
+
|
|
424
|
+
When wrapping MDX content in a `<div>` or custom component, add
|
|
425
|
+
`flex flex-col gap-(--prose-gap)` so children get correct vertical spacing.
|
|
426
|
+
Without it, elements collapse together. Add `no-bleed` too if the wrapper
|
|
427
|
+
contains images or code blocks that shouldn't escape its bounds.
|
|
428
|
+
|
|
429
|
+
```mdx
|
|
430
|
+
<div className='no-bleed flex flex-col gap-(--prose-gap)'>
|
|
431
|
+
|
|
432
|
+
First paragraph.
|
|
433
|
+
|
|
434
|
+
Second paragraph with correct spacing above.
|
|
435
|
+
|
|
436
|
+
</div>
|
|
437
|
+
```
|
|
438
|
+
|
|
405
439
|
## MDX container components
|
|
406
440
|
|
|
407
441
|
Always use multi-line form for container components like `Callout`, `Note`,
|
|
@@ -505,7 +539,7 @@ section above.
|
|
|
505
539
|
Run `--help` to see all available commands. Never truncate the output.
|
|
506
540
|
|
|
507
541
|
```bash
|
|
508
|
-
npx -y @holocron.so/cli --help
|
|
542
|
+
npx -y "@holocron.so/cli" --help
|
|
509
543
|
```
|
|
510
544
|
|
|
511
545
|
Key commands: `login`, `logout`, `whoami`, `deploy`, `projects list`,
|
|
@@ -514,19 +548,26 @@ Key commands: `login`, `logout`, `whoami`, `deploy`, `projects list`,
|
|
|
514
548
|
Before logging in, always check if the user is already authenticated:
|
|
515
549
|
|
|
516
550
|
```bash
|
|
517
|
-
npx -y @holocron.so/cli whoami
|
|
551
|
+
npx -y "@holocron.so/cli" whoami
|
|
518
552
|
```
|
|
519
553
|
|
|
520
554
|
If `whoami` succeeds and shows user, orgs, and projects, skip login. Only run
|
|
521
|
-
`npx -y @holocron.so/cli login` if `whoami` fails.
|
|
555
|
+
`npx -y "@holocron.so/cli" login` if `whoami` fails.
|
|
522
556
|
|
|
523
557
|
## Deploy
|
|
524
558
|
|
|
559
|
+
When the user asks to "deploy the site", they may mean deploying with their own
|
|
560
|
+
script and platform (Cloudflare Workers, a Node server, CI pipeline), not
|
|
561
|
+
`holocron deploy`. Check `package.json` scripts first: if there is a `deploy`,
|
|
562
|
+
`deployment`, or similar script (e.g. wrangler deploy), use that instead of the
|
|
563
|
+
Holocron CLI. Only use `holocron deploy` when the project has no own deploy
|
|
564
|
+
script or the user explicitly asks for holocron.so hosting.
|
|
565
|
+
|
|
525
566
|
`holocron deploy` builds the docs site and uploads it to holocron.so hosting.
|
|
526
567
|
It is the fastest way to publish without managing your own server.
|
|
527
568
|
|
|
528
569
|
```bash
|
|
529
|
-
npx -y @holocron.so/cli deploy
|
|
570
|
+
npx -y "@holocron.so/cli" deploy
|
|
530
571
|
```
|
|
531
572
|
|
|
532
573
|
The command runs the build, uploads only changed files, finalizes the deployment,
|
|
@@ -606,7 +647,7 @@ Use ASCII diagrams frequently in MDX pages. Always use the **`diagram`** languag
|
|
|
606
647
|
- Never exceed 94 characters per line.
|
|
607
648
|
- Prefer a **varied, organic layout**. Mix plain text labels, boxes for major components, and directional arrows.
|
|
608
649
|
- All connections must use **directional arrows**. Never use plain lines without an arrowhead.
|
|
609
|
-
- Verify alignment by running `npx -y @holocron.so/cli diagrams fix <file>` (see dedicated section below).
|
|
650
|
+
- Verify alignment by running `npx -y "@holocron.so/cli" diagrams fix <file>` (see dedicated section below).
|
|
610
651
|
|
|
611
652
|
````mdx
|
|
612
653
|
```diagram
|
|
@@ -632,7 +673,7 @@ docs.jsonc ───►│ Vite Plugin │──────► Build Output
|
|
|
632
673
|
LLMs cannot count characters reliably. Every time you create or edit a diagram in an MDX page, you **must** run the alignment fixer before committing. This is not optional.
|
|
633
674
|
|
|
634
675
|
```bash
|
|
635
|
-
npx -y @holocron.so/cli diagrams fix path/to/file.mdx
|
|
676
|
+
npx -y "@holocron.so/cli" diagrams fix path/to/file.mdx
|
|
636
677
|
```
|
|
637
678
|
|
|
638
679
|
The command:
|
|
@@ -664,6 +705,29 @@ Accordion apply `no-bleed` automatically to keep descendants inside their frame.
|
|
|
664
705
|
|
|
665
706
|
See https://holocron.so/docs/customize/bleed.md for the full reference.
|
|
666
707
|
|
|
708
|
+
## Custom CSS — prefer CSS variables over class selectors
|
|
709
|
+
|
|
710
|
+
When customizing the look of a Holocron site, **always use CSS variable overrides** in `:root` instead of targeting internal class names, DOM structure, or aria labels. Holocron exposes a set of documented CSS variables for colors, typography, spacing, code blocks, blockquotes, and sidebar navigation. These are stable across Holocron updates; internal markup is not.
|
|
711
|
+
|
|
712
|
+
```css
|
|
713
|
+
/* style.css */
|
|
714
|
+
:root {
|
|
715
|
+
--weight-heading: 700;
|
|
716
|
+
--code-block-background: var(--muted);
|
|
717
|
+
--code-block-border: 1px solid var(--border-subtle);
|
|
718
|
+
--sidebar-link-radius: var(--radius-sm);
|
|
719
|
+
--blockquote-border-color: var(--border-subtle);
|
|
720
|
+
}
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
Fetch the full list of available tokens:
|
|
724
|
+
|
|
725
|
+
```bash
|
|
726
|
+
curl -fsSL https://holocron.so/docs/customize/theme.md
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
If a user wants to customize something that has no CSS variable, **do not hack it with fragile selectors**. Instead, open an issue on the Holocron repo (https://github.com/remorses/holocron/issues) requesting a new CSS variable for that use case. Holocron actively adds new variables based on user needs. Internal selectors like `.slot-sidebar-left nav > div:first-child > a` or `figure[class~='group/code'] button[aria-label='Copy code']` will break on any refactor and should never be used.
|
|
730
|
+
|
|
667
731
|
## Agent rules
|
|
668
732
|
|
|
669
733
|
- **Always place MDX pages inside the Holocron `pagesDir`.** Before creating or
|
|
@@ -677,7 +741,7 @@ See https://holocron.so/docs/customize/bleed.md for the full reference.
|
|
|
677
741
|
- All ASCII diagrams in MDX pages must use the `diagram` language hint on the
|
|
678
742
|
code fence (` ```diagram `). This renders them with proper styling on the
|
|
679
743
|
website instead of plain monospace.
|
|
680
|
-
- After creating or editing any diagram, run `npx -y @holocron.so/cli diagrams fix <file>`
|
|
744
|
+
- After creating or editing any diagram, run `npx -y "@holocron.so/cli" diagrams fix <file>`
|
|
681
745
|
to auto-fix alignment. LLMs cannot count characters reliably.
|
|
682
746
|
- Never pipe curl or `--help` output through `head`, `tail`, or any truncation
|
|
683
747
|
command. Always read the full output.
|
|
@@ -62,6 +62,93 @@ Claude Code, Cursor, Windsurf, and others. Skills teach agents the
|
|
|
62
62
|
workflows, patterns, and tools specific to this project.
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
## Making a skill installable from a URL
|
|
66
|
+
|
|
67
|
+
Use this when the project does **not have a public GitHub repo** (private repos, closed-source SaaS products) or when you want the install command to use your own domain:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx skills add https://example.com
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The `skills` CLI treats any non-GitHub/GitLab HTTP(S) URL as a **well-known discovery endpoint** (RFC 8615). It fetches `/.well-known/agent-skills/index.json` and expects the v0.2.0 discovery schema:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json",
|
|
78
|
+
"skills": [
|
|
79
|
+
{
|
|
80
|
+
"name": "my-skill",
|
|
81
|
+
"type": "skill-md",
|
|
82
|
+
"description": "One-line description shown in the CLI skill picker.",
|
|
83
|
+
"url": "./my-skill/SKILL.md",
|
|
84
|
+
"digest": "sha256:<hex sha256 of the exact artifact bytes>"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Rules:
|
|
91
|
+
|
|
92
|
+
- **The digest must match the served bytes exactly.** The CLI downloads the artifact from `url` and verifies its sha256 before installing. Never hardcode the digest; compute it from the same string you serve.
|
|
93
|
+
- **`url` is resolved relative to index.json**, so `./my-skill/SKILL.md` works and survives domain changes. Absolute URLs also work.
|
|
94
|
+
- **`name` must be kebab-case** (`^[a-z0-9-]+$`, no leading/trailing/double dashes) and match the SKILL.md frontmatter name.
|
|
95
|
+
- `type: "skill-md"` serves a single markdown file. Use `type: "archive"` (zip or tar.gz with a root SKILL.md) only when the skill ships companion files.
|
|
96
|
+
- Keep the canonical SKILL.md in the repo (`skills/<name>/SKILL.md`) and serve those exact bytes, so the published skill can never drift from git.
|
|
97
|
+
|
|
98
|
+
Example with **spiceflow** on Cloudflare Workers: import the SKILL.md with vite `?raw` and compute the digest once per isolate with WebCrypto.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { Spiceflow } from 'spiceflow'
|
|
102
|
+
import skillMd from '../../skills/my-skill/SKILL.md?raw'
|
|
103
|
+
|
|
104
|
+
let digestPromise: Promise<string> | undefined
|
|
105
|
+
function getSkillDigest(): Promise<string> {
|
|
106
|
+
digestPromise ??= (async () => {
|
|
107
|
+
const bytes = new TextEncoder().encode(skillMd)
|
|
108
|
+
const hash = await crypto.subtle.digest('SHA-256', bytes)
|
|
109
|
+
const hex = Array.from(new Uint8Array(hash), (b) => b.toString(16).padStart(2, '0')).join('')
|
|
110
|
+
return `sha256:${hex}`
|
|
111
|
+
})()
|
|
112
|
+
return digestPromise
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const skillDiscoveryApp = new Spiceflow()
|
|
116
|
+
.route({
|
|
117
|
+
method: 'GET',
|
|
118
|
+
path: '/.well-known/agent-skills/index.json',
|
|
119
|
+
handler: async () =>
|
|
120
|
+
Response.json({
|
|
121
|
+
$schema: 'https://schemas.agentskills.io/discovery/0.2.0/schema.json',
|
|
122
|
+
skills: [
|
|
123
|
+
{
|
|
124
|
+
name: 'my-skill',
|
|
125
|
+
type: 'skill-md',
|
|
126
|
+
description: 'One-line description shown in the CLI skill picker.',
|
|
127
|
+
url: './my-skill/SKILL.md',
|
|
128
|
+
digest: await getSkillDigest(),
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
}),
|
|
132
|
+
})
|
|
133
|
+
.route({
|
|
134
|
+
method: 'GET',
|
|
135
|
+
path: '/.well-known/agent-skills/my-skill/SKILL.md',
|
|
136
|
+
handler: () =>
|
|
137
|
+
new Response(skillMd, {
|
|
138
|
+
headers: { 'content-type': 'text/markdown; charset=utf-8' },
|
|
139
|
+
}),
|
|
140
|
+
})
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Validate end-to-end against a local dev server before deploying:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npx skills add http://localhost:3000 --list
|
|
147
|
+
npx skills add http://localhost:3000 -y --copy
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
If the digest is wrong the CLI silently skips the skill, so an empty `--list` result usually means a digest mismatch.
|
|
151
|
+
|
|
65
152
|
## Frontmatter
|
|
66
153
|
|
|
67
154
|
Every SKILL.md starts with YAML frontmatter containing three required fields:
|
|
@@ -3,9 +3,9 @@ name: playwriter
|
|
|
3
3
|
description: Control the user own Chrome browser via Playwriter extension with Playwright code snippets in a stateful local js sandbox. Use this over other Playwright MCPs to automate the browser — it connects to the user's existing Chrome instead of launching a new one. Use this cli for navigating JS-heavy websites (Instagram, Twitter, cookie/login walls, lazy-loaded UIs) instead of webfetch/curl. ALWAYS load this skill before using any playwriter commands
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## Read Full Documentation (once per session)
|
|
7
7
|
|
|
8
|
-
**Before
|
|
8
|
+
**Before the first playwriter command in a session, run:**
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
playwriter skill # IMPORTANT! do not use | head here. read in full!
|
|
@@ -19,9 +19,9 @@ This outputs the complete documentation including:
|
|
|
19
19
|
- Best practices for slow pages and SPAs
|
|
20
20
|
- Context variables, utility functions, and more
|
|
21
21
|
|
|
22
|
-
**Do NOT skip this step.** The
|
|
22
|
+
**Do NOT skip this step.** The examples below will fail without understanding timeouts, selector rules, and pitfalls from the full docs. You only need to do this once per session; subsequent playwriter commands in the same session do not require re-reading.
|
|
23
23
|
|
|
24
|
-
**Read the ENTIRE output.** Do NOT pipe through `head`, `tail`, or any truncation command.
|
|
24
|
+
**Read the ENTIRE output.** Do NOT pipe through `head`, `tail`, or any truncation command. Critical rules are spread throughout the document, not just at the top.
|
|
25
25
|
|
|
26
26
|
## Minimal Example (after reading full docs)
|
|
27
27
|
|
|
@@ -11,6 +11,8 @@ Every time you work with spiceflow, you MUST fetch the **entire** README from th
|
|
|
11
11
|
curl -s https://raw.githubusercontent.com/remorses/spiceflow/main/README.md
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
If you are about to design any navigation, cookie, redirect, or refresh behavior and you have not fetched the README in this session, stop and fetch it first.
|
|
15
|
+
|
|
14
16
|
**Do NOT truncate, summarize, or skip sections.** Never pipe to `head`, `tail`, `sed`, or any command that cuts the output short. Never stop reading early because it "looks long enough." The README contains sections on routing, RSC, server actions, layouts, error handling, forms, federation, deployment, and more. Missing any of them means missing framework behavior you will get wrong.
|
|
15
17
|
|
|
16
18
|
After reading the full README, check if it references any docs/ files relevant to your task. If it does, fetch those too in full:
|
|
@@ -710,14 +710,17 @@ describe('agent model resolution', () => {
|
|
|
710
710
|
await db.delete(schema.channel_agents).where(orm.eq(schema.channel_agents.channel_id, TEXT_CHANNEL_ID))
|
|
711
711
|
await db.delete(schema.channel_models).where(orm.eq(schema.channel_models.channel_id, TEXT_CHANNEL_ID))
|
|
712
712
|
|
|
713
|
+
const existingThreadIds = new Set(
|
|
714
|
+
(await discord.channel(TEXT_CHANNEL_ID).getThreads()).map((thread) => thread.id),
|
|
715
|
+
)
|
|
713
716
|
await discord.channel(TEXT_CHANNEL_ID).user(TEST_USER_ID).sendMessage({
|
|
714
717
|
content: 'Reply with exactly: btw-source-msg',
|
|
715
718
|
})
|
|
716
719
|
|
|
717
720
|
const sourceThread = await discord.channel(TEXT_CHANNEL_ID).waitForThread({
|
|
718
721
|
timeout: 4_000,
|
|
719
|
-
predicate: (
|
|
720
|
-
return
|
|
722
|
+
predicate: (thread) => {
|
|
723
|
+
return !existingThreadIds.has(thread.id)
|
|
721
724
|
},
|
|
722
725
|
})
|
|
723
726
|
|
|
@@ -742,14 +745,17 @@ describe('agent model resolution', () => {
|
|
|
742
745
|
modelId: `${PROVIDER_NAME}/${CHANNEL_MODEL}`,
|
|
743
746
|
})
|
|
744
747
|
|
|
748
|
+
const existingForkThreadIds = new Set(
|
|
749
|
+
(await discord.channel(TEXT_CHANNEL_ID).getThreads()).map((thread) => thread.id),
|
|
750
|
+
)
|
|
745
751
|
await discord.thread(sourceThread.id).user(TEST_USER_ID).sendMessage({
|
|
746
752
|
content: 'Reply with exactly: btw-model-check. btw',
|
|
747
753
|
})
|
|
748
754
|
|
|
749
755
|
const forkedThread = await discord.channel(TEXT_CHANNEL_ID).waitForThread({
|
|
750
756
|
timeout: 4_000,
|
|
751
|
-
predicate: (
|
|
752
|
-
return
|
|
757
|
+
predicate: (thread) => {
|
|
758
|
+
return !existingForkThreadIds.has(thread.id)
|
|
753
759
|
},
|
|
754
760
|
})
|
|
755
761
|
|