@ryuenn3123/agentic-senior-core 4.3.2 → 4.3.5

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 (48) hide show
  1. package/.agent-context/prompts/bootstrap-design.md +56 -222
  2. package/.agent-context/rules/api-docs.md +17 -126
  3. package/.agent-context/rules/api-versioning.md +9 -86
  4. package/.agent-context/rules/architecture.md +18 -136
  5. package/.agent-context/rules/background-jobs.md +9 -85
  6. package/.agent-context/rules/config-and-flags.md +8 -71
  7. package/.agent-context/rules/database-design.md +9 -65
  8. package/.agent-context/rules/docker-runtime.md +9 -62
  9. package/.agent-context/rules/efficiency-vs-hype.md +7 -37
  10. package/.agent-context/rules/error-handling.md +8 -33
  11. package/.agent-context/rules/event-driven.md +8 -34
  12. package/.agent-context/rules/frontend-architecture.md +22 -140
  13. package/.agent-context/rules/git-workflow.md +8 -77
  14. package/.agent-context/rules/microservices.md +8 -36
  15. package/.agent-context/rules/migrations.md +8 -76
  16. package/.agent-context/rules/observability.md +7 -60
  17. package/.agent-context/rules/performance.md +8 -28
  18. package/.agent-context/rules/realtime.md +7 -22
  19. package/.agent-context/rules/resilience.md +9 -69
  20. package/.agent-context/rules/security.md +9 -64
  21. package/.agent-context/rules/testing.md +8 -34
  22. package/AGENTS.md +11 -18
  23. package/README.md +1 -1
  24. package/lib/cli/adaptive-context/catalog.mjs +1 -6
  25. package/lib/cli/commands/audit-design-anti-repeat.mjs +26 -185
  26. package/lib/cli/commands/init/project-context.mjs +0 -41
  27. package/lib/cli/commands/init.mjs +12 -41
  28. package/lib/cli/commands/upgrade.mjs +12 -35
  29. package/lib/cli/compiler.mjs +5 -81
  30. package/lib/cli/preflight.mjs +0 -21
  31. package/lib/cli/project-scaffolder/constants.mjs +1 -1
  32. package/lib/cli/project-scaffolder/design-contract.mjs +3 -45
  33. package/lib/cli/project-scaffolder/prompt-builders.mjs +18 -161
  34. package/lib/cli/project-scaffolder/storage.mjs +0 -9
  35. package/lib/cli/project-scaffolder.mjs +0 -1
  36. package/package.json +1 -1
  37. package/scripts/frontend-usability-audit.mjs +4 -45
  38. package/scripts/release-gate/constants.mjs +1 -0
  39. package/scripts/release-gate/static-checks.mjs +0 -36
  40. package/scripts/validate/config.mjs +20 -144
  41. package/scripts/validate/coverage-checks.mjs +2 -12
  42. package/scripts/validate/file-structure.mjs +165 -0
  43. package/scripts/validate/markdown-content.mjs +109 -0
  44. package/scripts/validate/project-metadata.mjs +166 -0
  45. package/scripts/validate.mjs +42 -435
  46. package/.agent-context/prompts/research-design.md +0 -160
  47. package/lib/cli/commands/upgrade/design-intent-seed.mjs +0 -46
  48. package/lib/cli/project-scaffolder/design-contract/research-dossier-migration.mjs +0 -190
@@ -21,16 +21,7 @@ export const FORMAL_ARTIFACT_PATHS = [
21
21
  'GEMINI.md',
22
22
  ];
