Commit 04b709d
feat: declarative multi-host platform + OpenCode, Slate, Cursor, OpenClaw (v0.15.5.0) (#793)
* test: add golden-file baselines for host config refactor
Snapshot generated SKILL.md output for ship skill across all 3 existing
hosts (Claude, Codex, Factory). These baselines verify the config-driven
refactor produces identical output to the current hardcoded system.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add HostConfig interface and validator for declarative host system
New scripts/host-config.ts defines the typed HostConfig interface that
captures all per-host variation: paths, frontmatter rules, path/tool
rewrites, suppressed resolvers, runtime root symlinks, install strategy,
and behavioral config (co-author trailer, learnings mode, boundary
instruction). Includes validateHostConfig() and validateAllConfigs() with
regex-based security validation and cross-config uniqueness checks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add typed host configs for Claude, Codex, Factory, and Kiro
Extract all hardcoded host-specific values from gen-skill-docs.ts,
types.ts, preamble.ts, review.ts, and setup into typed HostConfig
objects. Each host is a single file in hosts/ with its paths, frontmatter
rules, path/tool rewrites, runtime root manifest, and install behavior.
hosts/index.ts exports all configs, derives the Host type, and provides
resolveHostArg() for CLI alias handling (e.g., 'agents' -> 'codex',
'droid' -> 'factory').
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: derive Host type and HOST_PATHS from host configs
types.ts no longer hardcodes host names or paths. The Host type is
derived from ALL_HOST_CONFIGS in hosts/index.ts, and HOST_PATHS is
built dynamically from each config's globalRoot/localSkillRoot/usesEnvVars.
Adding a new host to hosts/index.ts automatically extends the type system.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: gen-skill-docs.ts consumes typed host configs
Replace hardcoded EXTERNAL_HOST_CONFIG, transformFrontmatter host
branches, path/tool rewrite if-chains, and ALL_HOSTS array with
config-driven lookups from hosts/*.ts.
- Host detection uses resolveHostArg() (handles aliases like agents/droid)
- transformFrontmatter uses config's allowlist/denylist mode, extraFields,
conditionalFields, renameFields, and descriptionLimitBehavior
- Path rewrites use config's pathRewrites array (replaceAll, order matters)
- Tool rewrites use config's toolRewrites object
- Skill skipping uses config's generation.skipSkills
- ALL_HOSTS derived from ALL_HOST_NAMES
- Token budget display regex derived from host configs
Golden-file comparison: all 3 hosts produce IDENTICAL output to baselines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: preamble, co-author trailer, and resolver suppression use host configs
- preamble.ts: hostConfigDir derived from config.globalRoot instead of
hardcoded Record
- utility.ts: generateCoAuthorTrailer reads from config.coAuthorTrailer
instead of host switch statement
- gen-skill-docs.ts: suppressedResolvers from config skip resolver
execution at placeholder replacement time (belt+suspenders with
existing ctx.host checks in individual resolvers)
Golden-file comparison: all 3 hosts produce IDENTICAL output to baselines.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: setup tooling uses config-driven host detection
- host-config-export.ts: new CLI that exposes host configs to bash
(list, get, detect, validate, symlinks commands)
- bin/gstack-platform-detect: reads host configs instead of hardcoded
binary/path mapping
- scripts/skill-check.ts: iterates host configs for skill validation
and freshness checks instead of separate Codex/Factory blocks
- lib/worktree.ts: iterates host configs for directory copy instead
of hardcoded .agents
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add OpenCode, Slate, and Cursor host configs
Three new hosts added to the declarative config system. Each is a typed
HostConfig object with paths, frontmatter rules, and path rewrites.
All generate valid SKILL.md output with zero .claude/skills path leakage.
- hosts/opencode.ts: OpenCode (opencode.ai), skills at ~/.config/opencode/
- hosts/slate.ts: Slate (Random Labs), skills at ~/.slate/
- hosts/cursor.ts: Cursor, skills at ~/.cursor/
- .gitignore: add .kiro/, .opencode/, .slate/, .cursor/, .openclaw/
Zero code changes needed — just config files + re-export in index.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add OpenClaw host config with adapter for tool mapping
OpenClaw gets a hybrid approach: typed config for paths/frontmatter/
detection + a post-processing adapter for semantic tool rewrites.
Config handles: path rewrites, frontmatter (name+description+version),
CLAUDE.md→AGENTS.md, tool name rewrites (Bash→exec, Read→read, etc.),
suppressed resolvers, SOUL.md via staticFiles.
Adapter handles: AskUserQuestion→prose, Agent→sessions_spawn, $B→exec $B.
Zero .claude/skills path leakage. Zero hardcoded tool references remaining.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: contributor add-host skill + fix version sync
- contrib/add-host/SKILL.md.tmpl: contributor-only skill that guides
new host config creation. Lives in contrib/, excluded from user installs.
- package.json: sync version with VERSION file (0.15.2.1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add parameterized host smoke tests for all hosts
35 new tests covering all 7 external hosts (Codex, Factory, Kiro,
OpenCode, Slate, Cursor, OpenClaw). Each host gets 4-5 tests:
- output exists on disk with SKILL.md files
- no .claude/skills path leakage in non-root skills
- frontmatter has name + description fields
- --dry-run freshness check passes
- /codex skill excluded (for hosts with skipSkills: ['codex'])
Tests are parameterized over ALL_HOST_CONFIGS so adding a new host
automatically gets smoke-tested with zero new test code.
Also updates --host all test to verify all registered hosts generate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: 100% coverage for host config system
71 new tests in test/host-config.test.ts covering:
- hosts/index.ts: ALL_HOST_CONFIGS, getHostConfig, resolveHostArg (aliases),
getExternalHosts, uniqueness checks
- host-config.ts validateHostConfig: name regex, displayName, cliCommand,
cliAliases, globalRoot, localSkillRoot, hostSubdir, frontmatter.mode,
linkingStrategy, shell injection attempts, paths with $ and ~
- host-config.ts validateAllConfigs: duplicate name/hostSubdir/globalRoot
detection, error prefix format, real configs pass
- HOST_PATHS derivation: env vars for external hosts, literal paths for
Claude, localSkillRoot matches config, every host has entry
- host-config-export.ts CLI: list, get (string/boolean/array), detect,
validate, symlinks, error cases (missing args, unknown field/host)
- Golden-file regression: claude/codex/factory ship SKILL.md vs baselines
- Individual host config correctness: prefixable, linkingStrategy,
usesEnvVars, description limits, metadata, sidecar, tool rewrites,
conditional fields, suppressed resolvers, boundary instruction,
co-author trailers, skip rules, path rewrites, runtime root assets
Combined with the 35 parameterized smoke tests from gen-skill-docs.test.ts,
total new test coverage for multi-host: 106 tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: update golden baselines and sync version after merge from main
Golden files refreshed to match post-merge generated output. package.json
version synced to VERSION file (0.15.4.0).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: bump version and changelog (v0.15.5.0)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: sidebar E2E tests now self-contained and passing
- sidebar-url-accuracy: fix stale assertion that expected extensionUrl
in prompt text (prompt format changed, URL is now in pageUrl field)
- sidebar-css-interaction: simplify task from multi-step HN comment
navigation to single-page example.com style injection (faster, more
reliable, still exercises goto + style + completion flow)
- Update golden baselines after merge from main
All 3 sidebar tests now pass: 3/3, 0 fail, ~36s total.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add ADDING_A_HOST.md guide + update docs for multi-host system
- docs/ADDING_A_HOST.md: step-by-step guide for adding a new host
(create config, register, gitignore, generate, test). Covers the
full HostConfig interface, adapter pattern, and validation.
- CONTRIBUTING.md: replace stale "Dual-host development" section with
"Multi-host development" covering all 8 hosts and linking to the guide.
- README.md: consolidate Codex/Factory install sections into one
"Other AI Agents" section listing all supported hosts with auto-detect.
- CLAUDE.md: add hosts/, host-config.ts, host-adapters/, contrib/ to
project structure tree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: README per-host install instructions for all 8 agents
Each supported agent now has its own copy-paste install block with
the exact command and where skills end up on disk. Includes: auto-detect,
Codex, OpenCode, Cursor, Factory, OpenClaw, Slate, and Kiro.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 4478514 commit 04b709d
File tree
34 files changed
+8529
-274
lines changed- bin
- contrib/add-host
- docs
- hosts
- lib
- scripts
- host-adapters
- resolvers
- test
- fixtures/golden
34 files changed
+8529
-274
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
11 | 16 | | |
12 | 17 | | |
13 | 18 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
3 | 29 | | |
4 | 30 | | |
5 | 31 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
66 | 71 | | |
67 | | - | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
68 | 76 | | |
69 | 77 | | |
70 | 78 | | |
| |||
108 | 116 | | |
109 | 117 | | |
110 | 118 | | |
| 119 | + | |
| 120 | + | |
111 | 121 | | |
112 | 122 | | |
113 | 123 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
216 | 216 | | |
217 | 217 | | |
218 | 218 | | |
219 | | - | |
220 | | - | |
221 | | - | |
| 219 | + | |
| 220 | + | |
222 | 221 | | |
223 | | - | |
| 222 | + | |
224 | 223 | | |
225 | 224 | | |
226 | 225 | | |
| |||
231 | 230 | | |
232 | 231 | | |
233 | 232 | | |
234 | | - | |
| 233 | + | |
235 | 234 | | |
236 | | - | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
237 | 238 | | |
238 | | - | |
| 239 | + | |
239 | 240 | | |
240 | | - | |
241 | | - | |
242 | | - | |
| 241 | + | |
243 | 242 | | |
244 | | - | |
245 | | - | |
246 | | - | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
247 | 249 | | |
248 | | - | |
| 250 | + | |
249 | 251 | | |
250 | 252 | | |
251 | 253 | | |
252 | 254 | | |
253 | 255 | | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
260 | | - | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
261 | 266 | | |
262 | | - | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
263 | 270 | | |
264 | 271 | | |
265 | | - | |
| 272 | + | |
266 | 273 | | |
267 | 274 | | |
268 | | - | |
269 | | - | |
270 | | - | |
| 275 | + | |
| 276 | + | |
271 | 277 | | |
272 | | - | |
| 278 | + | |
273 | 279 | | |
274 | 280 | | |
275 | 281 | | |
276 | | - | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
277 | 291 | | |
278 | | - | |
| 292 | + | |
279 | 293 | | |
280 | 294 | | |
281 | 295 | | |
282 | | - | |
| 296 | + | |
283 | 297 | | |
284 | | - | |
285 | | - | |
286 | | - | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
287 | 301 | | |
288 | 302 | | |
289 | 303 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | | - | |
| 62 | + | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
65 | 67 | | |
66 | | - | |
| 68 | + | |
67 | 69 | | |
68 | 70 | | |
69 | | - | |
70 | | - | |
| 71 | + | |
| 72 | + | |
71 | 73 | | |
72 | 74 | | |
73 | | - | |
74 | | - | |
75 | | - | |
| 75 | + | |
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
83 | | - | |
84 | | - | |
| 82 | + | |
| 83 | + | |
85 | 84 | | |
86 | | - | |
| 85 | + | |
87 | 86 | | |
88 | 87 | | |
89 | 88 | | |
90 | | - | |
| 89 | + | |
91 | 90 | | |
92 | 91 | | |
93 | | - | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
94 | 100 | | |
95 | | - | |
| 101 | + | |
96 | 102 | | |
97 | | - | |
| 103 | + | |
98 | 104 | | |
99 | 105 | | |
100 | 106 | | |
101 | 107 | | |
102 | 108 | | |
103 | 109 | | |
104 | | - | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
105 | 135 | | |
106 | 136 | | |
107 | 137 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
5 | 10 | | |
6 | 11 | | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
19 | 26 | | |
20 | 27 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
0 commit comments