{"_id":"@bragi-ai/eslint-config","name":"@bragi-ai/eslint-config","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"@bragi-ai/eslint-config","version":"0.0.1","private":false,"description":"Shared ESLint flat-config preset for the Bragi monorepo (Portal, AppKit, AudioApp). Placeholder — no rules yet; upstream per-repo rules here over time.","type":"module","main":"./index.js","exports":{".":"./index.js","./package.json":"./package.json"},"peerDependencies":{"eslint":">=9.0.0"},"publishConfig":{"access":"restricted"},"repository":{"type":"git","url":"git+https://github.com/nihviid/bragi-portal.git","directory":"packages/eslint-config"},"license":"UNLICENSED","_id":"@bragi-ai/eslint-config@0.0.1","bugs":{"url":"https://github.com/nihviid/bragi-portal/issues"},"homepage":"https://github.com/nihviid/bragi-portal#readme","_integrity":"sha512-EBwWLC8cAhEunukWuMmgGzsfQPJnM62SyrqUStIDTPl+SwlMIOwscVsyFQAsZB+vrG28rK5ErdaSIYSWsD3sKg==","_resolved":"/private/var/folders/98/cbv2fl9n2qbdbtnbcpdd8gq00000gn/T/e0eb6cd1bd5a28230c745bd2c6c1b49a/bragi-ai-eslint-config-0.0.1.tgz","_from":"file:bragi-ai-eslint-config-0.0.1.tgz","_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-EBwWLC8cAhEunukWuMmgGzsfQPJnM62SyrqUStIDTPl+SwlMIOwscVsyFQAsZB+vrG28rK5ErdaSIYSWsD3sKg==","shasum":"e600efff24cebbe0420568745e30f0bda4a4b459","tarball":"https://registry.npmjs.org/@bragi-ai/eslint-config/-/eslint-config-0.0.1.tgz","fileCount":3,"unpackedSize":6038,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGkOh5DtQzaqA+xPzf8oaz9sX0gErbwpJB3iW6fcy9pWAiEAoAu2pCEuv/qeDQz1RIXlndOAU+CgMPCWnyaoB+x7cZo="}]},"_npmUser":{"name":"nihviid","email":"nikolaj.hviid@bragi.com"},"directories":{},"maintainers":[{"name":"nihviid","email":"nikolaj.hviid@bragi.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/eslint-config_0.0.1_1776963515979_0.44144874003733814"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-23T16:58:35.850Z","0.0.1":"2026-04-23T16:58:36.116Z","modified":"2026-04-23T16:58:36.378Z"},"maintainers":[{"name":"nihviid","email":"nikolaj.hviid@bragi.com"}],"description":"Shared ESLint flat-config preset for the Bragi monorepo (Portal, AppKit, AudioApp). Placeholder — no rules yet; upstream per-repo rules here over time.","homepage":"https://github.com/nihviid/bragi-portal#readme","repository":{"type":"git","url":"git+https://github.com/nihviid/bragi-portal.git","directory":"packages/eslint-config"},"bugs":{"url":"https://github.com/nihviid/bragi-portal/issues"},"license":"UNLICENSED","readme":"# @bragi-ai/eslint-config\n\nShared ESLint flat-config preset for the Bragi monorepo workspace.\n\n## Status: placeholder\n\nCurrently exports `[]` — no shared rules yet. The package exists so Portal, Bragi-AppKit, and Bragi-AudioApp can wire the workspace dependency now. Rules land here as each repo's ESLint migration completes.\n\nCandidates queued for upstreaming (both earned from real incidents — see the source comments for context):\n\n- **`no-navigate-in-index-route`** — blocks declarative `<Navigate>` inside react-router `index: true` routes. Came out of AppKit's 2026-04-18 bootstrap-loop autopsy.\n- **`no-system-literal-in-audit`** — AST equivalent of Portal's `apps/portal/scripts/check-audit-gates.sh` (gates 2/4/5). Formalizes the Phase 11 \"no `'system'` literal\" invariant as a lint rule instead of a grep run.\n\n## Why a placeholder?\n\nThe package exists before the rules do because three repos want to agree on where shared rules live *before* anyone writes the migration PR. With the shell published, each repo can:\n\n1. Add `@bragi-ai/eslint-config` as a dev-dep in its own timeline.\n2. Import and spread the preset in its `eslint.config.js`.\n3. No-op today (empty array); automatically inherit rules when they land here.\n\nThat avoids a cascade-merge where \"Portal lands `@bragi-ai/eslint-config`, then AppKit lands it, then AudioApp lands it\" has to happen in order.\n\n## Adoption\n\n```js\n// <repo>/eslint.config.js\nimport bragiConfig from '@bragi-ai/eslint-config';\nimport tsEslint from 'typescript-eslint';\n\nexport default [\n  ...bragiConfig,\n  ...tsEslint.configs.recommended,\n  // repo-specific overrides below\n];\n```\n\n## Consumers\n\n- **Portal** — not yet wired (ESLint flat-config migration is on the roadmap backlog).\n- **Bragi-AppKit** — ready to consume.\n- **Bragi-AudioApp** — ready to consume.\n\n## Adding a rule\n\n1. Write the rule (usually under `rules/<name>.js`).\n2. Add to the exported array in `index.js`.\n3. Bump version per the breaking-change policy below.\n4. Tag `eslint-config-v<version>` and push — the `publish-eslint-config.yml` workflow publishes to npm.\n5. Binform the other repos via the Bragi vault so they can pull + re-lint.\n6. Consider adding to each repo's CI as an enforcement gate.\n\n## Breaking-change policy\n\nMatches AudioApp's spec-versioning convention (Bragi-AudioApp `docs/specs/README.md`).\n\n| Change | Semver bump | Examples |\n|--------|-------------|----------|\n| Rule removed or renamed | **major** (`1.0.0` → `2.0.0`) | Consumer lint will pass where it previously failed — behavior change |\n| Existing rule tightened (more code newly fails lint) | **major** | Can break CI in downstream repos |\n| New rule added | **minor** (`0.1.0` → `0.2.0`) | Additive |\n| Existing rule loosened or rule config changed without new failures | **minor** | |\n| Docs / README / source comments only | **patch** | |\n| First real rule added to the placeholder | minor → `0.1.0` | |\n\n## Publishing to npm\n\nTriggered by a tag push matching `eslint-config-v*`:\n\n```bash\n# Bump version in package.json, commit.\n# Then:\ngit tag eslint-config-v0.1.0\ngit push origin eslint-config-v0.1.0\n```\n\nGitHub Actions workflow `publish-eslint-config.yml` runs `pnpm --filter @bragi-ai/eslint-config publish --no-git-checks --access public` using `NPM_TOKEN` from repo secrets.\n\nCross-repo consumers (AppKit, AudioApp) add `\"@bragi-ai/eslint-config\": \"^0.1.0\"` as a dev-dep once published.\n\n## Why not `workspace:*` for other repos?\n\nAudioApp and AppKit live in separate git repos and pnpm workspaces. `workspace:*` resolution is monorepo-local — it only sees packages declared in the same `pnpm-workspace.yaml`. Cross-repo sharing goes through npm (or a `file:` path, but that's brittle). Hence the publish pipeline above.\n\nPortal itself can consume via `workspace:*` once its ESLint flat-config migration lands — faster iteration, zero publish latency for in-house rules.\n\n## License\n\nInternal — Bragi monorepo only. Published to npm for cross-repo consumption; do not redistribute.\n","readmeFilename":"README.md","_rev":"1-1ba4ecf9b329d0b22b28a8f033f9c149"}