docspec 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 (42) hide show
  1. package/README.md +121 -0
  2. package/dist/__tests__/cli.test.d.ts +2 -0
  3. package/dist/__tests__/cli.test.d.ts.map +1 -0
  4. package/dist/__tests__/cli.test.js +257 -0
  5. package/dist/__tests__/cli.test.js.map +1 -0
  6. package/dist/__tests__/constants.test.d.ts +2 -0
  7. package/dist/__tests__/constants.test.d.ts.map +1 -0
  8. package/dist/__tests__/constants.test.js +67 -0
  9. package/dist/__tests__/constants.test.js.map +1 -0
  10. package/dist/__tests__/generator.test.d.ts +2 -0
  11. package/dist/__tests__/generator.test.d.ts.map +1 -0
  12. package/dist/__tests__/generator.test.js +118 -0
  13. package/dist/__tests__/generator.test.js.map +1 -0
  14. package/dist/__tests__/validator.test.d.ts +2 -0
  15. package/dist/__tests__/validator.test.d.ts.map +1 -0
  16. package/dist/__tests__/validator.test.js +375 -0
  17. package/dist/__tests__/validator.test.js.map +1 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +134 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/constants.d.ts +13 -0
  23. package/dist/constants.d.ts.map +1 -0
  24. package/dist/constants.js +55 -0
  25. package/dist/constants.js.map +1 -0
  26. package/dist/generator.d.ts +12 -0
  27. package/dist/generator.d.ts.map +1 -0
  28. package/dist/generator.js +77 -0
  29. package/dist/generator.js.map +1 -0
  30. package/dist/index.d.ts +8 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +15 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/types.d.ts +16 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +3 -0
  37. package/dist/types.js.map +1 -0
  38. package/dist/validator.d.ts +7 -0
  39. package/dist/validator.d.ts.map +1 -0
  40. package/dist/validator.js +173 -0
  41. package/dist/validator.js.map +1 -0
  42. package/package.json +38 -0
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs/promises"));
37
+ const path = __importStar(require("path"));
38
+ const os = __importStar(require("os"));
39
+ const validator_1 = require("../validator");
40
+ const generator_1 = require("../generator");
41
+ const constants_1 = require("../constants");
42
+ describe("validator", () => {
43
+ let tempDir;
44
+ beforeEach(async () => {
45
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "docspec-test-"));
46
+ });
47
+ afterEach(async () => {
48
+ await fs.rm(tempDir, { recursive: true, force: true });
49
+ });
50
+ describe("validateDocspec", () => {
51
+ it("should validate a properly customized docspec file", async () => {
52
+ const filePath = path.join(tempDir, "valid.docspec.md");
53
+ // Create a valid docspec with customized content
54
+ const validContent = `---
55
+
56
+ # DOCSPEC: Test Document
57
+
58
+ > Short phrase: *Test document*
59
+
60
+ ---
61
+
62
+ ## 1. Purpose of This Document
63
+
64
+ This document describes the test suite for the docspec validator. It provides comprehensive test coverage for all validation scenarios and edge cases that the validator needs to handle correctly.
65
+
66
+ ## 2. When This Document Should Be Updated
67
+
68
+ Update this document when adding new test cases or when the validation logic changes. It should always reflect the current state of the test suite.
69
+
70
+ ## 3. Structure & Required Sections
71
+
72
+ This section describes the test structure and how tests are organized. Each test file covers a specific module or functionality area of the docspec package.
73
+
74
+ ## 4. Style & Editing Guidelines
75
+
76
+ Keep test descriptions clear and concise. Use descriptive test names that explain what is being tested. Follow the AAA pattern: Arrange, Act, Assert. Do: Write comprehensive tests that cover edge cases. Don't: Skip edge cases or write tests that are too simple. Always test both success and failure scenarios.
77
+
78
+ ## 5. Known Gaps or Intentional Omissions
79
+
80
+ No gaps at this time. All major functionality is covered by the test suite.
81
+ `;
82
+ await fs.writeFile(filePath, validContent, "utf-8");
83
+ const result = await (0, validator_1.validateDocspec)(filePath);
84
+ expect(result.valid).toBe(true);
85
+ expect(result.errors).toHaveLength(0);
86
+ });
87
+ it("should reject a file with only boilerplate content", async () => {
88
+ const filePath = path.join(tempDir, "boilerplate.docspec.md");
89
+ await (0, generator_1.generateDocspec)(filePath, "Test");
90
+ const result = await (0, validator_1.validateDocspec)(filePath);
91
+ expect(result.valid).toBe(false);
92
+ expect(result.errors.length).toBeGreaterThan(0);
93
+ expect(result.errors.some(e => e.includes("boilerplate"))).toBe(true);
94
+ });
95
+ it("should detect missing sections", async () => {
96
+ const filePath = path.join(tempDir, "incomplete.docspec.md");
97
+ const incompleteContent = `---
98
+
99
+ # DOCSPEC: Test
100
+
101
+ ---
102
+
103
+ ## 1. Purpose of This Document
104
+
105
+ Custom content here.
106
+
107
+ ## 2. When This Document Should Be Updated
108
+
109
+ More custom content.
110
+ `;
111
+ await fs.writeFile(filePath, incompleteContent, "utf-8");
112
+ const result = await (0, validator_1.validateDocspec)(filePath);
113
+ expect(result.valid).toBe(false);
114
+ // Should have errors for missing sections
115
+ expect(result.errors.some(e => e.includes("Missing required section"))).toBe(true);
116
+ });
117
+ it("should detect empty sections", async () => {
118
+ const filePath = path.join(tempDir, "empty-section.docspec.md");
119
+ let content = `---
120
+
121
+ # DOCSPEC: Test
122
+
123
+ ---
124
+
125
+ `;
126
+ // Add all sections but leave one empty
127
+ constants_1.REQUIRED_SECTIONS.forEach((section, index) => {
128
+ content += `## ${index + 1}. ${section}\n\n`;
129
+ if (index === 2) {
130
+ // Leave section 3 empty
131
+ content += "\n";
132
+ }
133
+ else {
134
+ content += "Custom content for this section.\n";
135
+ }
136
+ content += "\n---\n\n";
137
+ });
138
+ await fs.writeFile(filePath, content, "utf-8");
139
+ const result = await (0, validator_1.validateDocspec)(filePath);
140
+ expect(result.valid).toBe(false);
141
+ expect(result.errors.some(e => e.includes("empty"))).toBe(true);
142
+ });
143
+ it("should handle files with section numbers in headers", async () => {
144
+ const filePath = path.join(tempDir, "numbered.docspec.md");
145
+ const content = `---
146
+
147
+ # DOCSPEC: Test
148
+
149
+ ---
150
+
151
+ ## 1. Purpose of This Document
152
+
153
+ This document serves as a test case for validating docspec files with numbered section headers. It contains custom content that is different from the boilerplate template.
154
+
155
+ ## 2. When This Document Should Be Updated
156
+
157
+ This document should be updated whenever the validation logic for numbered headers changes. It tests the parser's ability to handle section numbers correctly.
158
+
159
+ ## 3. Structure & Required Sections
160
+
161
+ This section describes the structure of the test document. It includes all required sections with sufficient content to pass validation checks.
162
+
163
+ ## 4. Style & Editing Guidelines
164
+
165
+ The style for this test document is straightforward and technical. It focuses on clarity and precision in describing test scenarios. Do: Ensure all sections have adequate content. Don't: Use boilerplate text or leave sections empty. Always provide meaningful test data.
166
+
167
+ ## 5. Known Gaps or Intentional Omissions
168
+
169
+ There are no known gaps in this test document. All sections are complete and properly formatted.
170
+ `;
171
+ await fs.writeFile(filePath, content, "utf-8");
172
+ const result = await (0, validator_1.validateDocspec)(filePath);
173
+ expect(result.valid).toBe(true);
174
+ });
175
+ it("should handle files without section numbers in headers", async () => {
176
+ const filePath = path.join(tempDir, "unnumbered.docspec.md");
177
+ const content = `---
178
+
179
+ # DOCSPEC: Test
180
+
181
+ ---
182
+
183
+ ## Purpose of This Document
184
+
185
+ This document serves as a test case for validating docspec files without numbered section headers. It contains custom content that differs from the boilerplate template.
186
+
187
+ ## When This Document Should Be Updated
188
+
189
+ This document should be updated whenever the validation logic for unnumbered headers changes. It tests the parser's flexibility in handling different header formats.
190
+
191
+ ## Structure & Required Sections
192
+
193
+ This section describes the structure of the test document. It includes all required sections with sufficient content to pass validation checks.
194
+
195
+ ## Style & Editing Guidelines
196
+
197
+ The style for this test document is straightforward and technical. It focuses on clarity and precision in describing test scenarios. Do: Ensure all sections have adequate content. Don't: Use boilerplate text or leave sections empty. Always provide meaningful test data.
198
+
199
+ ## Known Gaps or Intentional Omissions
200
+
201
+ There are no known gaps in this test document. All sections are complete and properly formatted.
202
+ `;
203
+ await fs.writeFile(filePath, content, "utf-8");
204
+ const result = await (0, validator_1.validateDocspec)(filePath);
205
+ expect(result.valid).toBe(true);
206
+ });
207
+ it("should ignore separator lines (---) when validating content", async () => {
208
+ const filePath = path.join(tempDir, "with-separators.docspec.md");
209
+ const content = `---
210
+
211
+ # DOCSPEC: Test
212
+
213
+ ---
214
+
215
+ ## 1. Purpose of This Document
216
+
217
+ This document tests the validator's ability to handle separator lines between sections. The content here is custom and different from boilerplate.
218
+
219
+ ---
220
+
221
+ ## 2. When This Document Should Be Updated
222
+
223
+ This document should be updated when testing separator line handling. The content is sufficient to pass validation.
224
+
225
+ ---
226
+
227
+ ## 3. Structure & Required Sections
228
+
229
+ This section describes the document structure. It includes all required sections with adequate content length.
230
+
231
+ ---
232
+
233
+ ## 4. Style & Editing Guidelines
234
+
235
+ The style rules for this test document are straightforward. Content is technical and precise. Do: Test separator handling. Don't: Skip validation of separator lines. Ensure content is meaningful.
236
+
237
+ ---
238
+
239
+ ## 5. Known Gaps or Intentional Omissions
240
+
241
+ No gaps in this test document. All sections are complete with sufficient content.
242
+ `;
243
+ await fs.writeFile(filePath, content, "utf-8");
244
+ const result = await (0, validator_1.validateDocspec)(filePath);
245
+ // Should be valid even with separators
246
+ expect(result.valid).toBe(true);
247
+ });
248
+ it("should reject content that only differs by whitespace from boilerplate", async () => {
249
+ const filePath = path.join(tempDir, "whitespace-only.docspec.md");
250
+ let content = `---
251
+
252
+ # DOCSPEC: Test
253
+
254
+ ---
255
+
256
+ `;
257
+ // Create content that's just boilerplate with different whitespace
258
+ constants_1.REQUIRED_SECTIONS.forEach((section, index) => {
259
+ content += `## ${index + 1}. ${section}\n\n`;
260
+ // Use boilerplate but with extra spaces
261
+ const boilerplate = constants_1.SECTION_BOILERPLATE[section];
262
+ content += boilerplate.replace(/\n/g, " \n") + "\n";
263
+ content += "\n---\n\n";
264
+ });
265
+ await fs.writeFile(filePath, content, "utf-8");
266
+ const result = await (0, validator_1.validateDocspec)(filePath);
267
+ expect(result.valid).toBe(false);
268
+ expect(result.errors.some(e => e.includes("too similar to boilerplate"))).toBe(true);
269
+ });
270
+ it("should reject sections that are too short", async () => {
271
+ const filePath = path.join(tempDir, "short-section.docspec.md");
272
+ let content = `---
273
+
274
+ # DOCSPEC: Test
275
+
276
+ ---
277
+
278
+ `;
279
+ constants_1.REQUIRED_SECTIONS.forEach((section, index) => {
280
+ content += `## ${index + 1}. ${section}\n\n`;
281
+ if (index === 0) {
282
+ // Make first section too short
283
+ content += "Short.\n";
284
+ }
285
+ else {
286
+ content += "This is a longer section with enough content to pass validation.\n";
287
+ }
288
+ content += "\n---\n\n";
289
+ });
290
+ await fs.writeFile(filePath, content, "utf-8");
291
+ const result = await (0, validator_1.validateDocspec)(filePath);
292
+ expect(result.valid).toBe(false);
293
+ expect(result.errors.some(e => e.includes("too short") || e.includes("incomplete"))).toBe(true);
294
+ });
295
+ it("should handle non-existent files gracefully", async () => {
296
+ const filePath = path.join(tempDir, "nonexistent.docspec.md");
297
+ const result = await (0, validator_1.validateDocspec)(filePath);
298
+ expect(result.valid).toBe(false);
299
+ expect(result.errors.length).toBeGreaterThan(0);
300
+ expect(result.errors[0]).toContain("Failed to read file");
301
+ });
302
+ it("should handle files with extra sections (non-required)", async () => {
303
+ const filePath = path.join(tempDir, "extra-sections.docspec.md");
304
+ const content = `---
305
+
306
+ # DOCSPEC: Test
307
+
308
+ ---
309
+
310
+ ## 1. Purpose of This Document
311
+
312
+ This document tests the validator's handling of extra sections beyond the required ones. The content is custom and sufficient to pass validation.
313
+
314
+ ## 2. When This Document Should Be Updated
315
+
316
+ This document should be updated when testing extra section handling. The content is meaningful and not boilerplate.
317
+
318
+ ## 3. Structure & Required Sections
319
+
320
+ This section describes the document structure including both required and optional sections. All content is customized.
321
+
322
+ ## 4. Style & Editing Guidelines
323
+
324
+ The style rules for this test document are clear and technical. Content is sufficient in length. Do: Test extra sections. Don't: Reject valid documents with additional sections. Ensure all required sections are present.
325
+
326
+ ## 5. Known Gaps or Intentional Omissions
327
+
328
+ No gaps in this test document. All sections are complete with adequate content.
329
+
330
+ ## 7. Additional Section
331
+
332
+ This is an extra section that shouldn't cause validation to fail. It contains additional information beyond the required sections.
333
+ `;
334
+ await fs.writeFile(filePath, content, "utf-8");
335
+ const result = await (0, validator_1.validateDocspec)(filePath);
336
+ // Extra sections should be allowed
337
+ expect(result.valid).toBe(true);
338
+ });
339
+ it("should handle case-insensitive section matching", async () => {
340
+ const filePath = path.join(tempDir, "case-test.docspec.md");
341
+ const content = `---
342
+
343
+ # DOCSPEC: Test
344
+
345
+ ---
346
+
347
+ ## 1. PURPOSE OF THIS DOCUMENT
348
+
349
+ Custom content.
350
+
351
+ ## 2. when this document should be updated
352
+
353
+ Custom content.
354
+
355
+ ## 3. Structure & Required Sections
356
+
357
+ Custom content.
358
+
359
+ ## 4. Style & Editing Guidelines
360
+
361
+ Custom style and editing guidelines content.
362
+
363
+ ## 5. Known Gaps or Intentional Omissions
364
+
365
+ Custom gaps content.
366
+ `;
367
+ await fs.writeFile(filePath, content, "utf-8");
368
+ const result = await (0, validator_1.validateDocspec)(filePath);
369
+ // Currently the validator is case-sensitive, so this will fail
370
+ // This test documents current behavior - could be enhanced later
371
+ expect(result.valid).toBe(false);
372
+ });
373
+ });
374
+ });
375
+ //# sourceMappingURL=validator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.test.js","sourceRoot":"","sources":["../../src/__tests__/validator.test.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const commander_1 = require("commander");
38
+ const fs = __importStar(require("fs/promises"));
39
+ const path = __importStar(require("path"));
40
+ const validator_1 = require("./validator");
41
+ const generator_1 = require("./generator");
42
+ const program = new commander_1.Command();
43
+ program
44
+ .name("docspec")
45
+ .description("Generate and validate docspec files (*.docspec.md)")
46
+ .version("0.1.0");
47
+ program
48
+ .command("validate")
49
+ .description("Validate docspec files")
50
+ .argument("[paths...]", "Paths to docspec files (if not provided, finds all *.docspec.md files)")
51
+ .action(async (filePaths) => {
52
+ let filesToValidate = [];
53
+ if (filePaths.length > 0) {
54
+ // Use provided file paths (from pre-commit or user)
55
+ filesToValidate = filePaths;
56
+ }
57
+ else {
58
+ // Find all *.docspec.md files in current directory tree
59
+ filesToValidate = await findDocspecFiles(process.cwd());
60
+ }
61
+ if (filesToValidate.length === 0) {
62
+ console.log("No docspec files found to validate.");
63
+ process.exit(0);
64
+ }
65
+ let hasErrors = false;
66
+ for (const filePath of filesToValidate) {
67
+ const result = await (0, validator_1.validateDocspec)(filePath);
68
+ if (!result.valid) {
69
+ hasErrors = true;
70
+ console.error(`\n❌ ${filePath}:`);
71
+ for (const error of result.errors) {
72
+ console.error(` - ${error}`);
73
+ }
74
+ }
75
+ else {
76
+ console.log(`✅ ${filePath}`);
77
+ }
78
+ }
79
+ if (hasErrors) {
80
+ process.exit(1);
81
+ }
82
+ });
83
+ program
84
+ .command("generate")
85
+ .description("Generate a new docspec file")
86
+ .argument("<path>", "Path where the docspec file should be created")
87
+ .option("-n, --name <name>", "Name of the document (defaults to filename)")
88
+ .action(async (filePath, options) => {
89
+ try {
90
+ // Ensure the path ends with .docspec.md
91
+ if (!filePath.endsWith(".docspec.md")) {
92
+ filePath = filePath + ".docspec.md";
93
+ }
94
+ await (0, generator_1.generateDocspec)(filePath, options.name);
95
+ console.log(`✅ Generated docspec file: ${filePath}`);
96
+ }
97
+ catch (error) {
98
+ console.error(`❌ Failed to generate docspec file: ${error instanceof Error ? error.message : String(error)}`);
99
+ process.exit(1);
100
+ }
101
+ });
102
+ // Parse command line arguments
103
+ program.parse();
104
+ /**
105
+ * Recursively find all *.docspec.md files in a directory
106
+ */
107
+ async function findDocspecFiles(dir) {
108
+ const files = [];
109
+ try {
110
+ const entries = await fs.readdir(dir, { withFileTypes: true });
111
+ for (const entry of entries) {
112
+ const fullPath = path.join(dir, entry.name);
113
+ // Skip node_modules and .git directories
114
+ if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist") {
115
+ continue;
116
+ }
117
+ if (entry.isDirectory()) {
118
+ const subFiles = await findDocspecFiles(fullPath);
119
+ files.push(...subFiles);
120
+ }
121
+ else if (entry.isFile() && entry.name.endsWith(".docspec.md")) {
122
+ files.push(fullPath);
123
+ }
124
+ }
125
+ }
126
+ catch (error) {
127
+ // Ignore permission errors
128
+ if (error instanceof Error && "code" in error && error.code !== "EACCES") {
129
+ throw error;
130
+ }
131
+ }
132
+ return files;
133
+ }
134
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Required section headers for docspec files
3
+ */
4
+ export declare const REQUIRED_SECTIONS: readonly ["Purpose of This Document", "When This Document Should Be Updated", "Structure & Required Sections", "Style & Editing Guidelines", "Known Gaps or Intentional Omissions"];
5
+ /**
6
+ * Boilerplate template text for each section
7
+ */
8
+ export declare const SECTION_BOILERPLATE: Record<string, string>;
9
+ /**
10
+ * Generate the full docspec template
11
+ */
12
+ export declare function getDocspecTemplate(name: string): string;
13
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iBAAiB,qLAMpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAoBtD,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBvD"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SECTION_BOILERPLATE = exports.REQUIRED_SECTIONS = void 0;
4
+ exports.getDocspecTemplate = getDocspecTemplate;
5
+ /**
6
+ * Required section headers for docspec files
7
+ */
8
+ exports.REQUIRED_SECTIONS = [
9
+ "Purpose of This Document",
10
+ "When This Document Should Be Updated",
11
+ "Structure & Required Sections",
12
+ "Style & Editing Guidelines",
13
+ "Known Gaps or Intentional Omissions",
14
+ ];
15
+ /**
16
+ * Boilerplate template text for each section
17
+ */
18
+ exports.SECTION_BOILERPLATE = {
19
+ "Purpose of This Document": `Explain **what this Markdown file is supposed to achieve**, not what it currently contains.
20
+
21
+ What questions should this document always be able to answer? What *kind* of document is it (overview, spec, tutorial, ops runbook, etc.)?`,
22
+ "When This Document Should Be Updated": `Describe **triggers** based on code changes.
23
+
24
+ Write as concrete rules that can be checked against a diff. Examples: "If new subdirectories are added, update the contents section" or "If public APIs change, update the interaction section."`,
25
+ "Structure & Required Sections": `Describe the **expected sections** and what belongs in each, without restating the actual content.
26
+
27
+ For each section, specify: its name/role, what it should cover (conceptual, not literal), and any constraints (e.g., "Keep high-level; don't enumerate every file").`,
28
+ "Style & Editing Guidelines": `Rules **specific to this doc or directory**, not global writing rules.
29
+
30
+ Include both style preferences (e.g., "Use non-technical language" or "Prefer bullet lists") and concrete editing guidelines (e.g., "Do: Update examples when APIs change" or "Don't: Remove placeholder sections").`,
31
+ "Known Gaps or Intentional Omissions": `Note things that **should not be documented yet** or are deliberately vague.
32
+
33
+ Examples: "Auth design is intentionally not detailed here; see \`/security/README.md\`" or "This doc avoids internal business logic; keep it conceptual."`,
34
+ };
35
+ /**
36
+ * Generate the full docspec template
37
+ */
38
+ function getDocspecTemplate(name) {
39
+ const sections = exports.REQUIRED_SECTIONS.map((sectionName, index) => {
40
+ const sectionNumber = index + 1;
41
+ const boilerplate = exports.SECTION_BOILERPLATE[sectionName];
42
+ return `## ${sectionNumber}. ${sectionName}\n\n${boilerplate}`;
43
+ }).join("\n\n---\n\n");
44
+ return `---
45
+
46
+ # DOCSPEC: ${name}
47
+
48
+ > Short phrase: *What this doc is for* (e.g. "Overview of this directory's purpose and structure.")
49
+
50
+ ---
51
+
52
+ ${sections}
53
+ `;
54
+ }
55
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAuCA,gDAiBC;AAxDD;;GAEG;AACU,QAAA,iBAAiB,GAAG;IAC/B,0BAA0B;IAC1B,sCAAsC;IACtC,+BAA+B;IAC/B,4BAA4B;IAC5B,qCAAqC;CAC7B,CAAC;AAEX;;GAEG;AACU,QAAA,mBAAmB,GAA2B;IACzD,0BAA0B,EAAE;;2IAE6G;IAEzI,sCAAsC,EAAE;;iMAEuJ;IAE/L,+BAA+B,EAAE;;qKAEkI;IAEnK,4BAA4B,EAAE;;qNAEqL;IAEnN,qCAAqC,EAAE;;0JAEiH;CACzJ,CAAC;AAEF;;GAEG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,MAAM,QAAQ,GAAG,yBAAiB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE;QAC5D,MAAM,aAAa,GAAG,KAAK,GAAG,CAAC,CAAC;QAChC,MAAM,WAAW,GAAG,2BAAmB,CAAC,WAAW,CAAC,CAAC;QACrD,OAAO,MAAM,aAAa,KAAK,WAAW,OAAO,WAAW,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAEvB,OAAO;;aAEI,IAAI;;;;;;EAMf,QAAQ;CACT,CAAC;AACF,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Generate a new docspec file at the specified path
3
+ * @param filePath Path where the docspec file should be created
4
+ * @param name Name of the document (used in the header)
5
+ */
6
+ export declare function generateDocspec(filePath: string, name?: string): Promise<void>;
7
+ /**
8
+ * Generate docspec content as a string (for library use)
9
+ * @param name Name of the document
10
+ */
11
+ export declare function generateDocspecContent(name: string): string;
12
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAepF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3D"}