@spikedpunch/align-core 0.1.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 (203) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +27 -0
  3. package/dist/baseline/fingerprint.d.ts +19 -0
  4. package/dist/baseline/fingerprint.d.ts.map +1 -0
  5. package/dist/baseline/fingerprint.js +0 -0
  6. package/dist/baseline/fingerprint.js.map +1 -0
  7. package/dist/baseline/store.d.ts +81 -0
  8. package/dist/baseline/store.d.ts.map +1 -0
  9. package/dist/baseline/store.js +111 -0
  10. package/dist/baseline/store.js.map +1 -0
  11. package/dist/build/diff.d.ts +22 -0
  12. package/dist/build/diff.d.ts.map +1 -0
  13. package/dist/build/diff.js +61 -0
  14. package/dist/build/diff.js.map +1 -0
  15. package/dist/build/export-ir.d.ts +11 -0
  16. package/dist/build/export-ir.d.ts.map +1 -0
  17. package/dist/build/export-ir.js +4 -0
  18. package/dist/build/export-ir.js.map +1 -0
  19. package/dist/build/ground.d.ts +32 -0
  20. package/dist/build/ground.d.ts.map +1 -0
  21. package/dist/build/ground.js +162 -0
  22. package/dist/build/ground.js.map +1 -0
  23. package/dist/build/hash.d.ts +10 -0
  24. package/dist/build/hash.d.ts.map +1 -0
  25. package/dist/build/hash.js +13 -0
  26. package/dist/build/hash.js.map +1 -0
  27. package/dist/build/impact.d.ts +20 -0
  28. package/dist/build/impact.d.ts.map +1 -0
  29. package/dist/build/impact.js +15 -0
  30. package/dist/build/impact.js.map +1 -0
  31. package/dist/build/index.d.ts +14 -0
  32. package/dist/build/index.d.ts.map +1 -0
  33. package/dist/build/index.js +14 -0
  34. package/dist/build/index.js.map +1 -0
  35. package/dist/build/merge.d.ts +27 -0
  36. package/dist/build/merge.d.ts.map +1 -0
  37. package/dist/build/merge.js +85 -0
  38. package/dist/build/merge.js.map +1 -0
  39. package/dist/build/propose.d.ts +16 -0
  40. package/dist/build/propose.d.ts.map +1 -0
  41. package/dist/build/propose.js +126 -0
  42. package/dist/build/propose.js.map +1 -0
  43. package/dist/build/provenance.d.ts +19 -0
  44. package/dist/build/provenance.d.ts.map +1 -0
  45. package/dist/build/provenance.js +23 -0
  46. package/dist/build/provenance.js.map +1 -0
  47. package/dist/build/schema.d.ts +1825 -0
  48. package/dist/build/schema.d.ts.map +1 -0
  49. package/dist/build/schema.js +128 -0
  50. package/dist/build/schema.js.map +1 -0
  51. package/dist/build/sections.d.ts +30 -0
  52. package/dist/build/sections.d.ts.map +1 -0
  53. package/dist/build/sections.js +58 -0
  54. package/dist/build/sections.js.map +1 -0
  55. package/dist/build/tier1.d.ts +24 -0
  56. package/dist/build/tier1.d.ts.map +1 -0
  57. package/dist/build/tier1.js +68 -0
  58. package/dist/build/tier1.js.map +1 -0
  59. package/dist/build/tier2.d.ts +42 -0
  60. package/dist/build/tier2.d.ts.map +1 -0
  61. package/dist/build/tier2.js +187 -0
  62. package/dist/build/tier2.js.map +1 -0
  63. package/dist/build/types.d.ts +42 -0
  64. package/dist/build/types.d.ts.map +1 -0
  65. package/dist/build/types.js +2 -0
  66. package/dist/build/types.js.map +1 -0
  67. package/dist/components/glob.d.ts +10 -0
  68. package/dist/components/glob.d.ts.map +1 -0
  69. package/dist/components/glob.js +52 -0
  70. package/dist/components/glob.js.map +1 -0
  71. package/dist/components/registry.d.ts +51 -0
  72. package/dist/components/registry.d.ts.map +1 -0
  73. package/dist/components/registry.js +121 -0
  74. package/dist/components/registry.js.map +1 -0
  75. package/dist/dsl/factories.d.ts +86 -0
  76. package/dist/dsl/factories.d.ts.map +1 -0
  77. package/dist/dsl/factories.js +145 -0
  78. package/dist/dsl/factories.js.map +1 -0
  79. package/dist/dsl/index.d.ts +46 -0
  80. package/dist/dsl/index.d.ts.map +1 -0
  81. package/dist/dsl/index.js +67 -0
  82. package/dist/dsl/index.js.map +1 -0
  83. package/dist/dsl/reserved-names.typecheck.d.ts +2 -0
  84. package/dist/dsl/reserved-names.typecheck.d.ts.map +1 -0
  85. package/dist/dsl/reserved-names.typecheck.js +16 -0
  86. package/dist/dsl/reserved-names.typecheck.js.map +1 -0
  87. package/dist/dsl/verb-manifest.d.ts +12 -0
  88. package/dist/dsl/verb-manifest.d.ts.map +1 -0
  89. package/dist/dsl/verb-manifest.js +101 -0
  90. package/dist/dsl/verb-manifest.js.map +1 -0
  91. package/dist/fix/apply.d.ts +67 -0
  92. package/dist/fix/apply.d.ts.map +1 -0
  93. package/dist/fix/apply.js +163 -0
  94. package/dist/fix/apply.js.map +1 -0
  95. package/dist/fix/index.d.ts +3 -0
  96. package/dist/fix/index.d.ts.map +1 -0
  97. package/dist/fix/index.js +3 -0
  98. package/dist/fix/index.js.map +1 -0
  99. package/dist/fix/schema.d.ts +180 -0
  100. package/dist/fix/schema.d.ts.map +1 -0
  101. package/dist/fix/schema.js +41 -0
  102. package/dist/fix/schema.js.map +1 -0
  103. package/dist/gates/advisories.d.ts +11 -0
  104. package/dist/gates/advisories.d.ts.map +1 -0
  105. package/dist/gates/advisories.js +27 -0
  106. package/dist/gates/advisories.js.map +1 -0
  107. package/dist/gates/types.d.ts +36 -0
  108. package/dist/gates/types.d.ts.map +1 -0
  109. package/dist/gates/types.js +8 -0
  110. package/dist/gates/types.js.map +1 -0
  111. package/dist/index.d.ts +17 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +17 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/orchestrator.d.ts +51 -0
  116. package/dist/orchestrator.d.ts.map +1 -0
  117. package/dist/orchestrator.js +304 -0
  118. package/dist/orchestrator.js.map +1 -0
  119. package/dist/payload/builder.d.ts +49 -0
  120. package/dist/payload/builder.d.ts.map +1 -0
  121. package/dist/payload/builder.js +61 -0
  122. package/dist/payload/builder.js.map +1 -0
  123. package/dist/payload/mermaid.d.ts +22 -0
  124. package/dist/payload/mermaid.d.ts.map +1 -0
  125. package/dist/payload/mermaid.js +89 -0
  126. package/dist/payload/mermaid.js.map +1 -0
  127. package/dist/plugin/registry.d.ts +24 -0
  128. package/dist/plugin/registry.d.ts.map +1 -0
  129. package/dist/plugin/registry.js +24 -0
  130. package/dist/plugin/registry.js.map +1 -0
  131. package/dist/rules/component-refs.d.ts +26 -0
  132. package/dist/rules/component-refs.d.ts.map +1 -0
  133. package/dist/rules/component-refs.js +81 -0
  134. package/dist/rules/component-refs.js.map +1 -0
  135. package/dist/rules/evaluators.d.ts +50 -0
  136. package/dist/rules/evaluators.d.ts.map +1 -0
  137. package/dist/rules/evaluators.js +236 -0
  138. package/dist/rules/evaluators.js.map +1 -0
  139. package/dist/rules/host-rules.d.ts +109 -0
  140. package/dist/rules/host-rules.d.ts.map +1 -0
  141. package/dist/rules/host-rules.js +152 -0
  142. package/dist/rules/host-rules.js.map +1 -0
  143. package/dist/rules/index.d.ts +7 -0
  144. package/dist/rules/index.d.ts.map +1 -0
  145. package/dist/rules/index.js +7 -0
  146. package/dist/rules/index.js.map +1 -0
  147. package/dist/rules/manifest-evaluators.d.ts +32 -0
  148. package/dist/rules/manifest-evaluators.d.ts.map +1 -0
  149. package/dist/rules/manifest-evaluators.js +124 -0
  150. package/dist/rules/manifest-evaluators.js.map +1 -0
  151. package/dist/rules/rule-category.d.ts +13 -0
  152. package/dist/rules/rule-category.d.ts.map +1 -0
  153. package/dist/rules/rule-category.js +27 -0
  154. package/dist/rules/rule-category.js.map +1 -0
  155. package/dist/rules/tarjan.d.ts +9 -0
  156. package/dist/rules/tarjan.d.ts.map +1 -0
  157. package/dist/rules/tarjan.js +102 -0
  158. package/dist/rules/tarjan.js.map +1 -0
  159. package/dist/scanner.d.ts +12 -0
  160. package/dist/scanner.d.ts.map +1 -0
  161. package/dist/scanner.js +2 -0
  162. package/dist/scanner.js.map +1 -0
  163. package/dist/telemetry/diff.d.ts +27 -0
  164. package/dist/telemetry/diff.d.ts.map +1 -0
  165. package/dist/telemetry/diff.js +54 -0
  166. package/dist/telemetry/diff.js.map +1 -0
  167. package/dist/telemetry/index.d.ts +4 -0
  168. package/dist/telemetry/index.d.ts.map +1 -0
  169. package/dist/telemetry/index.js +4 -0
  170. package/dist/telemetry/index.js.map +1 -0
  171. package/dist/telemetry/serialize.d.ts +10 -0
  172. package/dist/telemetry/serialize.d.ts.map +1 -0
  173. package/dist/telemetry/serialize.js +11 -0
  174. package/dist/telemetry/serialize.js.map +1 -0
  175. package/dist/telemetry/types.d.ts +138 -0
  176. package/dist/telemetry/types.d.ts.map +1 -0
  177. package/dist/telemetry/types.js +3 -0
  178. package/dist/telemetry/types.js.map +1 -0
  179. package/dist/types/branded.d.ts +26 -0
  180. package/dist/types/branded.d.ts.map +1 -0
  181. package/dist/types/branded.js +24 -0
  182. package/dist/types/branded.js.map +1 -0
  183. package/dist/types/graph.d.ts +46 -0
  184. package/dist/types/graph.d.ts.map +1 -0
  185. package/dist/types/graph.js +2 -0
  186. package/dist/types/graph.js.map +1 -0
  187. package/dist/types/index.d.ts +6 -0
  188. package/dist/types/index.d.ts.map +1 -0
  189. package/dist/types/index.js +6 -0
  190. package/dist/types/index.js.map +1 -0
  191. package/dist/types/ir.d.ts +1747 -0
  192. package/dist/types/ir.d.ts.map +1 -0
  193. package/dist/types/ir.js +120 -0
  194. package/dist/types/ir.js.map +1 -0
  195. package/dist/types/manifest.d.ts +58 -0
  196. package/dist/types/manifest.d.ts.map +1 -0
  197. package/dist/types/manifest.js +2 -0
  198. package/dist/types/manifest.js.map +1 -0
  199. package/dist/types/violation.d.ts +94 -0
  200. package/dist/types/violation.d.ts.map +1 -0
  201. package/dist/types/violation.js +56 -0
  202. package/dist/types/violation.js.map +1 -0
  203. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dsl/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reserved-names.typecheck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reserved-names.typecheck.d.ts","sourceRoot":"","sources":["../../src/dsl/reserved-names.typecheck.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Compile-time-only check (not a vitest test — vitest never imports this file; `pnpm typecheck`
3
+ * / `tsc --noEmit` is the verifier). If a component key collides with a reserved factory name and
4
+ * `NoReservedComponentKeys` stops working, the `@ts-expect-error` directive below becomes unused,
5
+ * which `tsc` reports as an error under default settings — so this file fails to typecheck
6
+ * exactly when the guard it's testing has regressed.
7
+ */
8
+ import { defineProject } from './index.js';
9
+ // @ts-expect-error — 'arch' collides with the reserved `c.arch` factory name (ADR 002).
10
+ defineProject({ components: { arch: 'packages/oops/**' } });
11
+ // @ts-expect-error — 'security' collides with the reserved `c.security` factory name (ADR 013:
12
+ // `c.security.manifest.*` is now a real factory, not just a reserved name).
13
+ defineProject({ components: { security: 'packages/oops/**' } });
14
+ // A non-colliding key must NOT error.
15
+ defineProject({ components: { api: 'packages/api/**' } });
16
+ //# sourceMappingURL=reserved-names.typecheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reserved-names.typecheck.js","sourceRoot":"","sources":["../../src/dsl/reserved-names.typecheck.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,wFAAwF;AACxF,aAAa,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAE5D,+FAA+F;AAC/F,4EAA4E;AAC5E,aAAa,CAAC,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAEhE,sCAAsC;AACtC,aAAa,CAAC,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface DslVerbEntry {
2
+ /** Dotted call path as authored, e.g. `arch.layer(x).canOnlyDependOn(...)`. */
3
+ readonly path: string;
4
+ readonly description: string;
5
+ readonly producesRuleKind: readonly string[];
6
+ }
7
+ /** Fails fast (throws) if the live builder surface and `VERB_DESCRIPTIONS` have diverged in
8
+ * either direction — a verb introspected but undocumented, or a documented verb that no longer
9
+ * exists. Both are the same class of bug the plan's false-green invariant suite watches for
10
+ * elsewhere: a skill that silently stops describing reality. */
11
+ export declare function describeDslVerbs(): readonly DslVerbEntry[];
12
+ //# sourceMappingURL=verb-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verb-manifest.d.ts","sourceRoot":"","sources":["../../src/dsl/verb-manifest.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAsED;;;gEAGgE;AAChE,wBAAgB,gBAAgB,IAAI,SAAS,YAAY,EAAE,CAuB1D"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * DSL verb manifest (Stage 5, IMPLEMENTATION_PLAN.md "Elevated first items"): the single source
3
+ * of truth `align skill`'s generated DSL-verb-table section reads from
4
+ * (`packages/cli/src/skill/dsl-verbs.ts`).
5
+ *
6
+ * The verb *names* are runtime-introspected from the actual builder objects `factories.ts`
7
+ * constructs — not re-typed by hand — by instantiating each factory with placeholder tokens and
8
+ * walking `Object.keys()`. A hand-written verb added to `factories.ts` without a matching entry
9
+ * here (or a stale entry left behind after a verb is removed) fails `describeDslVerbs()` fast
10
+ * (CODING_BEST_PRACTICES.md's fail-fast doctrine) rather than silently drifting — the same
11
+ * "generated from the live registry, never a hand-written prose list" discipline
12
+ * `rule-kinds.ts`/`bullet-grammar.ts` apply on the CLI side.
13
+ */
14
+ import { toComponentName } from '../types/branded.js';
15
+ import { makeArchFactory, makeCustomFactory, makeSecurityFactory } from './factories.js';
16
+ // Hand-maintained prose, keyed by the same dotted path `introspectVerbPaths()` below produces at
17
+ // runtime — this is the part `describeDslVerbs()` guarantees stays complete, not the part it
18
+ // guarantees stays accurate English; a verb whose *name* changes fails introspection matching
19
+ // (caught immediately), a verb whose *behavior* changes without a description update is a normal
20
+ // code-review miss like any other stale comment.
21
+ const VERB_DESCRIPTIONS = {
22
+ 'arch.layer(x).canOnlyDependOn(...refs)': {
23
+ description: 'x may depend only on the listed components — any other outgoing dependency from x is a violation.',
24
+ producesRuleKind: ['arch.layers'],
25
+ },
26
+ 'arch.layer(x).cannotDependOn(...refs)': {
27
+ description: 'x must not depend on any of the listed components — one arch.no-dependency rule per listed component.',
28
+ producesRuleKind: ['arch.no-dependency'],
29
+ },
30
+ 'arch.component(x).isIsolated()': {
31
+ description: 'no other component may depend on x, and x depends on none of them — a no-dependency rule pair for every other component.',
32
+ producesRuleKind: ['arch.no-dependency'],
33
+ },
34
+ 'arch.component(x).maxLinesPerFile(max)': {
35
+ description: 'every file classified into x must stay at or under max lines (metric: loc — the only promoted arch.metric metric today).',
36
+ producesRuleKind: ['arch.metric'],
37
+ },
38
+ 'arch.noCycles(scope?, options?)': {
39
+ description: "no import cycles within scope (defaults to the whole repo). options.includeTypeOnly widens cycle detection to type-only edges (excluded by default).",
40
+ producesRuleKind: ['arch.no-cycles'],
41
+ },
42
+ 'custom.host(hostRuleName)': {
43
+ description: 'references a HostPredicate registered under the same name in align.config.ts\'s sibling `hostRules` export ' +
44
+ '(`Record<string, HostPredicate>`). Registration is required: an unregistered hostRuleName hard-errors the ' +
45
+ 'gate at check time (never silently reports green) — register the predicate, fix the typo, or remove the rule.',
46
+ producesRuleKind: ['custom.host'],
47
+ },
48
+ 'security.manifest.sourceHygiene()': {
49
+ description: 'any dependency specifier resolving to a git/http(s)/file/link source (not registry, not workspace:) is a violation. Takes no arguments — the manifest scan domain has no notion of file-classified components.',
50
+ producesRuleKind: ['security.manifest.source-hygiene'],
51
+ },
52
+ 'security.manifest.newDependencyGate()': {
53
+ description: 'every current runtime/dev dependency is fingerprinted at baseline time; only a genuinely new dependency added afterward shows red. Takes no arguments.',
54
+ producesRuleKind: ['security.manifest.new-dependency'],
55
+ },
56
+ };
57
+ const DUMMY_TOKEN = { name: toComponentName('x') };
58
+ /** Runtime-introspects the real builder objects `factories.ts` constructs — the "live registry"
59
+ * `align skill` reads instead of a hand-typed verb list. */
60
+ function introspectVerbPaths() {
61
+ const paths = [];
62
+ const arch = makeArchFactory([DUMMY_TOKEN]);
63
+ const layerBuilder = arch.layer(DUMMY_TOKEN);
64
+ for (const key of Object.keys(layerBuilder))
65
+ paths.push(`arch.layer(x).${key}(...refs)`);
66
+ const componentBuilder = arch.component(DUMMY_TOKEN);
67
+ for (const key of Object.keys(componentBuilder)) {
68
+ paths.push(key === 'maxLinesPerFile' ? `arch.component(x).${key}(max)` : `arch.component(x).${key}()`);
69
+ }
70
+ paths.push('arch.noCycles(scope?, options?)');
71
+ const custom = makeCustomFactory();
72
+ for (const key of Object.keys(custom))
73
+ paths.push(`custom.${key}(hostRuleName)`);
74
+ const security = makeSecurityFactory();
75
+ for (const key of Object.keys(security.manifest))
76
+ paths.push(`security.manifest.${key}()`);
77
+ return paths;
78
+ }
79
+ /** Fails fast (throws) if the live builder surface and `VERB_DESCRIPTIONS` have diverged in
80
+ * either direction — a verb introspected but undocumented, or a documented verb that no longer
81
+ * exists. Both are the same class of bug the plan's false-green invariant suite watches for
82
+ * elsewhere: a skill that silently stops describing reality. */
83
+ export function describeDslVerbs() {
84
+ const introspected = introspectVerbPaths();
85
+ const introspectedSet = new Set(introspected);
86
+ const documentedSet = new Set(Object.keys(VERB_DESCRIPTIONS));
87
+ const undocumented = introspected.filter((p) => !documentedSet.has(p));
88
+ if (undocumented.length > 0) {
89
+ throw new Error(`dsl/verb-manifest.ts: the following DSL verb(s) are introspected from the live builder ` +
90
+ `surface but have no entry in VERB_DESCRIPTIONS: ${undocumented.join(', ')}. Add a ` +
91
+ `description so \`align skill\` cannot silently drift from the installed DSL.`);
92
+ }
93
+ const stale = [...documentedSet].filter((p) => !introspectedSet.has(p));
94
+ if (stale.length > 0) {
95
+ throw new Error(`dsl/verb-manifest.ts: VERB_DESCRIPTIONS documents verb(s) that no longer exist on the ` +
96
+ `live builder surface: ${stale.join(', ')}. Remove the stale entry (or the verb was ` +
97
+ `renamed — update the path to match).`);
98
+ }
99
+ return introspected.map((path) => ({ path, ...VERB_DESCRIPTIONS[path] }));
100
+ }
101
+ //# sourceMappingURL=verb-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verb-manifest.js","sourceRoot":"","sources":["../../src/dsl/verb-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Edit-block apply pipeline — engine half (ADR 010).
3
+ *
4
+ * Pure functions only (CODING_BEST_PRACTICES.md §14): given immutable original text and a set of
5
+ * proposed edit blocks, decide whether the edits apply and what the resulting text is. No I/O —
6
+ * callers (in `@spikedpunch/align-agent`) are responsible for reading the original file and writing the
7
+ * result. This keeps the algorithm trivially unit-testable with plain strings.
8
+ *
9
+ * Algorithm (ADR 010):
10
+ * 1. Scan the immutable original text for the unique starting offset of every `search` block —
11
+ * literal character-for-character string matching, no line numbers.
12
+ * 2. Multi-match: use `nearLine` to pick the closest match (line-distance) instead of rejecting.
13
+ * 3. Reject atomically: 0 matches, unresolved ambiguity (>1 match, no `nearLine` to
14
+ * disambiguate, or a tie), or any two validated spans overlapping -> zero edits applied to
15
+ * the file. The failure carries `FailureContext` with ±3-line, line-numbered context of the
16
+ * nearest candidate region (LLM's eyes only — never fed back into the engine's search).
17
+ * 4. Sort validated edits descending by original offset and apply sequentially, so edits at the
18
+ * end of the file never shift the coordinates of earlier edits.
19
+ *
20
+ * No fuzzy/whitespace-normalized fallback (Design Reserve — IMPLEMENTATION_PLAN.md).
21
+ */
22
+ import type { RepoRelativePath } from '../types/branded.js';
23
+ import type { EditBlock, FixProposalFile } from './schema.js';
24
+ export interface ValidatedEdit {
25
+ readonly startOffset: number;
26
+ readonly endOffset: number;
27
+ readonly replacement: string;
28
+ }
29
+ export type FailureReason = 'zero-matches' | 'ambiguous-matches' | 'overlapping-spans';
30
+ export interface FailureContext {
31
+ readonly file: RepoRelativePath;
32
+ readonly reason: FailureReason;
33
+ readonly nearestCandidate?: {
34
+ readonly linesWithContext: string;
35
+ readonly startLine: number;
36
+ };
37
+ }
38
+ export type FileApplyResult = {
39
+ readonly ok: true;
40
+ readonly content: string;
41
+ readonly editCount: number;
42
+ } | {
43
+ readonly ok: false;
44
+ readonly failure: FailureContext;
45
+ };
46
+ /**
47
+ * Validate and apply every edit block for a single file against its immutable original text.
48
+ * Rejects the ENTIRE file patch atomically on any failure — matches ADR 010's pure-function
49
+ * memoization semantics (a proposal either fully applies or fully doesn't).
50
+ */
51
+ export declare function applyEditsToFile(originalText: string, file: RepoRelativePath, edits: readonly EditBlock[]): FileApplyResult;
52
+ export type ValidatedFile = {
53
+ readonly path: RepoRelativePath;
54
+ } & ({
55
+ readonly ok: true;
56
+ readonly content: string;
57
+ } | {
58
+ readonly ok: false;
59
+ readonly failure: FailureContext;
60
+ });
61
+ /**
62
+ * Apply every file's edits in a `FixProposal`. Each file is validated/applied independently and
63
+ * atomically — one file's failure does not block another file's success, but any single failure
64
+ * means that ONE file's patch was fully rejected (zero edits from it applied).
65
+ */
66
+ export declare function applyFixProposalFiles(originalContents: ReadonlyMap<RepoRelativePath, string>, files: readonly FixProposalFile[], toPath: (raw: string) => RepoRelativePath): readonly ValidatedFile[];
67
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/fix/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEvF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,CAAC,EAAE;QAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;QAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,CAAC;CACH;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC;AAsI7D;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,eAAe,CA6B3H;AAED,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAAG,CAC9D;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CAC3D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,gBAAgB,EAAE,WAAW,CAAC,gBAAgB,EAAE,MAAM,CAAC,EACvD,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,gBAAgB,GACxC,SAAS,aAAa,EAAE,CAU1B"}
@@ -0,0 +1,163 @@
1
+ /** All non-overlapping literal occurrences of `search` in `text`, in ascending offset order. */
2
+ function findAllOccurrences(text, search) {
3
+ const offsets = [];
4
+ let from = 0;
5
+ for (;;) {
6
+ const idx = text.indexOf(search, from);
7
+ if (idx === -1)
8
+ break;
9
+ offsets.push(idx);
10
+ from = idx + Math.max(search.length, 1);
11
+ }
12
+ return offsets;
13
+ }
14
+ /** 1-based line number containing `offset`. */
15
+ function lineNumberAt(text, offset) {
16
+ let line = 1;
17
+ for (let i = 0; i < offset && i < text.length; i++) {
18
+ if (text[i] === '\n')
19
+ line++;
20
+ }
21
+ return line;
22
+ }
23
+ function lineStartOffsets(text) {
24
+ const starts = [0];
25
+ for (let i = 0; i < text.length; i++) {
26
+ if (text[i] === '\n')
27
+ starts.push(i + 1);
28
+ }
29
+ return starts;
30
+ }
31
+ /** ±3-line, line-numbered context window around `centerOffset`, for the LLM's eyes only. */
32
+ function contextAround(text, centerOffset) {
33
+ const starts = lineStartOffsets(text);
34
+ const lines = text.split('\n');
35
+ const centerLine = lineNumberAt(text, centerOffset); // 1-based
36
+ const startLine = Math.max(1, centerLine - 3);
37
+ const endLine = Math.min(lines.length, centerLine + 3);
38
+ const windowLines = [];
39
+ for (let ln = startLine; ln <= endLine; ln++) {
40
+ windowLines.push(`${ln}: ${lines[ln - 1] ?? ''}`);
41
+ }
42
+ void starts;
43
+ return { linesWithContext: windowLines.join('\n'), startLine };
44
+ }
45
+ /** Best-effort nearest-candidate region when a search block has zero exact matches. */
46
+ function nearestCandidateForZeroMatches(text, search) {
47
+ const searchLines = search.split('\n').filter((l) => l.trim().length > 0);
48
+ for (const candidateLine of searchLines) {
49
+ const idx = text.indexOf(candidateLine);
50
+ if (idx !== -1)
51
+ return contextAround(text, idx);
52
+ }
53
+ return undefined;
54
+ }
55
+ function resolveEdit(text, file, edit) {
56
+ const matches = findAllOccurrences(text, edit.search);
57
+ if (matches.length === 0) {
58
+ const nearestCandidate = nearestCandidateForZeroMatches(text, edit.search);
59
+ return {
60
+ ok: false,
61
+ failure: nearestCandidate === undefined
62
+ ? { file, reason: 'zero-matches' }
63
+ : { file, reason: 'zero-matches', nearestCandidate },
64
+ };
65
+ }
66
+ if (matches.length === 1) {
67
+ const start = matches[0];
68
+ return { ok: true, edit: { startOffset: start, endOffset: start + edit.search.length, replacement: edit.replace } };
69
+ }
70
+ // Multiple matches — nearLine disambiguates by picking the closest, deterministically.
71
+ if (edit.nearLine === undefined) {
72
+ return {
73
+ ok: false,
74
+ failure: {
75
+ file,
76
+ reason: 'ambiguous-matches',
77
+ nearestCandidate: contextAround(text, matches[0]),
78
+ },
79
+ };
80
+ }
81
+ let best;
82
+ let tie = false;
83
+ for (const offset of matches) {
84
+ const distance = Math.abs(lineNumberAt(text, offset) - edit.nearLine);
85
+ if (best === undefined || distance < best.distance) {
86
+ best = { offset, distance };
87
+ tie = false;
88
+ }
89
+ else if (distance === best.distance) {
90
+ tie = true;
91
+ }
92
+ }
93
+ if (best === undefined) {
94
+ // unreachable (matches.length > 1 implies a best exists), satisfies strict null checks
95
+ return {
96
+ ok: false,
97
+ failure: { file, reason: 'ambiguous-matches', nearestCandidate: contextAround(text, matches[0]) },
98
+ };
99
+ }
100
+ if (tie) {
101
+ return {
102
+ ok: false,
103
+ failure: { file, reason: 'ambiguous-matches', nearestCandidate: contextAround(text, best.offset) },
104
+ };
105
+ }
106
+ return {
107
+ ok: true,
108
+ edit: { startOffset: best.offset, endOffset: best.offset + edit.search.length, replacement: edit.replace },
109
+ };
110
+ }
111
+ function spansOverlap(a, b) {
112
+ return a.startOffset < b.endOffset && b.startOffset < a.endOffset;
113
+ }
114
+ /**
115
+ * Validate and apply every edit block for a single file against its immutable original text.
116
+ * Rejects the ENTIRE file patch atomically on any failure — matches ADR 010's pure-function
117
+ * memoization semantics (a proposal either fully applies or fully doesn't).
118
+ */
119
+ export function applyEditsToFile(originalText, file, edits) {
120
+ const resolved = [];
121
+ for (const edit of edits) {
122
+ const result = resolveEdit(originalText, file, edit);
123
+ if (!result.ok)
124
+ return { ok: false, failure: result.failure };
125
+ resolved.push(result.edit);
126
+ }
127
+ // Overlap check across ALL edits in the file (sorted first for a simple adjacent-pair scan).
128
+ const bySpan = [...resolved].sort((a, b) => a.startOffset - b.startOffset);
129
+ for (let i = 1; i < bySpan.length; i++) {
130
+ const prev = bySpan[i - 1];
131
+ const curr = bySpan[i];
132
+ if (spansOverlap(prev, curr)) {
133
+ return {
134
+ ok: false,
135
+ failure: { file, reason: 'overlapping-spans', nearestCandidate: contextAround(originalText, curr.startOffset) },
136
+ };
137
+ }
138
+ }
139
+ // Sort descending by offset and apply sequentially — later edits never shift earlier offsets.
140
+ const descending = [...resolved].sort((a, b) => b.startOffset - a.startOffset);
141
+ let content = originalText;
142
+ for (const edit of descending) {
143
+ content = content.slice(0, edit.startOffset) + edit.replacement + content.slice(edit.endOffset);
144
+ }
145
+ return { ok: true, content, editCount: resolved.length };
146
+ }
147
+ /**
148
+ * Apply every file's edits in a `FixProposal`. Each file is validated/applied independently and
149
+ * atomically — one file's failure does not block another file's success, but any single failure
150
+ * means that ONE file's patch was fully rejected (zero edits from it applied).
151
+ */
152
+ export function applyFixProposalFiles(originalContents, files, toPath) {
153
+ return files.map((f) => {
154
+ const path = toPath(f.path);
155
+ const original = originalContents.get(path);
156
+ if (original === undefined) {
157
+ return { path, ok: false, failure: { file: path, reason: 'zero-matches' } };
158
+ }
159
+ const result = applyEditsToFile(original, path, f.edits);
160
+ return result.ok ? { path, ok: true, content: result.content } : { path, ok: false, failure: result.failure };
161
+ });
162
+ }
163
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/fix/apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './schema.js';
2
+ export * from './apply.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fix/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './schema.js';
2
+ export * from './apply.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fix/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Edit-block apply pipeline — schema half (ADR 010).
3
+ *
4
+ * `FixProposal` is the zod-validated shape an LLM `FixProvider` (Stage 4, `@spikedpunch/align-agent`) must
5
+ * emit: search/replace edit blocks, never full files, never line-number diffs. This module has
6
+ * zero LLM-client dependencies — it is just a zod IR, validated the same way any other IR in
7
+ * `@spikedpunch/align-core` is validated (parse-don't-validate, CODING_BEST_PRACTICES.md §12). The engine
8
+ * that applies a validated `FixProposal` lives in `./apply.js`.
9
+ */
10
+ import { z } from 'zod';
11
+ export declare const editBlockSchema: z.ZodObject<{
12
+ /** Exact, continuous block present in the file — literal character-for-character match. */
13
+ search: z.ZodString;
14
+ /** Replacement text. Empty string means deletion. */
15
+ replace: z.ZodString;
16
+ /** Disambiguation hint for the engine only — never injected into file content. */
17
+ nearLine: z.ZodOptional<z.ZodNumber>;
18
+ /** Violation ids this edit addresses (VERIFY attribution / REPAIR context). */
19
+ forViolations: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ search: string;
22
+ replace: string;
23
+ nearLine?: number | undefined;
24
+ forViolations?: string[] | undefined;
25
+ }, {
26
+ search: string;
27
+ replace: string;
28
+ nearLine?: number | undefined;
29
+ forViolations?: string[] | undefined;
30
+ }>;
31
+ export type EditBlock = z.infer<typeof editBlockSchema>;
32
+ export declare const fixProposalFileSchema: z.ZodObject<{
33
+ path: z.ZodString;
34
+ edits: z.ZodArray<z.ZodObject<{
35
+ /** Exact, continuous block present in the file — literal character-for-character match. */
36
+ search: z.ZodString;
37
+ /** Replacement text. Empty string means deletion. */
38
+ replace: z.ZodString;
39
+ /** Disambiguation hint for the engine only — never injected into file content. */
40
+ nearLine: z.ZodOptional<z.ZodNumber>;
41
+ /** Violation ids this edit addresses (VERIFY attribution / REPAIR context). */
42
+ forViolations: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
43
+ }, "strip", z.ZodTypeAny, {
44
+ search: string;
45
+ replace: string;
46
+ nearLine?: number | undefined;
47
+ forViolations?: string[] | undefined;
48
+ }, {
49
+ search: string;
50
+ replace: string;
51
+ nearLine?: number | undefined;
52
+ forViolations?: string[] | undefined;
53
+ }>, "many">;
54
+ }, "strip", z.ZodTypeAny, {
55
+ path: string;
56
+ edits: {
57
+ search: string;
58
+ replace: string;
59
+ nearLine?: number | undefined;
60
+ forViolations?: string[] | undefined;
61
+ }[];
62
+ }, {
63
+ path: string;
64
+ edits: {
65
+ search: string;
66
+ replace: string;
67
+ nearLine?: number | undefined;
68
+ forViolations?: string[] | undefined;
69
+ }[];
70
+ }>;
71
+ export type FixProposalFile = z.infer<typeof fixProposalFileSchema>;
72
+ export declare const suppressionSchema: z.ZodObject<{
73
+ ruleId: z.ZodString;
74
+ file: z.ZodString;
75
+ line: z.ZodNumber;
76
+ }, "strip", z.ZodTypeAny, {
77
+ file: string;
78
+ line: number;
79
+ ruleId: string;
80
+ }, {
81
+ file: string;
82
+ line: number;
83
+ ruleId: string;
84
+ }>;
85
+ export type Suppression = z.infer<typeof suppressionSchema>;
86
+ export declare const fixProposalSchema: z.ZodObject<{
87
+ files: z.ZodArray<z.ZodObject<{
88
+ path: z.ZodString;
89
+ edits: z.ZodArray<z.ZodObject<{
90
+ /** Exact, continuous block present in the file — literal character-for-character match. */
91
+ search: z.ZodString;
92
+ /** Replacement text. Empty string means deletion. */
93
+ replace: z.ZodString;
94
+ /** Disambiguation hint for the engine only — never injected into file content. */
95
+ nearLine: z.ZodOptional<z.ZodNumber>;
96
+ /** Violation ids this edit addresses (VERIFY attribution / REPAIR context). */
97
+ forViolations: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
98
+ }, "strip", z.ZodTypeAny, {
99
+ search: string;
100
+ replace: string;
101
+ nearLine?: number | undefined;
102
+ forViolations?: string[] | undefined;
103
+ }, {
104
+ search: string;
105
+ replace: string;
106
+ nearLine?: number | undefined;
107
+ forViolations?: string[] | undefined;
108
+ }>, "many">;
109
+ }, "strip", z.ZodTypeAny, {
110
+ path: string;
111
+ edits: {
112
+ search: string;
113
+ replace: string;
114
+ nearLine?: number | undefined;
115
+ forViolations?: string[] | undefined;
116
+ }[];
117
+ }, {
118
+ path: string;
119
+ edits: {
120
+ search: string;
121
+ replace: string;
122
+ nearLine?: number | undefined;
123
+ forViolations?: string[] | undefined;
124
+ }[];
125
+ }>, "many">;
126
+ /**
127
+ * Accepted and validated per ADR 010, but dormant in arch-first v1: no lint gates exist yet,
128
+ * so no rule category is suppressible. Any proposal that *uses* this field is rejected by the
129
+ * apply pipeline with "no suppressible rule categories active" — see `apply.ts`.
130
+ */
131
+ suppressions: z.ZodOptional<z.ZodArray<z.ZodObject<{
132
+ ruleId: z.ZodString;
133
+ file: z.ZodString;
134
+ line: z.ZodNumber;
135
+ }, "strip", z.ZodTypeAny, {
136
+ file: string;
137
+ line: number;
138
+ ruleId: string;
139
+ }, {
140
+ file: string;
141
+ line: number;
142
+ ruleId: string;
143
+ }>, "many">>;
144
+ /** Short rationale — becomes the git commit body. */
145
+ rationale: z.ZodString;
146
+ }, "strip", z.ZodTypeAny, {
147
+ files: {
148
+ path: string;
149
+ edits: {
150
+ search: string;
151
+ replace: string;
152
+ nearLine?: number | undefined;
153
+ forViolations?: string[] | undefined;
154
+ }[];
155
+ }[];
156
+ rationale: string;
157
+ suppressions?: {
158
+ file: string;
159
+ line: number;
160
+ ruleId: string;
161
+ }[] | undefined;
162
+ }, {
163
+ files: {
164
+ path: string;
165
+ edits: {
166
+ search: string;
167
+ replace: string;
168
+ nearLine?: number | undefined;
169
+ forViolations?: string[] | undefined;
170
+ }[];
171
+ }[];
172
+ rationale: string;
173
+ suppressions?: {
174
+ file: string;
175
+ line: number;
176
+ ruleId: string;
177
+ }[] | undefined;
178
+ }>;
179
+ export type FixProposal = z.infer<typeof fixProposalSchema>;
180
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/fix/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,eAAe;IAC1B,2FAA2F;;IAE3F,qDAAqD;;IAErD,kFAAkF;;IAElF,+EAA+E;;;;;;;;;;;;EAE/E,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,qBAAqB;;;QAXhC,2FAA2F;;QAE3F,qDAAqD;;QAErD,kFAAkF;;QAElF,+EAA+E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ/E,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;EAI5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,iBAAiB;;;;YAxB5B,2FAA2F;;YAE3F,qDAAqD;;YAErD,kFAAkF;;YAElF,+EAA+E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoB/E;;;;OAIG;;;;;;;;;;;;;;IAEH,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAErD,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}