diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index de090cd..d063682 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -72,8 +72,8 @@ jobs: - name: PrePluginPack # The pluginpack-action runs `npx pluginpack diff/build` directly (not # `npm run build`), so the repo's prebuild esbuild step never fires. - # sources/local-mcp/dist/index.js is gitignored, so build it here or - # pluginpack's additionalFiles source read fails for every target. + # shared/glean/mcp/dist/index.js is gitignored, so build it here or + # pluginpack's MCP shipping-file source read fails for every target. run: npm run build:bundle - name: Resolve pinned pluginpack version diff --git a/.gitignore b/.gitignore index 91b36b9..c91c0b6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ node_modules/ # Generated build output (published to the target repos by CI) dist/ # local-mcp runtime MCP server bundle (regenerated by build:bundle / prebuild) -sources/local-mcp/dist/ +shared/glean/mcp/dist/ # Claude Code runtime cache (local-mcp skills cache written during local runs) .claude/tmp/ diff --git a/README.md b/README.md index bd671c7..34add7a 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,22 @@ # Glean Agent Plugins The source-of-truth repository for Glean's official plugins for AI coding -assistants. One portable library of skills, agents, rules, commands, and hooks -is authored here once, and [`pluginpack`](https://github.com/gleanwork/pluginpack) +assistants. Each plugin is authored once under `shared/`, and +[`pluginpack`](https://github.com/gleanwork/pluginpack) compiles it into the native plugin layout each host expects — today **Claude -Code**, **Cursor**, and **Codex**. Most skills share one base source; target -overrides handle the few host-specific setup and capability differences. +Code**, **Cursor**, and **Codex**. Target overrides handle the few host-specific +setup and capability differences. ## Layout -| Path | What it is | -|------|------------| -| `skills/` | The portable skill library — one `SKILL.md` (plus optional `references/`) per capability, with host-specific files only under `targets//`. **The source of truth.** | -| `sources/shared/` | Components shared by targets that support them (subagents). | -| `sources/claude/` | Claude-only components (slash-commands, hooks). | -| `sources/codex/` | Codex-only plugin documentation and static files. | -| `sources/cursor/` | Cursor-only components (rules, commands, assets). | -| `sources/dev-docs/` | Source for the separate `glean-dev-docs` plugin. | -| `pluginpack.config.ts` | Build config — which sources compose into which plugin, per target. | -| `plugins/`, `glean/`, `glean-dev-docs/`, `.agents/`, `.codex-plugin/`, `.claude-plugin/`, `.cursor-plugin/` | **Generated** output. Don't edit by hand — it's rebuilt from source. | +| Path | What it is | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | +| `shared/glean/` | Canonical Glean plugin: skills, agents, static files, and the local MCP implementation. | +| `shared/glean-dev-docs/` | Canonical source for the separate developer-docs plugin. | +| `overrides///` | Target-specific additions and replacements applied after the shared source. | +| `repositories//` | Files emitted at the root of each generated marketplace repository. | +| `pluginpack.config.ts` | Build config — which shared source, overrides, and content kinds each target includes. | +| `dist//` | **Generated** marketplace repositories. Don't edit them by hand — they're rebuilt from `shared/`, `overrides/`, and `repositories/`. | ## Plugins produced @@ -28,13 +26,17 @@ Each target gets two single-purpose plugins: code exploration, people and experts, meetings, onboarding, and personal productivity. Skills auto-trigger by task; there's no per-skill install. - **`glean-dev-docs`** — searches the public Glean developer documentation - (separate MCP server, for people *building with* Glean). + (separate MCP server, for people _building with_ Glean). ## How it works `pluginpack` reads `pluginpack.config.ts`, collects the configured skills and components, and emits each host's native format: +Nothing under `shared/` ships implicitly. Each emitted plugin names its shared +`source`, optional target `overrides`, and any `include` or `exclude` selection in +`pluginpack.config.ts`. + - **Claude Code** — a marketplace + plugin manifest with convention-discovered skills, commands, and hooks. - **Cursor** — a marketplace + `plugin.json` referencing skills, agents, rules, @@ -44,42 +46,43 @@ components, and emits each host's native format: Skills use the open Agent Skills format — `SKILL.md` with `name`/`description` frontmatter and optional `references/` loaded on demand — which Claude Code, -Codex, Cursor, Gemini CLI, and Copilot all support. Base skills ship everywhere; -target overrides handle the few host-specific differences. +Codex, Cursor, Gemini CLI, and Copilot all support. Shared skills ship to each +target that includes them; target overrides handle host-specific differences. -> The plugins don't bundle a Glean MCP server — users connect one themselves -> (your host's Glean MCP setup guides that). The skills then use whatever Glean MCP -> tools are available in the host. +The Claude and Codex `glean` plugins bundle the local Glean MCP adapter under +`shared/glean/mcp/`. Cursor excludes that capability and uses a separately +connected Glean MCP server. MCP configuration lives in `mcp/config.json`, while +`mcp/pluginpack.json` lists the implementation files that ship. ## Develop Requires Node >= 24. Install once with `npm install`. -| Command | What it does | -|---------|--------------| -| `npm run build` | Compile all targets into the generated plugin output. | -| `npm run validate` | Validate each target's generated output. | -| `npm test` | Build every target, then validate each generated output. | -| `npm run prune` | Remove stale generated files. | -| `npm run clean` | Remove all generated output. | +| Command | What it does | +| ------------------ | -------------------------------------------------------- | +| `npm run build` | Compile all targets into the generated plugin output. | +| `npm run validate` | Validate each target's generated output. | +| `npm test` | Build every target, then validate each generated output. | +| `npm run prune` | Remove stale generated files. | +| `npm run clean` | Remove all generated output. | ### Add or change a skill -1. Edit or create `skills//SKILL.md` (add `references/*.md` for deep, +1. Edit or create `shared/glean/skills//SKILL.md` (add `references/*.md` for deep, load-on-demand detail). 2. `npm run build` to regenerate the plugins. 3. `npm test` to confirm every target builds and validates cleanly. Base skill changes reach every target that includes them. When one host needs different instructions, add a full replacement at -`skills//targets//SKILL.md`; other targets keep the base file. +`overrides//glean/skills//SKILL.md`; other targets keep the shared file. ### Commit conventions Releases and the changelog are driven by [Conventional Commits](https://www.conventionalcommits.org/). -In this repo the skill markdown *is* the shipped product, so: +In this repo the skill markdown _is_ the shipped product, so: -- Use `feat:` / `fix:` for any change to `skills/` or `sources/` content — +- Use `feat:` / `fix:` for any change to `shared/` or `overrides/` content — it alters what users install, even when the change is "just docs". - Reserve `docs:` for repo-level documentation that doesn't ship (README, contributing notes, etc.). diff --git a/RELEASE.md b/RELEASE.md index b1af8fb..5617ba3 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -58,8 +58,8 @@ release is what triggers the actual plugin distribution (below). 1. Determine the next version from commits since the last tag (`feat` → minor, `fix` → patch, a `BREAKING CHANGE` footer → major). 2. Regenerate `CHANGELOG.md`. Its `after:bump` hook then runs `npm run - build`, which syncs that changelog into `sources/claude`, - `sources/codex`, `sources/cursor`, `sources/dev-docs`, and rebuilds the + build`, which syncs that changelog into `shared/glean` and + `shared/glean-dev-docs`, then rebuilds the generated plugin output — all of which is included in the release commit. 3. Commit as `chore: release v${version}`, tag `v${version}`, and push both diff --git a/sources/local-mcp/hooks/auto-approve-run-tool.mjs b/overrides/claude/glean/hooks/auto-approve-run-tool.mjs similarity index 100% rename from sources/local-mcp/hooks/auto-approve-run-tool.mjs rename to overrides/claude/glean/hooks/auto-approve-run-tool.mjs diff --git a/sources/local-mcp/hooks/hooks.json b/overrides/claude/glean/hooks/hooks.json similarity index 100% rename from sources/local-mcp/hooks/hooks.json rename to overrides/claude/glean/hooks/hooks.json diff --git a/sources/dev-docs/targets/codex/README.md b/overrides/codex/glean-dev-docs/README.md similarity index 100% rename from sources/dev-docs/targets/codex/README.md rename to overrides/codex/glean-dev-docs/README.md diff --git a/sources/codex-assets/assets/avatar.png b/overrides/codex/glean-dev-docs/assets/avatar.png similarity index 100% rename from sources/codex-assets/assets/avatar.png rename to overrides/codex/glean-dev-docs/assets/avatar.png diff --git a/sources/codex/LICENSE b/overrides/codex/glean/LICENSE similarity index 100% rename from sources/codex/LICENSE rename to overrides/codex/glean/LICENSE diff --git a/sources/codex/README.md b/overrides/codex/glean/README.md similarity index 100% rename from sources/codex/README.md rename to overrides/codex/glean/README.md diff --git a/sources/cursor/assets/avatar.png b/overrides/codex/glean/assets/avatar.png similarity index 100% rename from sources/cursor/assets/avatar.png rename to overrides/codex/glean/assets/avatar.png diff --git a/sources/local-mcp/targets/codex/.mcp.json b/overrides/codex/glean/mcp/config.json similarity index 84% rename from sources/local-mcp/targets/codex/.mcp.json rename to overrides/codex/glean/mcp/config.json index d7bd1d2..d3dabb0 100644 --- a/sources/local-mcp/targets/codex/.mcp.json +++ b/overrides/codex/glean/mcp/config.json @@ -2,7 +2,7 @@ "mcpServers": { "glean_plugin": { "command": "node", - "args": ["./start.mjs"], + "args": ["./mcp/start.mjs"], "cwd": ".", "env": { "ENABLE_HITL": "true", diff --git a/skills/skill-creation-guide/targets/codex/SKILL.md b/overrides/codex/glean/skills/skill-creation-guide/SKILL.md similarity index 100% rename from skills/skill-creation-guide/targets/codex/SKILL.md rename to overrides/codex/glean/skills/skill-creation-guide/SKILL.md diff --git a/sources/cursor/README.md b/overrides/cursor/glean/README.md similarity index 100% rename from sources/cursor/README.md rename to overrides/cursor/glean/README.md diff --git a/overrides/cursor/glean/assets/avatar.png b/overrides/cursor/glean/assets/avatar.png new file mode 100644 index 0000000..14e232f Binary files /dev/null and b/overrides/cursor/glean/assets/avatar.png differ diff --git a/sources/cursor/assets/avatar.svg b/overrides/cursor/glean/assets/avatar.svg similarity index 100% rename from sources/cursor/assets/avatar.svg rename to overrides/cursor/glean/assets/avatar.svg diff --git a/sources/cursor/rules/glean-result-vetting.mdc b/overrides/cursor/glean/rules/glean-result-vetting.mdc similarity index 100% rename from sources/cursor/rules/glean-result-vetting.mdc rename to overrides/cursor/glean/rules/glean-result-vetting.mdc diff --git a/sources/cursor/rules/glean-tool-selection.mdc b/overrides/cursor/glean/rules/glean-tool-selection.mdc similarity index 100% rename from sources/cursor/rules/glean-tool-selection.mdc rename to overrides/cursor/glean/rules/glean-tool-selection.mdc diff --git a/package-lock.json b/package-lock.json index fcf7457..5f8763b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "yaml": "^2.7.0" }, "devDependencies": { - "@gleanwork/pluginpack": "^0.9.0", + "@gleanwork/pluginpack": "^0.11.0", "@release-it/conventional-changelog": "^11.0.1", "@types/node": "^22.0.0", "esbuild": "^0.28.1", @@ -496,9 +496,9 @@ } }, "node_modules/@gleanwork/pluginpack": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@gleanwork/pluginpack/-/pluginpack-0.9.0.tgz", - "integrity": "sha512-+5Nnink6evIVQoJLLwRIAwBaqSxTGmzA0qbrHOMLFFUCqIcYD7n8HXDcNLAvcu2n0T4TWsHzC+U0NjOKgova4Q==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@gleanwork/pluginpack/-/pluginpack-0.11.0.tgz", + "integrity": "sha512-9HY63m2VIcD26vQ/W9N8dzjA8XR0xN6K8u1RGlWun3pFdRlWfkBjKBy/0ANY6JA4Vtj0tebNJqf/JAJwcItvNA==", "dev": true, "license": "MIT", "dependencies": { @@ -506,6 +506,7 @@ "fast-glob": "^3.3.3", "gray-matter": "^4.0.3", "jiti": "^2.7.0", + "mustache": "^4.2.0", "zod": "^4.4.3" }, "bin": { @@ -3787,6 +3788,16 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/mute-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", diff --git a/package.json b/package.json index c993925..a4fca05 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,15 @@ "type": "module", "scripts": { "build": "pluginpack build", - "build:bundle": "node sources/local-mcp/build.mjs", + "build:bundle": "node shared/glean/mcp/build.mjs", "clean": "pluginpack clean", "check:no-shell": "node scripts/check-no-shell-scripts.mjs", "prune": "pluginpack prune", - "typecheck:bundle": "tsc --noEmit -p sources/local-mcp/tsconfig.json", - "test:bundle": "vitest run --root sources/local-mcp", + "typecheck:bundle": "tsc --noEmit -p shared/glean/mcp/tsconfig.json", + "test:bundle": "vitest run --root shared/glean/mcp", "validate": "pluginpack validate --target claude --dir dist/claude && pluginpack validate --target cursor --dir dist/cursor && pluginpack validate --target codex --dir dist/codex", "test": "npm run build && npm run validate", - "prebuild": "node scripts/sync-changelog.mjs && npm run build:bundle", + "prebuild": "node scripts/sync-release-metadata.mjs && npm run build:bundle", "release": "release-it" }, "dependencies": { @@ -27,7 +27,7 @@ "yaml": "^2.7.0" }, "devDependencies": { - "@gleanwork/pluginpack": "^0.9.0", + "@gleanwork/pluginpack": "^0.11.0", "@release-it/conventional-changelog": "^11.0.1", "@types/node": "^22.0.0", "esbuild": "^0.28.1", diff --git a/pluginpack.config.ts b/pluginpack.config.ts index 5a0bdf9..6e13601 100644 --- a/pluginpack.config.ts +++ b/pluginpack.config.ts @@ -4,14 +4,6 @@ import pkg from "./package.json" with { type: "json" }; export default defineConfig({ name: "glean-plugins", version: pkg.version, - source: { - plugins: "sources", - skills: "skills", - rootPlugin: { - id: "glean-lib", - description: "Portable Glean skill library.", - }, - }, metadata: { author: { name: "Glean", @@ -27,22 +19,22 @@ export default defineConfig({ claude: { outDir: "dist/claude", version: pkg.version, - rootFiles: { "README.md": "roots/claude/README.md" }, + repositoryFiles: "repositories/claude", manifest: { description: "Official Glean plugins for Claude Code — enterprise knowledge, search, people, code, and meetings.", }, plugins: { glean: { - from: ["glean-lib", "shared", "claude", "local-mcp"], - components: ["skills", "agents", "hooks"], + source: "shared/glean", + overrides: "overrides/claude/glean", displayName: "Glean", description: "Official Glean plugin — search documents, Slack, and email; explore code across repos; find experts and stakeholders; prep for meetings and onboarding.", }, "glean-dev-docs": { - from: ["dev-docs"], - components: ["skills"], + source: "shared/glean-dev-docs", + include: ["skills", "static"], displayName: "Glean Developer Docs", description: "Search the public Glean developer documentation — APIs, SDKs, MCP, and integration guides for building with Glean.", @@ -52,31 +44,58 @@ export default defineConfig({ cursor: { outDir: "dist/cursor", version: pkg.version, - rootFiles: { "README.md": "roots/cursor/README.md" }, + repositoryFiles: "repositories/cursor", manifest: { metadata: { description: "Official Glean plugins for Cursor — enterprise knowledge, code search, and people discovery.", - keywords: ["glean", "enterprise-search", "knowledge-management", "productivity", "workplace", "mcp"], + keywords: [ + "glean", + "enterprise-search", + "knowledge-management", + "productivity", + "workplace", + "mcp", + ], }, }, plugins: { glean: { - from: ["glean-lib", "shared", "cursor"], - components: ["skills", "agents", "rules", "assets"], + source: "shared/glean", + overrides: "overrides/cursor/glean", + exclude: ["mcp", "hooks", "scripts"], displayName: "Glean", description: "Official Glean plugin — search documents, Slack, and email; explore code across repos; find experts and stakeholders; prep for meetings and onboarding.", manifest: { logo: "assets/avatar.svg", - keywords: ["glean", "enterprise-search", "knowledge-management", "productivity", "workplace", "code-search", "people-search", "mcp"], + keywords: [ + "glean", + "enterprise-search", + "knowledge-management", + "productivity", + "workplace", + "code-search", + "people-search", + "mcp", + ], category: "productivity", - tags: ["mcp", "enterprise", "search", "documents", "slack", "code", "people", "experts", "org"], + tags: [ + "mcp", + "enterprise", + "search", + "documents", + "slack", + "code", + "people", + "experts", + "org", + ], }, }, "glean-dev-docs": { - from: ["dev-docs"], - components: ["skills"], + source: "shared/glean-dev-docs", + include: ["skills", "static"], displayName: "Glean Developer Docs", description: "Search the public Glean developer documentation — APIs, SDKs, MCP, and integration guides for building with Glean.", @@ -85,18 +104,15 @@ export default defineConfig({ }, codex: { outDir: "dist/codex", - rootFiles: { - "README.md": "roots/codex/README.md", - LICENSE: "LICENSE", - }, + repositoryFiles: "repositories/codex", manifest: { name: "glean-codex-plugins", interface: { displayName: "Glean for Codex" }, }, plugins: { glean: { - from: ["glean-lib", "codex", "codex-assets", "local-mcp"], - components: ["skills", "assets"], + source: "shared/glean", + overrides: "overrides/codex/glean", description: "Official Glean plugin — search documents, Slack, and email; explore code across repos; find experts and stakeholders; prep for meetings and onboarding.", manifest: { @@ -126,8 +142,9 @@ export default defineConfig({ }, }, "glean-dev-docs": { - from: ["dev-docs", "codex-assets"], - components: ["skills", "assets"], + source: "shared/glean-dev-docs", + overrides: "overrides/codex/glean-dev-docs", + include: ["skills", "assets", "static"], description: "Search the public Glean developer documentation — APIs, SDKs, MCP, and integration guides for building with Glean.", manifest: { diff --git a/sources/dev-docs/LICENSE b/repositories/claude/LICENSE similarity index 93% rename from sources/dev-docs/LICENSE rename to repositories/claude/LICENSE index feafbe9..eb02a81 100644 --- a/sources/dev-docs/LICENSE +++ b/repositories/claude/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Glean Technologies, Inc. +Copyright (c) 2025 Glean Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -17,6 +17,5 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/roots/claude/README.md b/repositories/claude/README.md similarity index 100% rename from roots/claude/README.md rename to repositories/claude/README.md diff --git a/repositories/codex/LICENSE b/repositories/codex/LICENSE new file mode 100644 index 0000000..eb02a81 --- /dev/null +++ b/repositories/codex/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Glean + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/roots/codex/README.md b/repositories/codex/README.md similarity index 100% rename from roots/codex/README.md rename to repositories/codex/README.md diff --git a/repositories/cursor/LICENSE b/repositories/cursor/LICENSE new file mode 100644 index 0000000..eb02a81 --- /dev/null +++ b/repositories/cursor/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Glean + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/roots/cursor/README.md b/repositories/cursor/README.md similarity index 100% rename from roots/cursor/README.md rename to repositories/cursor/README.md diff --git a/scripts/check-no-shell-scripts.mjs b/scripts/check-no-shell-scripts.mjs index 04ef0e9..55917dd 100644 --- a/scripts/check-no-shell-scripts.mjs +++ b/scripts/check-no-shell-scripts.mjs @@ -1,6 +1,5 @@ #!/usr/bin/env node -// CI guard: fail if any shell/bash script is added under the local-mcp -// source tree. +// CI guard: fail if any shell/bash script is added under the shared MCP tree. // // Why: the local-mcp plugin ships and runs on end-user machines, including // Windows, where POSIX shell (.sh / bash) is not available. We already @@ -15,9 +14,9 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; -// Scope: the local-mcp plugin source. Broaden this list if the rule should +// Scope: the local MCP source. Broaden this list if the rule should // cover other source trees too. -const SCAN_ROOTS = ["sources/local-mcp"]; +const SCAN_ROOTS = ["shared/glean/mcp"]; // Never descend into generated/vendored trees. const SKIP_DIRS = new Set(["node_modules", "dist", ".git"]); @@ -73,7 +72,7 @@ if (offenders.length > 0) { `Found ${offenders.length} shell script(s):\n${rel}\n\n` + `The plugin runs on end-user machines including Windows, where POSIX shell\n` + `is unavailable. Use a cross-platform Node.js script instead:\n\n` + - ` - Write it as a .mjs file (see sources/local-mcp/start.mjs).\n` + + ` - Write it as a .mjs file (see shared/glean/mcp/start.mjs).\n` + ` - Use Node built-ins (node:fs, node:path, node:child_process) instead of\n` + ` shell utilities, and avoid shell-only syntax.\n` + ` - Invoke it with "node