human-to-code 0.1.27 → 0.1.28

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 (68) hide show
  1. package/Readme.md +56 -36
  2. package/dist/agents/direct/file-memory.d.ts.map +1 -1
  3. package/dist/agents/direct/file-memory.js +70 -1
  4. package/dist/agents/direct/file-memory.js.map +1 -1
  5. package/dist/agents/direct/generation-client.d.ts +10 -0
  6. package/dist/agents/direct/generation-client.d.ts.map +1 -1
  7. package/dist/agents/direct/generation-client.js +19 -0
  8. package/dist/agents/direct/generation-client.js.map +1 -1
  9. package/dist/agents/direct/index.d.ts +3 -0
  10. package/dist/agents/direct/index.d.ts.map +1 -1
  11. package/dist/agents/direct/index.js +3 -0
  12. package/dist/agents/direct/index.js.map +1 -1
  13. package/dist/agents/direct/presentation.d.ts +20 -0
  14. package/dist/agents/direct/presentation.d.ts.map +1 -1
  15. package/dist/agents/direct/presentation.js +33 -3
  16. package/dist/agents/direct/presentation.js.map +1 -1
  17. package/dist/agents/direct/project-blueprint.d.ts +29 -0
  18. package/dist/agents/direct/project-blueprint.d.ts.map +1 -0
  19. package/dist/agents/direct/project-blueprint.js +170 -0
  20. package/dist/agents/direct/project-blueprint.js.map +1 -0
  21. package/dist/agents/direct/project-contracts.d.ts +34 -0
  22. package/dist/agents/direct/project-contracts.d.ts.map +1 -1
  23. package/dist/agents/direct/project-contracts.js +59 -42
  24. package/dist/agents/direct/project-contracts.js.map +1 -1
  25. package/dist/agents/direct/project-memory.d.ts +6 -0
  26. package/dist/agents/direct/project-memory.d.ts.map +1 -1
  27. package/dist/agents/direct/project-memory.js +20 -0
  28. package/dist/agents/direct/project-memory.js.map +1 -1
  29. package/dist/agents/direct/reference-validation.d.ts +55 -0
  30. package/dist/agents/direct/reference-validation.d.ts.map +1 -0
  31. package/dist/agents/direct/reference-validation.js +415 -0
  32. package/dist/agents/direct/reference-validation.js.map +1 -0
  33. package/dist/agents/direct/types.d.ts +45 -0
  34. package/dist/agents/direct/types.d.ts.map +1 -1
  35. package/dist/agents/direct/unit-todos.d.ts +51 -0
  36. package/dist/agents/direct/unit-todos.d.ts.map +1 -0
  37. package/dist/agents/direct/unit-todos.js +223 -0
  38. package/dist/agents/direct/unit-todos.js.map +1 -0
  39. package/dist/cli.d.ts.map +1 -1
  40. package/dist/cli.js +147 -10
  41. package/dist/cli.js.map +1 -1
  42. package/dist/config/config.d.ts +22 -1
  43. package/dist/config/config.d.ts.map +1 -1
  44. package/dist/config/config.js +40 -6
  45. package/dist/config/config.js.map +1 -1
  46. package/dist/prompts/direct-blueprint.d.ts +19 -0
  47. package/dist/prompts/direct-blueprint.d.ts.map +1 -0
  48. package/dist/prompts/direct-blueprint.js +49 -0
  49. package/dist/prompts/direct-blueprint.js.map +1 -0
  50. package/dist/prompts/direct-conversion.d.ts +8 -0
  51. package/dist/prompts/direct-conversion.d.ts.map +1 -1
  52. package/dist/prompts/direct-conversion.js +26 -0
  53. package/dist/prompts/direct-conversion.js.map +1 -1
  54. package/dist/prompts/direct-todos.d.ts +17 -0
  55. package/dist/prompts/direct-todos.d.ts.map +1 -0
  56. package/dist/prompts/direct-todos.js +43 -0
  57. package/dist/prompts/direct-todos.js.map +1 -0
  58. package/dist/prompts/index.d.ts +2 -0
  59. package/dist/prompts/index.d.ts.map +1 -1
  60. package/dist/prompts/index.js +2 -0
  61. package/dist/prompts/index.js.map +1 -1
  62. package/dist/providers/provider.d.ts.map +1 -1
  63. package/dist/providers/provider.js +3 -1
  64. package/dist/providers/provider.js.map +1 -1
  65. package/docs/ARCHITECTURE.md +23 -6
  66. package/docs/CONFIGURATION.md +251 -0
  67. package/docs/MODULES.md +5 -2
  68. package/package.json +1 -1
