@zelari/core 0.7.12 → 0.7.14

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 (138) hide show
  1. package/dist/agents/councilApi.d.ts +135 -0
  2. package/dist/agents/councilApi.d.ts.map +1 -1
  3. package/dist/agents/councilApi.js +520 -7
  4. package/dist/agents/councilApi.js.map +1 -1
  5. package/dist/agents/roles.d.ts.map +1 -1
  6. package/dist/agents/roles.js +11 -3
  7. package/dist/agents/roles.js.map +1 -1
  8. package/dist/agents/toolSchemas.d.ts.map +1 -1
  9. package/dist/agents/toolSchemas.js +32 -3
  10. package/dist/agents/toolSchemas.js.map +1 -1
  11. package/dist/core/AgentHarness.d.ts +21 -0
  12. package/dist/core/AgentHarness.d.ts.map +1 -1
  13. package/dist/core/AgentHarness.js +153 -0
  14. package/dist/core/AgentHarness.js.map +1 -1
  15. package/dist/core/tools/builtin/filesystem.d.ts.map +1 -1
  16. package/dist/core/tools/builtin/filesystem.js +4 -2
  17. package/dist/core/tools/builtin/filesystem.js.map +1 -1
  18. package/dist/council/completion/buildCompletion.d.ts +23 -0
  19. package/dist/council/completion/buildCompletion.d.ts.map +1 -0
  20. package/dist/council/completion/buildCompletion.js +75 -0
  21. package/dist/council/completion/buildCompletion.js.map +1 -0
  22. package/dist/council/completion/index.d.ts +3 -0
  23. package/dist/council/completion/index.d.ts.map +1 -0
  24. package/dist/council/completion/index.js +3 -0
  25. package/dist/council/completion/index.js.map +1 -0
  26. package/dist/council/completion/types.d.ts +38 -0
  27. package/dist/council/completion/types.d.ts.map +1 -0
  28. package/dist/council/completion/types.js +2 -0
  29. package/dist/council/completion/types.js.map +1 -0
  30. package/dist/council/index.d.ts +4 -0
  31. package/dist/council/index.d.ts.map +1 -1
  32. package/dist/council/index.js +4 -0
  33. package/dist/council/index.js.map +1 -1
  34. package/dist/council/lessons/index.d.ts +7 -0
  35. package/dist/council/lessons/index.d.ts.map +1 -0
  36. package/dist/council/lessons/index.js +7 -0
  37. package/dist/council/lessons/index.js.map +1 -0
  38. package/dist/council/lessons/io.d.ts +5 -0
  39. package/dist/council/lessons/io.d.ts.map +1 -0
  40. package/dist/council/lessons/io.js +30 -0
  41. package/dist/council/lessons/io.js.map +1 -0
  42. package/dist/council/lessons/isAnswerLeak.d.ts +7 -0
  43. package/dist/council/lessons/isAnswerLeak.d.ts.map +1 -0
  44. package/dist/council/lessons/isAnswerLeak.js +26 -0
  45. package/dist/council/lessons/isAnswerLeak.js.map +1 -0
  46. package/dist/council/lessons/recallLessons.d.ts +8 -0
  47. package/dist/council/lessons/recallLessons.d.ts.map +1 -0
  48. package/dist/council/lessons/recallLessons.js +56 -0
  49. package/dist/council/lessons/recallLessons.js.map +1 -0
  50. package/dist/council/lessons/recordFailure.d.ts +7 -0
  51. package/dist/council/lessons/recordFailure.d.ts.map +1 -0
  52. package/dist/council/lessons/recordFailure.js +86 -0
  53. package/dist/council/lessons/recordFailure.js.map +1 -0
  54. package/dist/council/lessons/signatures.d.ts +6 -0
  55. package/dist/council/lessons/signatures.d.ts.map +1 -0
  56. package/dist/council/lessons/signatures.js +31 -0
  57. package/dist/council/lessons/signatures.js.map +1 -0
  58. package/dist/council/lessons/types.d.ts +27 -0
  59. package/dist/council/lessons/types.d.ts.map +1 -0
  60. package/dist/council/lessons/types.js +2 -0
  61. package/dist/council/lessons/types.js.map +1 -0
  62. package/dist/council/modeBanners.d.ts +24 -1
  63. package/dist/council/modeBanners.d.ts.map +1 -1
  64. package/dist/council/modeBanners.js +31 -4
  65. package/dist/council/modeBanners.js.map +1 -1
  66. package/dist/council/scope/extractTaskScope.d.ts +35 -0
  67. package/dist/council/scope/extractTaskScope.d.ts.map +1 -0
  68. package/dist/council/scope/extractTaskScope.js +174 -0
  69. package/dist/council/scope/extractTaskScope.js.map +1 -0
  70. package/dist/council/scope/index.d.ts +3 -0
  71. package/dist/council/scope/index.d.ts.map +1 -0
  72. package/dist/council/scope/index.js +3 -0
  73. package/dist/council/scope/index.js.map +1 -0
  74. package/dist/council/scope/nfrSpecWarn.d.ts +6 -0
  75. package/dist/council/scope/nfrSpecWarn.d.ts.map +1 -0
  76. package/dist/council/scope/nfrSpecWarn.js +21 -0
  77. package/dist/council/scope/nfrSpecWarn.js.map +1 -0
  78. package/dist/council/verification/autofix.d.ts +12 -0
  79. package/dist/council/verification/autofix.d.ts.map +1 -0
  80. package/dist/council/verification/autofix.js +41 -0
  81. package/dist/council/verification/autofix.js.map +1 -0
  82. package/dist/council/verification/citeVerify.d.ts +13 -0
  83. package/dist/council/verification/citeVerify.d.ts.map +1 -0
  84. package/dist/council/verification/citeVerify.js +73 -0
  85. package/dist/council/verification/citeVerify.js.map +1 -0
  86. package/dist/council/verification/completion.d.ts +19 -0
  87. package/dist/council/verification/completion.d.ts.map +1 -0
  88. package/dist/council/verification/completion.js +50 -0
  89. package/dist/council/verification/completion.js.map +1 -0
  90. package/dist/council/verification/degraded.d.ts +26 -0
  91. package/dist/council/verification/degraded.d.ts.map +1 -0
  92. package/dist/council/verification/degraded.js +35 -0
  93. package/dist/council/verification/degraded.js.map +1 -0
  94. package/dist/council/verification/honesty.d.ts +6 -0
  95. package/dist/council/verification/honesty.d.ts.map +1 -0
  96. package/dist/council/verification/honesty.js +28 -0
  97. package/dist/council/verification/honesty.js.map +1 -0
  98. package/dist/council/verification/implementationDelivery.d.ts +26 -0
  99. package/dist/council/verification/implementationDelivery.d.ts.map +1 -0
  100. package/dist/council/verification/implementationDelivery.js +70 -0
  101. package/dist/council/verification/implementationDelivery.js.map +1 -0
  102. package/dist/council/verification/index.d.ts +15 -0
  103. package/dist/council/verification/index.d.ts.map +1 -0
  104. package/dist/council/verification/index.js +15 -0
  105. package/dist/council/verification/index.js.map +1 -0
  106. package/dist/council/verification/inlineJsAutofix.d.ts +8 -0
  107. package/dist/council/verification/inlineJsAutofix.d.ts.map +1 -0
  108. package/dist/council/verification/inlineJsAutofix.js +85 -0
  109. package/dist/council/verification/inlineJsAutofix.js.map +1 -0
  110. package/dist/council/verification/microGate.d.ts +18 -0
  111. package/dist/council/verification/microGate.d.ts.map +1 -0
  112. package/dist/council/verification/microGate.js +81 -0
  113. package/dist/council/verification/microGate.js.map +1 -0
  114. package/dist/council/verification/motionAutofix.d.ts +8 -0
  115. package/dist/council/verification/motionAutofix.d.ts.map +1 -0
  116. package/dist/council/verification/motionAutofix.js +160 -0
  117. package/dist/council/verification/motionAutofix.js.map +1 -0
  118. package/dist/council/verification/parseCssMotion.d.ts +22 -0
  119. package/dist/council/verification/parseCssMotion.d.ts.map +1 -0
  120. package/dist/council/verification/parseCssMotion.js +142 -0
  121. package/dist/council/verification/parseCssMotion.js.map +1 -0
  122. package/dist/council/verification/runChecks.d.ts +10 -0
  123. package/dist/council/verification/runChecks.d.ts.map +1 -0
  124. package/dist/council/verification/runChecks.js +254 -0
  125. package/dist/council/verification/runChecks.js.map +1 -0
  126. package/dist/council/verification/synthesisAudit.d.ts +14 -0
  127. package/dist/council/verification/synthesisAudit.d.ts.map +1 -0
  128. package/dist/council/verification/synthesisAudit.js +106 -0
  129. package/dist/council/verification/synthesisAudit.js.map +1 -0
  130. package/dist/council/verification/tiers.d.ts +8 -0
  131. package/dist/council/verification/tiers.d.ts.map +1 -0
  132. package/dist/council/verification/tiers.js +46 -0
  133. package/dist/council/verification/tiers.js.map +1 -0
  134. package/dist/council/verification/types.d.ts +53 -0
  135. package/dist/council/verification/types.d.ts.map +1 -0
  136. package/dist/council/verification/types.js +5 -0
  137. package/dist/council/verification/types.js.map +1 -0
  138. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+ import { appendFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { isAnswerLeak } from './isAnswerLeak.js';
4
+ import { LESSONS_FILE, readLessonsDeduped } from './io.js';
5
+ import { jaccardSimilarity, normalizeForSignature, tokenizeForSignature } from './signatures.js';
6
+ const JACCARD_MERGE_THRESHOLD = 0.72;
7
+ const ENFORCED_AFTER_RECURRENCE = 2;
8
+ const METHODOLOGY = {
9
+ 'motion.keyframes': 'Grep @keyframes in targets before PASS; compositor budget allows only transform and opacity.',
10
+ 'motion.transitions': 'Grep transition properties before PASS; forbid layout-affecting props (grid-template-rows, box-shadow, etc.).',
11
+ 'css.dead-hook': 'Every classList.add must have a matching CSS rule; grep both script and style blocks.',
12
+ 'synthesis.tier-inflation': 'Verification status tier cannot exceed the report; never PASS a check prefix that still has FAIL in verification-report.',
13
+ 'synthesis.honesty': 'Claims like verificato/regressione require Evidence table with path:Lline or tool output — not prose alone.',
14
+ 'synthesis.cite-invalid': 'Every path:Lline citation must exist and be non-empty; grep before citing.',
15
+ 'synthesis.degraded-banner': 'Degraded runs must include DEGRADED_RUN banner; do not claim ready-to-commit.',
16
+ 'plan.reality': 'Milestone keywords in plan.json must appear in implementation targets before claiming compatibility.',
17
+ };
18
+ function methodologyFor(check) {
19
+ return (METHODOLOGY[check.id] ??
20
+ `When ${check.id} fails, fix the underlying issue and cite grep/tool evidence before claiming PASS.`);
21
+ }
22
+ function keywordsFrom(check, signature) {
23
+ const words = signature.split(' ').filter((w) => w.length >= 4);
24
+ const fromId = check.id.split(/[.-]/).filter((p) => p.length >= 4);
25
+ return [...new Set([...fromId, ...words])].slice(0, 12);
26
+ }
27
+ function writeLesson(zelariRoot, lesson) {
28
+ const path = join(zelariRoot, LESSONS_FILE);
29
+ appendFileSync(path, `${JSON.stringify(lesson)}\n`, 'utf8');
30
+ }
31
+ function findSimilar(lessons, signature) {
32
+ const sigTokens = tokenizeForSignature(signature);
33
+ let best = null;
34
+ let bestScore = 0;
35
+ for (const l of lessons) {
36
+ const score = jaccardSimilarity(sigTokens, tokenizeForSignature(l.signature));
37
+ if (score > bestScore) {
38
+ bestScore = score;
39
+ best = l;
40
+ }
41
+ }
42
+ return bestScore >= JACCARD_MERGE_THRESHOLD ? best : null;
43
+ }
44
+ /**
45
+ * Capture a verification FAIL as a methodology lesson (append-only jsonl).
46
+ */
47
+ export function captureFailure(zelariRoot, check) {
48
+ if (check.ok) {
49
+ return { captured: false, reason: 'check passed' };
50
+ }
51
+ const methodology = methodologyFor(check);
52
+ const leak = isAnswerLeak(`${methodology} ${check.message} ${check.evidence ?? ''}`);
53
+ if (leak.leak) {
54
+ return { captured: false, rejected: true, reason: leak.reason };
55
+ }
56
+ const signature = normalizeForSignature(check.id, check.message);
57
+ const existing = readLessonsDeduped(zelariRoot);
58
+ const similar = findSimilar(existing, signature);
59
+ const now = new Date().toISOString();
60
+ if (similar) {
61
+ const recurrence = similar.recurrence + 1;
62
+ const tier = recurrence >= ENFORCED_AFTER_RECURRENCE ? 'enforced' : similar.tier;
63
+ const updated = {
64
+ ...similar,
65
+ recurrence,
66
+ tier,
67
+ updatedAt: now,
68
+ };
69
+ writeLesson(zelariRoot, updated);
70
+ return { captured: true, lesson: updated };
71
+ }
72
+ const lesson = {
73
+ id: `lesson-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
74
+ signature,
75
+ checkId: check.id,
76
+ methodology,
77
+ tier: 'advisory',
78
+ keywords: keywordsFrom(check, signature),
79
+ recurrence: 1,
80
+ createdAt: now,
81
+ updatedAt: now,
82
+ };
83
+ writeLesson(zelariRoot, lesson);
84
+ return { captured: true, lesson };
85
+ }
86
+ //# sourceMappingURL=recordFailure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordFailure.js","sourceRoot":"","sources":["../../../src/council/lessons/recordFailure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** Tokenize for Jaccard similarity (lowercase words ≥3 chars). */
2
+ export declare function tokenizeForSignature(text: string): Set<string>;
3
+ export declare function jaccardSimilarity(a: Set<string>, b: Set<string>): number;
4
+ /** Normalize check message for stable signatures (strip paths, lines, numbers). */
5
+ export declare function normalizeForSignature(checkId: string, message: string): string;
6
+ //# sourceMappingURL=signatures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../../src/council/lessons/signatures.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAM9D;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAQxE;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAQ9E"}
@@ -0,0 +1,31 @@
1
+ /** Tokenize for Jaccard similarity (lowercase words ≥3 chars). */
2
+ export function tokenizeForSignature(text) {
3
+ const out = new Set();
4
+ for (const w of text.toLowerCase().split(/\W+/)) {
5
+ if (w.length >= 3)
6
+ out.add(w);
7
+ }
8
+ return out;
9
+ }
10
+ export function jaccardSimilarity(a, b) {
11
+ if (a.size === 0 && b.size === 0)
12
+ return 1;
13
+ let inter = 0;
14
+ for (const x of a) {
15
+ if (b.has(x))
16
+ inter++;
17
+ }
18
+ const union = new Set([...a, ...b]).size;
19
+ return union === 0 ? 0 : inter / union;
20
+ }
21
+ /** Normalize check message for stable signatures (strip paths, lines, numbers). */
22
+ export function normalizeForSignature(checkId, message) {
23
+ const base = `${checkId} ${message}`
24
+ .toLowerCase()
25
+ .replace(/[A-Za-z]:\\[^\s]+/g, 'path')
26
+ .replace(/\/[\w./-]+/g, 'path')
27
+ .replace(/l\d{1,6}/gi, 'line')
28
+ .replace(/\d+/g, 'n');
29
+ return [...tokenizeForSignature(base)].sort().join(' ');
30
+ }
31
+ //# sourceMappingURL=signatures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signatures.js","sourceRoot":"","sources":["../../../src/council/lessons/signatures.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,CAAc,EAAE,CAAc;IAC9D,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC;AACzC,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,OAAe;IACpE,MAAM,IAAI,GAAG,GAAG,OAAO,IAAI,OAAO,EAAE;SACjC,WAAW,EAAE;SACb,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC;SACrC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC;SAC9B,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;SAC7B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,27 @@
1
+ export type LessonTier = 'advisory' | 'enforced';
2
+ export interface LessonRecord {
3
+ id: string;
4
+ /** Normalized tokens for recurrence matching. */
5
+ signature: string;
6
+ checkId: string;
7
+ /** Methodology guidance — not task-specific answers. */
8
+ methodology: string;
9
+ tier: LessonTier;
10
+ keywords: string[];
11
+ recurrence: number;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ }
15
+ export interface CaptureFailureResult {
16
+ captured: boolean;
17
+ rejected?: boolean;
18
+ reason?: string;
19
+ lesson?: LessonRecord;
20
+ }
21
+ export interface RecallLessonsOptions {
22
+ maxLessons?: number;
23
+ maxBytes?: number;
24
+ /** User task text for keyword overlap scoring. */
25
+ taskText?: string;
26
+ }
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/council/lessons/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/council/lessons/types.ts"],"names":[],"mappings":""}
@@ -1,5 +1,28 @@
1
1
  import type { CouncilRunMode } from './runMode.js';
2
2
  export declare const DESIGN_PHASE_MODE_BANNER = "COUNCIL RUN MODE: design-phase.\nWorkspace tool emissions described in your role prompt are MANDATORY in this run \u2014 prose alone does not count as a deliverable. Persist artifacts via the workspace tools listed in your AVAILABLE TOOLS section.";
3
3
  export declare const IMPLEMENTATION_MODE_BANNER = "COUNCIL RUN MODE: implementation.\nPrefer write_file, edit_file, and bash for code changes. Design-phase mandatory workspace blocks in your role prompt are INACTIVE in this run \u2014 only call workspace tools when they add durable project value.";
4
- export declare function councilModeBanner(runMode: CouncilRunMode): string;
4
+ /**
5
+ * Implementation-mode banner for the SOLE implementer (the chairman, Lucifero).
6
+ * Only this member writes/edits project files, so the "who implemented" signal
7
+ * stays unambiguous and multiple agents never edit the same files.
8
+ */
9
+ export declare const IMPLEMENTATION_IMPLEMENTER_BANNER = "COUNCIL RUN MODE: implementation \u2014 you are the IMPLEMENTER.\nYou are the only member that writes code this run. Implement the solution with write_file / edit_file and verify with bash. Reconcile the specialists' analysis and Minosse's critique into working, verified changes. Design-phase mandatory workspace blocks in your role prompt are INACTIVE \u2014 only call workspace tools when they add durable project value.";
10
+ /**
11
+ * Implementation-mode banner for advisors (specialists + Minosse). They analyze,
12
+ * plan and critique; they must NOT modify project files (the implementer does).
13
+ * This prevents multi-writer chaos where several agents edit the same files and
14
+ * pile up conflicting changes.
15
+ */
16
+ export declare const IMPLEMENTATION_ADVISOR_BANNER = "COUNCIL RUN MODE: implementation \u2014 you are an ADVISOR.\nDo NOT write or edit project files (not via write_file/edit_file, and not via bash) \u2014 the final synthesizer (Lucifero) is the sole implementer. Your job is to inspect the codebase (read_file, grep_content, list_files) and produce analysis, a concrete plan, or critique that the implementer will execute. Design-phase mandatory workspace blocks in your role prompt are INACTIVE in this run.";
17
+ /**
18
+ * Pick the run-mode banner for a member.
19
+ *
20
+ * @param opts.isImplementer In implementation mode, `true` selects the
21
+ * implementer banner (chairman/Lucifero), `false` the advisor banner
22
+ * (specialists + Minosse). Omitted → the legacy generic banner (kept for
23
+ * backward compatibility with callers that don't distinguish roles).
24
+ */
25
+ export declare function councilModeBanner(runMode: CouncilRunMode, opts?: {
26
+ isImplementer?: boolean;
27
+ }): string;
5
28
  //# sourceMappingURL=modeBanners.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modeBanners.d.ts","sourceRoot":"","sources":["../../src/council/modeBanners.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,eAAO,MAAM,wBAAwB,4PAC6K,CAAC;AAEnN,eAAO,MAAM,0BAA0B,2PACwK,CAAC;AAEhN,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAIjE"}
1
+ {"version":3,"file":"modeBanners.d.ts","sourceRoot":"","sources":["../../src/council/modeBanners.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,eAAO,MAAM,wBAAwB,4PAC6K,CAAC;AAEnN,eAAO,MAAM,0BAA0B,2PACwK,CAAC;AAEhN;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,4aACmT,CAAC;AAElW;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,4cAC4V,CAAC;AAEvY;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,cAAc,EACvB,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,MAAM,CAKR"}
@@ -2,9 +2,36 @@ export const DESIGN_PHASE_MODE_BANNER = `COUNCIL RUN MODE: design-phase.
2
2
  Workspace tool emissions described in your role prompt are MANDATORY in this run — prose alone does not count as a deliverable. Persist artifacts via the workspace tools listed in your AVAILABLE TOOLS section.`;
3
3
  export const IMPLEMENTATION_MODE_BANNER = `COUNCIL RUN MODE: implementation.
4
4
  Prefer write_file, edit_file, and bash for code changes. Design-phase mandatory workspace blocks in your role prompt are INACTIVE in this run — only call workspace tools when they add durable project value.`;
5
- export function councilModeBanner(runMode) {
6
- return runMode === 'design-phase'
7
- ? DESIGN_PHASE_MODE_BANNER
8
- : IMPLEMENTATION_MODE_BANNER;
5
+ /**
6
+ * Implementation-mode banner for the SOLE implementer (the chairman, Lucifero).
7
+ * Only this member writes/edits project files, so the "who implemented" signal
8
+ * stays unambiguous and multiple agents never edit the same files.
9
+ */
10
+ export const IMPLEMENTATION_IMPLEMENTER_BANNER = `COUNCIL RUN MODE: implementation — you are the IMPLEMENTER.
11
+ You are the only member that writes code this run. Implement the solution with write_file / edit_file and verify with bash. Reconcile the specialists' analysis and Minosse's critique into working, verified changes. Design-phase mandatory workspace blocks in your role prompt are INACTIVE — only call workspace tools when they add durable project value.`;
12
+ /**
13
+ * Implementation-mode banner for advisors (specialists + Minosse). They analyze,
14
+ * plan and critique; they must NOT modify project files (the implementer does).
15
+ * This prevents multi-writer chaos where several agents edit the same files and
16
+ * pile up conflicting changes.
17
+ */
18
+ export const IMPLEMENTATION_ADVISOR_BANNER = `COUNCIL RUN MODE: implementation — you are an ADVISOR.
19
+ Do NOT write or edit project files (not via write_file/edit_file, and not via bash) — the final synthesizer (Lucifero) is the sole implementer. Your job is to inspect the codebase (read_file, grep_content, list_files) and produce analysis, a concrete plan, or critique that the implementer will execute. Design-phase mandatory workspace blocks in your role prompt are INACTIVE in this run.`;
20
+ /**
21
+ * Pick the run-mode banner for a member.
22
+ *
23
+ * @param opts.isImplementer In implementation mode, `true` selects the
24
+ * implementer banner (chairman/Lucifero), `false` the advisor banner
25
+ * (specialists + Minosse). Omitted → the legacy generic banner (kept for
26
+ * backward compatibility with callers that don't distinguish roles).
27
+ */
28
+ export function councilModeBanner(runMode, opts) {
29
+ if (runMode === 'design-phase')
30
+ return DESIGN_PHASE_MODE_BANNER;
31
+ if (opts?.isImplementer === true)
32
+ return IMPLEMENTATION_IMPLEMENTER_BANNER;
33
+ if (opts?.isImplementer === false)
34
+ return IMPLEMENTATION_ADVISOR_BANNER;
35
+ return IMPLEMENTATION_MODE_BANNER;
9
36
  }
10
37
  //# sourceMappingURL=modeBanners.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"modeBanners.js","sourceRoot":"","sources":["../../src/council/modeBanners.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAG;kNAC0K,CAAC;AAEnN,MAAM,CAAC,MAAM,0BAA0B,GAAG;+MACqK,CAAC;AAEhN,MAAM,UAAU,iBAAiB,CAAC,OAAuB;IACvD,OAAO,OAAO,KAAK,cAAc;QAC/B,CAAC,CAAC,wBAAwB;QAC1B,CAAC,CAAC,0BAA0B,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"modeBanners.js","sourceRoot":"","sources":["../../src/council/modeBanners.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAG;kNAC0K,CAAC;AAEnN,MAAM,CAAC,MAAM,0BAA0B,GAAG;+MACqK,CAAC;AAEhN;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG;iWACgT,CAAC;AAElW;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG;sYACyV,CAAC;AAEvY;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAuB,EACvB,IAAkC;IAElC,IAAI,OAAO,KAAK,cAAc;QAAE,OAAO,wBAAwB,CAAC;IAChE,IAAI,IAAI,EAAE,aAAa,KAAK,IAAI;QAAE,OAAO,iCAAiC,CAAC;IAC3E,IAAI,IAAI,EAAE,aAAa,KAAK,KAAK;QAAE,OAAO,6BAA6B,CAAC;IACxE,OAAO,0BAA0B,CAAC;AACpC,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { NfrSpec } from '../verification/types.js';
2
+ /** Keywords that indicate measurable NFR constraints (motion, perf, budget). */
3
+ export declare const NFR_KEYWORDS: readonly ["motion", "animation", "animate", "keyframes", "transition", "compositor", "reduced-motion", "prefers-reduced-motion", "byte budget", "bytes", "performance", "perf budget", "nfr", "layout thrash", "box-shadow", "inline js", "inline-js"];
4
+ export interface TaskScope {
5
+ /** Project-relative file targets for this task. */
6
+ targets: string[];
7
+ /** Task theme keywords (animation, motion, …). */
8
+ keywords: string[];
9
+ /** Features explicitly deferred or out of scope for this run. */
10
+ explicitOut: string[];
11
+ /** Whether NFR-style constraints appear in the user request. */
12
+ nfrRelevant: boolean;
13
+ sources: Array<'userMessage' | 'nfr-spec'>;
14
+ }
15
+ export interface ExtractTaskScopeInput {
16
+ userMessage: string;
17
+ nfrSpec?: NfrSpec | null;
18
+ /** Optional plan text (JSON string or markdown) for backlog hints. */
19
+ planText?: string;
20
+ }
21
+ /** True when the task text mentions measurable NFR themes. */
22
+ export declare function taskMatchesNfrKeywords(userMessage: string, planText?: string): boolean;
23
+ /**
24
+ * Deterministic task scope from user message + optional nfr-spec.
25
+ * No NLP — keyword overlap, file-path regex, and nfr-spec targets only.
26
+ */
27
+ export declare function extractTaskScope(input: ExtractTaskScopeInput): TaskScope;
28
+ export interface ScopeMatchInput {
29
+ name?: string;
30
+ description?: string;
31
+ id?: string;
32
+ }
33
+ /** Classify a plan task relative to extracted scope. */
34
+ export declare function classifyTaskScope(task: ScopeMatchInput, scope: TaskScope): 'in-scope' | 'backlog' | 'neutral';
35
+ //# sourceMappingURL=extractTaskScope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractTaskScope.d.ts","sourceRoot":"","sources":["../../../src/council/scope/extractTaskScope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,gFAAgF;AAChF,eAAO,MAAM,YAAY,wPAkBf,CAAC;AAgCX,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iEAAiE;IACjE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,gEAAgE;IAChE,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,KAAK,CAAC,aAAa,GAAG,UAAU,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAqED,8DAA8D;AAC9D,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAGT;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CAiCxE;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,wDAAwD;AACxD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,SAAS,GACf,UAAU,GAAG,SAAS,GAAG,SAAS,CAgCpC"}
@@ -0,0 +1,174 @@
1
+ /** Keywords that indicate measurable NFR constraints (motion, perf, budget). */
2
+ export const NFR_KEYWORDS = [
3
+ 'motion',
4
+ 'animation',
5
+ 'animate',
6
+ 'keyframes',
7
+ 'transition',
8
+ 'compositor',
9
+ 'reduced-motion',
10
+ 'prefers-reduced-motion',
11
+ 'byte budget',
12
+ 'bytes',
13
+ 'performance',
14
+ 'perf budget',
15
+ 'nfr',
16
+ 'layout thrash',
17
+ 'box-shadow',
18
+ 'inline js',
19
+ 'inline-js',
20
+ ];
21
+ const FILE_PATH_RE = /\b((?:[\w.-]+\/)*[\w.-]+\.(?:html|css|js|ts|tsx|jsx|json|md|mjs|cjs))\b/gi;
22
+ const ANIMATE_KEYWORDS = [
23
+ 'animate',
24
+ 'animation',
25
+ 'motion',
26
+ 'transition',
27
+ 'keyframes',
28
+ 'fade',
29
+ 'slide',
30
+ ];
31
+ const BACKLOG_FEATURE_HINTS = [
32
+ 'command palette',
33
+ 'print stylesheet',
34
+ 'dark mode',
35
+ 'i18n',
36
+ 'localization',
37
+ 'auth',
38
+ 'login',
39
+ 'database',
40
+ 'api server',
41
+ ];
42
+ const EXPLICIT_OUT_RE = /\b(?:not|don't|do not|skip|defer(?:red)?|later|backlog|out of scope|exclude|without|no need for)\b[^.\n]{0,60}/gi;
43
+ const VERSION_DEFER_RE = /\bv\d+\.\d+(?:\.\d+)?\b/gi;
44
+ function normalizePath(p) {
45
+ return p.replace(/\\/g, '/').replace(/^\.\//, '');
46
+ }
47
+ function uniqueLower(items) {
48
+ const seen = new Set();
49
+ const out = [];
50
+ for (const item of items) {
51
+ const key = item.toLowerCase();
52
+ if (seen.has(key))
53
+ continue;
54
+ seen.add(key);
55
+ out.push(item);
56
+ }
57
+ return out;
58
+ }
59
+ function extractFilePaths(text) {
60
+ const found = [];
61
+ for (const match of text.matchAll(FILE_PATH_RE)) {
62
+ const raw = match[1];
63
+ if (!raw)
64
+ continue;
65
+ const norm = normalizePath(raw);
66
+ if (norm.includes('node_modules'))
67
+ continue;
68
+ found.push(norm);
69
+ }
70
+ return uniqueLower(found);
71
+ }
72
+ function extractKeywords(text) {
73
+ const lower = text.toLowerCase();
74
+ const hits = [];
75
+ for (const kw of [...ANIMATE_KEYWORDS, ...NFR_KEYWORDS]) {
76
+ if (lower.includes(kw))
77
+ hits.push(kw);
78
+ }
79
+ return uniqueLower(hits);
80
+ }
81
+ function extractExplicitOut(userMessage, planText) {
82
+ const combined = `${userMessage}\n${planText ?? ''}`;
83
+ const out = [];
84
+ for (const match of combined.matchAll(EXPLICIT_OUT_RE)) {
85
+ const phrase = match[0]?.trim();
86
+ if (phrase && phrase.length > 8)
87
+ out.push(phrase);
88
+ }
89
+ for (const hint of BACKLOG_FEATURE_HINTS) {
90
+ if (combined.toLowerCase().includes(hint)) {
91
+ const inScope = userMessage.toLowerCase().includes(hint) &&
92
+ !/\b(?:not|don't|do not|skip|later|backlog|without)\b[^.\n]{0,30}/i.test(userMessage);
93
+ if (!inScope)
94
+ out.push(hint);
95
+ }
96
+ }
97
+ for (const match of combined.matchAll(VERSION_DEFER_RE)) {
98
+ const ver = match[0];
99
+ if (ver && /later|backlog|defer|not yet|planned/i.test(combined)) {
100
+ out.push(`${ver} (deferred)`);
101
+ }
102
+ }
103
+ return uniqueLower(out);
104
+ }
105
+ /** True when the task text mentions measurable NFR themes. */
106
+ export function taskMatchesNfrKeywords(userMessage, planText) {
107
+ const lower = `${userMessage}\n${planText ?? ''}`.toLowerCase();
108
+ return NFR_KEYWORDS.some((kw) => lower.includes(kw));
109
+ }
110
+ /**
111
+ * Deterministic task scope from user message + optional nfr-spec.
112
+ * No NLP — keyword overlap, file-path regex, and nfr-spec targets only.
113
+ */
114
+ export function extractTaskScope(input) {
115
+ const sources = [];
116
+ const targets = [];
117
+ const keywords = extractKeywords(input.userMessage);
118
+ if (input.userMessage.trim())
119
+ sources.push('userMessage');
120
+ for (const p of extractFilePaths(input.userMessage)) {
121
+ targets.push(p);
122
+ }
123
+ if (input.nfrSpec?.targets?.length) {
124
+ sources.push('nfr-spec');
125
+ for (const t of input.nfrSpec.targets) {
126
+ targets.push(normalizePath(t));
127
+ }
128
+ if (input.nfrSpec.animation?.compositorOnly) {
129
+ keywords.push('compositor-only');
130
+ }
131
+ if (input.nfrSpec.inlineJs?.maxBytes) {
132
+ keywords.push(`inline-js<=${input.nfrSpec.inlineJs.maxBytes}b`);
133
+ }
134
+ }
135
+ const explicitOut = extractExplicitOut(input.userMessage, input.planText);
136
+ const nfrRelevant = taskMatchesNfrKeywords(input.userMessage, input.planText);
137
+ return {
138
+ targets: uniqueLower(targets),
139
+ keywords: uniqueLower(keywords),
140
+ explicitOut,
141
+ nfrRelevant,
142
+ sources: [...new Set(sources)],
143
+ };
144
+ }
145
+ /** Classify a plan task relative to extracted scope. */
146
+ export function classifyTaskScope(task, scope) {
147
+ const blob = `${task.name ?? ''} ${task.description ?? ''} ${task.id ?? ''}`.toLowerCase();
148
+ for (const out of scope.explicitOut) {
149
+ const needle = out.toLowerCase().replace(/\s*\(deferred\)$/i, '');
150
+ if (needle.length >= 4 && blob.includes(needle))
151
+ return 'backlog';
152
+ }
153
+ for (const hint of BACKLOG_FEATURE_HINTS) {
154
+ if (blob.includes(hint) &&
155
+ scope.explicitOut.some((o) => o.toLowerCase().includes(hint))) {
156
+ return 'backlog';
157
+ }
158
+ }
159
+ if (scope.targets.length > 0) {
160
+ const hitsTarget = scope.targets.some((t) => blob.includes(t.toLowerCase()));
161
+ if (hitsTarget)
162
+ return 'in-scope';
163
+ }
164
+ if (scope.keywords.length > 0) {
165
+ const hitsKeyword = scope.keywords.some((kw) => blob.includes(kw.toLowerCase()));
166
+ if (hitsKeyword)
167
+ return 'in-scope';
168
+ }
169
+ if (scope.targets.length > 0 || scope.keywords.length > 0) {
170
+ return 'backlog';
171
+ }
172
+ return 'neutral';
173
+ }
174
+ //# sourceMappingURL=extractTaskScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractTaskScope.js","sourceRoot":"","sources":["../../../src/council/scope/extractTaskScope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './extractTaskScope.js';
2
+ export * from './nfrSpecWarn.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/council/scope/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './extractTaskScope.js';
2
+ export * from './nfrSpecWarn.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/council/scope/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Soft design-phase check: warn when Nettuno plans motion/perf/budget work
3
+ * but does not emit createNfrSpec. No forced retry in v0.9.1.
4
+ */
5
+ export declare function warnIfNfrSpecMissing(memberId: string, userMessage: string, emittedToolNames: string[], planText?: string): boolean;
6
+ //# sourceMappingURL=nfrSpecWarn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nfrSpecWarn.d.ts","sourceRoot":"","sources":["../../../src/council/scope/nfrSpecWarn.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EAAE,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAcT"}
@@ -0,0 +1,21 @@
1
+ import { taskMatchesNfrKeywords } from './extractTaskScope.js';
2
+ /**
3
+ * Soft design-phase check: warn when Nettuno plans motion/perf/budget work
4
+ * but does not emit createNfrSpec. No forced retry in v0.9.1.
5
+ */
6
+ export function warnIfNfrSpecMissing(memberId, userMessage, emittedToolNames, planText) {
7
+ if (memberId !== 'nettun')
8
+ return false;
9
+ if (!taskMatchesNfrKeywords(userMessage, planText))
10
+ return false;
11
+ const count = emittedToolNames.filter((n) => n === 'createNfrSpec').length;
12
+ if (count >= 1)
13
+ return false;
14
+ // eslint-disable-next-line no-console
15
+ console.warn('[council] member "nettun" did not emit createNfrSpec for an NFR-heavy task ' +
16
+ '(motion/perf/budget keywords detected). Implementation will fall back to ' +
17
+ 'DEFAULT_NFR_SPEC until .zelari/nfr-spec.json exists. Emit createNfrSpec in ' +
18
+ 'design-phase when constraints are measurable.');
19
+ return true;
20
+ }
21
+ //# sourceMappingURL=nfrSpecWarn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nfrSpecWarn.js","sourceRoot":"","sources":["../../../src/council/scope/nfrSpecWarn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,WAAmB,EACnB,gBAA0B,EAC1B,QAAiB;IAEjB,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,MAAM,CAAC;IAC3E,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAE7B,sCAAsC;IACtC,OAAO,CAAC,IAAI,CACV,6EAA6E;QAC3E,2EAA2E;QAC3E,6EAA6E;QAC7E,+CAA+C,CAClD,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { VerificationReport } from './types.js';
2
+ export interface AutofixResult {
3
+ applied: boolean;
4
+ filesChanged: string[];
5
+ fixes: string[];
6
+ }
7
+ /**
8
+ * Deterministic autofix for motion, inline-js budget, and css.dead-hook.
9
+ * Max one pass per hook invocation — no LLM loop.
10
+ */
11
+ export declare function applyDeterministicAutofix(projectRoot: string, report: VerificationReport): AutofixResult;
12
+ //# sourceMappingURL=autofix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autofix.d.ts","sourceRoot":"","sources":["../../../src/council/verification/autofix.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GACzB,aAAa,CA+Bf"}
@@ -0,0 +1,41 @@
1
+ import { readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { applyInlineJsAutofix } from './inlineJsAutofix.js';
4
+ import { applyMotionAutofix } from './motionAutofix.js';
5
+ /**
6
+ * Deterministic autofix for motion, inline-js budget, and css.dead-hook.
7
+ * Max one pass per hook invocation — no LLM loop.
8
+ */
9
+ export function applyDeterministicAutofix(projectRoot, report) {
10
+ const motion = applyMotionAutofix(projectRoot, report);
11
+ const inlineJs = applyInlineJsAutofix(projectRoot, report);
12
+ const filesChanged = [...motion.filesChanged, ...inlineJs.filesChanged];
13
+ const fixes = [...motion.fixes, ...inlineJs.fixes];
14
+ const deadHooks = report.results.filter((r) => r.id === 'css.dead-hook' && !r.ok && r.file);
15
+ for (const r of deadHooks) {
16
+ const rel = r.file;
17
+ if (filesChanged.includes(rel))
18
+ continue;
19
+ const m = r.evidence?.match(/classList\.add\(\s*['"]([\w-]+)['"]\s*\)/);
20
+ if (!m || m[1] === 'rm')
21
+ continue;
22
+ const abs = join(projectRoot, rel);
23
+ let html = readFileSync(abs, 'utf8');
24
+ const snippet = m[0];
25
+ if (!html.includes(snippet))
26
+ continue;
27
+ const lines = html.split(/\r?\n/);
28
+ const filtered = lines.filter((line) => !line.includes(snippet));
29
+ if (filtered.length === lines.length)
30
+ continue;
31
+ writeFileSync(abs, filtered.join('\n'), 'utf8');
32
+ filesChanged.push(rel);
33
+ fixes.push(`removed dead hook line in ${rel}: ${snippet}`);
34
+ }
35
+ return {
36
+ applied: filesChanged.length > 0,
37
+ filesChanged: [...new Set(filesChanged)],
38
+ fixes,
39
+ };
40
+ }
41
+ //# sourceMappingURL=autofix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autofix.js","sourceRoot":"","sources":["../../../src/council/verification/autofix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AASxD;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,WAAmB,EACnB,MAA0B;IAE1B,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEnD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CACnD,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,CAAC,CAAC,IAAK,CAAC;QACpB,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACzC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACxE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,SAAS;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACnC,IAAI,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAAE,SAAS;QAC/C,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAChD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,6BAA6B,GAAG,KAAK,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,OAAO,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;QAChC,YAAY,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;QACxC,KAAK;KACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { VerificationCheckResult } from './types.js';
2
+ export interface CiteRef {
3
+ file: string;
4
+ line: number;
5
+ raw: string;
6
+ }
7
+ /** Extract path:line citations from synthesis text. */
8
+ export declare function extractCitations(text: string): CiteRef[];
9
+ /**
10
+ * Verify that cited path:line references exist and the line is non-empty.
11
+ */
12
+ export declare function verifyCitations(projectRoot: string, synthesisText: string | undefined): VerificationCheckResult[];
13
+ //# sourceMappingURL=citeVerify.d.ts.map