archprint 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +87 -46
  3. package/dist/cli/adoption-readme.d.ts +7 -0
  4. package/dist/cli/adoption-readme.d.ts.map +1 -0
  5. package/dist/cli/adoption-readme.js +76 -0
  6. package/dist/cli/adoption-readme.js.map +1 -0
  7. package/dist/cli/archprint-config.d.ts +33 -0
  8. package/dist/cli/archprint-config.d.ts.map +1 -0
  9. package/dist/cli/archprint-config.js +83 -0
  10. package/dist/cli/archprint-config.js.map +1 -0
  11. package/dist/cli/generate.d.ts +39 -43
  12. package/dist/cli/generate.d.ts.map +1 -1
  13. package/dist/cli/generate.js +143 -283
  14. package/dist/cli/generate.js.map +1 -1
  15. package/dist/cli/ignore-file.d.ts +8 -0
  16. package/dist/cli/ignore-file.d.ts.map +1 -0
  17. package/dist/cli/ignore-file.js +37 -0
  18. package/dist/cli/ignore-file.js.map +1 -0
  19. package/dist/cli/layout.d.ts +24 -0
  20. package/dist/cli/layout.d.ts.map +1 -0
  21. package/dist/cli/layout.js +74 -0
  22. package/dist/cli/layout.js.map +1 -0
  23. package/dist/cli/migrate.d.ts +27 -0
  24. package/dist/cli/migrate.d.ts.map +1 -0
  25. package/dist/cli/migrate.js +177 -0
  26. package/dist/cli/migrate.js.map +1 -0
  27. package/dist/cli/outputs-manifest.d.ts +0 -6
  28. package/dist/cli/outputs-manifest.d.ts.map +1 -1
  29. package/dist/cli/outputs-manifest.js +2 -29
  30. package/dist/cli/outputs-manifest.js.map +1 -1
  31. package/dist/cli/program.d.ts.map +1 -1
  32. package/dist/cli/program.js +151 -61
  33. package/dist/cli/program.js.map +1 -1
  34. package/dist/cli/report.d.ts +3 -2
  35. package/dist/cli/report.d.ts.map +1 -1
  36. package/dist/cli/report.js +19 -11
  37. package/dist/cli/report.js.map +1 -1
  38. package/dist/cli/wiring.d.ts +2 -13
  39. package/dist/cli/wiring.d.ts.map +1 -1
  40. package/dist/cli/wiring.js +18 -89
  41. package/dist/cli/wiring.js.map +1 -1
  42. package/dist/generator/eslint-preset-emitter.d.ts +4 -1
  43. package/dist/generator/eslint-preset-emitter.d.ts.map +1 -1
  44. package/dist/generator/eslint-preset-emitter.js +6 -4
  45. package/dist/generator/eslint-preset-emitter.js.map +1 -1
  46. package/dist/mcp/remote/clone.d.ts +7 -0
  47. package/dist/mcp/remote/clone.d.ts.map +1 -0
  48. package/dist/mcp/remote/clone.js +72 -0
  49. package/dist/mcp/remote/clone.js.map +1 -0
  50. package/dist/mcp/remote/http.d.ts +9 -0
  51. package/dist/mcp/remote/http.d.ts.map +1 -0
  52. package/dist/mcp/remote/http.js +92 -0
  53. package/dist/mcp/remote/http.js.map +1 -0
  54. package/dist/mcp/remote/repo-url.d.ts +8 -0
  55. package/dist/mcp/remote/repo-url.d.ts.map +1 -0
  56. package/dist/mcp/remote/repo-url.js +45 -0
  57. package/dist/mcp/remote/repo-url.js.map +1 -0
  58. package/dist/mcp/remote/server.d.ts +67 -0
  59. package/dist/mcp/remote/server.d.ts.map +1 -0
  60. package/dist/mcp/remote/server.js +83 -0
  61. package/dist/mcp/remote/server.js.map +1 -0
  62. package/dist/mcp/remote/tools.d.ts +11 -0
  63. package/dist/mcp/remote/tools.d.ts.map +1 -0
  64. package/dist/mcp/remote/tools.js +12 -0
  65. package/dist/mcp/remote/tools.js.map +1 -0
  66. package/dist/mcp/server.d.ts +54 -0
  67. package/dist/mcp/server.d.ts.map +1 -0
  68. package/dist/mcp/server.js +82 -0
  69. package/dist/mcp/server.js.map +1 -0
  70. package/dist/mcp/tool-response.d.ts +10 -0
  71. package/dist/mcp/tool-response.d.ts.map +1 -0
  72. package/dist/mcp/tool-response.js +7 -0
  73. package/dist/mcp/tool-response.js.map +1 -0
  74. package/dist/mcp/tools.d.ts +17 -0
  75. package/dist/mcp/tools.d.ts.map +1 -0
  76. package/dist/mcp/tools.js +39 -0
  77. package/dist/mcp/tools.js.map +1 -0
  78. package/dist/scanner/file-walker.d.ts +1 -0
  79. package/dist/scanner/file-walker.d.ts.map +1 -1
  80. package/dist/scanner/file-walker.js +27 -0
  81. package/dist/scanner/file-walker.js.map +1 -1
  82. package/dist/scanner/ignore-filter.d.ts.map +1 -1
  83. package/dist/scanner/ignore-filter.js +36 -10
  84. package/dist/scanner/ignore-filter.js.map +1 -1
  85. package/package.json +8 -5
  86. package/dist/cli/init.d.ts +0 -21
  87. package/dist/cli/init.d.ts.map +0 -1
  88. package/dist/cli/init.js +0 -19
  89. package/dist/cli/init.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # archprint
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add `archprint mcp --http`, a remote MCP server that scans a public repository by URL. It clones the repo shallow to a temp directory (public github.com, gitlab.com, or bitbucket.org only), runs the same read-only `scan`, `recommend`, and `explain` analysis, returns the result, and deletes the clone, so an agent can inspect a repo's architecture without anything being installed locally. The tools take a `repo` URL and an optional `ref`. The server is stateless and binds `0.0.0.0:8848/mcp` by default (`--host`/`--port`, or `$PORT`); put an authenticating, rate-limited proxy in front before exposing it publicly.
8
+ - Add `archprint mcp`, which runs archprint as an MCP server over stdio so Claude, Cursor, and other agents can inspect the architecture rules a repo already follows before they write code. It exposes three read-only tools, `archprint_scan` (the rules the repo follows, with evidence), `archprint_recommend` (what to enforce now, review, or adopt), and `archprint_explain` (the confidence-gate evidence behind one rule id), and never writes to the repo. Point any MCP client at `npx -y archprint mcp`.
9
+
10
+ ### Patch Changes
11
+
12
+ - Make deep scans dramatically faster on real repositories by not loading `node_modules` into the analysis. Deep resolution now resolves first-party imports (including `baseUrl` and `paths`) and workspace packages, but skips pulling external dependencies into the TypeScript program, and caches module resolution. A single large app drops from about 5 minutes to under 20 seconds and a 14-app monorepo from over 30 minutes to about 2 minutes, with byte-identical results, so `generate` is now practical on large codebases.
13
+ - Scanning now skips everything git ignores, not just the root `.gitignore`: nested `.gitignore` files in subdirectories and repo-local `.git/info/exclude` are honored too. This keeps generated, vendored, and locally excluded directories out of the analysis, so a scan of a monorepo root is both faster and matches what you would expect git to track. Machine-global excludes are intentionally not read, so the same repository scans identically across machines.
14
+
15
+ ## 0.6.0
16
+
17
+ ### Minor Changes
18
+
19
+ - Archprint now writes a minimal `.archprint/` directory instead of a folder of per-family files. `generate` and `init` emit one self-contained rules file per linter you actually use (`.archprint/eslint.mjs` and/or `.archprint/dependency-cruiser.json`) plus a `.archprint/config.json` that records what is enforced and what Archprint manages. The plain-language summary that used to be `ADOPTION.md` is now a managed section in your `README.md`, and a managed `.prettierignore` entry keeps the generated files out of your formatter.
20
+
21
+ - `--expand` writes the granular artifacts (per-family configs, per-rule cards and fixtures, the eslint-plugin, ts-arch tests, and the layer graph) inside `.archprint/` for anyone who wants to inspect or vendor individual rules.
22
+ - New `archprint migrate` (alias `upgrade`) moves an older `archprint-rules/` setup to the new layout and rewrites the reference in your linter config in place, writing the new files before removing the old ones so the config never points at a deleted file. `generate` and `init` stop and point you to it if they detect the old layout.
23
+ - `wire` imports the single rules file with an ESM-safe relative specifier, and `eject` removes the files, the config, the managed README section, and every wired reference.
24
+
3
25
  ## 0.5.0
