diff --git a/docs/stories/epic-123/STORY-123.17-publish-claude-settings-contract.md b/docs/stories/epic-123/STORY-123.17-publish-claude-settings-contract.md new file mode 100644 index 0000000000..766b6ce1ed --- /dev/null +++ b/docs/stories/epic-123/STORY-123.17-publish-claude-settings-contract.md @@ -0,0 +1,45 @@ +# STORY-123.17: Publicar settings Claude no pacote core + +## Status + +Done + +## Story + +Como release manager do AIOX Core, quero que o pacote npm publique o `.claude/settings.json` junto com hooks, regras e agentes Claude, para que correções em settings versionado também cheguem ao artefato consumível. + +## Acceptance Criteria + +- [x] AC1. `package.json.files` inclui `.claude/settings.json`. +- [x] AC2. `scripts/validate-package-completeness.js` exige `.claude/settings.json` no tarball. +- [x] AC3. `npm pack --dry-run` inclui `.claude/settings.json`. +- [x] AC4. O smoke npm publicado consegue validar os comandos shell-neutral dentro do pacote instalado. + +## Tasks + +- [x] Atualizar contrato de publicação em `package.json`. +- [x] Atualizar validador de completude do pacote. +- [x] Rodar gates de pacote e validações de release. + +## Dev Notes + +- A correção de STORY-123.16 chegou ao repositório, mas o smoke mostrou que `.claude/settings.json` não fazia parte do tarball npm. Como o pacote já publica `.claude/CLAUDE.md`, `.claude/hooks/`, `.claude/rules/`, `.claude/agents/`, `.claude/commands/` e `.claude/skills/`, publicar o settings fecha a superfície Claude distribuída. + +## Validation + +- `git diff --check` -> PASS. +- `node scripts/validate-package-completeness.js` -> PASS, 32/32 required package paths. +- `npm pack --dry-run --json` -> PASS, inclui `.claude/settings.json`. +- `npm run validate:publish` -> PASS. +- `npm run validate:semantic-lint` -> PASS. +- `npm run validate:manifest` -> PASS. +- `npm run lint -- --quiet` -> PASS. +- `npm run typecheck` -> PASS. +- `npm run test:ci` -> PASS, 315 suites / 7.847 tests. + +## File List + +- `package.json` +- `package-lock.json` +- `scripts/validate-package-completeness.js` +- `docs/stories/epic-123/STORY-123.17-publish-claude-settings-contract.md` diff --git a/package-lock.json b/package-lock.json index 47cea1752f..357672f63a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@aiox-squads/core", - "version": "5.1.11", + "version": "5.1.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@aiox-squads/core", - "version": "5.1.11", + "version": "5.1.12", "license": "MIT", "workspaces": [ "packages/*" diff --git a/package.json b/package.json index 145c3e8ffb..6d712a9a6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@aiox-squads/core", - "version": "5.1.11", + "version": "5.1.12", "description": "Synkra AIOX: AI-Orchestrated System for Full Stack Development - Core Framework", "bin": { "aiox": "bin/aiox.js", @@ -18,6 +18,7 @@ "packages/", ".aiox-core/", ".claude/CLAUDE.md", + ".claude/settings.json", ".claude/agents/", ".claude/commands/", ".claude/skills/", diff --git a/scripts/validate-package-completeness.js b/scripts/validate-package-completeness.js index 8e21a01be7..758a9fb504 100644 --- a/scripts/validate-package-completeness.js +++ b/scripts/validate-package-completeness.js @@ -34,6 +34,8 @@ const REQUIRED_PATHS = [ // Hooks (critical - these were missing in v4.0.0) '.claude/hooks/synapse-engine.cjs', '.claude/hooks/precompact-session-digest.cjs', + // Claude Code project settings + '.claude/settings.json', // Rules '.claude/rules/', // CLI binaries @@ -64,6 +66,7 @@ const EXCLUDED_PATHS = [ */ const REQUIRED_FILES_ENTRIES = [ '.claude/hooks/', + '.claude/settings.json', '.claude/rules/', '.aiox-core/', 'bin/', @@ -211,7 +214,12 @@ function validatePackageJson(pkg) { const filesArray = pkg.files || []; for (const entry of REQUIRED_FILES_ENTRIES) { - const found = filesArray.some((f) => f === entry || f.startsWith(entry)); + const found = filesArray.some((f) => { + if (entry.endsWith('/')) { + return f === entry || f.startsWith(entry); + } + return f === entry; + }); check( `files[] includes "${entry}"`, found,