@@ -0,0 +1,55 @@
1
+ /** Files whose cross-references this module understands. */
2
+ export declare const REFERENCE_EXTENSIONS: Set<string>;
3
+ /**
4
+ * `blocking` marks a broken reference — a name used that exists nowhere, or a
5
+ * state change that cannot take effect. `advisory` marks drift that is usually
6
+ * a defect but has legitimate uses (utility classes, a11y helpers).
7
+ *
8
+ * The severity is a priority label, not a gate. The CLI reports findings and
9
+ * feeds them to reconciliation; it does not refuse to write on a blocking
10
+ * finding, because a page that renders correctly can still trip one — the
11
+ * hidden-attribute check fires on real but cosmetic defects. Use
12
+ * {@link hasBlockingFindings} if you want a caller-side gate.
13
+ */
14
+ export type ReferenceSeverity = "blocking" | "advisory";
15
+ export type ReferenceFindingCode = "JS_SELECTOR_MISSING" | "HTML_ASSET_MISSING" | "STATE_CLASS_DEFEATED" | "HIDDEN_ATTRIBUTE_OVERRIDDEN" | "HTML_CLASS_UNSTYLED" | "CSS_SELECTOR_UNUSED";
16
+ export interface ReferenceFinding {
17
+ code: ReferenceFindingCode;
18
+ severity: ReferenceSeverity;
19
+ /** Project-relative file the finding is about. */
20
+ path: string;
21
+ /** Bounded, single-line explanation safe to show and to send as a repair hint. */
22
+ detail: string;
23
+ }
24
+ export interface ReferenceFile {
25
+ /** Project-relative POSIX path. */
26
+ path: string;
27
+ content: string;
28
+ /** True when this file is a candidate from the current run. */
29
+ generated: boolean;
30
+ }
31
+ interface CssRule {
32
+ selectors: string[];
33
+ declarations: Map<string, string>;
34
+ order: number;
35
+ }
36
+ /**
37
+ * Walk style rules with brace awareness so rules nested in `@media`/`@supports`
38
+ * are still seen and statement at-rules such as `@import` do not leak into the
39
+ * next selector.
40
+ */
41
+ export declare function scanCssRules(content: string): CssRule[];
42
+ /** CSS specificity as (ids, classes+attributes+pseudo-classes, elements+pseudo-elements). */
43
+ export declare function selectorSpecificity(selector: string): readonly [number, number, number];
44
+ /**
45
+ * Cross-check the supplied web files against one another. Only files produced
46
+ * by this run are reported against, so a pre-existing inconsistency in the
47
+ * working tree never blocks a run that did not touch it.
48
+ */
49
+ export declare function collectReferenceFindings(files: readonly ReferenceFile[]): ReferenceFinding[];
50
+ /** True when any finding must stop the run before files are written. */
51
+ export declare function hasBlockingFindings(findings: readonly ReferenceFinding[]): boolean;
52
+ /** Group findings by the file that has to change, for bounded repair. */
53
+ export declare function findingsByPath(findings: readonly ReferenceFinding[]): Map<string, ReferenceFinding[]>;
54
+ export {};
55
+ //# sourceMappingURL=reference-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-validation.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/reference-validation.ts"],"names":[],"mappings":"AAaA,4DAA4D;AAC5D,eAAO,MAAM,oBAAoB,aAA4D,CAAC;AAE9F;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,UAAU,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAC5B,qBAAqB,GACrB,oBAAoB,GACpB,sBAAsB,GACtB,6BAA6B,GAC7B,qBAAqB,GACrB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;CACpB;AAoBD,UAAU,OAAO;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf;AA2BD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CA2CvD;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAgBvF;AA4DD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,gBAAgB,EAAE,CA2M5F;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GAAG,OAAO,CAElF;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAQjC"}
@@ -0,0 +1,415 @@
1
+ /**
2
+ * Deterministic cross-file reference checking for generated web output. It
3
+ * answers one question the per-file syntax gate cannot: do the files that were
4
+ * generated independently actually agree with each other? Source is never
5
+ * executed and no model request is issued — every finding comes from the same
6
+ * static extractors ProjectMemory already uses.
7
+ *
8
+ * This is reference checking, not verification. A clean result means the named
9
+ * references line up, never that the project behaves correctly.
10
+ */
11
+ import { dirname, extname, resolve as resolvePath, sep } from "node:path";
12
+ import { cssFacts, htmlFacts, javaScriptFacts } from "./project-contracts.js";
13
+ /** Files whose cross-references this module understands. */
14
+ export const REFERENCE_EXTENSIONS = new Set([".html", ".htm", ".css", ".js", ".jsx", ".mjs"]);
15
+ const MAX_FINDINGS_PER_CODE = 12;
16
+ const MAX_DETAIL_CHARS = 220;
17
+ /** Only properties that can make content invisible are worth a blocking claim. */
18
+ const VISIBILITY_PROPERTIES = new Set(["opacity", "display", "visibility"]);
19
+ /**
20
+ * True when a declaration actually hides content. Comparing raw strings is not
21
+ * enough: `opacity:1 !important` and `opacity:1` differ textually but both
22
+ * reveal, and flagging that pair reports a working stylesheet as broken.
23
+ */
24
+ function hidesContent(property, value) {
25
+ const normalized = value.replace(/!important/u, "").trim().toLowerCase();
26
+ if (property === "opacity")
27
+ return Number.parseFloat(normalized) === 0;
28
+ if (property === "display")
29
+ return normalized === "none";
30
+ if (property === "visibility")
31
+ return normalized === "hidden" || normalized === "collapse";
32
+ return false;
33
+ }
34
+ function oneLine(value, limit = MAX_DETAIL_CHARS) {
35
+ const sanitized = value
36
+ .replace(/[\u0000-\u0008\u000b-\u001f\u007f]/gu, " ")
37
+ .replace(/\s+/gu, " ")
38
+ .trim();
39
+ return sanitized.length <= limit ? sanitized : `${sanitized.slice(0, Math.max(0, limit - 1))}…`;
40
+ }
41
+ function toPosix(path) {
42
+ return path.split(sep).join("/").replace(/^\.\//u, "");
43
+ }
44
+ function parseDeclarations(body) {
45
+ const declarations = new Map();
46
+ for (const part of body.split(";")) {
47
+ const colon = part.indexOf(":");
48
+ if (colon === -1)
49
+ continue;
50
+ const property = part.slice(0, colon).trim().toLowerCase();
51
+ const value = part.slice(colon + 1).trim();
52
+ if (property.length === 0 || value.length === 0)
53
+ continue;
54
+ declarations.set(property, value);
55
+ }
56
+ return declarations;
57
+ }
58
+ /**
59
+ * Walk style rules with brace awareness so rules nested in `@media`/`@supports`
60
+ * are still seen and statement at-rules such as `@import` do not leak into the
61
+ * next selector.
62
+ */
63
+ export function scanCssRules(content) {
64
+ const text = content.replace(/\/\*[\s\S]*?\*\//gu, " ");
65
+ const rules = [];
66
+ let prelude = "";
67
+ let order = 0;
68
+ let index = 0;
69
+ let groupDepth = 0;
70
+ while (index < text.length) {
71
+ const char = text[index];
72
+ if (char === "{") {
73
+ const head = prelude.trim();
74
+ prelude = "";
75
+ index += 1;
76
+ if (head.startsWith("@")) {
77
+ groupDepth += 1;
78
+ continue;
79
+ }
80
+ const end = text.indexOf("}", index);
81
+ const body = end === -1 ? text.slice(index) : text.slice(index, end);
82
+ const selectors = head.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
83
+ if (selectors.length > 0) {
84
+ rules.push({ selectors, declarations: parseDeclarations(body), order });
85
+ order += 1;
86
+ }
87
+ index = end === -1 ? text.length : end + 1;
88
+ continue;
89
+ }
90
+ if (char === "}") {
91
+ if (groupDepth > 0)
92
+ groupDepth -= 1;
93
+ prelude = "";
94
+ index += 1;
95
+ continue;
96
+ }
97
+ // A statement at-rule (`@import …;`, `@charset …;`) ends here, not at a brace.
98
+ if (char === ";") {
99
+ prelude = "";
100
+ index += 1;
101
+ continue;
102
+ }
103
+ prelude += char;
104
+ index += 1;
105
+ }
106
+ return rules;
107
+ }
108
+ /** CSS specificity as (ids, classes+attributes+pseudo-classes, elements+pseudo-elements). */
109
+ export function selectorSpecificity(selector) {
110
+ const cleaned = selector.replace(/\s*[>+~]\s*/gu, " ").trim();
111
+ const withoutPseudoElements = cleaned.replace(/::[A-Za-z-]+/gu, " ");
112
+ const ids = (cleaned.match(/#[A-Za-z0-9_-]+/gu) ?? []).length;
113
+ const classes = (cleaned.match(/\.[A-Za-z0-9_-]+/gu) ?? []).length;
114
+ const attributes = (cleaned.match(/\[[^\]]*\]/gu) ?? []).length;
115
+ const pseudoClasses = (withoutPseudoElements.match(/:[A-Za-z-]+/gu) ?? []).length;
116
+ const pseudoElements = (cleaned.match(/::[A-Za-z-]+/gu) ?? []).length;
117
+ const bare = withoutPseudoElements
118
+ .replace(/#[A-Za-z0-9_-]+/gu, " ")
119
+ .replace(/\.[A-Za-z0-9_-]+/gu, " ")
120
+ .replace(/\[[^\]]*\]/gu, " ")
121
+ .replace(/:[A-Za-z-]+(?:\([^)]*\))?/gu, " ")
122
+ .split(/\s+/u)
123
+ .filter((part) => /^[a-zA-Z][a-zA-Z0-9-]*$/u.test(part)).length;
124
+ return [ids, classes + attributes + pseudoClasses, bare + pseudoElements];
125
+ }
126
+ function comparesAtLeast(left, right) {
127
+ for (let index = 0; index < 3; index += 1) {
128
+ if (left[index] !== right[index])
129
+ return left[index] > right[index];
130
+ }
131
+ return true;
132
+ }
133
+ /** The rightmost compound selector — the element the rule actually styles. */
134
+ function subjectCompound(selector) {
135
+ const parts = selector.replace(/\s*[>+~]\s*/gu, " ").trim().split(/\s+/u);
136
+ return parts[parts.length - 1] ?? "";
137
+ }
138
+ function compoundClasses(compound) {
139
+ return new Set((compound.match(/\.[A-Za-z0-9_-]+/gu) ?? []).map((entry) => entry.slice(1)));
140
+ }
141
+ function isSubset(left, right) {
142
+ for (const value of left)
143
+ if (!right.has(value))
144
+ return false;
145
+ return true;
146
+ }
147
+ function selectorClassTokens(selector) {
148
+ return (selector.match(/\.[A-Za-z0-9_-]+/gu) ?? []).map((entry) => entry.slice(1));
149
+ }
150
+ function selectorIdTokens(selector) {
151
+ return (selector.match(/#[A-Za-z0-9_-]+/gu) ?? []).map((entry) => entry.slice(1));
152
+ }
153
+ function isExternalReference(reference) {
154
+ return /^(?:[a-z][a-z0-9+.-]*:|\/\/|#|data:)/iu.test(reference);
155
+ }
156
+ /** Resolve an HTML-relative reference to a project-relative POSIX path. */
157
+ function resolveReference(fromPath, reference) {
158
+ const withoutQuery = reference.split(/[?#]/u)[0] ?? "";
159
+ if (withoutQuery.length === 0)
160
+ return undefined;
161
+ if (withoutQuery.startsWith("/"))
162
+ return withoutQuery.slice(1);
163
+ const base = dirname(`/${fromPath}`);
164
+ const resolved = resolvePath(base, withoutQuery);
165
+ return toPosix(resolved).replace(/^\//u, "");
166
+ }
167
+ function push(findings, counts, finding) {
168
+ const seen = counts.get(finding.code) ?? 0;
169
+ if (seen >= MAX_FINDINGS_PER_CODE)
170
+ return;
171
+ counts.set(finding.code, seen + 1);
172
+ findings.push({ ...finding, detail: oneLine(finding.detail) });
173
+ }
174
+ /**
175
+ * Cross-check the supplied web files against one another. Only files produced
176
+ * by this run are reported against, so a pre-existing inconsistency in the
177
+ * working tree never blocks a run that did not touch it.
178
+ */
179
+ export function collectReferenceFindings(files) {
180
+ const html = files.filter((file) => [".html", ".htm"].includes(extname(file.path).toLowerCase()));
181
+ const css = files.filter((file) => extname(file.path).toLowerCase() === ".css");
182
+ const scripts = files.filter((file) => [".js", ".jsx", ".mjs"].includes(extname(file.path).toLowerCase()));
183
+ const findings = [];
184
+ const counts = new Map();
185
+ if (html.length === 0 && css.length === 0 && scripts.length === 0)
186
+ return findings;
187
+ const knownPaths = new Set(files.map((file) => file.path));
188
+ const htmlByFile = new Map(html.map((file) => [file.path, htmlFacts(file.content)]));
189
+ const cssByFile = new Map(css.map((file) => [file.path, cssFacts(file.content)]));
190
+ const scriptByFile = new Map(scripts.map((file) => [file.path, javaScriptFacts(file.content)]));
191
+ const htmlClasses = new Set();
192
+ const htmlIds = new Set();
193
+ for (const facts of htmlByFile.values()) {
194
+ for (const value of facts.classes)
195
+ if (value.length > 0)
196
+ htmlClasses.add(value);
197
+ for (const value of facts.ids)
198
+ if (value.length > 0)
199
+ htmlIds.add(value);
200
+ }
201
+ const cssSelectorClasses = new Set();
202
+ const cssSelectorIds = new Set();
203
+ for (const facts of cssByFile.values()) {
204
+ for (const selector of facts.selectors) {
205
+ for (const token of selectorClassTokens(selector))
206
+ cssSelectorClasses.add(token);
207
+ for (const token of selectorIdTokens(selector))
208
+ cssSelectorIds.add(token);
209
+ }
210
+ }
211
+ const toggledClasses = new Set();
212
+ for (const facts of scriptByFile.values()) {
213
+ for (const value of facts.toggledClasses)
214
+ if (value.length > 0)
215
+ toggledClasses.add(value);
216
+ }
217
+ // Blocking: a script queries a class or id that no markup in the project defines.
218
+ if (html.length > 0) {
219
+ for (const file of scripts) {
220
+ if (!file.generated)
221
+ continue;
222
+ const facts = scriptByFile.get(file.path);
223
+ for (const selector of new Set(facts.selectors)) {
224
+ for (const token of selectorIdTokens(selector)) {
225
+ if (!htmlIds.has(token)) {
226
+ push(findings, counts, {
227
+ code: "JS_SELECTOR_MISSING",
228
+ severity: "blocking",
229
+ path: file.path,
230
+ detail: `${file.path} queries "${selector}" but no id "${token}" exists in the generated markup.`,
231
+ });
232
+ }
233
+ }
234
+ for (const token of selectorClassTokens(selector)) {
235
+ if (!htmlClasses.has(token)) {
236
+ push(findings, counts, {
237
+ code: "JS_SELECTOR_MISSING",
238
+ severity: "blocking",
239
+ path: file.path,
240
+ detail: `${file.path} queries "${selector}" but no element with class "${token}" exists in the generated markup.`,
241
+ });
242
+ }
243
+ }
244
+ }
245
+ }
246
+ }
247
+ // Blocking: markup links a stylesheet or script that the project does not contain.
248
+ for (const file of html) {
249
+ if (!file.generated)
250
+ continue;
251
+ const facts = htmlByFile.get(file.path);
252
+ for (const reference of new Set([...facts.stylesheets, ...facts.scripts])) {
253
+ if (isExternalReference(reference))
254
+ continue;
255
+ const resolved = resolveReference(file.path, reference);
256
+ if (resolved === undefined || knownPaths.has(resolved))
257
+ continue;
258
+ push(findings, counts, {
259
+ code: "HTML_ASSET_MISSING",
260
+ severity: "blocking",
261
+ path: file.path,
262
+ detail: `${file.path} references "${reference}" but ${resolved} is not part of this project.`,
263
+ });
264
+ }
265
+ }
266
+ const rulesByFile = new Map(css.map((file) => [file.path, scanCssRules(file.content)]));
267
+ // Blocking: a class the script toggles to reveal content is outranked by a
268
+ // rule that hides the same element, so adding the class can never take effect.
269
+ for (const [path, rules] of rulesByFile) {
270
+ const file = css.find((entry) => entry.path === path);
271
+ if (!file.generated)
272
+ continue;
273
+ for (const stateClass of toggledClasses) {
274
+ for (const revealing of rules) {
275
+ for (const revealSelector of revealing.selectors) {
276
+ const revealSubject = subjectCompound(revealSelector);
277
+ const revealClasses = compoundClasses(revealSubject);
278
+ if (!revealClasses.has(stateClass))
279
+ continue;
280
+ for (const hiding of rules) {
281
+ for (const hideSelector of hiding.selectors) {
282
+ const hideClasses = compoundClasses(subjectCompound(hideSelector));
283
+ if (hideClasses.has(stateClass) || !isSubset(hideClasses, revealClasses))
284
+ continue;
285
+ for (const [property, hideValue] of hiding.declarations) {
286
+ if (!VISIBILITY_PROPERTIES.has(property))
287
+ continue;
288
+ const revealValue = revealing.declarations.get(property);
289
+ // Only a genuinely hiding value defeated by a revealing one is
290
+ // a defect; two rules that both reveal are not in conflict.
291
+ if (revealValue === undefined)
292
+ continue;
293
+ if (!hidesContent(property, hideValue) || hidesContent(property, revealValue))
294
+ continue;
295
+ const revealImportant = /!important/u.test(revealValue);
296
+ const hideImportant = /!important/u.test(hideValue);
297
+ if (revealImportant && !hideImportant)
298
+ continue;
299
+ if (!hideImportant && !revealImportant
300
+ && !comparesAtLeast(selectorSpecificity(hideSelector), selectorSpecificity(revealSelector))) {
301
+ continue;
302
+ }
303
+ push(findings, counts, {
304
+ code: "STATE_CLASS_DEFEATED",
305
+ severity: "blocking",
306
+ path,
307
+ detail: `"${hideSelector}" sets ${property}:${hideValue} and outranks "${revealSelector}"`
308
+ + ` (${property}:${revealValue}), so adding the "${stateClass}" class never reveals the element.`,
309
+ });
310
+ }
311
+ }
312
+ }
313
+ }
314
+ }
315
+ }
316
+ }
317
+ // Blocking: the script hides elements with the `hidden` attribute while the
318
+ // stylesheet gives them a `display`, which silently defeats hiding.
319
+ const hidesWithAttribute = [...scriptByFile.values()].some((facts) => facts.togglesHiddenAttribute);
320
+ if (hidesWithAttribute) {
321
+ // Name the rule the script actually operates on rather than whichever rule
322
+ // happens to set `display` first, so the hint points at the real fix.
323
+ const queriedClasses = new Set();
324
+ for (const facts of scriptByFile.values()) {
325
+ for (const selector of facts.selectors) {
326
+ for (const token of selectorClassTokens(selector))
327
+ queriedClasses.add(token);
328
+ }
329
+ }
330
+ for (const [path, rules] of rulesByFile) {
331
+ const file = css.find((entry) => entry.path === path);
332
+ if (!file.generated)
333
+ continue;
334
+ const handlesHidden = rules.some((rule) => rule.selectors.some((selector) => /\[hidden\]/u.test(selector)));
335
+ if (handlesHidden)
336
+ continue;
337
+ const laysOut = rules.filter((rule) => {
338
+ const display = rule.declarations.get("display");
339
+ return display !== undefined && !display.startsWith("none");
340
+ });
341
+ // Which element the script hides is a dataflow question this static pass
342
+ // cannot answer, so list the candidates rather than blaming one rule.
343
+ const candidates = laysOut
344
+ .flatMap((rule) => rule.selectors)
345
+ .filter((selector) => selectorClassTokens(subjectCompound(selector)).some((token) => queriedClasses.has(token)));
346
+ const named = (candidates.length > 0 ? candidates : laysOut.flatMap((rule) => rule.selectors)).slice(0, 3);
347
+ if (named.length === 0)
348
+ continue;
349
+ push(findings, counts, {
350
+ code: "HIDDEN_ATTRIBUTE_OVERRIDDEN",
351
+ severity: "blocking",
352
+ path,
353
+ detail: `A script toggles the hidden attribute, but ${path} has no [hidden] rule while`
354
+ + ` ${named.map((selector) => `"${selector}"`).join(", ")} set an explicit display,`
355
+ + ` so hidden elements still occupy layout. Add a [hidden] { display: none } rule.`,
356
+ });
357
+ }
358
+ }
359
+ // Advisory: markup class that no stylesheet styles.
360
+ if (css.length > 0) {
361
+ for (const file of html) {
362
+ if (!file.generated)
363
+ continue;
364
+ const facts = htmlByFile.get(file.path);
365
+ for (const value of new Set(facts.classes)) {
366
+ if (value.length === 0 || cssSelectorClasses.has(value) || toggledClasses.has(value))
367
+ continue;
368
+ push(findings, counts, {
369
+ code: "HTML_CLASS_UNSTYLED",
370
+ severity: "advisory",
371
+ path: file.path,
372
+ detail: `${file.path} uses class "${value}" that no generated stylesheet defines a rule for.`,
373
+ });
374
+ }
375
+ }
376
+ }
377
+ // Advisory: stylesheet rule that no markup or script can ever match.
378
+ if (html.length > 0) {
379
+ for (const file of css) {
380
+ if (!file.generated)
381
+ continue;
382
+ const facts = cssByFile.get(file.path);
383
+ const reported = new Set();
384
+ for (const selector of facts.selectors) {
385
+ for (const token of selectorClassTokens(selector)) {
386
+ if (htmlClasses.has(token) || toggledClasses.has(token) || reported.has(token))
387
+ continue;
388
+ reported.add(token);
389
+ push(findings, counts, {
390
+ code: "CSS_SELECTOR_UNUSED",
391
+ severity: "advisory",
392
+ path: file.path,
393
+ detail: `${file.path} styles class "${token}" that no generated markup or script uses.`,
394
+ });
395
+ }
396
+ }
397
+ }
398
+ }
399
+ return findings;
400
+ }
401
+ /** True when any finding must stop the run before files are written. */
402
+ export function hasBlockingFindings(findings) {
403
+ return findings.some((finding) => finding.severity === "blocking");
404
+ }
405
+ /** Group findings by the file that has to change, for bounded repair. */
406
+ export function findingsByPath(findings) {
407
+ const grouped = new Map();
408
+ for (const finding of findings) {
409
+ const bucket = grouped.get(finding.path) ?? [];
410
+ bucket.push(finding);
411
+ grouped.set(finding.path, bucket);
412
+ }
413
+ return grouped;
414
+ }
415
+ //# sourceMappingURL=reference-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-validation.js","sourceRoot":"","sources":["../../../src/agents/direct/reference-validation.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { StaticFileMemoryEntry } from "../../pipeline/file-memory.ts";
2
+ import type { UnitTodoList } from "./unit-todos.ts";
2
3
  export interface LanguageProfile {
3
4
  /** Output file extension without a dot. */
4
5
  ext: string;
@@ -36,6 +37,14 @@ export interface UnitGenerationContext {
36
37
  fileMemory?: string;
37
38
  /** Target-specific current/projected repository evidence. */
38
39
  projectMemory?: string;
40
+ /** Shared contract agreed for this run, when planning is enabled. */
41
+ blueprint?: string;
42
+ /** Rendered todo list for this target, when a todo pass ran. */
43
+ todos?: string;
44
+ /** Previous complete candidate; present only on a refinement pass. */
45
+ currentDraft?: string;
46
+ /** Todo items the deterministic coverage check did not find in the draft. */
47
+ unaddressedTodos?: readonly string[];
39
48
  }
40
49
  export interface ProjectRelationship {
41
50
  path: string;
@@ -61,6 +70,14 @@ export type ConversionProgress = {
61
70
  kind: "start";
62
71
  unit: ConversionUnit;
63
72
  attempt: number;
73
+ } | {
74
+ kind: "plan";
75
+ unit: ConversionUnit;
76
+ } | {
77
+ kind: "refine";
78
+ unit: ConversionUnit;
79
+ pass: number;
80
+ unaddressed: number;
64
81
  } | {
65
82
  kind: "done";
66
83
  unit: ConversionUnit;
@@ -69,6 +86,17 @@ export type ConversionProgress = {
69
86
  unit: ConversionUnit;
70
87
  reason: string;
71
88
  };
89
+ /** What one unit's planning passes produced, for honest run disclosure. */
90
+ export interface UnitPlanningOutcome {
91
+ unit: ConversionUnit;
92
+ todoRequests: number;
93
+ codingRequests: number;
94
+ /** Set when a refinement was generated and then rejected by the ratchet. */
95
+ refinementRejected?: string;
96
+ addressed: number;
97
+ unaddressed: number;
98
+ unverifiable: number;
99
+ }
72
100
  export interface GenerateUnitsOptions {
73
101
  /** Extra generation attempts when a unit trips the FileMemory guard or the provider errors. */
74
102
  retries?: number;
@@ -79,6 +107,15 @@ export interface GenerateUnitsOptions {
79
107
  projectMemory?: ProjectMemoryProvider;
80
108
  /** Total FileMemory + ProjectMemory character allowance for one request. */
81
109
  contextCharBudget?: number;
110
+ /**
111
+ * Per-unit todo planning. Returning undefined, or throwing, leaves the unit on
112
+ * the single-pass path: planning enriches context and must never fail a unit.
113
+ */
114
+ plan?: (unit: ConversionUnit, context: UnitGenerationContext) => Promise<UnitTodoList | undefined>;
115
+ /** Coding requests allowed per unit. 1 disables refinement entirely. */
116
+ maxCodingPasses?: number;
117
+ /** Collected per-unit planning outcomes, for run disclosure. */
118
+ onPlanningOutcome?: (outcome: UnitPlanningOutcome) => void;
82
119
  }
83
120
  export interface DirectDiscoveryNotice {
84
121
  code: "TARGET_EXISTS" | "UNSUPPORTED_MARKER_FILE" | "EXTENSION_CONFLICT" | "UNCONFIGURED_EXTENSION";
@@ -105,6 +142,14 @@ export interface GenerateOptions {
105
142
  fileMemory?: string;
106
143
  /** Compact current/projected repository evidence for this exact target. */
107
144
  projectMemory?: string;
145
+ /** Shared contract agreed for this run. */
146
+ blueprint?: string;
147
+ /** Rendered todo list for this target. */
148
+ todos?: string;
149
+ /** Previous complete candidate on a refinement pass. */
150
+ currentDraft?: string;
151
+ /** Todo items not found in the draft. */
152
+ unaddressedTodos?: readonly string[];
108
153
  signal?: AbortSignal;
109
154
  }
110
155
  export interface AppliedUnit {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { type BlueprintVocabularyKind } from "./project-blueprint.ts";
2
+ export interface UnitTodoExpectation {
3
+ kind: BlueprintVocabularyKind;
4
+ names: string[];
5
+ }
6
+ export interface UnitTodo {
7
+ id: string;
8
+ requirement: string;
9
+ expects?: UnitTodoExpectation;
10
+ }
11
+ export interface UnitTodoList {
12
+ todos: UnitTodo[];
13
+ }
14
+ export interface TodoCoverage {
15
+ /** Todo ids whose expected artifacts were all found in the candidate. */
16
+ addressed: string[];
17
+ /** Todo ids that promised artifacts the candidate does not contain. */
18
+ unaddressed: string[];
19
+ /** Todo ids with nothing statically checkable; disclosed, never gating. */
20
+ unverifiable: string[];
21
+ }
22
+ /** A refinement may not shrink a file below this fraction of the previous pass. */
23
+ export declare const MIN_REFINEMENT_LENGTH_RATIO = 0.6;
24
+ /**
25
+ * Strictly validate a todo list. When `allowedNames` is supplied, an expectation
26
+ * naming something outside the agreed vocabulary is dropped rather than
27
+ * rejected: the requirement text is still useful, and a stray name must never
28
+ * become a new instruction.
29
+ */
30
+ export declare function parseUnitTodoList(output: string, allowedNames?: ReadonlySet<string>): UnitTodoList;
31
+ /**
32
+ * Deterministically check which todos left a trace in the candidate. No model
33
+ * request, no execution. Generous on purpose: a false "addressed" only skips a
34
+ * refinement, while a false "unaddressed" would spend a request for nothing.
35
+ */
36
+ export declare function todoCoverage(todos: readonly UnitTodo[], targetPath: string, code: string): TodoCoverage;
37
+ /** Render unaddressed todos for a refinement request. */
38
+ export declare function unaddressedRequirements(todos: readonly UnitTodo[], coverage: TodoCoverage): string[];
39
+ /** Render a todo list into the block the coding prompt receives. */
40
+ export declare function renderTodoList(todos: readonly UnitTodo[]): string;
41
+ export interface ContractRegression {
42
+ /** Artifacts present in the previous pass and absent from the next one. */
43
+ lost: string[];
44
+ /** Next length divided by previous length. */
45
+ shrinkRatio: number;
46
+ }
47
+ /** Compare two passes over the same target. Empty `lost` plus an acceptable ratio means the refinement kept everything. */
48
+ export declare function contractRegression(targetPath: string, previous: string, next: string): ContractRegression;
49
+ /** The ratchet: a refinement is only accepted when it is a strict improvement in coverage terms. */
50
+ export declare function acceptsRefinement(regression: ContractRegression): boolean;
51
+ //# sourceMappingURL=unit-todos.d.ts.map