From 6e4548f85854e34675c77b2ec36c9b56fbd90c30 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Tue, 7 Apr 2026 18:22:39 +0000 Subject: [PATCH 1/2] [ef-35] fix: skip npm similarity-blocked aliases gracefully instead of crashing Co-Authored-By: Claude Sonnet 4.6 --- docs/package-aliases.md | 18 ++++++++++-------- scripts/publish-aliases.mjs | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/docs/package-aliases.md b/docs/package-aliases.md index cfca852c..b9ef5e9f 100644 --- a/docs/package-aliases.md +++ b/docs/package-aliases.md @@ -22,14 +22,16 @@ To eliminate this surface, **we pre-emptively own all common misspellings and fo **Formatting variants** — different ways to write "failproof ai": -| Package | Install command | -|---------|----------------| -| `failproof` | `npm install -g failproof` | -| `failproof-ai` | `npm install -g failproof-ai` | -| `fail-proof-ai` | `npm install -g fail-proof-ai` | -| `failproof_ai` | `npm install -g failproof_ai` | -| `fail_proof_ai` | `npm install -g fail_proof_ai` | -| `fail-proofai` | `npm install -g fail-proofai` | +| Package | Install command | Status | +|---------|----------------|--------| +| `failproof` | `npm install -g failproof` | ✅ published | +| `failproof-ai` | `npm install -g failproof-ai` | ⏳ pending npm support approval | +| `fail-proof-ai` | `npm install -g fail-proof-ai` | ⏳ pending npm support approval | +| `failproof_ai` | `npm install -g failproof_ai` | ⏳ pending npm support approval | +| `fail_proof_ai` | `npm install -g fail_proof_ai` | ⏳ pending npm support approval | +| `fail-proofai` | `npm install -g fail-proofai` | ⏳ pending npm support approval | + +> **Why pending?** npm's spam-prevention policy blocks registration of names that normalize to the same string as an existing package after stripping punctuation (e.g. `failproof-ai` → `failproofai`). We have contacted npm support to reserve these names for anti-squatting purposes. They will be activated once approved. **`failprof*` typos** — missing one `o` from "proof": diff --git a/scripts/publish-aliases.mjs b/scripts/publish-aliases.mjs index fa7947b3..ea46c2c2 100644 --- a/scripts/publish-aliases.mjs +++ b/scripts/publish-aliases.mjs @@ -29,6 +29,9 @@ const ALIASES = [ 'faliproofai', ]; +const skipped = []; +const failed = []; + for (const name of ALIASES) { const tmpDir = join('/tmp', `npm-alias-${name}-${Date.now()}`); const binDir = join(tmpDir, 'bin'); @@ -55,11 +58,39 @@ for (const name of ALIASES) { console.log(`[dry-run] Would publish ${name}@${VERSION}`); console.log(JSON.stringify(pkg, null, 2)); console.log('---'); - } else { - console.log(`Publishing ${name}@${VERSION}...`); - execSync('npm publish', { cwd: tmpDir, stdio: 'inherit' }); + rmSync(tmpDir, { recursive: true, force: true }); + continue; + } + + console.log(`Publishing ${name}@${VERSION}...`); + try { + execSync('npm publish', { cwd: tmpDir, stdio: 'pipe' }); console.log(`Done: ${name}`); + } catch (err) { + const output = (err.stdout?.toString() ?? '') + (err.stderr?.toString() ?? ''); + if (output.includes('E403') && output.includes('too similar')) { + // npm blocks names that normalize to the same string as an existing package + // (e.g. "failproof-ai" → "failproofai"). These must be requested via npm + // support at https://www.npmjs.com/support — skipping without failing the build. + console.warn(`[SKIP] ${name}: blocked by npm similarity check — request manually via npm support`); + skipped.push(name); + } else if (output.includes('E403') && output.includes('cannot publish over')) { + // Already published at this version — treat as success. + console.log(`[SKIP] ${name}: already published at ${VERSION}`); + } else { + console.error(`[FAIL] ${name}:\n${output}`); + failed.push(name); + } } rmSync(tmpDir, { recursive: true, force: true }); } + +if (skipped.length > 0) { + console.log(`\nSkipped (npm similarity block — request via npm support):\n ${skipped.join('\n ')}`); +} + +if (failed.length > 0) { + console.error(`\nFailed with unexpected errors:\n ${failed.join('\n ')}`); + process.exit(1); +} From 453deedeaee0b9014c6e5518b0ef5ac40fbd0b21 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Tue, 7 Apr 2026 18:27:32 +0000 Subject: [PATCH 2/2] [ef-35] fix: warn on all alias publish failures + bump to 0.0.1-beta.9 Co-Authored-By: Claude Sonnet 4.6 --- package.json | 2 +- scripts/publish-aliases.mjs | 29 +++++++++-------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 21cfd4bb..5777048a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "failproofai", - "version": "0.0.1-beta.8", + "version": "0.0.1-beta.9", "description": "Open-source hooks, policies, and project visualization for Claude Code & Agents SDK", "bin": { "failproofai": "./bin/failproofai.mjs" diff --git a/scripts/publish-aliases.mjs b/scripts/publish-aliases.mjs index ea46c2c2..8df8410f 100644 --- a/scripts/publish-aliases.mjs +++ b/scripts/publish-aliases.mjs @@ -29,8 +29,7 @@ const ALIASES = [ 'faliproofai', ]; -const skipped = []; -const failed = []; +const warnings = []; for (const name of ALIASES) { const tmpDir = join('/tmp', `npm-alias-${name}-${Date.now()}`); @@ -68,29 +67,19 @@ for (const name of ALIASES) { console.log(`Done: ${name}`); } catch (err) { const output = (err.stdout?.toString() ?? '') + (err.stderr?.toString() ?? ''); - if (output.includes('E403') && output.includes('too similar')) { - // npm blocks names that normalize to the same string as an existing package - // (e.g. "failproof-ai" → "failproofai"). These must be requested via npm - // support at https://www.npmjs.com/support — skipping without failing the build. - console.warn(`[SKIP] ${name}: blocked by npm similarity check — request manually via npm support`); - skipped.push(name); - } else if (output.includes('E403') && output.includes('cannot publish over')) { - // Already published at this version — treat as success. - console.log(`[SKIP] ${name}: already published at ${VERSION}`); + if (output.includes('too similar')) { + warnings.push(`${name}: blocked by npm similarity check — request via npm support`); + } else if (output.includes('cannot publish over')) { + console.log(`[skip] ${name}: already published at ${VERSION}`); } else { - console.error(`[FAIL] ${name}:\n${output}`); - failed.push(name); + warnings.push(`${name}: ${output.trim().split('\n').find(l => l.includes('npm error')) ?? 'unknown error'}`); } } rmSync(tmpDir, { recursive: true, force: true }); } -if (skipped.length > 0) { - console.log(`\nSkipped (npm similarity block — request via npm support):\n ${skipped.join('\n ')}`); -} - -if (failed.length > 0) { - console.error(`\nFailed with unexpected errors:\n ${failed.join('\n ')}`); - process.exit(1); +if (warnings.length > 0) { + console.log('\n::warning::Some alias packages were not published:'); + for (const w of warnings) console.log(` - ${w}`); }