4
26
 
5
27
  ### Minor Changes
package/README.md CHANGED
@@ -17,6 +17,11 @@ Your `CLAUDE.md` is guidance. Your lint rules are enforcement. Archprint closes
17
17
  enforcement from patterns your codebase already demonstrates, so you adopt rules you can trust instead of
18
18
  authoring them by hand.
19
19
 
20
+ When an AI agent is doing the writing, it can read those inferred rules and their evidence on demand through
21
+ Archprint's read-only MCP server (`archprint mcp`), so the context it works from is your codebase's real,
22
+ evidence-backed boundaries rather than a hand-written summary. It reports; enforcement still runs in your
23
+ linter. See [Use with AI agents](#use-with-ai-agents-mcp).
24
+
20
25
  Validated at scale: `scan` and `recommend` ran across all 92,861 real public TypeScript repositories with zero
21
26
  crashes, and the full `init`/`wire`/`eject` round-trip ran clean on a 2,000-repo stratified sample. A companion
22
27
  benchmark, [AgentRuleBench](https://github.com/Tommkruix/agentrulebench), measures the guidance-vs-enforcement
@@ -32,11 +37,12 @@ families held for human review by default, emitted only with `--include-structur
32
37
  server/client, feature-slice and app isolation), plus dependency hygiene, whose enforcement can over-flag.
33
38
  Nothing that could be wrong is written as enforcement without you opting in.
34
39
 
35
- > Status: published on npm and safe to try on your real repo. Every rule is review-gated by default,
40
+ > Status: published on npm and safe to run on your real repo. Every rule is review-gated by default,
36
41
  > reversible in one command (`archprint eject`), and deterministic, and a rule archprint marks
37
42
  > "enforce now" is checked to pass on your code before it says so. `scan` and `recommend` are stable;
38
- > the structural families stay review-only while they are hardened. Versioning is 0.x: the CLI surface
39
- > and rule-card format may still change before 1.0. The analysis is not experimental.
43
+ > the structural families stay review-only while they are hardened. Versioning is still 0.x, so the CLI
44
+ > surface and rule format can refine between minor versions (the 0.6.0 release moved output to the
45
+ > `.archprint/` layout; run `archprint migrate` to upgrade), but the analysis is not experimental.
40
46
 
41
47
  ## What makes it different
42
48
 
@@ -75,15 +81,15 @@ package such as `apps/web`; a monorepo root is fine too, Archprint discovers the
75
81
 
76
82
  ```bash
77
83
  # One-shot setup: detect the stack, enforce the rules your code already follows,
78
- # and record what to adopt next in archprint.json
84
+ # and record what to adopt next in .archprint/config.json
79
85
  archprint init apps/web
80
86
 
81
87
  # See the rules your repo already follows, with the evidence
82
88
  archprint scan apps/web
83
89
 
84
- # Write the auto-trusted (mechanical) rules to disk, only for the linters your repo uses.
90
+ # Write the auto-trusted (mechanical) rules to .archprint/, only for the linters your repo uses.
85
91
  # Structural-inference rules are held for review; add --include-structural to emit them too.
86
- archprint generate apps/web --out archprint-rules
92
+ archprint generate apps/web
87
93
 
88
94
  # Confirm the generated rules pass on your repo before wiring
89
95
  archprint generate apps/web --check
@@ -102,9 +108,12 @@ archprint wire
102
108
 
103
109
  # Remove archprint's files and any wired references (clean uninstall)
104
110
  archprint eject
111
+
112
+ # Upgrading from 0.5.x? move an older archprint-rules/ setup to the .archprint layout
113
+ archprint migrate
105
114
  ```
106
115
 
107
- Re-running `generate` (or `init`) refreshes the files in `archprint-rules/` and removes any rule the
116
+ Re-running `generate` (or `init`) refreshes the files in `.archprint/` and removes any rule the
108
117
  evidence no longer supports, so the output never drifts from the current codebase. `wire` detects the
109
118
  enforcement tools your repo already uses (a flat eslint config, a `.dependency-cruiser.json`) and inserts a
110
119
  single managed reference into each, one that survives those regenerations; `eject` removes archprint's files
@@ -206,31 +215,59 @@ zero rules.
206
215
 
207
216
  ## Output formats
208
217
 
209
- `archprint generate` writes only for the linters your repo actually uses, it detects ESLint and
210
- dependency-cruiser and emits each rule for a tool you already run, so you are not left with config for a
211
- tool you do not have. `--emit <eslint|dependency-cruiser|all>` forces the format. The formats it can
212
- produce:
213
-
214
- - **dependency-cruiser** `forbidden` rulesets (when dependency-cruiser is present): by default the
215
- mechanical boundaries (public-API deep-import, test-isolation); the review-held ones
216
- (layer, role-layering, feature-slice, app-isolation, entry-purity, dependency-internals, phantom deps) are
217
- written only with `--include-structural`, after you review them
218
- - **eslint-plugin-boundaries** element-types config, and **ESLint core** rules (`no-restricted-imports`) for
219
- import-style boundaries
220
- - **ESLint rule files** for marker based patterns: a rule card (`.md`), the rule (`.ts`), and a passing and a
221
- failing fixture
222
- - **A shareable ESLint preset**: one self-contained `eslint-preset.archprint.mjs` that inlines the inferred
223
- rules and needs only eslint, so you can commit it, publish it, or hand it to another repo and adopt the rules
224
- in one line
225
- - **ts-arch tests** for the first-party boundaries (layer, role, UI/data), so the inferred architecture can run
226
- inside your existing Vitest or Jest suite
227
- - **Mermaid** and **Graphviz DOT** of the layer dependency graph, so the inferred architecture is visible and
228
- its violations are marked
229
- - **`ADOPTION.md`**, a plain-language summary of what is enforced now, what is held for review, and what is
230
- worth adopting, with the tool that enforces each rule (written by `init`, or `generate --readme`)
218
+ `archprint generate` writes a minimal `.archprint/` directory: one self-contained rules file per linter your
219
+ repo actually uses, plus a `config.json` that records what is enforced and what Archprint manages. It detects
220
+ ESLint and dependency-cruiser and emits each rule for a tool you already run, so you are not left with config
221
+ for a tool you do not have. `--emit <eslint|dependency-cruiser|all>` forces the format. The default output:
222
+
223
+ - **`.archprint/eslint.mjs`**: one self-contained ESLint flat-config file that inlines every inferred ESLint
224
+ rule (marker-based forbidden imports, `no-restricted-imports` import-style boundaries, console isolation) and
225
+ needs only eslint, so you can commit it, publish it, or hand it to another repo and adopt it in one line
226
+ (`import archprint from './.archprint/eslint.mjs'`). It self-ignores `**/.archprint/**`.
227
+ - **`.archprint/dependency-cruiser.json`** (when dependency-cruiser is present): one `forbidden` ruleset with
228
+ the mechanical boundaries (public-API deep-import, test-isolation); the review-held ones (layer, role-layering,
229
+ feature-slice, app-isolation, entry-purity, dependency-internals, phantom deps) are added only with
230
+ `--include-structural`, after you review them.
231
+ - **`.archprint/config.json`**: the system file, what is enforced / held / worth adopting, and the managed
232
+ outputs list `eject` uses.
233
+ - **A managed README section** summarizing what is enforced now, held for review, and worth adopting (written
234
+ by `init`, or `generate --readme`), plus a managed `.prettierignore` entry so the generated files stay out of
235
+ your formatter.
236
+
237
+ `--expand` additionally writes the granular artifacts inside `.archprint/`: the per-family ESLint and
238
+ dependency-cruiser JSON, per-rule cards (`.md`) with passing and failing fixtures, the
239
+ eslint-plugin-boundaries element-types config, ts-arch tests, and the Mermaid and Graphviz DOT layer graph.
231
240
 
232
241
  `generate --check` runs the generated ESLint rules against your repo and reports whether they pass, so you
233
- can confirm before wiring.
242
+ can confirm before wiring. Upgrading from 0.5.x? `archprint migrate` moves an older `archprint-rules/` setup to
243
+ this layout and rewires your configs in place.
244
+
245
+ ## Use with AI agents (MCP)
246
+
247
+ `archprint mcp` runs archprint as an [MCP](https://modelcontextprotocol.io) server over stdio, so an agent can
248
+ ask what architecture rules your repo already follows, with the evidence, before it writes code. It exposes three
249
+ read-only tools: `archprint_scan`, `archprint_recommend`, and `archprint_explain`. Point Claude Desktop, Claude
250
+ Code, Cursor, or any MCP client at it:
251
+
252
+ ```json
253
+ {
254
+ "mcpServers": {
255
+ "archprint": { "command": "npx", "args": ["-y", "archprint", "mcp"] }
256
+ }
257
+ }
258
+ ```
259
+
260
+ That default is a local stdio server: it runs on your machine and reads the repo you point your client at.
261
+
262
+ To scan a public repository by URL instead, run a remote server over HTTP with `archprint mcp --http`. It clones
263
+ the repo shallow to a temp dir, runs the same read-only analysis, returns the result, and deletes the clone (only
264
+ public `github.com`, `gitlab.com`, and `bitbucket.org` URLs; nothing is written or kept). The tools then take a
265
+ `repo` URL (and an optional `ref`). It listens on `0.0.0.0:8848/mcp` by default (set `--host 127.0.0.1` to keep it
266
+ to your own machine, or `--port`/`$PORT` to change the port); put an authenticating rate-limited proxy in front
267
+ before exposing it publicly.
268
+
269
+ The tools are read-only (they never write to the repo); use the CLI's `generate`/`wire` to actually emit and
270
+ enforce rules.
234
271
 
235
272
  ## How it compares
236
273
 
@@ -254,15 +291,17 @@ orphans, reachability) and knip (dead code); rather than compete, it emits into
254
291
 
255
292
  ## Commands
256
293
 
257
- | Command | What it does |
258
- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
259
- | `archprint init [path]` | Zero-config setup: detect the stack, enforce the rules the code already follows, and write `archprint.json` plus a plain-language `ADOPTION.md`. `--include-structural`, `--out <dir>`, `--fast`, `--force`. |
260
- | `archprint scan [path]` | Report the rules the repo already follows, with evidence. `--deep` resolves through barrels and aliases. |
261
- | `archprint generate [path]` | Write the auto-trusted mechanical rules for the linters your repo uses; structural rules held for review. `--emit <eslint\|dependency-cruiser\|all>` forces the format, `--only <family>` and `--rules <ids>` narrow the output, `--check` runs the generated rules against your repo, `--readme` writes `ADOPTION.md`, `--rule <id>` emits one reviewed rule. Also `--include-structural`, `--no-graph`, `--out <dir>`, `--fast`. |
262
- | `archprint explain <id> [path]` | Show the gate breakdown for one rule, with a codeframe per exception plus how-to-fix, when-not-to-use, and how-to-enforce. |
263
- | `archprint recommend [path]` | Recommend a rule set from the repo's evidence and detected stack (works on a fresh repo too); names the installed tool that will enforce each rule. |
264
- | `archprint wire` | Reference the generated rules from the enforcement tools your repo uses (flat eslint config, `.dependency-cruiser.json`) via a managed, reversible reference. `--out <dir>`, `--dry-run`. |
265
- | `archprint eject` | Remove archprint's generated files, its manifests, and any wired references. `--out <dir>`, `--dry-run`. |
294
+ | Command | What it does |
295
+ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
296
+ | `archprint init [path]` | Zero-config setup: detect the stack, enforce the rules the code already follows, and write `.archprint/` plus a managed README section. `--expand`, `--include-structural`, `--out <dir>`, `--fast`, `--force`. |
297
+ | `archprint scan [path]` | Report the rules the repo already follows, with evidence. `--deep` resolves through barrels and aliases. |
298
+ | `archprint generate [path]` | Write the auto-trusted mechanical rules to `.archprint/` for the linters your repo uses; structural rules held for review. `--emit <eslint\|dependency-cruiser\|all>` forces the format, `--only <family>` and `--rules <ids>` narrow the output, `--check` runs the generated rules against your repo, `--readme` adds the README section, `--expand` also writes the per-family files/cards/fixtures/graph, `--rule <id>` emits one reviewed rule. Also `--include-structural`, `--no-graph`, `--out <dir>`, `--fast`. |
299
+ | `archprint migrate` (`upgrade`) | Move an older `archprint-rules/` setup to the `.archprint/` layout and rewire your configs in place. `--dry-run`. |
300
+ | `archprint explain <id> [path]` | Show the gate breakdown for one rule, with a codeframe per exception plus how-to-fix, when-not-to-use, and how-to-enforce. |
301
+ | `archprint recommend [path]` | Recommend a rule set from the repo's evidence and detected stack (works on a fresh repo too); names the installed tool that will enforce each rule. |
302
+ | `archprint wire` | Reference the generated rules from the enforcement tools your repo uses (flat eslint config, `.dependency-cruiser.json`) via a managed, reversible reference. `--out <dir>`, `--dry-run`. |
303
+ | `archprint eject` | Remove archprint's generated files, its config, the managed README section, and any wired references. `--out <dir>`, `--dry-run`. |
304
+ | `archprint mcp` | Run archprint as an MCP server so Claude, Cursor, and other agents can call read-only `scan`, `recommend`, and `explain` tools for a repo's inferred architecture rules and evidence. Serves over stdio by default; `--http` runs a remote server that scans a public repo by URL. |
266
305
 
267
306
  ## Documentation
268
307
 
@@ -285,13 +324,15 @@ Same repo plus same version produces the same output. Analysis is pure and sorte
285
324
 
286
325
  ## Status and roadmap
287
326
 
288
- Versioning is 0.x (pre-1.0): the CLI surface and rule-card format may still change between minor versions,
289
- but the analysis is not experimental and the tool is safe to adopt (every rule is review-gated and reversible
290
- via `archprint eject`). The engine (twenty detectors, the confidence gate, and emitters for ESLint, a shareable
291
- preset, dependency-cruiser, ts-arch, and the layer graph) is in place and tested, and an adversarial
292
- correctness audit (three rounds, four real repositories) drove the false-positive rate on auto-generated rules
293
- to zero for the mechanical families, which is why those auto-enforce while the structural-inference families
294
- are held for review.
327
+ Archprint is safe to adopt today: every rule is review-gated and reversible via `archprint eject`, the analysis
328
+ is deterministic, and `scan`/`recommend` are battle-tested at census scale. The engine (twenty detectors, the
329
+ confidence gate, and emitters for a self-contained ESLint file, dependency-cruiser, ts-arch, and the layer
330
+ graph) is in place and tested, and an adversarial correctness audit (three rounds, four real repositories) drove
331
+ the false-positive rate on auto-generated rules to zero for the mechanical families, which is why those
332
+ auto-enforce while the structural-inference families are held for review. Versioning is still 0.x, so the CLI
333
+ surface and rule format can refine between minor versions, that is a maturing surface, not experimental
334
+ analysis; the 0.6.0 release moved the output to the compact `.archprint/` layout, and `archprint migrate`
335
+ upgrades an older setup in place.
295
336
 
296
337
  Production-ready today: `scan` and `recommend` (insight), and auto-enforcement of the mechanical families,
297
338
  with a self-consistency check at generate time, an `init` scaffolder for fresh repos, and framework coverage
@@ -0,0 +1,7 @@
1
+ export interface ReadmeResult {
2
+ status: 'created' | 'updated' | 'skipped';
3
+ reason?: string;
4
+ }
5
+ export declare function injectAdoptionSection(readmePath: string, body: string): ReadmeResult;
6
+ export declare function stripAdoptionSection(readmePath: string, createdByArchprint: boolean): ReadmeResult;
7
+ //# sourceMappingURL=adoption-readme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adoption-readme.d.ts","sourceRoot":"","sources":["../../src/cli/adoption-readme.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsBD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CA6BpF;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,OAAO,GAC1B,YAAY,CAwBd"}
@@ -0,0 +1,76 @@
1
+ import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
+ const START = '<!-- archprint:start -->';
3
+ const END = '<!-- archprint:end -->';
4
+ function detectLayout(content) {
5
+ const bom = content.startsWith('') ? '' : '';
6
+ const eol = /\r\n/.test(content) ? '\r\n' : '\n';
7
+ return { eol, bom };
8
+ }
9
+ function block(body, eol) {
10
+ const lines = [
11
+ '## Architecture rules (managed by archprint, do not edit between the markers)',
12
+ '',
13
+ body.trim(),
14
+ ];
15
+ return [START, ...lines, END].join(eol);
16
+ }
17
+ export function injectAdoptionSection(readmePath, body) {
18
+ try {
19
+ if (!existsSync(readmePath)) {
20
+ writeFileSync(readmePath, `${block(body, '\n')}\n`);
21
+ return { status: 'created' };
22
+ }
23
+ const raw = readFileSync(readmePath, 'utf8');
24
+ const { eol, bom } = detectLayout(raw);
25
+ const content = bom ? raw.slice(bom.length) : raw;
26
+ const start = content.indexOf(START);
27
+ const end = content.indexOf(END);
28
+ if ((start !== -1) !== (end !== -1) || (start !== -1 && end < start)) {
29
+ return { status: 'skipped', reason: 'unpaired archprint markers in README; left untouched' };
30
+ }
31
+ const normalized = content.replace(/\r\n/g, '\n');
32
+ const fresh = block(body, '\n');
33
+ let next;
34
+ if (start !== -1) {
35
+ const s = normalized.indexOf(START);
36
+ const e = normalized.indexOf(END) + END.length;
37
+ next = normalized.slice(0, s) + fresh + normalized.slice(e);
38
+ }
39
+ else {
40
+ next = `${normalized.replace(/\n+$/, '')}\n\n${fresh}\n`;
41
+ }
42
+ writeFileSync(readmePath, bom + (eol === '\r\n' ? next.replace(/\n/g, '\r\n') : next));
43
+ return { status: 'updated' };
44
+ }
45
+ catch (error) {
46
+ return { status: 'skipped', reason: `could not write README (${error.message})` };
47
+ }
48
+ }
49
+ export function stripAdoptionSection(readmePath, createdByArchprint) {
50
+ try {
51
+ if (!existsSync(readmePath))
52
+ return { status: 'skipped', reason: 'no README' };
53
+ const raw = readFileSync(readmePath, 'utf8');
54
+ const { eol, bom } = detectLayout(raw);
55
+ const content = (bom ? raw.slice(bom.length) : raw).replace(/\r\n/g, '\n');
56
+ const start = content.indexOf(START);
57
+ const end = content.indexOf(END);
58
+ if (start === -1 || end === -1 || end < start) {
59
+ return { status: 'skipped', reason: 'no archprint section' };
60
+ }
61
+ const head = content.slice(0, start).replace(/\n+$/, '');
62
+ const tail = content.slice(end + END.length).replace(/^\n+/, '');
63
+ const without = head === '' ? tail : tail === '' ? head : `${head}\n\n${tail}`;
64
+ if (createdByArchprint && without.trim() === '') {
65
+ rmSync(readmePath, { force: true });
66
+ return { status: 'updated', reason: 'removed archprint-created README' };
67
+ }
68
+ const out = without.trim() === '' ? '' : `${without.replace(/\n+$/, '')}\n`;
69
+ writeFileSync(readmePath, bom + (eol === '\r\n' ? out.replace(/\n/g, '\r\n') : out));
70
+ return { status: 'updated' };
71
+ }
72
+ catch (error) {
73
+ return { status: 'skipped', reason: `could not update README (${error.message})` };
74
+ }
75
+ }
76
+ //# sourceMappingURL=adoption-readme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adoption-readme.js","sourceRoot":"","sources":["../../src/cli/adoption-readme.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { Recommendation, Recommendations } from './recommend.js';
2
+ export declare const CONFIG_FILE = "config.json";
3
+ export interface ManagedOutputs {
4
+ files: string[];
5
+ readme: boolean;
6
+ readmeCreated: boolean;
7
+ prettierignore: boolean;
8
+ prettierignoreCreated: boolean;
9
+ npmignore: boolean;
10
+ npmignoreCreated: boolean;
11
+ }
12
+ export interface ArchprintConfig {
13
+ archprintVersion: string;
14
+ app: string;
15
+ stack: string[];
16
+ rulesDir: string;
17
+ enforced: Recommendation[];
18
+ review: Recommendation[];
19
+ adopt: Recommendation[];
20
+ evidence: {
21
+ apps: number;
22
+ asOf: string;
23
+ };
24
+ managed: ManagedOutputs;
25
+ }
26
+ export declare function buildConfig(recommendations: Recommendations, version: string, location: {
27
+ app: string;
28
+ rulesDir: string;
29
+ }, managed: ManagedOutputs): ArchprintConfig;
30
+ export declare function writeConfig(outDir: string, config: ArchprintConfig): string;
31
+ export declare function recordManagedFiles(outDir: string, cwd: string, version: string, absoluteFiles: readonly string[]): void;
32
+ export declare function readConfig(outDir: string): ArchprintConfig | null;
33
+ //# sourceMappingURL=archprint-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archprint-config.d.ts","sourceRoot":"","sources":["../../src/cli/archprint-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,OAAO,EAAE,cAAc,CAAC;CACzB;AAgBD,wBAAgB,WAAW,CACzB,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC3C,OAAO,EAAE,cAAc,GACtB,eAAe,CAYjB;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CAK3E;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,IAAI,CAmBN;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAwBjE"}
@@ -0,0 +1,83 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import * as path from 'node:path';
3
+ export const CONFIG_FILE = 'config.json';
4
+ const EMPTY_MANAGED = {
5
+ files: [],
6
+ readme: false,
7
+ readmeCreated: false,
8
+ prettierignore: false,
9
+ prettierignoreCreated: false,
10
+ npmignore: false,
11
+ npmignoreCreated: false,
12
+ };
13
+ function configPath(outDir) {
14
+ return path.join(outDir, CONFIG_FILE);
15
+ }
16
+ export function buildConfig(recommendations, version, location, managed) {
17
+ return {
18
+ archprintVersion: version,
19
+ app: location.app,
20
+ stack: recommendations.stack,
21
+ rulesDir: location.rulesDir,
22
+ enforced: recommendations.enforceNow,
23
+ review: recommendations.review,
24
+ adopt: recommendations.adopt,
25
+ evidence: recommendations.evidence,
26
+ managed,
27
+ };
28
+ }
29
+ export function writeConfig(outDir, config) {
30
+ mkdirSync(outDir, { recursive: true });
31
+ const file = configPath(outDir);
32
+ writeFileSync(file, `${JSON.stringify(config, null, 2)}\n`);
33
+ return file;
34
+ }
35
+ export function recordManagedFiles(outDir, cwd, version, absoluteFiles) {
36
+ const relative = absoluteFiles.map((file) => path.relative(cwd, file));
37
+ const existing = readConfig(outDir);
38
+ if (existing) {
39
+ const files = [...new Set([...existing.managed.files, ...relative])];
40
+ writeConfig(outDir, { ...existing, managed: { ...existing.managed, files } });
41
+ return;
42
+ }
43
+ writeConfig(outDir, {
44
+ archprintVersion: version,
45
+ app: '.',
46
+ stack: [],
47
+ rulesDir: path.relative(cwd, outDir) || outDir,
48
+ enforced: [],
49
+ review: [],
50
+ adopt: [],
51
+ evidence: { apps: 0, asOf: '' },
52
+ managed: { ...EMPTY_MANAGED, files: relative },
53
+ });
54
+ }
55
+ export function readConfig(outDir) {
56
+ const file = configPath(outDir);
57
+ if (!existsSync(file))
58
+ return null;
59
+ try {
60
+ const parsed = JSON.parse(readFileSync(file, 'utf8'));
61
+ if (typeof parsed.archprintVersion !== 'string')
62
+ return null;
63
+ return {
64
+ archprintVersion: parsed.archprintVersion,
65
+ app: parsed.app ?? '.',
66
+ stack: parsed.stack ?? [],
67
+ rulesDir: parsed.rulesDir ?? '.archprint',
68
+ enforced: parsed.enforced ?? [],
69
+ review: parsed.review ?? [],
70
+ adopt: parsed.adopt ?? [],
71
+ evidence: parsed.evidence ?? { apps: 0, asOf: '' },
72
+ managed: {
73
+ ...EMPTY_MANAGED,
74
+ ...(parsed.managed ?? {}),
75
+ files: Array.isArray(parsed.managed?.files) ? parsed.managed.files : [],
76
+ },
77
+ };
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ //# sourceMappingURL=archprint-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archprint-config.js","sourceRoot":"","sources":["../../src/cli/archprint-config.ts"],"names":[],"mappings":"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"}
@@ -1,52 +1,48 @@
1
- import type { GenerationStatus } from '../detector/confidence-gate.js';
2
1
  import type { InstalledEnforcers } from '../scanner/enforcers.js';
3
- import { type NoRestrictedImportsBlock } from '../generator/eslint-scope.js';
2
+ import { type BoundaryRule } from '../generator/tsarch-emitter.js';
3
+ import { type ForbiddenImportSpec } from '../generator/eslint-plugin-emitter.js';
4
4
  import type { ScannedPattern, ScanResult } from './scan.js';
5
- export declare function writeRules(scan: ScanResult, outDir: string, statuses?: readonly GenerationStatus[], ids?: readonly string[]): string[];
6
- export declare function emitOne(pattern: ScannedPattern, appDir: string, outDir: string): string;
7
- export declare function writeLayerConfig(scan: ScanResult, outDir: string, statuses?: readonly GenerationStatus[]): string[];
8
- export declare function writePublicApiConfig(scan: ScanResult, outDir: string, statuses?: readonly GenerationStatus[]): string[];
9
- export declare function writeFeatureSliceConfig(scan: ScanResult, outDir: string, statuses?: readonly GenerationStatus[]): string[];
10
- export declare function writeAppIsolationConfig(scan: ScanResult, outDir: string, statuses?: readonly GenerationStatus[]): string[];
11
- export declare function writeTestIsolationConfig(scan: ScanResult, outDir: string): string[];
12
- export declare function writeRoleLayeringConfig(scan: ScanResult, outDir: string, statuses?: readonly GenerationStatus[]): string[];
13
- export declare function writeConsoleIsolationConfig(scan: ScanResult, outDir: string): string[];
14
- export declare function writeMergedNoRestrictedImports(blocks: readonly (NoRestrictedImportsBlock | null)[], outDir: string): string[];
15
- export declare function writeServerClientConfig(scan: ScanResult, outDir: string): string[];
16
- export declare function writeUiDataConfig(scan: ScanResult, outDir: string): string[];
17
- export declare function writeStoriesIsolationConfig(scan: ScanResult, outDir: string): string[];
18
- export declare function writeEnvAccessConfig(scan: ScanResult, outDir: string): string[];
19
- export declare function writePhantomDependencyConfig(scan: ScanResult, outDir: string): string[];
20
- export declare function writeEntryPurityConfig(scan: ScanResult, outDir: string): string[];
21
- export declare function writeDependencyInternalsConfig(scan: ScanResult, outDir: string): string[];
22
- export declare function writeEslintPreset(scan: ScanResult, outDir: string, options?: {
23
- structural?: boolean;
24
- }): string[];
25
- export declare function writeEslintPlugin(scan: ScanResult, outDir: string): string[];
26
- export declare function writeTsArchTests(scan: ScanResult, outDir: string, statuses?: readonly GenerationStatus[]): string[];
27
- export declare function writeGraph(scan: ScanResult, outDir: string): string[];
28
- export interface WrittenConfig {
29
- files: string[];
30
- label: string | null;
31
- }
5
+ export declare const ESLINT_FILE = "eslint.mjs";
6
+ export declare const DEPCRUISE_FILE = "dependency-cruiser.json";
7
+ export declare const ARCHPRINT_DIR = ".archprint";
32
8
  export declare const FAMILY_NAMES: readonly ["forbidden-imports", "layer", "role-layering", "public-api", "feature-slice", "app-isolation", "test-isolation", "dependency-hygiene", "entry-purity", "phantom-deps", "import-style", "console", "env-access", "workspace-package", "stories-isolation", "ui-data", "server-client"];
33
- export declare function writeEnforcementConfigs(scan: ScanResult, outDir: string, options: {
9
+ interface DependencyCruiserRule {
10
+ name: string;
11
+ }
12
+ interface EslintFamilyBlock {
13
+ family: string;
14
+ block: unknown;
15
+ }
16
+ interface DependencyCruiserFamily {
17
+ family: string;
18
+ forbidden: DependencyCruiserRule[];
19
+ }
20
+ export interface CollectedEnforcement {
21
+ eslintSpecs: ForbiddenImportSpec[];
22
+ eslintBlocks: EslintFamilyBlock[];
23
+ depcruise: DependencyCruiserFamily[];
24
+ boundaries: unknown | null;
25
+ tsArchRules: BoundaryRule[];
26
+ hasGraph: boolean;
27
+ }
28
+ export interface CollectOptions {
34
29
  structural?: boolean;
35
30
  enforcers: InstalledEnforcers;
36
- graph?: boolean;
37
31
  only?: string;
38
32
  ruleIds?: readonly string[];
39
- }): WrittenConfig[];
40
- export declare function regenerateConfigs(scan: ScanResult, outDir: string, options: {
41
- structural?: boolean;
42
- version: string;
43
- enforcers: InstalledEnforcers;
33
+ }
34
+ export declare function collectEnforcement(scan: ScanResult, options: CollectOptions): CollectedEnforcement;
35
+ export declare function writeArchprintEslint(collected: CollectedEnforcement, outDir: string): string | null;
36
+ export declare function writeArchprintDepcruise(collected: CollectedEnforcement, outDir: string): string | null;
37
+ export interface EmitResult {
38
+ eslint: string | null;
39
+ depcruise: string | null;
40
+ expanded: string[];
41
+ }
42
+ export declare function emitLayout(scan: ScanResult, outDir: string, options: CollectOptions & {
43
+ expand?: boolean;
44
44
  graph?: boolean;
45
- adoptionReadme?: string;
46
- only?: string;
47
- ruleIds?: readonly string[];
48
- }): {
49
- configs: WrittenConfig[];
50
- removed: string[];
51
- };
45
+ }): EmitResult;
46
+ export declare function emitOne(pattern: ScannedPattern, appDir: string, outDir: string): string;
47
+ export {};
52
48
  //# sourceMappingURL=generate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AASlE,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEtF,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAM/C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,cAAc,4BAA4B,CAAC;AACxD,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C,eAAO,MAAM,YAAY,iSAkBf,CAAC;AAEX,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,qBAAqB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,SAAS,EAAE,uBAAuB,EAAE,CAAC;IACrC,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAKD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,cAAc,GACtB,oBAAoB,CA0FtB;AAwCD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,oBAAoB,EAC/B,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAOf;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,oBAAoB,EAC/B,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAKf;AAwED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D,UAAU,CAQZ;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvF"}