mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-18 14:07:33 +02:00
fix(package): publish scripts/github-coordination.js for the /epic-* commands
`package.json` `files[]` enumerates each top-level `scripts/*.js` by hand, and
`scripts/github-coordination.js` was never added. npm therefore drops it from
the tarball while `scripts/lib/` still ships wholesale, so only the CLI entry
disappears.
All seven `/epic-*` commands ship in `commands/` and each instructs the agent
to run:
node scripts/github-coordination.js <command> <issue> --repo <owner/repo>
so anyone who installs from npm -- including the documented
`npm i -g ecc-universal` path -- gets seven commands that cannot run:
Error: Cannot find module '.../ecc-universal/scripts/github-coordination.js'
It works from a git clone, which is what masked it locally.
Add the missing `files[]` entry, the matching publish-surface allowlist entry in
`tests/scripts/npm-publish-surface.test.js` (CONTRIBUTING asks for both), and a
guard test that fails when any published command invokes a `scripts/*.js` that
the publish surface does not cover. The guard reproduces this exact bug: with
`package.json` reverted it fails naming only `github-coordination.js`.
Refs #3270
This commit is contained in:
@@ -124,6 +124,7 @@
|
||||
"scripts/memory.js",
|
||||
"scripts/memory-mcp.mjs",
|
||||
"scripts/gemini-adapt-agents.js",
|
||||
"scripts/github-coordination.js",
|
||||
"scripts/harness-adapter-compliance.js",
|
||||
"scripts/harness-audit.js",
|
||||
"scripts/eval-harness.js",
|
||||
|
||||
@@ -36,6 +36,25 @@ function isCoveredByAncestor(target, roots) {
|
||||
return false
|
||||
}
|
||||
|
||||
// `node scripts/<name>.js`, tolerating an optional "$SKILL_DIR/" style prefix.
|
||||
const SCRIPT_INVOCATION_RE = /node\s+(?:\$\{?SKILL_DIR\}?\/)?scripts\/([A-Za-z0-9._/-]+\.js)/g
|
||||
|
||||
function collectCommandScriptReferences(repoRoot) {
|
||||
const commandsDir = path.join(repoRoot, "commands")
|
||||
if (!fs.existsSync(commandsDir)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const references = []
|
||||
for (const file of fs.readdirSync(commandsDir).filter((name) => name.endsWith(".md"))) {
|
||||
const content = fs.readFileSync(path.join(commandsDir, file), "utf8")
|
||||
for (const match of content.matchAll(SCRIPT_INVOCATION_RE)) {
|
||||
references.push({ script: `scripts/${match[1]}`, command: file })
|
||||
}
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
function buildExpectedPublishPaths(repoRoot) {
|
||||
const modules = JSON.parse(
|
||||
fs.readFileSync(path.join(repoRoot, "manifests", "install-modules.json"), "utf8")
|
||||
@@ -80,6 +99,7 @@ function buildExpectedPublishPaths(repoRoot) {
|
||||
"scripts/harness-adapter-compliance.js",
|
||||
"scripts/session-inspect.js",
|
||||
"scripts/setup.js",
|
||||
"scripts/github-coordination.js",
|
||||
"scripts/uninstall.js",
|
||||
"scripts/welcome.js",
|
||||
"scripts/gemini-adapt-agents.js",
|
||||
@@ -153,6 +173,20 @@ function main() {
|
||||
["package.json files align to the module graph and explicit runtime allowlist", () => {
|
||||
assert.deepStrictEqual(actualPublishPaths, expectedPublishPaths)
|
||||
}],
|
||||
["every scripts/*.js a published command invokes is on the publish surface", () => {
|
||||
// commands/ ships in full, so a command that tells an agent to run a script
|
||||
// that npm never packages breaks only after install. See issue #3270.
|
||||
const publishRoots = new Set(actualPublishPaths)
|
||||
const unpublished = collectCommandScriptReferences(repoRoot)
|
||||
.filter(({ script }) => !publishRoots.has(script) && !isCoveredByAncestor(script, publishRoots))
|
||||
.map(({ script, command }) => `${script} (invoked by commands/${command})`)
|
||||
|
||||
assert.deepStrictEqual(
|
||||
[...new Set(unpublished)].sort(),
|
||||
[],
|
||||
`published commands invoke unpublished scripts: ${[...new Set(unpublished)].join(", ")}`
|
||||
)
|
||||
}],
|
||||
["npm pack --ignore-scripts publishes the reduced runtime surface (prepack not tested)", () => {
|
||||
const cache = fs.mkdtempSync(path.join(os.tmpdir(), "ecc-pack-surface-"))
|
||||
let result
|
||||
|
||||
Reference in New Issue
Block a user