From 8b5256342b7aead8fb04e3a7e4642df84506fcce Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 3 Apr 2026 16:33:54 -0700 Subject: [PATCH] feat: add OpenCode, Slate, and Cursor host configs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .gitignore | 5 +++++ hosts/cursor.ts | 46 ++++++++++++++++++++++++++++++++++++++++++++++ hosts/index.ts | 7 +++++-- hosts/opencode.ts | 46 ++++++++++++++++++++++++++++++++++++++++++++++ hosts/slate.ts | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 hosts/cursor.ts create mode 100644 hosts/opencode.ts create mode 100644 hosts/slate.ts diff --git a/.gitignore b/.gitignore index 71f7943d..e56390cc 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,11 @@ bin/gstack-global-discover .claude/skills/ .agents/ .factory/ +.kiro/ +.opencode/ +.slate/ +.cursor/ +.openclaw/ .context/ extension/.auth.json .gstack-worktrees/ diff --git a/hosts/cursor.ts b/hosts/cursor.ts new file mode 100644 index 00000000..5aa38407 --- /dev/null +++ b/hosts/cursor.ts @@ -0,0 +1,46 @@ +import type { HostConfig } from '../scripts/host-config'; + +const cursor: HostConfig = { + name: 'cursor', + displayName: 'Cursor', + cliCommand: 'cursor', + cliAliases: [], + + globalRoot: '.cursor/skills/gstack', + localSkillRoot: '.cursor/skills/gstack', + hostSubdir: '.cursor', + usesEnvVars: true, + + frontmatter: { + mode: 'allowlist', + keepFields: ['name', 'description'], + descriptionLimit: null, + }, + + generation: { + generateMetadata: false, + skipSkills: ['codex'], + }, + + pathRewrites: [ + { from: '~/.claude/skills/gstack', to: '~/.cursor/skills/gstack' }, + { from: '.claude/skills/gstack', to: '.cursor/skills/gstack' }, + { from: '.claude/skills', to: '.cursor/skills' }, + ], + + runtimeRoot: { + globalSymlinks: ['bin', 'browse/dist', 'browse/bin', 'gstack-upgrade', 'ETHOS.md'], + globalFiles: { + 'review': ['checklist.md', 'TODOS-format.md'], + }, + }, + + install: { + prefixable: false, + linkingStrategy: 'symlink-generated', + }, + + learningsMode: 'basic', +}; + +export default cursor; diff --git a/hosts/index.ts b/hosts/index.ts index 0cd8553e..1cd19cdf 100644 --- a/hosts/index.ts +++ b/hosts/index.ts @@ -10,9 +10,12 @@ import claude from './claude'; import codex from './codex'; import factory from './factory'; import kiro from './kiro'; +import opencode from './opencode'; +import slate from './slate'; +import cursor from './cursor'; /** All registered host configs. Add new hosts here. */ -export const ALL_HOST_CONFIGS: HostConfig[] = [claude, codex, factory, kiro]; +export const ALL_HOST_CONFIGS: HostConfig[] = [claude, codex, factory, kiro, opencode, slate, cursor]; /** Map from host name to config. */ export const HOST_CONFIG_MAP: Record = Object.fromEntries( @@ -59,4 +62,4 @@ export function getExternalHosts(): HostConfig[] { } // Re-export individual configs for direct import -export { claude, codex, factory, kiro }; +export { claude, codex, factory, kiro, opencode, slate, cursor }; diff --git a/hosts/opencode.ts b/hosts/opencode.ts new file mode 100644 index 00000000..de1dcbca --- /dev/null +++ b/hosts/opencode.ts @@ -0,0 +1,46 @@ +import type { HostConfig } from '../scripts/host-config'; + +const opencode: HostConfig = { + name: 'opencode', + displayName: 'OpenCode', + cliCommand: 'opencode', + cliAliases: [], + + globalRoot: '.config/opencode/skills/gstack', + localSkillRoot: '.opencode/skills/gstack', + hostSubdir: '.opencode', + usesEnvVars: true, + + frontmatter: { + mode: 'allowlist', + keepFields: ['name', 'description'], + descriptionLimit: null, + }, + + generation: { + generateMetadata: false, + skipSkills: ['codex'], + }, + + pathRewrites: [ + { from: '~/.claude/skills/gstack', to: '~/.config/opencode/skills/gstack' }, + { from: '.claude/skills/gstack', to: '.opencode/skills/gstack' }, + { from: '.claude/skills', to: '.opencode/skills' }, + ], + + runtimeRoot: { + globalSymlinks: ['bin', 'browse/dist', 'browse/bin', 'gstack-upgrade', 'ETHOS.md'], + globalFiles: { + 'review': ['checklist.md', 'TODOS-format.md'], + }, + }, + + install: { + prefixable: false, + linkingStrategy: 'symlink-generated', + }, + + learningsMode: 'basic', +}; + +export default opencode; diff --git a/hosts/slate.ts b/hosts/slate.ts new file mode 100644 index 00000000..3db9ac99 --- /dev/null +++ b/hosts/slate.ts @@ -0,0 +1,46 @@ +import type { HostConfig } from '../scripts/host-config'; + +const slate: HostConfig = { + name: 'slate', + displayName: 'Slate', + cliCommand: 'slate', + cliAliases: [], + + globalRoot: '.slate/skills/gstack', + localSkillRoot: '.slate/skills/gstack', + hostSubdir: '.slate', + usesEnvVars: true, + + frontmatter: { + mode: 'allowlist', + keepFields: ['name', 'description'], + descriptionLimit: null, + }, + + generation: { + generateMetadata: false, + skipSkills: ['codex'], + }, + + pathRewrites: [ + { from: '~/.claude/skills/gstack', to: '~/.slate/skills/gstack' }, + { from: '.claude/skills/gstack', to: '.slate/skills/gstack' }, + { from: '.claude/skills', to: '.slate/skills' }, + ], + + runtimeRoot: { + globalSymlinks: ['bin', 'browse/dist', 'browse/bin', 'gstack-upgrade', 'ETHOS.md'], + globalFiles: { + 'review': ['checklist.md', 'TODOS-format.md'], + }, + }, + + install: { + prefixable: false, + linkingStrategy: 'symlink-generated', + }, + + learningsMode: 'basic', +}; + +export default slate;