Add first-class Grok Build harness support

Emit .grok skills, agents, and PostToolUse/Stop hooks; wire the CLI
installer and downloads; fix the plugin install path to #plugin; and
document Grok in HARNESSES.md and README.

AI assistance: written with Grok Build.
This commit is contained in:
Paul Bakaus
2026-07-21 18:02:58 -07:00
parent 68f42c4e33
commit 06d21dea7d
18 changed files with 205 additions and 43 deletions
+39 -11
View File
@@ -462,11 +462,15 @@ This folder contains skills for all supported tools:
.codex/ -> Codex custom agents (Codex skills use .agents/)
.agents/ -> Codex CLI
.github/ -> GitHub Copilot
.grok/ -> Grok Build
.kiro/ -> Kiro
.opencode/ -> OpenCode
.pi/ -> Pi
.trae-cn/ -> Trae China
.trae/ -> Trae International
.rovodev/ -> Rovo Dev
.vibe/ -> Mistral Vibe
.qoder/ -> Qoder
To install, copy the relevant folder(s) into your project root.
For Codex, repo and user skill installs come from .agents/skills.
@@ -590,18 +594,21 @@ async function build() {
console.log(`📋 Synced skills to: ${syncConfigs.map(p => p.configDir).join(', ')}`);
// Build the Claude Code plugin subtree at ./plugin/.
// The Claude Code marketplace is configured with `source: "./plugin"`, so
// the plugin cache only copies this slim directory (~0.3 MB) instead of
// the entire monorepo (~291 MB on the previous "./" source). The harness
// dirs above stay where they are because `npx skills add pbakaus/impeccable`
// reads them directly from the GitHub repo at install time.
// Build the shared plugin subtree at ./plugin/.
// Claude Code marketplace is configured with `source: "./plugin"`, so the
// plugin cache only copies this slim directory (~0.3 MB) instead of the
// entire monorepo. Grok Build installs the same subtree via
// `grok plugin install pbakaus/impeccable#plugin --trust` (or the
// marketplace source). The harness dirs above stay where they are because
// `npx skills add pbakaus/impeccable` reads them from the GitHub repo.
const pluginRoot = path.join(ROOT_DIR, 'plugin');
const pluginManifestDir = path.join(pluginRoot, '.claude-plugin');
const grokPluginManifestDir = path.join(pluginRoot, '.grok-plugin');
const pluginSkillsDir = path.join(pluginRoot, 'skills');
const pluginAgentsDir = path.join(pluginRoot, 'agents');
const pluginHooksDir = path.join(pluginRoot, 'hooks');
if (fs.existsSync(pluginManifestDir)) fs.rmSync(pluginManifestDir, { recursive: true });
if (fs.existsSync(grokPluginManifestDir)) fs.rmSync(grokPluginManifestDir, { recursive: true });
if (fs.existsSync(pluginSkillsDir)) fs.rmSync(pluginSkillsDir, { recursive: true });
if (fs.existsSync(pluginAgentsDir)) fs.rmSync(pluginAgentsDir, { recursive: true });
if (fs.existsSync(pluginHooksDir)) fs.rmSync(pluginHooksDir, { recursive: true });
@@ -636,6 +643,26 @@ async function build() {
JSON.stringify(pluginManifest, null, 2) + '\n',
);
// Native Grok plugin manifest. Grok also reads `.claude-plugin/`; dual
// manifests keep both marketplaces and `grok plugin validate` happy when
// Claude compat is disabled.
// https://docs.x.ai/build/features/skills-plugins-marketplaces
const grokPluginManifest = {
name: pluginManifest.name,
version: pluginManifest.version,
description: pluginManifest.description,
author: pluginManifest.author,
homepage: pluginManifest.homepage,
repository: pluginManifest.repository,
license: pluginManifest.license || 'MIT',
keywords: ['design', 'frontend', 'ui', 'ux', 'skills', 'hooks'],
};
fs.mkdirSync(grokPluginManifestDir, { recursive: true });
fs.writeFileSync(
path.join(grokPluginManifestDir, 'plugin.json'),
JSON.stringify(grokPluginManifest, null, 2) + '\n',
);
const claudeSkillsSrc = path.join(DIST_DIR, 'claude-code', '.claude', 'skills', 'impeccable');
if (fs.existsSync(claudeSkillsSrc)) {
fs.mkdirSync(pluginSkillsDir, { recursive: true });
@@ -646,17 +673,18 @@ async function build() {
copyDirSync(claudeAgentsSrc, pluginAgentsDir);
}
// Ship the design detector as a plugin-packaged hook. Claude Code
// auto-discovers `hooks/hooks.json` at the plugin root, so marketplace /
// `/plugin install` users get the PostToolUse hook without it being merged
// into their project `.claude/settings.json` (that path is the CLI's job).
// Ship the design detector as a plugin-packaged hook. Claude Code and
// Grok Build both auto-discover `hooks/hooks.json` at the plugin root
// (Grok aliases CLAUDE_PLUGIN_ROOT → GROK_PLUGIN_ROOT), so marketplace /
// plugin-install users get PostToolUse + Stop without merging into project
// settings (that path remains the CLI's job for project-scoped installs).
fs.mkdirSync(pluginHooksDir, { recursive: true });
fs.writeFileSync(
path.join(pluginHooksDir, 'hooks.json'),
JSON.stringify(buildClaudePluginHooksManifest(), null, 2) + '\n',
);
console.log('📦 Built Claude Code plugin subtree at ./plugin/');
console.log('📦 Built Claude Code / Grok Build plugin subtree at ./plugin/');
} else {
console.log('📋 Skipped root harness and plugin sync (--skip-root-sync)');
}