@rasensio/aidlc 1.15.2 → 1.17.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 (209) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +4 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/compliance.d.ts +36 -0
  6. package/dist/commands/compliance.d.ts.map +1 -0
  7. package/dist/commands/compliance.js +275 -0
  8. package/dist/commands/compliance.js.map +1 -0
  9. package/dist/commands/constitution.d.ts +26 -0
  10. package/dist/commands/constitution.d.ts.map +1 -0
  11. package/dist/commands/constitution.js +145 -0
  12. package/dist/commands/constitution.js.map +1 -0
  13. package/dist/commands/cost.d.ts.map +1 -1
  14. package/dist/commands/cost.js +54 -35
  15. package/dist/commands/cost.js.map +1 -1
  16. package/dist/commands/doctor.js +7 -0
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/gate.d.ts.map +1 -1
  19. package/dist/commands/gate.js +13 -0
  20. package/dist/commands/gate.js.map +1 -1
  21. package/dist/commands/init.d.ts.map +1 -1
  22. package/dist/commands/init.js +119 -10
  23. package/dist/commands/init.js.map +1 -1
  24. package/dist/commands/metrics.d.ts.map +1 -1
  25. package/dist/commands/metrics.js +6 -1
  26. package/dist/commands/metrics.js.map +1 -1
  27. package/dist/commands/review.d.ts +2 -27
  28. package/dist/commands/review.d.ts.map +1 -1
  29. package/dist/commands/review.js +10 -166
  30. package/dist/commands/review.js.map +1 -1
  31. package/dist/commands/status.d.ts.map +1 -1
  32. package/dist/commands/status.js +7 -0
  33. package/dist/commands/status.js.map +1 -1
  34. package/dist/commands/transition.d.ts.map +1 -1
  35. package/dist/commands/transition.js +24 -1
  36. package/dist/commands/transition.js.map +1 -1
  37. package/dist/compile/adapters/claude-code.d.ts.map +1 -1
  38. package/dist/compile/adapters/claude-code.js +2 -1
  39. package/dist/compile/adapters/claude-code.js.map +1 -1
  40. package/dist/compile/adapters/codex.d.ts +22 -1
  41. package/dist/compile/adapters/codex.d.ts.map +1 -1
  42. package/dist/compile/adapters/codex.js +61 -27
  43. package/dist/compile/adapters/codex.js.map +1 -1
  44. package/dist/compile/adapters/cursor.d.ts.map +1 -1
  45. package/dist/compile/adapters/cursor.js +2 -19
  46. package/dist/compile/adapters/cursor.js.map +1 -1
  47. package/dist/compile/adapters/kiro.d.ts.map +1 -1
  48. package/dist/compile/adapters/kiro.js +1 -19
  49. package/dist/compile/adapters/kiro.js.map +1 -1
  50. package/dist/compile/adapters/windsurf.d.ts.map +1 -1
  51. package/dist/compile/adapters/windsurf.js +2 -1
  52. package/dist/compile/adapters/windsurf.js.map +1 -1
  53. package/dist/compile/guidance-install.d.ts +16 -19
  54. package/dist/compile/guidance-install.d.ts.map +1 -1
  55. package/dist/compile/guidance-install.js +26 -111
  56. package/dist/compile/guidance-install.js.map +1 -1
  57. package/dist/compile/layer-install.d.ts +122 -0
  58. package/dist/compile/layer-install.d.ts.map +1 -0
  59. package/dist/compile/layer-install.js +195 -0
  60. package/dist/compile/layer-install.js.map +1 -0
  61. package/dist/compile/loaders.d.ts +14 -0
  62. package/dist/compile/loaders.d.ts.map +1 -1
  63. package/dist/compile/loaders.js +23 -18
  64. package/dist/compile/loaders.js.map +1 -1
  65. package/dist/compile/skill-format.d.ts +39 -0
  66. package/dist/compile/skill-format.d.ts.map +1 -0
  67. package/dist/compile/skill-format.js +50 -0
  68. package/dist/compile/skill-format.js.map +1 -0
  69. package/dist/compliance/check.d.ts +79 -0
  70. package/dist/compliance/check.d.ts.map +1 -0
  71. package/dist/compliance/check.js +224 -0
  72. package/dist/compliance/check.js.map +1 -0
  73. package/dist/compliance/config.d.ts +91 -0
  74. package/dist/compliance/config.d.ts.map +1 -0
  75. package/dist/compliance/config.js +173 -0
  76. package/dist/compliance/config.js.map +1 -0
  77. package/dist/compliance/findings.d.ts +70 -0
  78. package/dist/compliance/findings.d.ts.map +1 -0
  79. package/dist/compliance/findings.js +132 -0
  80. package/dist/compliance/findings.js.map +1 -0
  81. package/dist/compliance/gate-criterion.d.ts +87 -0
  82. package/dist/compliance/gate-criterion.d.ts.map +1 -0
  83. package/dist/compliance/gate-criterion.js +168 -0
  84. package/dist/compliance/gate-criterion.js.map +1 -0
  85. package/dist/compliance/install.d.ts +135 -0
  86. package/dist/compliance/install.d.ts.map +1 -0
  87. package/dist/compliance/install.js +291 -0
  88. package/dist/compliance/install.js.map +1 -0
  89. package/dist/compliance/report.d.ts +144 -0
  90. package/dist/compliance/report.d.ts.map +1 -0
  91. package/dist/compliance/report.js +347 -0
  92. package/dist/compliance/report.js.map +1 -0
  93. package/dist/compliance/resolver.d.ts +65 -0
  94. package/dist/compliance/resolver.d.ts.map +1 -0
  95. package/dist/compliance/resolver.js +176 -0
  96. package/dist/compliance/resolver.js.map +1 -0
  97. package/dist/compliance/schema.d.ts +74 -0
  98. package/dist/compliance/schema.d.ts.map +1 -0
  99. package/dist/compliance/schema.js +474 -0
  100. package/dist/compliance/schema.js.map +1 -0
  101. package/dist/compliance/types.d.ts +140 -0
  102. package/dist/compliance/types.d.ts.map +1 -0
  103. package/dist/compliance/types.js +29 -0
  104. package/dist/compliance/types.js.map +1 -0
  105. package/dist/constitution/check.d.ts +22 -0
  106. package/dist/constitution/check.d.ts.map +1 -0
  107. package/dist/constitution/check.js +89 -0
  108. package/dist/constitution/check.js.map +1 -0
  109. package/dist/constitution/docx.d.ts +51 -0
  110. package/dist/constitution/docx.d.ts.map +1 -0
  111. package/dist/constitution/docx.js +157 -0
  112. package/dist/constitution/docx.js.map +1 -0
  113. package/dist/constitution/entries.d.ts +27 -0
  114. package/dist/constitution/entries.d.ts.map +1 -0
  115. package/dist/constitution/entries.js +65 -0
  116. package/dist/constitution/entries.js.map +1 -0
  117. package/dist/constitution/extract.d.ts +34 -0
  118. package/dist/constitution/extract.d.ts.map +1 -0
  119. package/dist/constitution/extract.js +117 -0
  120. package/dist/constitution/extract.js.map +1 -0
  121. package/dist/constitution/snapshot.d.ts +47 -0
  122. package/dist/constitution/snapshot.d.ts.map +1 -0
  123. package/dist/constitution/snapshot.js +159 -0
  124. package/dist/constitution/snapshot.js.map +1 -0
  125. package/dist/constitution/statements.d.ts +37 -0
  126. package/dist/constitution/statements.d.ts.map +1 -0
  127. package/dist/constitution/statements.js +64 -0
  128. package/dist/constitution/statements.js.map +1 -0
  129. package/dist/constitution/types.d.ts +80 -0
  130. package/dist/constitution/types.d.ts.map +1 -0
  131. package/dist/constitution/types.js +9 -0
  132. package/dist/constitution/types.js.map +1 -0
  133. package/dist/core/gate.d.ts +10 -0
  134. package/dist/core/gate.d.ts.map +1 -1
  135. package/dist/core/gate.js.map +1 -1
  136. package/dist/core/paths.d.ts +48 -0
  137. package/dist/core/paths.d.ts.map +1 -0
  138. package/dist/core/paths.js +57 -0
  139. package/dist/core/paths.js.map +1 -0
  140. package/dist/core/types.d.ts +12 -1
  141. package/dist/core/types.d.ts.map +1 -1
  142. package/dist/cost/hooks/registry.d.ts +44 -0
  143. package/dist/cost/hooks/registry.d.ts.map +1 -0
  144. package/dist/cost/hooks/registry.js +66 -0
  145. package/dist/cost/hooks/registry.js.map +1 -0
  146. package/dist/cost/pin.d.ts +63 -0
  147. package/dist/cost/pin.d.ts.map +1 -0
  148. package/dist/cost/pin.js +95 -0
  149. package/dist/cost/pin.js.map +1 -0
  150. package/dist/cost/providers/claude-code.d.ts +9 -2
  151. package/dist/cost/providers/claude-code.d.ts.map +1 -1
  152. package/dist/cost/providers/claude-code.js +10 -5
  153. package/dist/cost/providers/claude-code.js.map +1 -1
  154. package/dist/cost/providers/codex.d.ts +107 -0
  155. package/dist/cost/providers/codex.d.ts.map +1 -0
  156. package/dist/cost/providers/codex.js +283 -0
  157. package/dist/cost/providers/codex.js.map +1 -0
  158. package/dist/cost/providers/index.d.ts.map +1 -1
  159. package/dist/cost/providers/index.js +6 -0
  160. package/dist/cost/providers/index.js.map +1 -1
  161. package/dist/cost/rates.d.ts.map +1 -1
  162. package/dist/cost/rates.js +14 -0
  163. package/dist/cost/rates.js.map +1 -1
  164. package/dist/cost/report.d.ts +23 -1
  165. package/dist/cost/report.d.ts.map +1 -1
  166. package/dist/cost/report.js +26 -5
  167. package/dist/cost/report.js.map +1 -1
  168. package/dist/cost/sessions.d.ts +10 -1
  169. package/dist/cost/sessions.d.ts.map +1 -1
  170. package/dist/cost/sessions.js +10 -2
  171. package/dist/cost/sessions.js.map +1 -1
  172. package/dist/cost/sync.d.ts.map +1 -1
  173. package/dist/cost/sync.js +190 -5
  174. package/dist/cost/sync.js.map +1 -1
  175. package/dist/doctor/migrations/compliance-pack-drift.d.ts +62 -0
  176. package/dist/doctor/migrations/compliance-pack-drift.d.ts.map +1 -0
  177. package/dist/doctor/migrations/compliance-pack-drift.js +255 -0
  178. package/dist/doctor/migrations/compliance-pack-drift.js.map +1 -0
  179. package/dist/doctor/migrations/index.d.ts.map +1 -1
  180. package/dist/doctor/migrations/index.js +11 -0
  181. package/dist/doctor/migrations/index.js.map +1 -1
  182. package/dist/doctor/migrations/legacy-cost-hooks.d.ts.map +1 -1
  183. package/dist/doctor/migrations/legacy-cost-hooks.js +7 -4
  184. package/dist/doctor/migrations/legacy-cost-hooks.js.map +1 -1
  185. package/dist/doctor/migrations/missing-cost-shim.d.ts.map +1 -1
  186. package/dist/doctor/migrations/missing-cost-shim.js +5 -4
  187. package/dist/doctor/migrations/missing-cost-shim.js.map +1 -1
  188. package/dist/doctor/migrations/outdated-cost-hooks.d.ts.map +1 -1
  189. package/dist/doctor/migrations/outdated-cost-hooks.js +7 -4
  190. package/dist/doctor/migrations/outdated-cost-hooks.js.map +1 -1
  191. package/dist/doctor/runner.js +14 -0
  192. package/dist/doctor/runner.js.map +1 -1
  193. package/dist/doctor/types.d.ts +35 -3
  194. package/dist/doctor/types.d.ts.map +1 -1
  195. package/dist/menu/roster.d.ts.map +1 -1
  196. package/dist/menu/roster.js +5 -0
  197. package/dist/menu/roster.js.map +1 -1
  198. package/dist/metrics/report.d.ts.map +1 -1
  199. package/dist/metrics/report.js +11 -2
  200. package/dist/metrics/report.js.map +1 -1
  201. package/dist/review/findings-parser.d.ts +92 -0
  202. package/dist/review/findings-parser.d.ts.map +1 -0
  203. package/dist/review/findings-parser.js +196 -0
  204. package/dist/review/findings-parser.js.map +1 -0
  205. package/dist/setup/setup-compute.d.ts +10 -15
  206. package/dist/setup/setup-compute.d.ts.map +1 -1
  207. package/dist/setup/setup-compute.js +39 -0
  208. package/dist/setup/setup-compute.js.map +1 -1
  209. package/package.json +2 -2
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Compliance pack types.
3
+ *
4
+ * A pack carries four separable things, and keeping them separate is the whole
5
+ * design: **constraints** (guidance layers an agent reads on every phase),
6
+ * **controls** (structured data with a fail condition per control id),
7
+ * **exclusions** (what the pack deliberately does not cover, by control id), and
8
+ * **metadata**.
9
+ *
10
+ * Two distinctions in here are load-bearing and easy to conflate.
11
+ *
12
+ * `kind` answers *what the lifecycle trail can establish*. An `evidenced` control
13
+ * is one the artifact trail genuinely demonstrates — SOC 2 CC8.1, change
14
+ * management, is the only one in the shipped pack. A `checked-only` control
15
+ * operates over a running system ("the entity monitors system components for
16
+ * anomalies"), which no markdown file evidences; the pack supplies a fail
17
+ * condition an agent applies, and the trail records only that the check happened.
18
+ * Reporting a `checked-only` control as evidenced would be the overclaim this
19
+ * whole feature exists to prevent, in the one artifact a buyer hands an auditor.
20
+ *
21
+ * `check_kind` answers a different question: *who applies the fail condition*.
22
+ * `fails_when` is prose, so no code evaluates it — a `mechanical` control carries
23
+ * a `pattern` the diff check can apply itself, and an `agent` control is
24
+ * assessable only in an agent session. An unassessed control is never a pass.
25
+ *
26
+ * Requirements: compliance-packs/AC-1, AC-2, AC-3
27
+ */
28
+ import type { FindingSeverity, PhaseName } from '../core/types.js';
29
+ /** What the lifecycle trail can establish about a control. */
30
+ export type ControlKind = 'evidenced' | 'checked-only';
31
+ /** Who applies a control's fail condition. */
32
+ export type ControlCheckKind = 'agent' | 'mechanical';
33
+ /** Why a regime criterion is not covered. */
34
+ export type ExclusionReason = 'organizational' | 'not-yet-built';
35
+ /**
36
+ * Entitlement state of a pack.
37
+ *
38
+ * Only `unrestricted` exists in this release: the seam is built so that adding a
39
+ * licensed pack later changes the resolver and nothing else, but no code path
40
+ * checks a licence, contacts a network service, or reads a key.
41
+ */
42
+ export type PackEntitlement = 'unrestricted';
43
+ /** Pack metadata, from `pack.yaml`. */
44
+ export interface PackMeta {
45
+ /** Slug, matching the pack's directory name. */
46
+ id: string;
47
+ /** Human name of the regime, e.g. `SOC 2`. */
48
+ regime: string;
49
+ /** Pack content version, independent of the CLI version. */
50
+ version: string;
51
+ /**
52
+ * Industries the pack applies to. `['any']` for a regime that is not
53
+ * industry-scoped, which is every pack in this release.
54
+ */
55
+ industries: string[];
56
+ entitlement: PackEntitlement;
57
+ /**
58
+ * Who reviewed the control text, or `null` for an unreviewed draft. A null value
59
+ * obliges the pack to carry the unreviewed-draft notice, and obliges every
60
+ * report to state it.
61
+ */
62
+ reviewed_by: string | null;
63
+ }
64
+ /** One control of a regime. */
65
+ export interface Control {
66
+ /** The regime's own id, e.g. `CC8.1`. Never an AIDLC criterion id. */
67
+ id: string;
68
+ kind: ControlKind;
69
+ check_kind: ControlCheckKind;
70
+ /** Lifecycle phases this control applies to. */
71
+ phases: PhaseName[];
72
+ /** What the control requires, in the regime's terms. */
73
+ requires: string;
74
+ /** Where an agent should look. */
75
+ look_at: string;
76
+ /** A single decidable predicate over a diff hunk or an artifact path. */
77
+ fails_when: string;
78
+ /** Applied by the diff check; `mechanical` controls only. */
79
+ pattern?: string;
80
+ severity: FindingSeverity;
81
+ /**
82
+ * The artifact that evidences this control. Required on `evidenced`, and
83
+ * rejected on `checked-only` — a checked-only control has no evidence, and
84
+ * letting it name one is how a check becomes an attestation.
85
+ */
86
+ evidence_artifact?: string;
87
+ /**
88
+ * Anchor into an existing guidance layer whose rule this control restates, e.g.
89
+ * `secure-defaults#transport-and-data-protection`. Present so a verbatim
90
+ * restatement stays traceable to the layer it came from.
91
+ */
92
+ references?: string;
93
+ }
94
+ /** A regime criterion the pack deliberately does not cover. */
95
+ export interface Exclusion {
96
+ /** The regime's own id, e.g. `CC1.1`. */
97
+ id: string;
98
+ reason: ExclusionReason;
99
+ /** Required when the reason alone would misrepresent the boundary. */
100
+ note?: string;
101
+ }
102
+ /** A guidance layer a pack installs. */
103
+ export interface PackLayer {
104
+ name: string;
105
+ file: string;
106
+ /**
107
+ * Always true. Pack layers are delivered as a read-instruction regardless of
108
+ * size, bypassing the inline threshold that applies to framework layers,
109
+ * because inlining pack text into an emitted skill is forbidden outright.
110
+ */
111
+ always_pointer: true;
112
+ }
113
+ /** A validated pack. */
114
+ export interface Pack {
115
+ meta: PackMeta;
116
+ controls: Control[];
117
+ exclusions: Exclusion[];
118
+ layers: PackLayer[];
119
+ }
120
+ /** Why a pack could not be resolved. */
121
+ export type PackErrorCode = 'not-found' | 'unreadable' | 'invalid';
122
+ /** A pack that could not be loaded, with every reason found. */
123
+ export interface PackError {
124
+ code: PackErrorCode;
125
+ /** The pack id as asked for, so the message can name it. */
126
+ id: string;
127
+ /** Repo- or package-relative path, never an absolute one. */
128
+ path?: string;
129
+ /** Every problem found, not just the first — a pack is validated whole. */
130
+ errors: string[];
131
+ }
132
+ /** Resolution outcome. Never `null`: an absent pack has a reason. */
133
+ export type PackResult = {
134
+ ok: true;
135
+ pack: Pack;
136
+ } | {
137
+ ok: false;
138
+ error: PackError;
139
+ };
140
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/compliance/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEnE,8DAA8D;AAC9D,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC;AAEvD,8CAA8C;AAC9C,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,CAAC;AAEtD,6CAA6C;AAC7C,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC;AAE7C,uCAAuC;AACvC,MAAM,WAAW,QAAQ;IACvB,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,eAAe,CAAC;IAC7B;;;;OAIG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,+BAA+B;AAC/B,MAAM,WAAW,OAAO;IACtB,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,gDAAgD;IAChD,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,eAAe,CAAC;IACxB,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wCAAwC;AACxC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,cAAc,EAAE,IAAI,CAAC;CACtB;AAED,wBAAwB;AACxB,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;AAEnE,gEAAgE;AAChE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qEAAqE;AACrE,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Compliance pack types.
3
+ *
4
+ * A pack carries four separable things, and keeping them separate is the whole
5
+ * design: **constraints** (guidance layers an agent reads on every phase),
6
+ * **controls** (structured data with a fail condition per control id),
7
+ * **exclusions** (what the pack deliberately does not cover, by control id), and
8
+ * **metadata**.
9
+ *
10
+ * Two distinctions in here are load-bearing and easy to conflate.
11
+ *
12
+ * `kind` answers *what the lifecycle trail can establish*. An `evidenced` control
13
+ * is one the artifact trail genuinely demonstrates — SOC 2 CC8.1, change
14
+ * management, is the only one in the shipped pack. A `checked-only` control
15
+ * operates over a running system ("the entity monitors system components for
16
+ * anomalies"), which no markdown file evidences; the pack supplies a fail
17
+ * condition an agent applies, and the trail records only that the check happened.
18
+ * Reporting a `checked-only` control as evidenced would be the overclaim this
19
+ * whole feature exists to prevent, in the one artifact a buyer hands an auditor.
20
+ *
21
+ * `check_kind` answers a different question: *who applies the fail condition*.
22
+ * `fails_when` is prose, so no code evaluates it — a `mechanical` control carries
23
+ * a `pattern` the diff check can apply itself, and an `agent` control is
24
+ * assessable only in an agent session. An unassessed control is never a pass.
25
+ *
26
+ * Requirements: compliance-packs/AC-1, AC-2, AC-3
27
+ */
28
+ export {};
29
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/compliance/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Drift between the vision document and the snapshot it was last read from.
3
+ *
4
+ * Because statement ids are content-addressed, drift is a set difference: ids in
5
+ * the source and not the snapshot were **added**, ids in the snapshot and not the
6
+ * source were **removed** — and an edited statement shows up as one of each,
7
+ * which is the honest description of what happened.
8
+ *
9
+ * The three states that are not `ok` are reported explicitly rather than
10
+ * collapsing into "no drift". A check that cannot evaluate must say so; a silent
11
+ * no-op is indistinguishable from success (`design-reads-existing-seams`,
12
+ * 2026-09-03).
13
+ *
14
+ * Requirements: project-constitution/AC-12, project-constitution/AC-13,
15
+ * project-constitution/AC-15
16
+ *
17
+ * @module
18
+ */
19
+ import type { CheckReport } from './types.js';
20
+ /** Compare the recorded source against the snapshot. Never throws, never mutates. */
21
+ export declare function checkDrift(projectRoot: string): CheckReport;
22
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/constitution/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAQH,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7D,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAyC3D"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Drift between the vision document and the snapshot it was last read from.
3
+ *
4
+ * Because statement ids are content-addressed, drift is a set difference: ids in
5
+ * the source and not the snapshot were **added**, ids in the snapshot and not the
6
+ * source were **removed** — and an edited statement shows up as one of each,
7
+ * which is the honest description of what happened.
8
+ *
9
+ * The three states that are not `ok` are reported explicitly rather than
10
+ * collapsing into "no drift". A check that cannot evaluate must say so; a silent
11
+ * no-op is indistinguishable from success (`design-reads-existing-seams`,
12
+ * 2026-09-03).
13
+ *
14
+ * Requirements: project-constitution/AC-12, project-constitution/AC-13,
15
+ * project-constitution/AC-15
16
+ *
17
+ * @module
18
+ */
19
+ import { existsSync } from 'node:fs';
20
+ import { join } from 'node:path';
21
+ import { extractVision } from './extract.js';
22
+ import { readEntries } from './entries.js';
23
+ import { readSnapshot } from './snapshot.js';
24
+ import { splitStatements } from './statements.js';
25
+ /** Compare the recorded source against the snapshot. Never throws, never mutates. */
26
+ export function checkDrift(projectRoot) {
27
+ const snapshot = readSnapshot(projectRoot);
28
+ if (snapshot === null) {
29
+ return {
30
+ ...empty(null),
31
+ state: 'no-snapshot',
32
+ detail: 'no vision snapshot yet — run `aidlc constitution import <path>` first',
33
+ };
34
+ }
35
+ const source = join(projectRoot, snapshot.sourcePath);
36
+ if (!existsSync(source)) {
37
+ return {
38
+ ...empty(snapshot.sourcePath),
39
+ state: 'source-missing',
40
+ detail: `${snapshot.sourcePath} is recorded as the vision document but is not there`,
41
+ };
42
+ }
43
+ const extracted = extractVision(projectRoot, source);
44
+ if (!extracted.ok) {
45
+ return {
46
+ ...empty(snapshot.sourcePath),
47
+ state: 'source-unreadable',
48
+ detail: extracted.detail,
49
+ };
50
+ }
51
+ const currentIds = new Set(splitStatements(extracted.text).map((s) => s.id));
52
+ const snapshotIds = new Set(snapshot.statements.map((s) => s.id));
53
+ const added = [...currentIds].filter((id) => !snapshotIds.has(id)).sort();
54
+ const removed = [...snapshotIds].filter((id) => !currentIds.has(id)).sort();
55
+ return {
56
+ state: 'ok',
57
+ source_path: snapshot.sourcePath,
58
+ added,
59
+ removed,
60
+ affected_entries: affectedEntries(projectRoot, new Set(removed)),
61
+ };
62
+ }
63
+ /**
64
+ * Constitution entries whose cited statement is gone. This is the part a human
65
+ * has to act on: the prose is still there, but the vision no longer says what it
66
+ * was derived from (AC-13).
67
+ */
68
+ function affectedEntries(projectRoot, removed) {
69
+ if (removed.size === 0)
70
+ return [];
71
+ const affected = [];
72
+ for (const entry of readEntries(projectRoot)) {
73
+ for (const cite of entry.cites) {
74
+ if (removed.has(cite))
75
+ affected.push({ entry: entry.id, cites: cite, line: entry.line });
76
+ }
77
+ }
78
+ return affected;
79
+ }
80
+ function empty(sourcePath) {
81
+ return {
82
+ state: 'ok',
83
+ source_path: sourcePath,
84
+ added: [],
85
+ removed: [],
86
+ affected_entries: [],
87
+ };
88
+ }
89
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/constitution/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `.docx` text extraction with no runtime dependency (design D2, D3).
3
+ *
4
+ * A `.docx` is a ZIP archive whose main text part is `word/document.xml`. Node's
5
+ * `zlib.inflateRawSync` decompresses a deflated ZIP entry directly, so reading
6
+ * one needs ~100 lines rather than a fifth runtime dependency (AC-2).
7
+ *
8
+ * Two deliberate choices, both probed against real archives before adopting:
9
+ *
10
+ * 1. **Sizes come from the central directory, never the local header.** A writer
11
+ * that streams uses a data descriptor (general-purpose bit 3) and writes
12
+ * zeroes for the compressed size in the *local* header. The central directory
13
+ * is always authoritative.
14
+ * 2. **No XML parser is constructed.** Tags are stripped textually, so XXE and
15
+ * entity-expansion have no surface here at all (design NFR-3). Unknown markup
16
+ * degrades to its text content rather than leaking angle brackets (risk R1).
17
+ *
18
+ * Requirements: project-constitution/AC-3, project-constitution/AC-5
19
+ *
20
+ * @module
21
+ */
22
+ /** The only part of a `.docx` this reader wants. */
23
+ export declare const DOCX_MAIN_PART = "word/document.xml";
24
+ /** A ZIP this reader cannot make sense of, or one whose entry exceeds the cap. */
25
+ export declare class ZipReadError extends Error {
26
+ readonly code: 'not-a-zip' | 'malformed' | 'entry-too-large' | 'unsupported-method';
27
+ constructor(message: string, code: 'not-a-zip' | 'malformed' | 'entry-too-large' | 'unsupported-method');
28
+ }
29
+ /**
30
+ * Read one entry out of a ZIP archive by exact name.
31
+ *
32
+ * @param buf - The whole archive.
33
+ * @param name - Entry name, matched exactly (`word/document.xml`).
34
+ * @param maxInflated - Refuse any entry declaring or producing more than this
35
+ * many bytes, so a malicious archive cannot exhaust memory (AC-5).
36
+ * @returns The entry's bytes, or `null` when the archive has no such entry.
37
+ * @throws ZipReadError when the archive is not readable as a ZIP.
38
+ */
39
+ export declare function readZipEntry(buf: Buffer, name: string, maxInflated: number): Buffer | null;
40
+ /**
41
+ * Convert WordprocessingML to plain text.
42
+ *
43
+ * `</w:p>` ends a paragraph, `<w:br/>` and `<w:cr/>` are line breaks, `<w:tab/>`
44
+ * is a tab. Every other tag is dropped and its text content kept, which is what
45
+ * makes unknown markup (tables, revision marks, smart tags) degrade safely.
46
+ *
47
+ * Entity decoding runs with `&amp;` LAST — decoding it first would turn a
48
+ * literal `&amp;lt;` into `<` (AC-3, design D3).
49
+ */
50
+ export declare function docxToText(xml: string): string;
51
+ //# sourceMappingURL=docx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx.d.ts","sourceRoot":"","sources":["../../src/constitution/docx.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAeH,oDAAoD;AACpD,eAAO,MAAM,cAAc,sBAAsB,CAAC;AAElD,kFAAkF;AAClF,qBAAa,YAAa,SAAQ,KAAK;IAGnC,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,iBAAiB,GAAG,oBAAoB;gBADnF,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,iBAAiB,GAAG,oBAAoB;CAKtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiC1F;AAgED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgB9C"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * `.docx` text extraction with no runtime dependency (design D2, D3).
3
+ *
4
+ * A `.docx` is a ZIP archive whose main text part is `word/document.xml`. Node's
5
+ * `zlib.inflateRawSync` decompresses a deflated ZIP entry directly, so reading
6
+ * one needs ~100 lines rather than a fifth runtime dependency (AC-2).
7
+ *
8
+ * Two deliberate choices, both probed against real archives before adopting:
9
+ *
10
+ * 1. **Sizes come from the central directory, never the local header.** A writer
11
+ * that streams uses a data descriptor (general-purpose bit 3) and writes
12
+ * zeroes for the compressed size in the *local* header. The central directory
13
+ * is always authoritative.
14
+ * 2. **No XML parser is constructed.** Tags are stripped textually, so XXE and
15
+ * entity-expansion have no surface here at all (design NFR-3). Unknown markup
16
+ * degrades to its text content rather than leaking angle brackets (risk R1).
17
+ *
18
+ * Requirements: project-constitution/AC-3, project-constitution/AC-5
19
+ *
20
+ * @module
21
+ */
22
+ import { inflateRawSync } from 'node:zlib';
23
+ /** ZIP signatures. */
24
+ const SIG_EOCD = 0x06054b50;
25
+ const SIG_CENTRAL = 0x02014b50;
26
+ const SIG_LOCAL = 0x04034b50;
27
+ /** Fixed size of the end-of-central-directory record, without any comment. */
28
+ const EOCD_MIN = 22;
29
+ /** Largest trailing comment a ZIP may carry, so the backward scan is bounded. */
30
+ const MAX_COMMENT = 0xffff;
31
+ /** The only part of a `.docx` this reader wants. */
32
+ export const DOCX_MAIN_PART = 'word/document.xml';
33
+ /** A ZIP this reader cannot make sense of, or one whose entry exceeds the cap. */
34
+ export class ZipReadError extends Error {
35
+ code;
36
+ constructor(message, code) {
37
+ super(message);
38
+ this.code = code;
39
+ this.name = 'ZipReadError';
40
+ }
41
+ }
42
+ /**
43
+ * Read one entry out of a ZIP archive by exact name.
44
+ *
45
+ * @param buf - The whole archive.
46
+ * @param name - Entry name, matched exactly (`word/document.xml`).
47
+ * @param maxInflated - Refuse any entry declaring or producing more than this
48
+ * many bytes, so a malicious archive cannot exhaust memory (AC-5).
49
+ * @returns The entry's bytes, or `null` when the archive has no such entry.
50
+ * @throws ZipReadError when the archive is not readable as a ZIP.
51
+ */
52
+ export function readZipEntry(buf, name, maxInflated) {
53
+ const eocd = findEocd(buf);
54
+ const entryCount = buf.readUInt16LE(eocd + 10);
55
+ let p = buf.readUInt32LE(eocd + 16);
56
+ for (let n = 0; n < entryCount; n++) {
57
+ if (p + 46 > buf.length || buf.readUInt32LE(p) !== SIG_CENTRAL) {
58
+ throw new ZipReadError('central directory entry is malformed', 'malformed');
59
+ }
60
+ const method = buf.readUInt16LE(p + 10);
61
+ const compressedSize = buf.readUInt32LE(p + 20);
62
+ const uncompressedSize = buf.readUInt32LE(p + 24);
63
+ const nameLen = buf.readUInt16LE(p + 28);
64
+ const extraLen = buf.readUInt16LE(p + 30);
65
+ const commentLen = buf.readUInt16LE(p + 32);
66
+ const localOffset = buf.readUInt32LE(p + 42);
67
+ const entryName = buf.toString('utf8', p + 46, p + 46 + nameLen);
68
+ if (entryName === name) {
69
+ // Declared size first: refuse before allocating anything (AC-5).
70
+ if (uncompressedSize > maxInflated) {
71
+ throw new ZipReadError(`${name} declares ${uncompressedSize} bytes, over the ${maxInflated}-byte limit`, 'entry-too-large');
72
+ }
73
+ return readLocalEntry(buf, localOffset, method, compressedSize, maxInflated, name);
74
+ }
75
+ p += 46 + nameLen + extraLen + commentLen;
76
+ }
77
+ return null;
78
+ }
79
+ /** Locate the end-of-central-directory record by bounded backward scan. */
80
+ function findEocd(buf) {
81
+ if (buf.length < EOCD_MIN) {
82
+ throw new ZipReadError('file is too short to be a ZIP archive', 'not-a-zip');
83
+ }
84
+ const floor = Math.max(0, buf.length - EOCD_MIN - MAX_COMMENT);
85
+ for (let i = buf.length - EOCD_MIN; i >= floor; i--) {
86
+ if (buf.readUInt32LE(i) === SIG_EOCD)
87
+ return i;
88
+ }
89
+ throw new ZipReadError('no end-of-central-directory record — not a ZIP archive', 'not-a-zip');
90
+ }
91
+ /** Read and decompress the entry body the central directory pointed at. */
92
+ function readLocalEntry(buf, localOffset, method, compressedSize, maxInflated, name) {
93
+ if (localOffset + 30 > buf.length || buf.readUInt32LE(localOffset) !== SIG_LOCAL) {
94
+ throw new ZipReadError(`${name} has no local file header`, 'malformed');
95
+ }
96
+ const nameLen = buf.readUInt16LE(localOffset + 26);
97
+ const extraLen = buf.readUInt16LE(localOffset + 28);
98
+ const start = localOffset + 30 + nameLen + extraLen;
99
+ const end = start + compressedSize;
100
+ if (end > buf.length) {
101
+ throw new ZipReadError(`${name} extends past the end of the archive`, 'malformed');
102
+ }
103
+ const raw = buf.subarray(start, end);
104
+ if (method === 0) {
105
+ if (raw.length > maxInflated) {
106
+ throw new ZipReadError(`${name} is ${raw.length} bytes, over the ${maxInflated}-byte limit`, 'entry-too-large');
107
+ }
108
+ return raw;
109
+ }
110
+ if (method !== 8) {
111
+ throw new ZipReadError(`${name} uses unsupported compression method ${method}`, 'unsupported-method');
112
+ }
113
+ // maxOutputLength makes zlib itself refuse an over-large expansion, so a
114
+ // lying central directory cannot get past the declared-size check above.
115
+ try {
116
+ return inflateRawSync(raw, { maxOutputLength: maxInflated });
117
+ }
118
+ catch (err) {
119
+ const message = err instanceof Error ? err.message : String(err);
120
+ if (/maxOutputLength|buffer/i.test(message)) {
121
+ throw new ZipReadError(`${name} inflates past the ${maxInflated}-byte limit`, 'entry-too-large');
122
+ }
123
+ throw new ZipReadError(`${name} could not be decompressed: ${message}`, 'malformed');
124
+ }
125
+ }
126
+ /**
127
+ * Convert WordprocessingML to plain text.
128
+ *
129
+ * `</w:p>` ends a paragraph, `<w:br/>` and `<w:cr/>` are line breaks, `<w:tab/>`
130
+ * is a tab. Every other tag is dropped and its text content kept, which is what
131
+ * makes unknown markup (tables, revision marks, smart tags) degrade safely.
132
+ *
133
+ * Entity decoding runs with `&amp;` LAST — decoding it first would turn a
134
+ * literal `&amp;lt;` into `<` (AC-3, design D3).
135
+ */
136
+ export function docxToText(xml) {
137
+ const withBreaks = xml
138
+ .replace(/<w:tab\b[^>]*\/?>/g, '\t')
139
+ .replace(/<w:(?:br|cr)\b[^>]*\/?>/g, '\n')
140
+ .replace(/<\/w:p>/g, '\n\n');
141
+ const stripped = withBreaks.replace(/<[^>]*>/g, '');
142
+ return stripped
143
+ .replace(/&lt;/g, '<')
144
+ .replace(/&gt;/g, '>')
145
+ .replace(/&quot;/g, '"')
146
+ .replace(/&apos;/g, "'")
147
+ .replace(/&#(\d+);/g, (_, d) => safeCodePoint(Number(d)))
148
+ .replace(/&#x([0-9a-fA-F]+);/g, (_, h) => safeCodePoint(parseInt(h, 16)))
149
+ .replace(/&amp;/g, '&');
150
+ }
151
+ /** Numeric character references, ignoring anything outside Unicode. */
152
+ function safeCodePoint(code) {
153
+ if (!Number.isInteger(code) || code < 0 || code > 0x10ffff)
154
+ return '';
155
+ return String.fromCodePoint(code);
156
+ }
157
+ //# sourceMappingURL=docx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx.js","sourceRoot":"","sources":["../../src/constitution/docx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Parse `.aidlc/context/constitution.md` for its scope and prohibition entries.
3
+ *
4
+ * The grammar is deliberately narrow, and only two things are read: the entry id
5
+ * and the `V-…` statement ids it cites. Everything else on the line is prose the
6
+ * human owns.
7
+ *
8
+ * - IN-1 [V-a1b2c3d4]: the repo builds the ingest pipeline
9
+ * - NOT-2 [V-e5f6a7b8, V-11223344]: it never stores customer PII
10
+ *
11
+ * Bold variants are accepted the way the AC parser accepts them, because someone
12
+ * will write one.
13
+ *
14
+ * Requirements: project-constitution/AC-13
15
+ *
16
+ * @module
17
+ */
18
+ import type { Entry } from './types.js';
19
+ /** Where the constitution lives, relative to the project root. */
20
+ export declare const CONSTITUTION_RELATIVE: string;
21
+ export declare function constitutionPath(projectRoot: string): string;
22
+ export declare function constitutionExists(projectRoot: string): boolean;
23
+ /** Parse entries out of constitution markdown. Pure over text. */
24
+ export declare function parseEntries(markdown: string): Entry[];
25
+ /** Read and parse the project's constitution, or `[]` when there is none. */
26
+ export declare function readEntries(projectRoot: string): Entry[];
27
+ //# sourceMappingURL=entries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/constitution/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,kEAAkE;AAClE,eAAO,MAAM,qBAAqB,QAA+C,CAAC;AAYlF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,EAAE,CAkBtD;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,KAAK,EAAE,CAOxD"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Parse `.aidlc/context/constitution.md` for its scope and prohibition entries.
3
+ *
4
+ * The grammar is deliberately narrow, and only two things are read: the entry id
5
+ * and the `V-…` statement ids it cites. Everything else on the line is prose the
6
+ * human owns.
7
+ *
8
+ * - IN-1 [V-a1b2c3d4]: the repo builds the ingest pipeline
9
+ * - NOT-2 [V-e5f6a7b8, V-11223344]: it never stores customer PII
10
+ *
11
+ * Bold variants are accepted the way the AC parser accepts them, because someone
12
+ * will write one.
13
+ *
14
+ * Requirements: project-constitution/AC-13
15
+ *
16
+ * @module
17
+ */
18
+ import { existsSync, readFileSync } from 'node:fs';
19
+ import { join } from 'node:path';
20
+ /** Where the constitution lives, relative to the project root. */
21
+ export const CONSTITUTION_RELATIVE = join('.aidlc', 'context', 'constitution.md');
22
+ /**
23
+ * An entry line: a dash bullet, an `IN-`/`NOT-` id with optional bold, then the
24
+ * citation bracket. Emphasis is coupled — `- **IN-1: ...` does not match, the
25
+ * same near-miss rule the AC grammar uses.
26
+ */
27
+ const ENTRY_RE = /^\s*-\s+(?:(IN|NOT)-([1-9][0-9]*)|\*\*(IN|NOT)-([1-9][0-9]*)\*\*)\s*\[([^\]]*)\]\s*:/;
28
+ /** A statement id anywhere inside the citation bracket. */
29
+ const CITE_RE = /V-[0-9a-f]{8}/g;
30
+ export function constitutionPath(projectRoot) {
31
+ return join(projectRoot, CONSTITUTION_RELATIVE);
32
+ }
33
+ export function constitutionExists(projectRoot) {
34
+ return existsSync(constitutionPath(projectRoot));
35
+ }
36
+ /** Parse entries out of constitution markdown. Pure over text. */
37
+ export function parseEntries(markdown) {
38
+ const entries = [];
39
+ const lines = markdown.split('\n');
40
+ for (let i = 0; i < lines.length; i++) {
41
+ const match = ENTRY_RE.exec(lines[i]);
42
+ if (!match)
43
+ continue;
44
+ const prefix = match[1] ?? match[3];
45
+ const number = match[2] ?? match[4];
46
+ entries.push({
47
+ id: `${prefix}-${number}`,
48
+ kind: prefix === 'IN' ? 'in-scope' : 'prohibition',
49
+ cites: [...new Set(match[5].match(CITE_RE) ?? [])],
50
+ line: i + 1,
51
+ });
52
+ }
53
+ return entries;
54
+ }
55
+ /** Read and parse the project's constitution, or `[]` when there is none. */
56
+ export function readEntries(projectRoot) {
57
+ const file = constitutionPath(projectRoot);
58
+ try {
59
+ return parseEntries(readFileSync(file, 'utf8'));
60
+ }
61
+ catch {
62
+ return [];
63
+ }
64
+ }
65
+ //# sourceMappingURL=entries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entries.js","sourceRoot":"","sources":["../../src/constitution/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,kEAAkE;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAElF;;;;GAIG;AACH,MAAM,QAAQ,GAAG,sFAAsF,CAAC;AAExG,2DAA2D;AAC3D,MAAM,OAAO,GAAG,gBAAgB,CAAC;AAEjC,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,OAAO,UAAU,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC;YACX,EAAE,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE;YACzB,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa;YAClD,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAClD,IAAI,EAAE,CAAC,GAAG,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,MAAM,IAAI,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}