23
23
  export const REQUIRED_HUMAN_WRITING_SNIPPETS = [
24
- {
25
- path: '.agent-context/rules/api-docs.md',
26
- snippets: [
27
- '## API-006: Human Writing Standard (Mandatory)',
28
- 'This applies to documentation, release notes, onboarding text, review summaries, and agent-facing explanations.',
29
- 'Style baseline findings are advisory by default and must not block endpoint-change commits that already include accurate docs/spec updates.',
30
- 'Write formal project docs in English by default',
31
- 'No emoji in formal artifacts.',
32
- ],
33
- },
24
+
34
25
  {
35
26
  path: '.agent-context/review-checklists/pr-checklist.md',
36
27
  snippets: [
@@ -161,18 +152,8 @@ export const REQUIRED_STACK_DECISION_BOUNDARY_SNIPPETS = [
161
152
  'produce a short evidence-backed recommendation from the brief, repo evidence, and live official documentation before coding',
162
153
  ],
163
154
  },
164
- {
165
- path: '.agent-context/rules/architecture.md',
166
- snippets: [
167
- 'Do not force a default architecture label before the repo, delivery model, and boundary evidence are clear.',
168
- ],
169
- },
170
- {
171
- path: '.agent-context/rules/microservices.md',
172
- snippets: [
173
- 'Do not start with microservices by fashion, fear, or habit.',
174
- ],
175
- },
155
+
156
+
176
157
  {
177
158
  path: 'lib/cli/commands/init.mjs',
178
159
  snippets: [
@@ -192,16 +173,7 @@ export const REQUIRED_UNIVERSAL_SOP_SNIPPETS = [
192
173
  'Do not write application, firmware, or UI code',
193
174
  ],
194
175
  },
195
- {
196
- path: '.agent-context/rules/architecture.md',
197
- snippets: [
198
- '## ARCH-003: Universal SOP Baseline (Mandatory)',
199
- 'Root `README.md` must exist for every fresh or existing project',
200
- '`docs/doc-index.md` must exist whenever `docs/` exists',
201
- 'Security and testing are non-negotiable baseline requirements.',
202
- 'If required project context docs are missing, stop implementation and bootstrap docs before writing application code.',
203
- ],
204
- },
176
+
205
177
  {
206
178
  path: '.agent-context/prompts/init-project.md',
207
179
  snippets: [
@@ -252,20 +224,12 @@ export const REQUIRED_UNIVERSAL_SOP_SNIPPETS = [
252
224
  'Documentation-first policy:',
253
225
  'Keep README.md public and developer friendly',
254
226
  'For docs-only/docs-first requests, do not write application, firmware, or UI code until the user asks or approves an implementation plan.',
255
- 'For UI scope: if docs/DESIGN.md or docs/design-intent.json is missing, execute bootstrap-design prompt before implementing UI surfaces.',
227
+ 'Follow the three-step design direction process in bootstrap-design.md',
256
228
  ],
257
229
  },
258
230
  ];
259
231
  export const REQUIRED_DIAGRAM_FORMAT_SNIPPETS = [
260
- {
261
- path: '.agent-context/rules/api-docs.md',
262
- snippets: [
263
- '## API-013: Documentation Diagram Format (Mandatory)',
264
- 'Mermaid.js as the default diagram format',
265
- 'Do not use PlantUML',
266
- 'convert the relevant sections to Mermaid diagrams in the same change',
267
- ],
268
- },
232
+
269
233
  {
270
234
  path: 'lib/cli/project-scaffolder/prompt-builders.mjs',
271
235
  snippets: [
@@ -303,18 +267,9 @@ export const REQUIRED_UPGRADE_UI_CONTRACT_WARNING_SNIPPETS = [
303
267
  path: 'lib/cli/commands/upgrade.mjs',
304
268
  snippets: [
305
269
  'UI/frontend scope was detected, but the dynamic design contract is incomplete:',
306
- 'docs/design-intent.json',
307
- 'Planned seed on apply: docs/design-intent.json',
308
- 'Upgrade synchronizes governance assets and can seed docs/design-intent.json, but it does not author project-specific docs/DESIGN.md automatically.',
309
270
  'detectUiScopeSignals',
310
271
  ],
311
272
  },
312
- {
313
- path: 'lib/cli/commands/upgrade/design-intent-seed.mjs',
314
- snippets: [
315
- 'seed-generated-during-upgrade',
316
- ],
317
- },
318
273
  ];
319
274
  export const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
320
275
  {
@@ -324,19 +279,12 @@ export const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
324
279
  'bootstrap-design.md',
325
280
  'frontend-architecture.md',
326
281
  'docs/DESIGN.md',
327
- 'docs/design-intent.json',
328
282
  'Documentation-First Mode',
329
283
  'English by default',
330
284
  'do not write application, firmware, or UI code',
331
- 'Motion/Palette Decision',
332
- 'product categories are heuristics',
285
+ 'three-step direction process',
286
+ 'anti-repeat ledger',
333
287
  'perform live web research',
334
- 'research-design.md',
335
- 'researchDossier.metadata',
336
- 'researchVerifiedAt',
337
- 'freshnessWindowDays',
338
- 'Anti-repeat ledger',
339
- 'user-explicit redesign',
340
288
  ],
341
289
  },
342
290
  {
@@ -346,8 +294,6 @@ export const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
346
294
  'UI Design Mode',
347
295
  'bootstrap-design.md',
348
296
  'frontend-architecture.md',
349
- 'Motion/Palette Decision',
350
- 'product categories are heuristics',
351
297
  'do not eagerly load unrelated backend-only rules',
352
298
  'valid style context',
353
299
  'External references, prior-chat memory, unrelated-project visuals, and remembered screenshots are tainted',
@@ -358,63 +304,16 @@ export const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
358
304
  {
359
305
  path: '.agent-context/prompts/bootstrap-design.md',
360
306
  snippets: [
361
- 'This contract is a decision scaffold, not a style preset.',
362
- 'We guide the agent; we do not pick the final style',
363
- 'Token Architecture and Alias Strategy',
364
- '`repoEvidence.designEvidenceSummary`',
365
- 'Responsive Recomposition Plan',
366
- 'source of truth',
307
+ 'WCAG 2.2 AA is the hard compliance floor',
308
+ 'Name Your Defaults',
309
+ 'Choose an Anchor',
310
+ 'Creative Commitments',
311
+ 'anti-repeat ledger',
312
+ 'Named Defaults to Avoid',
313
+ 'Post-Implementation Check',
314
+ 'Redesign Protocol',
367
315
  'research current official docs',
368
- 'motionPaletteDecision',
369
- 'AI-safe UI',
370
- 'Creative Ambition Floor',
371
- 'AI Color and Template Residue Audit',
372
- 'Motion and 3D Courage Rule',
373
- 'Design Flexibility Layer',
374
- 'visually exploratory, product-derived palettes',
375
- 'decorative grid wallpaper',
376
- '`aiSafeUiAudit`',
377
- 'AI color drift',
378
- 'first-class UI options',
379
- 'product categories are heuristics',
380
- 'Responsive design means recomposition, not resizing.',
381
- 'agent-chosen visual direction',
382
- 'viewport mutation rules',
383
- 'WCAG 2.2 AA is the hard floor',
384
- 'APCA may be used only as advisory perceptual tuning',
385
- 'unresearched dependency choices',
386
- 'Dynamic UI Foundation Selection',
387
- 'Adaptive Research Freshness',
388
- 'fixed calendar range',
389
- 'research vocabulary internal',
390
- 'locked outcomes from flexible expression',
391
- 'A new dependency, package count, or vague performance concern is not a blocker by itself.',
392
- 'default component-kit styling without product rationale',
393
- 'genericity findings that cannot name the exact drift signal',
394
- 'research-design.md',
395
- 'Section 3 gate from `research-design.md`',
396
- 'Pre-Emit Identity Check',
397
- ],
398
- },
399
- {
400
- path: '.agent-context/prompts/research-design.md',
401
- snippets: [
402
- '# Research-Design Brief',
403
- '## Section 3 — Creative Direction',
404
- '### 3a. Category defaults to avoid',
405
- '### 3b. Anchor reference',
406
- '### 3c. Four creative commitments',
407
- 'AI slop',
408
- 'Anti-Repeat Ledger Gate',
409
- 'Live Source Freshness Gate',
410
- 'rolling-current',
411
- 'evidenceTable[]',
412
- 'old-timeless',
413
- 'Research vocabulary is internal-only',
414
- 'previousAnchors',
415
- 'previousMotionSignatures',
416
- 'tokenContinuityClassification',
417
- 'categoryCodes',
316
+ 'product-specific reason',
418
317
  ],
419
318
  },
420
319
  {
@@ -566,8 +465,7 @@ export const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
566
465
  'LAYER 1: RULES (SCOPE-RESOLVED)',
567
466
  'LAYER 5: EXECUTION PROMPTS AND UI TRIGGERS',
568
467
  'bootstrap-design.md -> ui, ux, layout, screen, tailwind, frontend, redesign',
569
- 'Keep UI-only requests context-isolated',
570
- 'git-workflow.md',
468
+ 'three-step design direction process in bootstrap-design.md',
571
469
  'designEvidenceSummary',
572
470
  ],
573
471
  },
@@ -580,18 +478,7 @@ export const REQUIRED_DOCKER_RUNTIME_AUTOMATION_SNIPPETS = [
580
478
  'For Docker or Compose work, load `docker-runtime.md` and verify the latest official Docker docs before authoring container assets.',
581
479
  ],
582
480
  },
583
- {
584
- path: '.agent-context/rules/docker-runtime.md',
585
- snippets: [
586
- 'latest official Docker documentation first',
587
- 'Docker Compose Quickstart',
588
- 'Compose file reference',
589
- 'Dockerfile best practices',
590
- 'Use current `docker compose` workflows and `compose.yaml`.',
591
- 'Do not add the top-level Compose `version` field by default.',
592
- 'Use the latest stable compatible Docker base image',
593
- ],
594
- },
481
+
595
482
  {
596
483
  path: '.agent-context/prompts/init-project.md',
597
484
  snippets: [
@@ -607,17 +494,7 @@ export const REQUIRED_DEPENDENCY_FRESHNESS_AUTOMATION_SNIPPETS = [
607
494
  'use the latest stable compatible dependency set and official setup flow',
608
495
  ],
609
496
  },
610
- {
611
- path: '.agent-context/rules/efficiency-vs-hype.md',
612
- snippets: [
613
- 'Latest-Compatible-First Rule',
614
- 'latest stable compatible dependency version',
615
- 'official scaffolder or setup command',
616
- 'Only step down to an older dependency version after documenting',
617
- 'Do not treat dependency avoidance as an engineering virtue by itself.',
618
- 'performance-fear choices',
619
- ],
620
- },
497
+
621
498
  {
622
499
  path: '.agent-context/prompts/init-project.md',
623
500
  snippets: [
@@ -649,7 +526,6 @@ export const FORBIDDEN_ACTIVE_BIAS_ANCHOR_SNIPPETS = [
649
526
  snippets: [
650
527
  'stylistic inspiration',
651
528
  'famous brand reference',
652
- 'If no approved reference system exists',
653
529
  'explicitly approved reference systems',
654
530
  ],
655
531
  },
@@ -360,13 +360,9 @@ export async function validateInstructionAdapters(context) {
360
360
  'unreachable_files',
361
361
  'validation_plan',
362
362
  ];
363
- const requiredUiReadabilitySnippets = [
364
- 'Motion/Palette Decision',
365
- 'product categories are heuristics',
366
- ];
367
363
  const instructionFootprintLimits = [
368
364
  { path: 'AGENTS.md', maxLines: 180 },
369
- { path: '.agent-context/prompts/bootstrap-design.md', maxLines: 235 },
365
+ { path: '.agent-context/prompts/bootstrap-design.md', maxLines: 80 },
370
366
  { path: '.agent-context/rules/frontend-architecture.md', maxLines: 180 },
371
367
  ];
372
368
 
@@ -378,13 +374,7 @@ export async function validateInstructionAdapters(context) {
378
374
  }
379
375
  }
380
376
 
381
- for (const requiredUiReadabilitySnippet of requiredUiReadabilitySnippets) {
382
- if (canonicalInstructionContent.includes(requiredUiReadabilitySnippet)) {
383
- pass(`AGENTS.md includes UI readability snippet: ${requiredUiReadabilitySnippet}`);
384
- } else {
385
- fail(`AGENTS.md is missing UI readability snippet: ${requiredUiReadabilitySnippet}`);
386
- }
387
- }
377
+
388
378
 
389
379
  for (const footprintLimit of instructionFootprintLimits) {
390
380
  const absoluteFootprintPath = join(ROOT_DIR, footprintLimit.path);
@@ -0,0 +1,165 @@
1
+ import { join } from 'node:path';
2
+ import { readdir } from 'node:fs/promises';
3
+
4
+ export async function validateRequiredFiles(context) {
5
+ const { ROOT_DIR, fileExists, pass, fail } = context;
6
+ console.log('\nChecking required files...');
7
+
8
+ const requiredFiles = [
9
+ 'bin/agentic-senior-core.js',
10
+ 'scripts/validate.mjs',
11
+ 'scripts/llm-judge.mjs',
12
+ 'scripts/detection-benchmark.mjs',
13
+ 'scripts/benchmark-evidence-bundle.mjs',
14
+ 'scripts/benchmark-writer-judge-matrix.mjs',
15
+ 'scripts/benchmark-gate.mjs',
16
+ 'scripts/benchmark-intelligence.mjs',
17
+ 'scripts/memory-continuity-benchmark.mjs',
18
+ 'scripts/docs-quality-drift-report.mjs',
19
+ 'scripts/governance-weekly-report.mjs',
20
+ 'scripts/mcp-server.mjs',
21
+ 'scripts/mcp-server/constants.mjs',
22
+ 'scripts/mcp-server/tool-registry.mjs',
23
+ 'scripts/mcp-server/tools.mjs',
24
+ 'scripts/frontend-usability-audit.mjs',
25
+ 'scripts/ui-design-judge.mjs',
26
+ 'scripts/documentation-boundary-audit.mjs',
27
+ 'scripts/context-triggered-audit.mjs',
28
+ 'scripts/rules-guardian-audit.mjs',
29
+ 'scripts/explain-on-demand-audit.mjs',
30
+ 'scripts/single-source-lazy-loading-audit.mjs',
31
+ 'scripts/audit-cache-layer-contract.mjs',
32
+ 'scripts/audit-typography-palette-anti-repeat.mjs',
33
+ 'lib/cli/audits/typography-palette-anti-repeat-audit.mjs',
34
+ 'lib/cli/commands/audit-design-anti-repeat.mjs',
35
+ 'scripts/sync-thin-adapters.mjs',
36
+ 'scripts/release-gate.mjs',
37
+ 'scripts/generate-sbom.mjs',
38
+ '.agent-context/policies/llm-judge-threshold.json',
39
+ '.agent-context/prompts/compact-natural-mode.md',
40
+ 'mcp.json',
41
+ 'AGENTS.md',
42
+ 'CLAUDE.md',
43
+ 'GEMINI.md',
44
+ 'README.md',
45
+ 'CHANGELOG.md',
46
+ 'docs/doc-index.md',
47
+ 'docs/project-brief.md',
48
+ 'docs/flow-overview.md',
49
+ 'docs/api-contract.md',
50
+ 'docs/faq.md',
51
+ 'docs/deep-dive.md',
52
+ 'docs/archive/HISTORY.md',
53
+ 'docs/archive/CHANGELOG-archive.md',
54
+ '.agent-context/state/benchmark-reproducibility.json',
55
+ '.agent-context/state/benchmark-writer-judge-config.json',
56
+ '.agent-context/state/memory-schema-v1.json',
57
+ '.agent-context/state/memory-adapter-contract.json',
58
+ '.vscode/mcp.json',
59
+ '.github/workflows/release-gate.yml',
60
+ '.github/workflows/sbom-compliance.yml',
61
+ '.github/workflows/benchmark-intelligence.yml',
62
+ '.github/workflows/docs-quality-drift-report.yml',
63
+ '.github/workflows/governance-weekly-report.yml',
64
+ 'tests/cli-smoke.test.mjs',
65
+ 'tests/mcp-server.test.mjs',
66
+ 'tests/llm-judge.test.mjs',
67
+ 'tests/operations.test.mjs',
68
+ 'LICENSE',
69
+ '.gitignore',
70
+ ];
71
+
72
+ for (const requiredFilePath of requiredFiles) {
73
+ const absoluteRequiredFilePath = join(ROOT_DIR, requiredFilePath);
74
+
75
+ if (await fileExists(absoluteRequiredFilePath)) {
76
+ pass(requiredFilePath);
77
+ continue;
78
+ }
79
+
80
+ fail(`Missing required file: ${requiredFilePath}`);
81
+ }
82
+ }
83
+
84
+ export async function validateRuleFiles(context) {
85
+ const { AGENT_CONTEXT_DIR, fileExists, readTextFile, pass, fail } = context;
86
+ console.log('\nChecking rule, checklist, prompt, and state files...');
87
+
88
+ const expectedPaths = [
89
+ 'rules/naming-conv.md',
90
+ 'rules/architecture.md',
91
+ 'rules/security.md',
92
+ 'rules/performance.md',
93
+ 'rules/error-handling.md',
94
+ 'rules/testing.md',
95
+ 'rules/git-workflow.md',
96
+ 'rules/efficiency-vs-hype.md',
97
+ 'rules/api-docs.md',
98
+ 'rules/microservices.md',
99
+ 'rules/event-driven.md',
100
+ 'rules/database-design.md',
101
+ 'rules/realtime.md',
102
+ 'rules/frontend-architecture.md',
103
+ 'rules/docker-runtime.md',
104
+ 'rules/observability.md',
105
+ 'rules/resilience.md',
106
+ 'rules/migrations.md',
107
+ 'rules/background-jobs.md',
108
+ 'rules/config-and-flags.md',
109
+ 'rules/api-versioning.md',
110
+ 'review-checklists/pr-checklist.md',
111
+ 'review-checklists/architecture-review.md',
112
+ 'prompts/init-project.md',
113
+ 'prompts/compact-natural-mode.md',
114
+ 'prompts/bootstrap-design.md',
115
+ 'prompts/refactor.md',
116
+ 'prompts/review-code.md',
117
+ 'state/architecture-map.md',
118
+ 'state/dependency-map.md',
119
+ ];
120
+
121
+ for (const expectedPath of expectedPaths) {
122
+ const absoluteExpectedPath = join(AGENT_CONTEXT_DIR, expectedPath);
123
+
124
+ if (!(await fileExists(absoluteExpectedPath))) {
125
+ fail(`Missing agent context file: .agent-context/${expectedPath}`);
126
+ continue;
127
+ }
128
+
129
+ const fileContent = await readTextFile(absoluteExpectedPath);
130
+ if (fileContent.trim().length < 100) {
131
+ fail(`Agent context file is suspiciously short: .agent-context/${expectedPath}`);
132
+ continue;
133
+ }
134
+
135
+ pass(`.agent-context/${expectedPath}`);
136
+ }
137
+ }
138
+
139
+ export async function validateChecklistConsolidation(context) {
140
+ const { AGENT_CONTEXT_DIR, pass, fail } = context;
141
+ console.log('\nChecking review checklist consolidation...');
142
+
143
+ const reviewChecklistDirectoryPath = join(AGENT_CONTEXT_DIR, 'review-checklists');
144
+ const checklistEntries = await readdir(reviewChecklistDirectoryPath, { withFileTypes: true });
145
+ const checklistFileNames = checklistEntries
146
+ .filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
147
+ .map((entry) => entry.name)
148
+ .sort((leftName, rightName) => leftName.localeCompare(rightName));
149
+
150
+ const expectedChecklistFileNames = ['architecture-review.md', 'pr-checklist.md'];
151
+
152
+ if (checklistFileNames.length <= 2) {
153
+ pass(`Checklist count is consolidated (${checklistFileNames.length}/2)`);
154
+ } else {
155
+ fail(`Checklist count exceeds limit (${checklistFileNames.length}/2): ${checklistFileNames.join(', ')}`);
156
+ }
157
+
158
+ for (const expectedChecklistFileName of expectedChecklistFileNames) {
159
+ if (checklistFileNames.includes(expectedChecklistFileName)) {
160
+ pass(`Checklist exists: .agent-context/review-checklists/${expectedChecklistFileName}`);
161
+ } else {
162
+ fail(`Missing consolidated checklist: .agent-context/review-checklists/${expectedChecklistFileName}`);
163
+ }
164
+ }
165
+ }
@@ -0,0 +1,109 @@
1
+ import { dirname, join, relative, resolve } from 'node:path';
2
+
3
+ export async function validateMarkdownFiles(context) {
4
+ const { ROOT_DIR, collectFiles, readTextFile, pass, fail } = context;
5
+ console.log('\nChecking markdown content...');
6
+
7
+ const markdownFilePaths = await collectFiles(ROOT_DIR, (fileName) => fileName.endsWith('.md'));
8
+
9
+ for (const markdownFilePath of markdownFilePaths) {
10
+ const markdownContent = await readTextFile(markdownFilePath);
11
+ const relativeMarkdownPath = relative(ROOT_DIR, markdownFilePath);
12
+
13
+ if (markdownContent.trim().length === 0) {
14
+ fail(`Empty markdown file: ${relativeMarkdownPath}`);
15
+ continue;
16
+ }
17
+
18
+ pass(`${relativeMarkdownPath} (${markdownContent.length} chars)`);
19
+ }
20
+ }
21
+
22
+ export async function validateCrossReferences(context) {
23
+ const { ROOT_DIR, collectFiles, readTextFile, fileExists, pass, fail, warn } = context;
24
+ console.log('\nChecking internal links...');
25
+
26
+ const markdownFilePaths = await collectFiles(ROOT_DIR, (fileName) => fileName.endsWith('.md'));
27
+ const linkPattern = /\[([^\]]*)\]\((?!https?:\/\/|#)([^)]+)\)/g;
28
+ let checkedLinkCount = 0;
29
+
30
+ for (const markdownFilePath of markdownFilePaths) {
31
+ const markdownContent = await readTextFile(markdownFilePath);
32
+ const currentFileDirectory = dirname(markdownFilePath);
33
+ const relativeMarkdownPath = relative(ROOT_DIR, markdownFilePath);
34
+ let linkMatch = linkPattern.exec(markdownContent);
35
+
36
+ while (linkMatch) {
37
+ const rawLinkTarget = linkMatch[2].split('#')[0];
38
+ if (rawLinkTarget) {
39
+ checkedLinkCount += 1;
40
+ const resolvedLinkPath = resolve(currentFileDirectory, rawLinkTarget);
41
+
42
+ if (await fileExists(resolvedLinkPath)) {
43
+ pass(`${relativeMarkdownPath} → ${linkMatch[2]}`);
44
+ } else {
45
+ fail(`Broken link in ${relativeMarkdownPath}: ${linkMatch[2]}`);
46
+ }
47
+ }
48
+
49
+ linkMatch = linkPattern.exec(markdownContent);
50
+ }
51
+ }
52
+
53
+ if (checkedLinkCount === 0) {
54
+ warn('No internal links were found in markdown files');
55
+ }
56
+ }
57
+
58
+ export async function validateAgentsManifest(context) {
59
+ const { ROOT_DIR, readTextFile, fileExists, pass, fail, warn } = context;
60
+ console.log('\nChecking AGENTS.md manifest links...');
61
+
62
+ const agentsContent = await readTextFile(join(ROOT_DIR, 'AGENTS.md'));
63
+ const fileReferencePattern = /\[`?([^`\]]+)`?\]\(([^)]+)\)/g;
64
+ let manifestLinkCount = 0;
65
+ let fileReferenceMatch = fileReferencePattern.exec(agentsContent);
66
+
67
+ while (fileReferenceMatch) {
68
+ const manifestLinkTarget = fileReferenceMatch[2];
69
+
70
+ if (!manifestLinkTarget.startsWith('http')) {
71
+ manifestLinkCount += 1;
72
+ const resolvedManifestLinkPath = resolve(ROOT_DIR, manifestLinkTarget);
73
+
74
+ if (await fileExists(resolvedManifestLinkPath)) {
75
+ pass(`AGENTS.md → ${manifestLinkTarget}`);
76
+ } else {
77
+ fail(`AGENTS.md references missing file: ${manifestLinkTarget}`);
78
+ }
79
+ }
80
+
81
+ fileReferenceMatch = fileReferencePattern.exec(agentsContent);
82
+ }
83
+
84
+ if (manifestLinkCount === 0) {
85
+ warn('AGENTS.md does not contain any local manifest links');
86
+ }
87
+ }
88
+
89
+ export async function validateDocumentationFlow(context) {
90
+ const { README_PATH, readTextFile, pass, fail } = context;
91
+ console.log('\nChecking documentation flow...');
92
+
93
+ const readmeContent = await readTextFile(README_PATH);
94
+ const requiredReadmeSnippets = [
95
+ 'npx @ryuenn3123/agentic-senior-core init',
96
+ 'npm run validate',
97
+ 'docs/faq.md',
98
+ 'docs/deep-dive.md',
99
+ 'docs/archive/HISTORY.md',
100
+ ];
101
+
102
+ for (const requiredReadmeSnippet of requiredReadmeSnippets) {
103
+ if (readmeContent.includes(requiredReadmeSnippet)) {
104
+ pass(`README.md mentions ${requiredReadmeSnippet}`);
105
+ } else {
106
+ fail(`README.md must mention ${requiredReadmeSnippet}`);
107
+ }
108
+ }
109
+ }