memnant 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -0
  3. package/dist/cli/ask.d.ts +9 -0
  4. package/dist/cli/ask.d.ts.map +1 -0
  5. package/dist/cli/ask.js +103 -0
  6. package/dist/cli/ask.js.map +1 -0
  7. package/dist/cli/check-copy.d.ts +8 -0
  8. package/dist/cli/check-copy.d.ts.map +1 -0
  9. package/dist/cli/check-copy.js +68 -0
  10. package/dist/cli/check-copy.js.map +1 -0
  11. package/dist/cli/check-design.d.ts +8 -0
  12. package/dist/cli/check-design.d.ts.map +1 -0
  13. package/dist/cli/check-design.js +100 -0
  14. package/dist/cli/check-design.js.map +1 -0
  15. package/dist/cli/default-action.d.ts +10 -0
  16. package/dist/cli/default-action.d.ts.map +1 -0
  17. package/dist/cli/default-action.js +94 -0
  18. package/dist/cli/default-action.js.map +1 -0
  19. package/dist/cli/export.d.ts +10 -0
  20. package/dist/cli/export.d.ts.map +1 -0
  21. package/dist/cli/export.js +109 -0
  22. package/dist/cli/export.js.map +1 -0
  23. package/dist/cli/index.d.ts +12 -0
  24. package/dist/cli/index.d.ts.map +1 -0
  25. package/dist/cli/index.js +77 -0
  26. package/dist/cli/index.js.map +1 -0
  27. package/dist/cli/init.d.ts +10 -0
  28. package/dist/cli/init.d.ts.map +1 -0
  29. package/dist/cli/init.js +157 -0
  30. package/dist/cli/init.js.map +1 -0
  31. package/dist/cli/instructions.d.ts +12 -0
  32. package/dist/cli/instructions.d.ts.map +1 -0
  33. package/dist/cli/instructions.js +117 -0
  34. package/dist/cli/instructions.js.map +1 -0
  35. package/dist/cli/lint.d.ts +9 -0
  36. package/dist/cli/lint.d.ts.map +1 -0
  37. package/dist/cli/lint.js +131 -0
  38. package/dist/cli/lint.js.map +1 -0
  39. package/dist/cli/log.d.ts +10 -0
  40. package/dist/cli/log.d.ts.map +1 -0
  41. package/dist/cli/log.js +83 -0
  42. package/dist/cli/log.js.map +1 -0
  43. package/dist/cli/promote.d.ts +9 -0
  44. package/dist/cli/promote.d.ts.map +1 -0
  45. package/dist/cli/promote.js +70 -0
  46. package/dist/cli/promote.js.map +1 -0
  47. package/dist/cli/recall.d.ts +10 -0
  48. package/dist/cli/recall.d.ts.map +1 -0
  49. package/dist/cli/recall.js +98 -0
  50. package/dist/cli/recall.js.map +1 -0
  51. package/dist/cli/serve.d.ts +10 -0
  52. package/dist/cli/serve.d.ts.map +1 -0
  53. package/dist/cli/serve.js +17 -0
  54. package/dist/cli/serve.js.map +1 -0
  55. package/dist/cli/session.d.ts +10 -0
  56. package/dist/cli/session.d.ts.map +1 -0
  57. package/dist/cli/session.js +226 -0
  58. package/dist/cli/session.js.map +1 -0
  59. package/dist/cli/setup.d.ts +11 -0
  60. package/dist/cli/setup.d.ts.map +1 -0
  61. package/dist/cli/setup.js +103 -0
  62. package/dist/cli/setup.js.map +1 -0
  63. package/dist/cli/snapshot.d.ts +9 -0
  64. package/dist/cli/snapshot.d.ts.map +1 -0
  65. package/dist/cli/snapshot.js +126 -0
  66. package/dist/cli/snapshot.js.map +1 -0
  67. package/dist/cli/specs.d.ts +8 -0
  68. package/dist/cli/specs.d.ts.map +1 -0
  69. package/dist/cli/specs.js +96 -0
  70. package/dist/cli/specs.js.map +1 -0
  71. package/dist/cli/status.d.ts +8 -0
  72. package/dist/cli/status.d.ts.map +1 -0
  73. package/dist/cli/status.js +40 -0
  74. package/dist/cli/status.js.map +1 -0
  75. package/dist/cli/telegram.d.ts +8 -0
  76. package/dist/cli/telegram.d.ts.map +1 -0
  77. package/dist/cli/telegram.js +40 -0
  78. package/dist/cli/telegram.js.map +1 -0
  79. package/dist/cli/test-persona.d.ts +9 -0
  80. package/dist/cli/test-persona.d.ts.map +1 -0
  81. package/dist/cli/test-persona.js +176 -0
  82. package/dist/cli/test-persona.js.map +1 -0
  83. package/dist/config/defaults.d.ts +9 -0
  84. package/dist/config/defaults.d.ts.map +1 -0
  85. package/dist/config/defaults.js +56 -0
  86. package/dist/config/defaults.js.map +1 -0
  87. package/dist/context/compile.d.ts +29 -0
  88. package/dist/context/compile.d.ts.map +1 -0
  89. package/dist/context/compile.js +415 -0
  90. package/dist/context/compile.js.map +1 -0
  91. package/dist/governor/copy-check.d.ts +24 -0
  92. package/dist/governor/copy-check.d.ts.map +1 -0
  93. package/dist/governor/copy-check.js +75 -0
  94. package/dist/governor/copy-check.js.map +1 -0
  95. package/dist/governor/design-check.d.ts +20 -0
  96. package/dist/governor/design-check.d.ts.map +1 -0
  97. package/dist/governor/design-check.js +40 -0
  98. package/dist/governor/design-check.js.map +1 -0
  99. package/dist/governor/specs.d.ts +58 -0
  100. package/dist/governor/specs.d.ts.map +1 -0
  101. package/dist/governor/specs.js +183 -0
  102. package/dist/governor/specs.js.map +1 -0
  103. package/dist/ledger/database.d.ts +12 -0
  104. package/dist/ledger/database.d.ts.map +1 -0
  105. package/dist/ledger/database.js +56 -0
  106. package/dist/ledger/database.js.map +1 -0
  107. package/dist/ledger/records.d.ts +19 -0
  108. package/dist/ledger/records.d.ts.map +1 -0
  109. package/dist/ledger/records.js +40 -0
  110. package/dist/ledger/records.js.map +1 -0
  111. package/dist/ledger/sessions.d.ts +15 -0
  112. package/dist/ledger/sessions.d.ts.map +1 -0
  113. package/dist/ledger/sessions.js +54 -0
  114. package/dist/ledger/sessions.js.map +1 -0
  115. package/dist/mcp/server.d.ts +9 -0
  116. package/dist/mcp/server.d.ts.map +1 -0
  117. package/dist/mcp/server.js +295 -0
  118. package/dist/mcp/server.js.map +1 -0
  119. package/dist/orchestrator/context.d.ts +22 -0
  120. package/dist/orchestrator/context.d.ts.map +1 -0
  121. package/dist/orchestrator/context.js +142 -0
  122. package/dist/orchestrator/context.js.map +1 -0
  123. package/dist/orchestrator/providers.d.ts +17 -0
  124. package/dist/orchestrator/providers.d.ts.map +1 -0
  125. package/dist/orchestrator/providers.js +57 -0
  126. package/dist/orchestrator/providers.js.map +1 -0
  127. package/dist/orchestrator/router.d.ts +30 -0
  128. package/dist/orchestrator/router.d.ts.map +1 -0
  129. package/dist/orchestrator/router.js +83 -0
  130. package/dist/orchestrator/router.js.map +1 -0
  131. package/dist/snapshot/scanner.d.ts +63 -0
  132. package/dist/snapshot/scanner.d.ts.map +1 -0
  133. package/dist/snapshot/scanner.js +293 -0
  134. package/dist/snapshot/scanner.js.map +1 -0
  135. package/dist/telegram/bot.d.ts +14 -0
  136. package/dist/telegram/bot.d.ts.map +1 -0
  137. package/dist/telegram/bot.js +139 -0
  138. package/dist/telegram/bot.js.map +1 -0
  139. package/dist/types.d.ts +99 -0
  140. package/dist/types.d.ts.map +1 -0
  141. package/dist/types.js +16 -0
  142. package/dist/types.js.map +1 -0
  143. package/dist/vector/embeddings.d.ts +11 -0
  144. package/dist/vector/embeddings.d.ts.map +1 -0
  145. package/dist/vector/embeddings.js +30 -0
  146. package/dist/vector/embeddings.js.map +1 -0
  147. package/dist/vector/search.d.ts +26 -0
  148. package/dist/vector/search.d.ts.map +1 -0
  149. package/dist/vector/search.js +51 -0
  150. package/dist/vector/search.js.map +1 -0
  151. package/package.json +57 -0
