@ktpartners/dgs-platform 2.6.2

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 (256) hide show
  1. package/LICENSE +38 -0
  2. package/README.md +851 -0
  3. package/agents/dgs-codebase-cross-analyzer.md +183 -0
  4. package/agents/dgs-codebase-mapper.md +782 -0
  5. package/agents/dgs-codebase-synthesizer.md +156 -0
  6. package/agents/dgs-debugger.md +1256 -0
  7. package/agents/dgs-executor.md +550 -0
  8. package/agents/dgs-integration-checker.md +481 -0
  9. package/agents/dgs-nyquist-auditor.md +178 -0
  10. package/agents/dgs-phase-researcher.md +563 -0
  11. package/agents/dgs-phase-verifier.md +450 -0
  12. package/agents/dgs-plan-checker.md +708 -0
  13. package/agents/dgs-planner.md +1324 -0
  14. package/agents/dgs-project-researcher.md +631 -0
  15. package/agents/dgs-research-synthesizer.md +249 -0
  16. package/agents/dgs-roadmapper.md +652 -0
  17. package/agents/dgs-verifier.md +607 -0
  18. package/bin/install.js +2073 -0
  19. package/commands/dgs/add-doc.md +45 -0
  20. package/commands/dgs/add-idea.md +38 -0
  21. package/commands/dgs/add-phase.md +43 -0
  22. package/commands/dgs/add-repo.md +54 -0
  23. package/commands/dgs/add-tests.md +41 -0
  24. package/commands/dgs/add-todo.md +47 -0
  25. package/commands/dgs/approve-spec.md +38 -0
  26. package/commands/dgs/audit-milestone.md +36 -0
  27. package/commands/dgs/audit-phase.md +37 -0
  28. package/commands/dgs/cancel-job.md +23 -0
  29. package/commands/dgs/capture-principle.md +143 -0
  30. package/commands/dgs/check-todos.md +45 -0
  31. package/commands/dgs/cleanup.md +18 -0
  32. package/commands/dgs/complete-milestone.md +136 -0
  33. package/commands/dgs/complete-project.md +70 -0
  34. package/commands/dgs/consolidate-ideas.md +50 -0
  35. package/commands/dgs/create-milestone-job.md +37 -0
  36. package/commands/dgs/debug.md +164 -0
  37. package/commands/dgs/develop-idea.md +53 -0
  38. package/commands/dgs/discuss-idea.md +41 -0
  39. package/commands/dgs/discuss-phase.md +83 -0
  40. package/commands/dgs/execute-phase.md +41 -0
  41. package/commands/dgs/fast.md +38 -0
  42. package/commands/dgs/find-related-ideas.md +43 -0
  43. package/commands/dgs/health.md +28 -0
  44. package/commands/dgs/help.md +22 -0
  45. package/commands/dgs/import-spec.md +36 -0
  46. package/commands/dgs/init-product.md +28 -0
  47. package/commands/dgs/insert-phase.md +32 -0
  48. package/commands/dgs/join-discord.md +18 -0
  49. package/commands/dgs/list-docs.md +40 -0
  50. package/commands/dgs/list-ideas.md +42 -0
  51. package/commands/dgs/list-jobs.md +22 -0
  52. package/commands/dgs/list-phase-assumptions.md +46 -0
  53. package/commands/dgs/list-projects.md +57 -0
  54. package/commands/dgs/list-specs.md +40 -0
  55. package/commands/dgs/map-codebase.md +92 -0
  56. package/commands/dgs/new-milestone.md +44 -0
  57. package/commands/dgs/new-project.md +42 -0
  58. package/commands/dgs/node-repair.md +26 -0
  59. package/commands/dgs/overlap-check.md +20 -0
  60. package/commands/dgs/pause-work.md +38 -0
  61. package/commands/dgs/plan-milestone-gaps.md +34 -0
  62. package/commands/dgs/plan-phase.md +44 -0
  63. package/commands/dgs/progress.md +24 -0
  64. package/commands/dgs/quick.md +41 -0
  65. package/commands/dgs/reactivate-project.md +70 -0
  66. package/commands/dgs/reapply-patches.md +110 -0
  67. package/commands/dgs/refine-spec.md +38 -0
  68. package/commands/dgs/reject-idea.md +43 -0
  69. package/commands/dgs/remove-doc.md +44 -0
  70. package/commands/dgs/remove-phase.md +31 -0
  71. package/commands/dgs/remove-repo.md +69 -0
  72. package/commands/dgs/research-idea.md +43 -0
  73. package/commands/dgs/research-phase.md +189 -0
  74. package/commands/dgs/restore-idea.md +45 -0
  75. package/commands/dgs/resume-work.md +40 -0
  76. package/commands/dgs/rollback-job.md +24 -0
  77. package/commands/dgs/run-job.md +35 -0
  78. package/commands/dgs/search.md +40 -0
  79. package/commands/dgs/set-profile.md +34 -0
  80. package/commands/dgs/settings.md +38 -0
  81. package/commands/dgs/switch-project.md +58 -0
  82. package/commands/dgs/undo-consolidation.md +42 -0
  83. package/commands/dgs/update-idea.md +44 -0
  84. package/commands/dgs/update.md +37 -0
  85. package/commands/dgs/validate-phase.md +35 -0
  86. package/commands/dgs/verify-work.md +39 -0
  87. package/commands/dgs/write-spec.md +49 -0
  88. package/deliver-great-systems/.planning/phases/09-backend-wiring-and-error-handling/09-01-SUMMARY.md +84 -0
  89. package/deliver-great-systems/.planning/phases/09-backend-wiring-and-error-handling/09-02-SUMMARY.md +86 -0
  90. package/deliver-great-systems/.planning/phases/10-v1-to-v2-migration-flow/10-01-SUMMARY.md +85 -0
  91. package/deliver-great-systems/bin/dgs-tools.cjs +1444 -0
  92. package/deliver-great-systems/bin/lib/auto-test.cjs +1365 -0
  93. package/deliver-great-systems/bin/lib/commands.cjs +570 -0
  94. package/deliver-great-systems/bin/lib/config.cjs +417 -0
  95. package/deliver-great-systems/bin/lib/conflict-agent.cjs +1063 -0
  96. package/deliver-great-systems/bin/lib/conflict-agent.test.cjs +554 -0
  97. package/deliver-great-systems/bin/lib/context.cjs +929 -0
  98. package/deliver-great-systems/bin/lib/context.test.cjs +693 -0
  99. package/deliver-great-systems/bin/lib/core.cjs +744 -0
  100. package/deliver-great-systems/bin/lib/core.test.cjs +822 -0
  101. package/deliver-great-systems/bin/lib/docs.cjs +919 -0
  102. package/deliver-great-systems/bin/lib/docs.test.cjs +211 -0
  103. package/deliver-great-systems/bin/lib/execution.cjs +705 -0
  104. package/deliver-great-systems/bin/lib/execution.test.cjs +1472 -0
  105. package/deliver-great-systems/bin/lib/frontmatter.cjs +324 -0
  106. package/deliver-great-systems/bin/lib/ideas.cjs +1406 -0
  107. package/deliver-great-systems/bin/lib/ideas.test.cjs +1417 -0
  108. package/deliver-great-systems/bin/lib/identity.cjs +125 -0
  109. package/deliver-great-systems/bin/lib/init.cjs +1114 -0
  110. package/deliver-great-systems/bin/lib/init.test.cjs +1271 -0
  111. package/deliver-great-systems/bin/lib/jobs.cjs +2015 -0
  112. package/deliver-great-systems/bin/lib/jobs.test.cjs +2619 -0
  113. package/deliver-great-systems/bin/lib/merge-conflicts.cjs +654 -0
  114. package/deliver-great-systems/bin/lib/merge-conflicts.test.cjs +370 -0
  115. package/deliver-great-systems/bin/lib/migration.cjs +352 -0
  116. package/deliver-great-systems/bin/lib/migration.test.cjs +582 -0
  117. package/deliver-great-systems/bin/lib/milestone.cjs +243 -0
  118. package/deliver-great-systems/bin/lib/overlap.cjs +437 -0
  119. package/deliver-great-systems/bin/lib/overlap.test.cjs +747 -0
  120. package/deliver-great-systems/bin/lib/path-audit.test.cjs +384 -0
  121. package/deliver-great-systems/bin/lib/paths.cjs +144 -0
  122. package/deliver-great-systems/bin/lib/paths.test.cjs +486 -0
  123. package/deliver-great-systems/bin/lib/phase.cjs +910 -0
  124. package/deliver-great-systems/bin/lib/projects.cjs +691 -0
  125. package/deliver-great-systems/bin/lib/projects.test.cjs +871 -0
  126. package/deliver-great-systems/bin/lib/repos.cjs +1432 -0
  127. package/deliver-great-systems/bin/lib/repos.test.cjs +1882 -0
  128. package/deliver-great-systems/bin/lib/roadmap.cjs +305 -0
  129. package/deliver-great-systems/bin/lib/search.cjs +570 -0
  130. package/deliver-great-systems/bin/lib/specs.cjs +1303 -0
  131. package/deliver-great-systems/bin/lib/state.cjs +893 -0
  132. package/deliver-great-systems/bin/lib/template.cjs +228 -0
  133. package/deliver-great-systems/bin/lib/test-helpers.cjs +291 -0
  134. package/deliver-great-systems/bin/lib/verify.cjs +796 -0
  135. package/deliver-great-systems/references/checkpoints.md +776 -0
  136. package/deliver-great-systems/references/conflict-resolution.md +66 -0
  137. package/deliver-great-systems/references/context-tiers.md +166 -0
  138. package/deliver-great-systems/references/continuation-format.md +249 -0
  139. package/deliver-great-systems/references/decimal-phase-calculation.md +67 -0
  140. package/deliver-great-systems/references/git-integration.md +250 -0
  141. package/deliver-great-systems/references/git-planning-commit.md +40 -0
  142. package/deliver-great-systems/references/model-profile-resolution.md +36 -0
  143. package/deliver-great-systems/references/model-profiles.md +95 -0
  144. package/deliver-great-systems/references/phase-argument-parsing.md +61 -0
  145. package/deliver-great-systems/references/planning-config.md +224 -0
  146. package/deliver-great-systems/references/questioning.md +162 -0
  147. package/deliver-great-systems/references/spec-review-loop.md +177 -0
  148. package/deliver-great-systems/references/tdd.md +265 -0
  149. package/deliver-great-systems/references/ui-brand.md +160 -0
  150. package/deliver-great-systems/references/verification-patterns.md +612 -0
  151. package/deliver-great-systems/templates/DEBUG.md +166 -0
  152. package/deliver-great-systems/templates/UAT.md +251 -0
  153. package/deliver-great-systems/templates/VALIDATION.md +95 -0
  154. package/deliver-great-systems/templates/claude-md.md +74 -0
  155. package/deliver-great-systems/templates/codebase/architecture.md +257 -0
  156. package/deliver-great-systems/templates/codebase/concerns.md +312 -0
  157. package/deliver-great-systems/templates/codebase/conventions.md +309 -0
  158. package/deliver-great-systems/templates/codebase/integrations.md +282 -0
  159. package/deliver-great-systems/templates/codebase/stack.md +188 -0
  160. package/deliver-great-systems/templates/codebase/structure.md +287 -0
  161. package/deliver-great-systems/templates/codebase/testing.md +482 -0
  162. package/deliver-great-systems/templates/config.json +38 -0
  163. package/deliver-great-systems/templates/context.md +354 -0
  164. package/deliver-great-systems/templates/continue-here.md +80 -0
  165. package/deliver-great-systems/templates/debug-subagent-prompt.md +93 -0
  166. package/deliver-great-systems/templates/discovery.md +148 -0
  167. package/deliver-great-systems/templates/milestone-archive.md +125 -0
  168. package/deliver-great-systems/templates/milestone.md +117 -0
  169. package/deliver-great-systems/templates/phase-prompt.md +615 -0
  170. package/deliver-great-systems/templates/planner-subagent-prompt.md +119 -0
  171. package/deliver-great-systems/templates/project.md +186 -0
  172. package/deliver-great-systems/templates/requirements.md +233 -0
  173. package/deliver-great-systems/templates/research-project/ARCHITECTURE.md +206 -0
  174. package/deliver-great-systems/templates/research-project/FEATURES.md +149 -0
  175. package/deliver-great-systems/templates/research-project/PITFALLS.md +202 -0
  176. package/deliver-great-systems/templates/research-project/STACK.md +122 -0
  177. package/deliver-great-systems/templates/research-project/SUMMARY.md +172 -0
  178. package/deliver-great-systems/templates/research.md +554 -0
  179. package/deliver-great-systems/templates/retrospective.md +54 -0
  180. package/deliver-great-systems/templates/roadmap.md +204 -0
  181. package/deliver-great-systems/templates/state.md +178 -0
  182. package/deliver-great-systems/templates/summary-complex.md +59 -0
  183. package/deliver-great-systems/templates/summary-minimal.md +41 -0
  184. package/deliver-great-systems/templates/summary-standard.md +48 -0
  185. package/deliver-great-systems/templates/summary.md +253 -0
  186. package/deliver-great-systems/templates/user-setup.md +313 -0
  187. package/deliver-great-systems/templates/verification-report.md +324 -0
  188. package/deliver-great-systems/workflows/add-doc.md +151 -0
  189. package/deliver-great-systems/workflows/add-idea.md +96 -0
  190. package/deliver-great-systems/workflows/add-phase.md +120 -0
  191. package/deliver-great-systems/workflows/add-tests.md +359 -0
  192. package/deliver-great-systems/workflows/add-todo.md +162 -0
  193. package/deliver-great-systems/workflows/approve-spec.md +194 -0
  194. package/deliver-great-systems/workflows/audit-milestone.md +364 -0
  195. package/deliver-great-systems/workflows/audit-phase.md +462 -0
  196. package/deliver-great-systems/workflows/cancel-job.md +108 -0
  197. package/deliver-great-systems/workflows/check-todos.md +181 -0
  198. package/deliver-great-systems/workflows/cleanup.md +247 -0
  199. package/deliver-great-systems/workflows/codereview.md +526 -0
  200. package/deliver-great-systems/workflows/complete-milestone.md +1298 -0
  201. package/deliver-great-systems/workflows/consolidate-ideas.md +365 -0
  202. package/deliver-great-systems/workflows/create-milestone-job.md +177 -0
  203. package/deliver-great-systems/workflows/develop-idea.md +544 -0
  204. package/deliver-great-systems/workflows/diagnose-issues.md +231 -0
  205. package/deliver-great-systems/workflows/discovery-phase.md +301 -0
  206. package/deliver-great-systems/workflows/discuss-idea.md +263 -0
  207. package/deliver-great-systems/workflows/discuss-phase.md +733 -0
  208. package/deliver-great-systems/workflows/execute-phase.md +571 -0
  209. package/deliver-great-systems/workflows/execute-plan.md +592 -0
  210. package/deliver-great-systems/workflows/find-related-ideas.md +271 -0
  211. package/deliver-great-systems/workflows/health.md +173 -0
  212. package/deliver-great-systems/workflows/help.md +997 -0
  213. package/deliver-great-systems/workflows/import-spec.md +381 -0
  214. package/deliver-great-systems/workflows/init-product.md +767 -0
  215. package/deliver-great-systems/workflows/insert-phase.md +138 -0
  216. package/deliver-great-systems/workflows/list-docs.md +119 -0
  217. package/deliver-great-systems/workflows/list-ideas.md +154 -0
  218. package/deliver-great-systems/workflows/list-jobs.md +89 -0
  219. package/deliver-great-systems/workflows/list-phase-assumptions.md +192 -0
  220. package/deliver-great-systems/workflows/list-specs.md +101 -0
  221. package/deliver-great-systems/workflows/map-codebase.md +621 -0
  222. package/deliver-great-systems/workflows/new-milestone.md +591 -0
  223. package/deliver-great-systems/workflows/new-project.md +1113 -0
  224. package/deliver-great-systems/workflows/node-repair.md +94 -0
  225. package/deliver-great-systems/workflows/overlap-check.md +86 -0
  226. package/deliver-great-systems/workflows/pause-work.md +134 -0
  227. package/deliver-great-systems/workflows/plan-milestone-gaps.md +306 -0
  228. package/deliver-great-systems/workflows/plan-phase.md +698 -0
  229. package/deliver-great-systems/workflows/progress.md +386 -0
  230. package/deliver-great-systems/workflows/quick.md +845 -0
  231. package/deliver-great-systems/workflows/refine-spec.md +275 -0
  232. package/deliver-great-systems/workflows/reject-idea.md +109 -0
  233. package/deliver-great-systems/workflows/remove-doc.md +117 -0
  234. package/deliver-great-systems/workflows/remove-phase.md +163 -0
  235. package/deliver-great-systems/workflows/research-idea.md +325 -0
  236. package/deliver-great-systems/workflows/research-phase.md +81 -0
  237. package/deliver-great-systems/workflows/restore-idea.md +101 -0
  238. package/deliver-great-systems/workflows/resume-project.md +311 -0
  239. package/deliver-great-systems/workflows/rollback-job.md +130 -0
  240. package/deliver-great-systems/workflows/run-job.md +498 -0
  241. package/deliver-great-systems/workflows/search.md +130 -0
  242. package/deliver-great-systems/workflows/set-profile.md +83 -0
  243. package/deliver-great-systems/workflows/settings.md +470 -0
  244. package/deliver-great-systems/workflows/transition.md +563 -0
  245. package/deliver-great-systems/workflows/undo-consolidation.md +155 -0
  246. package/deliver-great-systems/workflows/update-idea.md +157 -0
  247. package/deliver-great-systems/workflows/update.md +242 -0
  248. package/deliver-great-systems/workflows/validate-phase.md +177 -0
  249. package/deliver-great-systems/workflows/verify-phase.md +253 -0
  250. package/deliver-great-systems/workflows/verify-work.md +671 -0
  251. package/deliver-great-systems/workflows/write-spec.md +450 -0
  252. package/hooks/dist/dgs-check-update.js +62 -0
  253. package/hooks/dist/dgs-context-monitor.js +141 -0
  254. package/hooks/dist/dgs-statusline.js +115 -0
  255. package/package.json +60 -0
  256. package/scripts/build-hooks.js +43 -0
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Tests for docs.cjs — BUG-008 fixes
3
+ *
4
+ * Covers resolveDocsDir product path resolution and isDirectory guards
5
+ * in scanDocsDir, updateIndexWithNames, and updateIndex.
6
+ *
7
+ * Uses Node.js built-in test runner (node:test) and assert (node:assert).
8
+ */
9
+
10
+ const { describe, it, beforeEach, afterEach } = require('node:test');
11
+ const assert = require('node:assert/strict');
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+ const os = require('os');
15
+
16
+ const {
17
+ resolveDocsDir,
18
+ scanDocsDir,
19
+ updateIndexWithNames,
20
+ updateIndex,
21
+ } = require('./docs.cjs');
22
+
23
+ // ─── resolveDocsDir Tests ────────────────────────────────────────────────────
24
+
25
+ describe('docs', () => {
26
+
27
+ describe('resolveDocsDir', () => {
28
+ let tmpDir;
29
+
30
+ beforeEach(() => {
31
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dgs-resolve-docs-'));
32
+ });
33
+
34
+ afterEach(() => {
35
+ fs.rmSync(tmpDir, { recursive: true, force: true });
36
+ });
37
+
38
+ it('product scope returns .planning/docs/product', () => {
39
+ const result = resolveDocsDir(tmpDir, 'product');
40
+ assert.equal(result, path.join(tmpDir, '.planning', 'docs', 'product'));
41
+ });
42
+
43
+ it('product scope path ends with /docs/product', () => {
44
+ const result = resolveDocsDir(tmpDir, 'product');
45
+ assert.ok(result.endsWith(path.join('docs', 'product')),
46
+ `Expected path ending with docs/product, got: ${result}`);
47
+ });
48
+
49
+ it('idea scope returns docs path for idea found in pending', () => {
50
+ // Create the fixture directory that resolveDocsDir searches for
51
+ fs.mkdirSync(path.join(tmpDir, '.planning', 'ideas', 'pending', 'my-idea'), { recursive: true });
52
+ const result = resolveDocsDir(tmpDir, 'idea', 'my-idea');
53
+ assert.ok(result.includes(path.join('ideas', 'pending', 'my-idea', 'docs')),
54
+ `Expected ideas/pending/my-idea/docs in path, got: ${result}`);
55
+ });
56
+
57
+ it('spec scope returns correct path', () => {
58
+ const result = resolveDocsDir(tmpDir, 'spec', 'my-spec');
59
+ assert.ok(result.includes(path.join('specs', 'my-spec', 'docs')),
60
+ `Expected specs/my-spec/docs in path, got: ${result}`);
61
+ });
62
+ });
63
+
64
+ // ─── scanDocsDir directory resilience ──────────────────────────────────────
65
+
66
+ describe('scanDocsDir', () => {
67
+ let tmpDir;
68
+
69
+ beforeEach(() => {
70
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dgs-docs-test-'));
71
+ });
72
+
73
+ afterEach(() => {
74
+ fs.rmSync(tmpDir, { recursive: true, force: true });
75
+ });
76
+
77
+ it('returns metadata for regular files only, skipping subdirectories', () => {
78
+ // Create a regular file
79
+ fs.writeFileSync(path.join(tmpDir, 'test-doc.txt'), 'hello world');
80
+ // Create a subdirectory (would cause EISDIR without the guard)
81
+ fs.mkdirSync(path.join(tmpDir, 'subdir'));
82
+
83
+ const results = scanDocsDir(tmpDir);
84
+
85
+ // Should return exactly 1 entry (the file)
86
+ assert.equal(results.length, 1);
87
+ assert.equal(results[0].slug, 'test-doc.txt');
88
+ });
89
+
90
+ it('does not crash when only subdirectories exist', () => {
91
+ fs.mkdirSync(path.join(tmpDir, 'subdir-a'));
92
+ fs.mkdirSync(path.join(tmpDir, 'subdir-b'));
93
+
94
+ const results = scanDocsDir(tmpDir);
95
+ assert.equal(results.length, 0);
96
+ });
97
+
98
+ it('returns empty array for non-existent directory', () => {
99
+ const results = scanDocsDir(path.join(tmpDir, 'nonexistent'));
100
+ assert.equal(results.length, 0);
101
+ });
102
+ });
103
+
104
+ // ─── updateIndexWithNames directory resilience ─────────────────────────────
105
+
106
+ describe('updateIndexWithNames', () => {
107
+ let tmpDir;
108
+
109
+ beforeEach(() => {
110
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dgs-docs-idx-'));
111
+ });
112
+
113
+ afterEach(() => {
114
+ fs.rmSync(tmpDir, { recursive: true, force: true });
115
+ });
116
+
117
+ it('completes without EISDIR error when subdirectory exists', () => {
118
+ // Create a regular file
119
+ fs.writeFileSync(path.join(tmpDir, 'report.pdf'), 'fake pdf content');
120
+ // Create a subdirectory
121
+ fs.mkdirSync(path.join(tmpDir, 'nested-dir'));
122
+
123
+ // Should not throw
124
+ assert.doesNotThrow(() => {
125
+ updateIndexWithNames(tmpDir);
126
+ });
127
+
128
+ // INDEX.md should be created
129
+ const indexPath = path.join(tmpDir, 'INDEX.md');
130
+ assert.ok(fs.existsSync(indexPath), 'INDEX.md should exist');
131
+
132
+ // INDEX.md should contain only the file, not the subdirectory
133
+ const content = fs.readFileSync(indexPath, 'utf-8');
134
+ assert.ok(content.includes('report.pdf'), 'INDEX.md should list report.pdf');
135
+ assert.ok(!content.includes('nested-dir'), 'INDEX.md should not list nested-dir');
136
+ });
137
+
138
+ it('does not include subdirectories in INDEX.md when only subdirs remain', () => {
139
+ // Create a file + subdir, generate INDEX, then remove the file
140
+ fs.writeFileSync(path.join(tmpDir, 'temp.txt'), 'temp');
141
+ fs.mkdirSync(path.join(tmpDir, 'subdir'));
142
+ updateIndexWithNames(tmpDir);
143
+ // Remove the file — only subdir remains
144
+ fs.unlinkSync(path.join(tmpDir, 'temp.txt'));
145
+ updateIndexWithNames(tmpDir);
146
+
147
+ // INDEX.md may still exist (subdir passes filename filter) but must not
148
+ // contain the subdir name in any data row
149
+ const indexPath = path.join(tmpDir, 'INDEX.md');
150
+ if (fs.existsSync(indexPath)) {
151
+ const content = fs.readFileSync(indexPath, 'utf-8');
152
+ assert.ok(!content.includes('subdir'), 'INDEX.md should not list subdirectory');
153
+ }
154
+ // If INDEX.md was removed, that is also acceptable
155
+ });
156
+ });
157
+
158
+ // ─── updateIndex directory resilience ──────────────────────────────────────
159
+
160
+ describe('updateIndex', () => {
161
+ let tmpDir;
162
+
163
+ beforeEach(() => {
164
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dgs-docs-upd-'));
165
+ });
166
+
167
+ afterEach(() => {
168
+ fs.rmSync(tmpDir, { recursive: true, force: true });
169
+ });
170
+
171
+ it('completes without EISDIR error when subdirectory exists', () => {
172
+ // Create a regular file
173
+ fs.writeFileSync(path.join(tmpDir, 'design.png'), 'fake image');
174
+ // Create a subdirectory
175
+ fs.mkdirSync(path.join(tmpDir, 'another-dir'));
176
+
177
+ // Should not throw
178
+ assert.doesNotThrow(() => {
179
+ updateIndex(tmpDir);
180
+ });
181
+
182
+ // INDEX.md should be created
183
+ const indexPath = path.join(tmpDir, 'INDEX.md');
184
+ assert.ok(fs.existsSync(indexPath), 'INDEX.md should exist');
185
+
186
+ // INDEX.md should contain only the file
187
+ const content = fs.readFileSync(indexPath, 'utf-8');
188
+ assert.ok(content.includes('design.png'), 'INDEX.md should list design.png');
189
+ assert.ok(!content.includes('another-dir'), 'INDEX.md should not list another-dir');
190
+ });
191
+
192
+ it('handles mixed files and directories correctly', () => {
193
+ fs.writeFileSync(path.join(tmpDir, 'alpha.txt'), 'a');
194
+ fs.writeFileSync(path.join(tmpDir, 'beta.csv'), 'b');
195
+ fs.mkdirSync(path.join(tmpDir, 'gamma-dir'));
196
+ fs.mkdirSync(path.join(tmpDir, 'delta-dir'));
197
+
198
+ updateIndex(tmpDir);
199
+
200
+ const indexPath = path.join(tmpDir, 'INDEX.md');
201
+ const content = fs.readFileSync(indexPath, 'utf-8');
202
+
203
+ // Should list both files
204
+ assert.ok(content.includes('alpha.txt'), 'Should list alpha.txt');
205
+ assert.ok(content.includes('beta.csv'), 'Should list beta.csv');
206
+ // Should not list directories
207
+ assert.ok(!content.includes('gamma-dir'), 'Should not list gamma-dir');
208
+ assert.ok(!content.includes('delta-dir'), 'Should not list delta-dir');
209
+ });
210
+ });
211
+ });