@@ -0,0 +1,415 @@
1
+ /**
2
+ * memnant — Context compilation.
3
+ *
4
+ * Story 2.1: Compiles a context package from the ledger and docs.
5
+ * This is the core of the "3-week Monday morning" experience.
6
+ *
7
+ * Compilation steps (in order):
8
+ * 1. Last session summary
9
+ * 2. Open TODOs from recent session logs
10
+ * 3. Epic context (decisions mentioning the epic)
11
+ * 4. Framework fixes (5 most recent, filtered by epic)
12
+ * 5. Spec constraints (from docs with matching frontmatter)
13
+ * 6. Persona tests (from docs with type: persona)
14
+ */
15
+ import { existsSync, readFileSync, readdirSync } from 'fs';
16
+ import { join } from 'path';
17
+ import { getLastClosedSession } from '../ledger/sessions.js';
18
+ import { scanProject, diffSnapshots, getLastSnapshot, getChangedPaths, getChangedDeps, } from '../snapshot/scanner.js';
19
+ export function compileContext(db, opts) {
20
+ const warnings = [];
21
+ // 1. Last session summary
22
+ const lastSession = getLastClosedSession(db);
23
+ let lastSessionText = null;
24
+ if (lastSession) {
25
+ if (lastSession.log_skipped) {
26
+ const date = lastSession.closed_at?.slice(0, 10) ?? 'unknown';
27
+ warnings.push(`\u26a0 Previous session (${date}) has no log. Context from that session is not available. You may have blind spots.`);
28
+ }
29
+ else if (lastSession.log_record_id) {
30
+ const logRecord = db.get('SELECT content_text FROM record WHERE id = ?', [lastSession.log_record_id]);
31
+ lastSessionText = logRecord?.content_text ?? null;
32
+ }
33
+ }
34
+ // 2. Open TODOs from last 3 session logs
35
+ const recentLogs = db.all(`SELECT content_text FROM record
36
+ WHERE type = 'session_log'
37
+ ORDER BY created_at DESC
38
+ LIMIT 3`);
39
+ const openTodos = [];
40
+ for (const log of recentLogs) {
41
+ const todos = extractTodos(log.content_text);
42
+ openTodos.push(...todos);
43
+ }
44
+ // 3. Epic context
45
+ let epicContext = null;
46
+ if (opts.epic) {
47
+ const epicRecords = db.all(`SELECT id, type, content_text, created_at, tags FROM record
48
+ WHERE type = 'decision'
49
+ AND (tags LIKE ? OR content_text LIKE ?)
50
+ ORDER BY created_at DESC`, [`%${opts.epic}%`, `%${opts.epic}%`]);
51
+ if (epicRecords.length > 0) {
52
+ const lines = epicRecords.map((r) => {
53
+ const shortId = r.id.slice(0, 8);
54
+ const date = r.created_at.slice(0, 10);
55
+ return `- [${shortId}] (${date}) ${r.content_text.slice(0, 200)}`;
56
+ });
57
+ epicContext = `Decisions related to "${opts.epic}":\n${lines.join('\n')}`;
58
+ }
59
+ }
60
+ // 4. Framework fixes (5 most recent, filtered by epic if provided)
61
+ let fwQuery = `SELECT id, type, content_text, created_at, tags FROM record
62
+ WHERE type = 'framework_fix'`;
63
+ const fwParams = [];
64
+ if (opts.epic) {
65
+ fwQuery += ` AND (tags LIKE ? OR content_text LIKE ?)`;
66
+ fwParams.push(`%${opts.epic}%`, `%${opts.epic}%`);
67
+ }
68
+ fwQuery += ` ORDER BY created_at DESC LIMIT 5`;
69
+ const fwRecords = db.all(fwQuery, fwParams);
70
+ const frameworkFixes = fwRecords.map((r) => {
71
+ const shortId = r.id.slice(0, 8);
72
+ const date = r.created_at.slice(0, 10);
73
+ return `[${shortId}] (${date}) ${r.content_text}`;
74
+ });
75
+ // 5. Spec constraints (from docs with matching frontmatter)
76
+ const specConstraints = scanDocsForSpecs(opts.docsPath, opts.epic);
77
+ // 6. Persona tests
78
+ const personaTests = scanDocsForPersonas(opts.docsPath, opts.epic);
79
+ // 7. Staleness detection
80
+ const staleDecisions = detectStaleness(db, opts.projectRoot);
81
+ // Build the compiled context
82
+ const ctx = {
83
+ token_estimate: 0,
84
+ warnings,
85
+ sections: {
86
+ last_session: lastSessionText,
87
+ open_todos: openTodos,
88
+ epic_context: epicContext,
89
+ framework_fixes: frameworkFixes,
90
+ spec_constraints: specConstraints,
91
+ persona_tests: personaTests,
92
+ stale_decisions: staleDecisions,
93
+ },
94
+ };
95
+ // Estimate tokens (~4 chars per token)
96
+ ctx.token_estimate = Math.ceil(contextToString(ctx).length / 4);
97
+ return ctx;
98
+ }
99
+ function extractTodos(text) {
100
+ const lines = text.split('\n');
101
+ let inTodos = false;
102
+ const todos = [];
103
+ for (const line of lines) {
104
+ if (/^##\s+TODOs?\s*$/i.test(line)) {
105
+ inTodos = true;
106
+ continue;
107
+ }
108
+ if (inTodos && /^##\s/.test(line)) {
109
+ break; // Next section
110
+ }
111
+ if (inTodos) {
112
+ const trimmed = line.trim();
113
+ if (trimmed && trimmed !== '-' && trimmed !== '*') {
114
+ todos.push(trimmed);
115
+ }
116
+ }
117
+ }
118
+ return todos;
119
+ }
120
+ function parseFrontmatter(content) {
121
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
122
+ if (!match)
123
+ return { frontmatter: null, body: content };
124
+ try {
125
+ // Simple YAML parsing for frontmatter — handles key: value and key: [array]
126
+ const fm = {};
127
+ const lines = match[1].split('\n');
128
+ for (const line of lines) {
129
+ const kv = line.match(/^(\w+):\s*(.+)$/);
130
+ if (kv) {
131
+ const value = kv[2].trim();
132
+ if (value.startsWith('[') && value.endsWith(']')) {
133
+ fm[kv[1]] = value.slice(1, -1).split(',').map((s) => s.trim().replace(/^["']|["']$/g, ''));
134
+ }
135
+ else {
136
+ fm[kv[1]] = value.replace(/^["']|["']$/g, '');
137
+ }
138
+ }
139
+ }
140
+ return { frontmatter: fm, body: match[2] };
141
+ }
142
+ catch {
143
+ return { frontmatter: null, body: content };
144
+ }
145
+ }
146
+ function matchesEpic(appliesTo, epic) {
147
+ if (!epic)
148
+ return true; // No epic filter — include all
149
+ if (!appliesTo)
150
+ return false;
151
+ const targets = Array.isArray(appliesTo) ? appliesTo : [appliesTo];
152
+ return targets.some((t) => t === 'all' || t.toLowerCase().includes(epic.toLowerCase()));
153
+ }
154
+ function scanDocsForSpecs(docsPath, epic) {
155
+ if (!existsSync(docsPath))
156
+ return [];
157
+ const specs = [];
158
+ let files;
159
+ try {
160
+ files = readdirSync(docsPath).filter((f) => f.endsWith('.md'));
161
+ }
162
+ catch {
163
+ return [];
164
+ }
165
+ for (const file of files) {
166
+ const content = readFileSync(join(docsPath, file), 'utf-8');
167
+ const { frontmatter, body } = parseFrontmatter(content);
168
+ if (!frontmatter)
169
+ continue;
170
+ if (!frontmatter.applies_to)
171
+ continue;
172
+ // Spec types that count as constraints
173
+ const specTypes = ['design_system', 'copy_audit', 'data_model', 'product_spec'];
174
+ if (!frontmatter.type || !specTypes.includes(frontmatter.type))
175
+ continue;
176
+ if (matchesEpic(frontmatter.applies_to, epic)) {
177
+ const summary = body.trim().slice(0, 500);
178
+ specs.push(`[${file}] ${summary}`);
179
+ }
180
+ }
181
+ return specs;
182
+ }
183
+ function scanDocsForPersonas(docsPath, epic) {
184
+ if (!existsSync(docsPath))
185
+ return [];
186
+ const tests = [];
187
+ let files;
188
+ try {
189
+ files = readdirSync(docsPath).filter((f) => f.endsWith('.md'));
190
+ }
191
+ catch {
192
+ return [];
193
+ }
194
+ for (const file of files) {
195
+ const content = readFileSync(join(docsPath, file), 'utf-8');
196
+ const { frontmatter, body } = parseFrontmatter(content);
197
+ if (!frontmatter)
198
+ continue;
199
+ if (frontmatter.type !== 'persona')
200
+ continue;
201
+ if (epic && frontmatter.applies_to && !matchesEpic(frontmatter.applies_to, epic)) {
202
+ continue;
203
+ }
204
+ // Extract test questions — look for lines that end with "?"
205
+ const questions = body
206
+ .split('\n')
207
+ .filter((line) => line.trim().endsWith('?'))
208
+ .map((line) => line.trim())
209
+ .filter((line) => line.length > 10); // Skip trivially short lines
210
+ if (questions.length > 0) {
211
+ tests.push(`[${file}] ${questions.join(' | ')}`);
212
+ }
213
+ }
214
+ return tests;
215
+ }
216
+ /**
217
+ * Detect stale decisions and framework fixes by comparing the latest
218
+ * snapshot against the current codebase state.
219
+ */
220
+ function detectStaleness(db, projectRoot) {
221
+ if (!projectRoot)
222
+ return [];
223
+ const lastSnapshot = getLastSnapshot(db);
224
+ if (!lastSnapshot)
225
+ return [];
226
+ // Scan current state and diff against last snapshot
227
+ const currentState = scanProject(projectRoot);
228
+ const diff = diffSnapshots(lastSnapshot, currentState);
229
+ const changedPaths = getChangedPaths(diff);
230
+ const changedDeps = getChangedDeps(diff);
231
+ if (changedPaths.length === 0 && changedDeps.length === 0)
232
+ return [];
233
+ const stale = [];
234
+ // Check decision records for mentions of changed file paths
235
+ const decisions = db.all(`SELECT id, content_text, created_at FROM record WHERE type = 'decision'`);
236
+ for (const record of decisions) {
237
+ const triggers = findPathMentions(record.content_text, changedPaths);
238
+ if (triggers.length > 0) {
239
+ const shortId = record.id.slice(0, 8);
240
+ const date = record.created_at.slice(0, 10);
241
+ const firstLine = record.content_text.split('\n')[0].slice(0, 100);
242
+ stale.push(`[${shortId}] (${date}) ${firstLine} — triggered by: ${triggers.join(', ')}`);
243
+ }
244
+ }
245
+ // Check framework fixes for mentions of changed dependencies
246
+ if (changedDeps.length > 0) {
247
+ const fixes = db.all(`SELECT id, content_text, created_at FROM record WHERE type = 'framework_fix'`);
248
+ for (const record of fixes) {
249
+ const triggers = findDepMentions(record.content_text, changedDeps);
250
+ if (triggers.length > 0) {
251
+ const shortId = record.id.slice(0, 8);
252
+ const date = record.created_at.slice(0, 10);
253
+ const firstLine = record.content_text.split('\n')[0].slice(0, 100);
254
+ stale.push(`[${shortId}] (${date}) ${firstLine} — dependency changed: ${triggers.join(', ')}`);
255
+ }
256
+ }
257
+ }
258
+ return stale;
259
+ }
260
+ /**
261
+ * Find which changed paths are mentioned in text.
262
+ * Matches exact file paths and directory-level matches.
263
+ */
264
+ function findPathMentions(text, changedPaths) {
265
+ const triggers = [];
266
+ const lowerText = text.toLowerCase();
267
+ for (const path of changedPaths) {
268
+ // Exact path match
269
+ if (lowerText.includes(path.toLowerCase())) {
270
+ triggers.push(path);
271
+ continue;
272
+ }
273
+ // Directory-level match (e.g. "src/components" matches "src/components/Button.tsx")
274
+ const dir = path.split('/').slice(0, -1).join('/');
275
+ if (dir && lowerText.includes(dir.toLowerCase())) {
276
+ triggers.push(path);
277
+ }
278
+ }
279
+ return triggers;
280
+ }
281
+ /**
282
+ * Find which changed dependencies are mentioned in text.
283
+ */
284
+ function findDepMentions(text, changedDeps) {
285
+ const triggers = [];
286
+ const lowerText = text.toLowerCase();
287
+ for (const dep of changedDeps) {
288
+ if (lowerText.includes(dep.toLowerCase())) {
289
+ triggers.push(dep);
290
+ }
291
+ }
292
+ return triggers;
293
+ }
294
+ /**
295
+ * Compute staleness for a set of record IDs. Used by recall to add [stale] markers.
296
+ * Returns a Set of record IDs that are potentially stale.
297
+ */
298
+ export function computeStaleRecordIds(db, projectRoot) {
299
+ const staleIds = new Set();
300
+ const lastSnapshot = getLastSnapshot(db);
301
+ if (!lastSnapshot)
302
+ return staleIds;
303
+ const currentState = scanProject(projectRoot);
304
+ const diff = diffSnapshots(lastSnapshot, currentState);
305
+ const changedPaths = getChangedPaths(diff);
306
+ const changedDeps = getChangedDeps(diff);
307
+ if (changedPaths.length === 0 && changedDeps.length === 0)
308
+ return staleIds;
309
+ // Check decisions against changed paths
310
+ const decisions = db.all(`SELECT id, content_text FROM record WHERE type = 'decision'`);
311
+ for (const record of decisions) {
312
+ if (findPathMentions(record.content_text, changedPaths).length > 0) {
313
+ staleIds.add(record.id);
314
+ }
315
+ }
316
+ // Check framework fixes against changed deps
317
+ if (changedDeps.length > 0) {
318
+ const fixes = db.all(`SELECT id, content_text FROM record WHERE type = 'framework_fix'`);
319
+ for (const record of fixes) {
320
+ if (findDepMentions(record.content_text, changedDeps).length > 0) {
321
+ staleIds.add(record.id);
322
+ }
323
+ }
324
+ }
325
+ return staleIds;
326
+ }
327
+ export function formatContextAsMarkdown(ctx) {
328
+ const parts = [];
329
+ parts.push(`Compiled context: ~${ctx.token_estimate} tokens\n`);
330
+ if (ctx.warnings.length > 0) {
331
+ parts.push(ctx.warnings.join('\n'));
332
+ parts.push('');
333
+ }
334
+ // 1. Last session summary
335
+ parts.push('## Last Session Summary\n');
336
+ if (ctx.sections.last_session) {
337
+ parts.push(ctx.sections.last_session);
338
+ }
339
+ else {
340
+ parts.push('No previous session log available.');
341
+ }
342
+ parts.push('');
343
+ // 2. Open TODOs
344
+ parts.push('## Open TODOs\n');
345
+ if (ctx.sections.open_todos.length > 0) {
346
+ for (const todo of ctx.sections.open_todos) {
347
+ parts.push(todo);
348
+ }
349
+ }
350
+ else {
351
+ parts.push('No open TODOs.');
352
+ }
353
+ parts.push('');
354
+ // 3. Epic context
355
+ if (ctx.sections.epic_context) {
356
+ parts.push('## Epic Context\n');
357
+ parts.push(ctx.sections.epic_context);
358
+ parts.push('');
359
+ }
360
+ // 4. Framework fixes
361
+ parts.push('## Framework Fixes\n');
362
+ if (ctx.sections.framework_fixes.length > 0) {
363
+ for (const fix of ctx.sections.framework_fixes) {
364
+ parts.push(`- ${fix}`);
365
+ }
366
+ }
367
+ else {
368
+ parts.push('No framework fixes recorded.');
369
+ }
370
+ parts.push('');
371
+ // 5. Spec constraints
372
+ parts.push('## Spec Constraints\n');
373
+ if (ctx.sections.spec_constraints.length > 0) {
374
+ for (const spec of ctx.sections.spec_constraints) {
375
+ parts.push(`- ${spec}`);
376
+ }
377
+ }
378
+ else {
379
+ parts.push('No applicable spec constraints.');
380
+ }
381
+ parts.push('');
382
+ // 6. Persona tests
383
+ parts.push('## Persona Tests\n');
384
+ if (ctx.sections.persona_tests.length > 0) {
385
+ for (const test of ctx.sections.persona_tests) {
386
+ parts.push(`- ${test}`);
387
+ }
388
+ }
389
+ else {
390
+ parts.push('No active persona tests.');
391
+ }
392
+ parts.push('');
393
+ // 7. Stale decisions
394
+ if (ctx.sections.stale_decisions.length > 0) {
395
+ parts.push('## \u26a0 Potentially Stale Decisions\n');
396
+ for (const stale of ctx.sections.stale_decisions) {
397
+ parts.push(`- ${stale}`);
398
+ }
399
+ }
400
+ return parts.join('\n');
401
+ }
402
+ function contextToString(ctx) {
403
+ const parts = [
404
+ ctx.warnings.join(' '),
405
+ ctx.sections.last_session ?? '',
406
+ ctx.sections.open_todos.join(' '),
407
+ ctx.sections.epic_context ?? '',
408
+ ctx.sections.framework_fixes.join(' '),
409
+ ctx.sections.spec_constraints.join(' '),
410
+ ctx.sections.persona_tests.join(' '),
411
+ ctx.sections.stale_decisions.join(' '),
412
+ ];
413
+ return parts.join(' ');
414
+ }
415
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/context/compile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * memnant — Copy audit checker.
3
+ *
4
+ * Story 5.2: Checks text against copy audit spec rules.
5
+ * Reports banned phrases, discouraged phrases, and tone violations.
6
+ */
7
+ import { type SpecDocument } from './specs.js';
8
+ export type ViolationLevel = 'banned' | 'discouraged' | 'tone';
9
+ export interface CopyViolation {
10
+ level: ViolationLevel;
11
+ message: string;
12
+ line?: number;
13
+ term?: string;
14
+ }
15
+ export interface CopyCheckResult {
16
+ violations: CopyViolation[];
17
+ hasBanned: boolean;
18
+ }
19
+ /**
20
+ * Check text against copy audit spec.
21
+ */
22
+ export declare function checkCopy(text: string, docsPath: string): CopyCheckResult;
23
+ export declare function checkCopyAgainstSpec(text: string, spec: SpecDocument): CopyCheckResult;
24
+ //# sourceMappingURL=copy-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy-check.d.ts","sourceRoot":"","sources":["../../src/governor/copy-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgC,KAAK,YAAY,EAAwD,MAAM,YAAY,CAAC;AAEnI,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CASzE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,eAAe,CAkDtF"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * memnant — Copy audit checker.
3
+ *
4
+ * Story 5.2: Checks text against copy audit spec rules.
5
+ * Reports banned phrases, discouraged phrases, and tone violations.
6
+ */
7
+ import { scanSpecs, extractSpecDetail } from './specs.js';
8
+ /**
9
+ * Check text against copy audit spec.
10
+ */
11
+ export function checkCopy(text, docsPath) {
12
+ const specs = scanSpecs(docsPath);
13
+ const copySpec = specs.find((s) => s.frontmatter.type === 'copy_audit');
14
+ if (!copySpec) {
15
+ return { violations: [], hasBanned: false };
16
+ }
17
+ return checkCopyAgainstSpec(text, copySpec);
18
+ }
19
+ export function checkCopyAgainstSpec(text, spec) {
20
+ const detail = extractSpecDetail(spec);
21
+ const violations = [];
22
+ const lines = text.split('\n');
23
+ // Check banned phrases
24
+ for (const banned of detail.banned) {
25
+ for (let i = 0; i < lines.length; i++) {
26
+ if (containsTerm(lines[i], banned.term)) {
27
+ let msg = `[BANNED] "${banned.term}"`;
28
+ if (banned.replacement)
29
+ msg += ` → use "${banned.replacement}"`;
30
+ if (banned.reason)
31
+ msg += ` — ${banned.reason}`;
32
+ violations.push({ level: 'banned', message: msg, line: i + 1, term: banned.term });
33
+ }
34
+ }
35
+ }
36
+ // Check discouraged phrases
37
+ for (const disc of detail.discouraged) {
38
+ for (let i = 0; i < lines.length; i++) {
39
+ if (containsTerm(lines[i], disc.term)) {
40
+ let msg = `[DISCOURAGED] "${disc.term}"`;
41
+ if (disc.replacement)
42
+ msg += ` → "${disc.replacement}"`;
43
+ if (disc.reason)
44
+ msg += ` — ${disc.reason}`;
45
+ violations.push({ level: 'discouraged', message: msg, line: i + 1, term: disc.term });
46
+ }
47
+ }
48
+ }
49
+ // Check tone rules
50
+ for (const rule of detail.tone_rules) {
51
+ if (rule.type === 'max_sentence_length' && typeof rule.value === 'number') {
52
+ for (let i = 0; i < lines.length; i++) {
53
+ const sentences = lines[i].split(/[.!?]+/).filter((s) => s.trim());
54
+ for (const sentence of sentences) {
55
+ const wordCount = sentence.trim().split(/\s+/).length;
56
+ if (wordCount > rule.value) {
57
+ violations.push({
58
+ level: 'tone',
59
+ message: `[TONE] Sentence exceeds max length (${wordCount} words, max ${rule.value})`,
60
+ line: i + 1,
61
+ });
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ const hasBanned = violations.some((v) => v.level === 'banned');
68
+ return { violations, hasBanned };
69
+ }
70
+ function containsTerm(text, term) {
71
+ const escaped = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
72
+ const regex = new RegExp(`\\b${escaped}\\b`, 'i');
73
+ return regex.test(text);
74
+ }
75
+ //# sourceMappingURL=copy-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy-check.js","sourceRoot":"","sources":["../../src/governor/copy-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * memnant — Design system validation.
3
+ *
4
+ * Story 5.3: Scans source files for banned components from the design system spec.
5
+ */
6
+ export interface DesignViolation {
7
+ file: string;
8
+ line: number;
9
+ message: string;
10
+ term: string;
11
+ }
12
+ export interface DesignCheckResult {
13
+ violations: DesignViolation[];
14
+ hasBanned: boolean;
15
+ }
16
+ /**
17
+ * Check source code for banned components.
18
+ */
19
+ export declare function checkDesign(code: string, filename: string, docsPath: string): DesignCheckResult;
20
+ //# sourceMappingURL=design-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-check.d.ts","sourceRoot":"","sources":["../../src/governor/design-check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAgC/F"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * memnant — Design system validation.
3
+ *
4
+ * Story 5.3: Scans source files for banned components from the design system spec.
5
+ */
6
+ import { scanSpecs, extractSpecDetail } from './specs.js';
7
+ /**
8
+ * Check source code for banned components.
9
+ */
10
+ export function checkDesign(code, filename, docsPath) {
11
+ const specs = scanSpecs(docsPath);
12
+ const designSpec = specs.find((s) => s.frontmatter.type === 'design_system');
13
+ if (!designSpec) {
14
+ return { violations: [], hasBanned: false };
15
+ }
16
+ const detail = extractSpecDetail(designSpec);
17
+ const violations = [];
18
+ const lines = code.split('\n');
19
+ for (const banned of detail.banned) {
20
+ const escaped = banned.term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
21
+ const regex = new RegExp(`\\b${escaped}\\b`, 'i');
22
+ for (let i = 0; i < lines.length; i++) {
23
+ if (regex.test(lines[i])) {
24
+ let msg = `[BANNED] "${banned.term}" is a banned component.`;
25
+ if (banned.reason)
26
+ msg += ` Design system says: "${banned.reason}"`;
27
+ if (banned.replacement)
28
+ msg += ` Use "${banned.replacement}" instead.`;
29
+ violations.push({
30
+ file: filename,
31
+ line: i + 1,
32
+ message: msg,
33
+ term: banned.term,
34
+ });
35
+ }
36
+ }
37
+ }
38
+ return { violations, hasBanned: violations.length > 0 };
39
+ }
40
+ //# sourceMappingURL=design-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-check.js","sourceRoot":"","sources":["../../src/governor/design-check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAc1D;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,QAAgB,EAAE,QAAgB;IAC1E,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;IAE7E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE/B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,OAAO,KAAK,EAAE,GAAG,CAAC,CAAC;QAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzB,IAAI,GAAG,GAAG,aAAa,MAAM,CAAC,IAAI,0BAA0B,CAAC;gBAC7D,IAAI,MAAM,CAAC,MAAM;oBAAE,GAAG,IAAI,yBAAyB,MAAM,CAAC,MAAM,GAAG,CAAC;gBACpE,IAAI,MAAM,CAAC,WAAW;oBAAE,GAAG,IAAI,SAAS,MAAM,CAAC,WAAW,YAAY,CAAC;gBACvE,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,OAAO,EAAE,GAAG;oBACZ,IAAI,EAAE,MAAM,CAAC,IAAI;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;AAC1D,CAAC"}