docspec 0.2.0 → 0.3.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 (80) hide show
  1. package/README.md +64 -142
  2. package/dist/__tests__/changed.test.d.ts +2 -0
  3. package/dist/__tests__/changed.test.d.ts.map +1 -0
  4. package/dist/__tests__/changed.test.js +98 -0
  5. package/dist/__tests__/changed.test.js.map +1 -0
  6. package/dist/__tests__/cli.test.js +34 -142
  7. package/dist/__tests__/cli.test.js.map +1 -1
  8. package/dist/__tests__/create.test.d.ts +2 -0
  9. package/dist/__tests__/create.test.d.ts.map +1 -0
  10. package/dist/__tests__/create.test.js +122 -0
  11. package/dist/__tests__/create.test.js.map +1 -0
  12. package/dist/__tests__/generate.test.d.ts +2 -0
  13. package/dist/__tests__/generate.test.d.ts.map +1 -0
  14. package/dist/__tests__/generate.test.js +113 -0
  15. package/dist/__tests__/generate.test.js.map +1 -0
  16. package/dist/__tests__/generator.test.js +26 -22
  17. package/dist/__tests__/generator.test.js.map +1 -1
  18. package/dist/__tests__/path-utils.test.d.ts +2 -0
  19. package/dist/__tests__/path-utils.test.d.ts.map +1 -0
  20. package/dist/__tests__/path-utils.test.js +49 -0
  21. package/dist/__tests__/path-utils.test.js.map +1 -0
  22. package/dist/__tests__/template.test.d.ts +2 -0
  23. package/dist/__tests__/template.test.d.ts.map +1 -0
  24. package/dist/__tests__/template.test.js +95 -0
  25. package/dist/__tests__/template.test.js.map +1 -0
  26. package/dist/changed.d.ts +25 -0
  27. package/dist/changed.d.ts.map +1 -0
  28. package/dist/changed.js +210 -0
  29. package/dist/changed.js.map +1 -0
  30. package/dist/cli.js +89 -72
  31. package/dist/cli.js.map +1 -1
  32. package/dist/constants.d.ts +2 -0
  33. package/dist/constants.d.ts.map +1 -1
  34. package/dist/constants.js +118 -15
  35. package/dist/constants.js.map +1 -1
  36. package/dist/create.d.ts +12 -0
  37. package/dist/create.d.ts.map +1 -0
  38. package/dist/create.js +93 -0
  39. package/dist/create.js.map +1 -0
  40. package/dist/docspec-changed.d.ts +25 -0
  41. package/dist/docspec-changed.d.ts.map +1 -0
  42. package/dist/docspec-changed.js +210 -0
  43. package/dist/docspec-changed.js.map +1 -0
  44. package/dist/docspec-generate.d.ts +22 -0
  45. package/dist/docspec-generate.d.ts.map +1 -0
  46. package/dist/docspec-generate.js +171 -0
  47. package/dist/docspec-generate.js.map +1 -0
  48. package/dist/format-parser.d.ts +2 -1
  49. package/dist/format-parser.d.ts.map +1 -1
  50. package/dist/format-parser.js +45 -15
  51. package/dist/format-parser.js.map +1 -1
  52. package/dist/generate.d.ts +26 -0
  53. package/dist/generate.d.ts.map +1 -0
  54. package/dist/generate.js +175 -0
  55. package/dist/generate.js.map +1 -0
  56. package/dist/generator.d.ts +4 -3
  57. package/dist/generator.d.ts.map +1 -1
  58. package/dist/generator.js +35 -12
  59. package/dist/generator.js.map +1 -1
  60. package/dist/index.d.ts +8 -4
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +16 -7
  63. package/dist/index.js.map +1 -1
  64. package/dist/logger.d.ts +40 -0
  65. package/dist/logger.d.ts.map +1 -0
  66. package/dist/logger.js +74 -0
  67. package/dist/logger.js.map +1 -0
  68. package/dist/path-utils.d.ts +17 -0
  69. package/dist/path-utils.d.ts.map +1 -0
  70. package/dist/path-utils.js +76 -0
  71. package/dist/path-utils.js.map +1 -0
  72. package/dist/template.d.ts +20 -0
  73. package/dist/template.d.ts.map +1 -0
  74. package/dist/template.js +151 -0
  75. package/dist/template.js.map +1 -0
  76. package/dist/validator.d.ts.map +1 -1
  77. package/dist/validator.js +34 -1
  78. package/dist/validator.js.map +1 -1
  79. package/package.json +1 -1
  80. package/README.docspec.md +0 -180
@@ -0,0 +1,122 @@
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 create_1 = require("../create");
40
+ const constants_1 = require("../constants");
41
+ const path_utils_1 = require("../path-utils");
42
+ describe("create", () => {
43
+ let tempDir;
44
+ let originalCwd;
45
+ beforeEach(async () => {
46
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "docspec-test-"));
47
+ originalCwd = process.cwd();
48
+ process.chdir(tempDir);
49
+ });
50
+ afterEach(async () => {
51
+ process.chdir(originalCwd);
52
+ await fs.rm(tempDir, { recursive: true, force: true });
53
+ });
54
+ describe("generateDocspecContent", () => {
55
+ it("should generate content with link to target file", () => {
56
+ const content = (0, create_1.generateDocspecContent)("README.md");
57
+ expect(content).toContain("# DOCSPEC: [README.md](/README.md)");
58
+ });
59
+ it("should include all required sections", () => {
60
+ const content = (0, create_1.generateDocspecContent)("test.md");
61
+ constants_1.REQUIRED_SECTIONS.forEach((section) => {
62
+ expect(content).toContain(section);
63
+ });
64
+ });
65
+ });
66
+ describe("generateDocspec", () => {
67
+ it("should generate a file under .docspec/ for markdown path", async () => {
68
+ await (0, create_1.generateDocspec)("test.md");
69
+ const filePath = path.join(tempDir, ".docspec", "test.docspec.md");
70
+ const exists = await fs.access(filePath).then(() => true).catch(() => false);
71
+ expect(exists).toBe(true);
72
+ });
73
+ it("should generate link to target markdown file", async () => {
74
+ await (0, create_1.generateDocspec)("test.md");
75
+ const filePath = path.join(tempDir, (0, path_utils_1.markdownToDocspecPath)("test.md"));
76
+ const content = await fs.readFile(filePath, "utf-8");
77
+ expect(content).toContain("# DOCSPEC: [test.md](/test.md)");
78
+ });
79
+ it("should accept docspec path under .docspec/", async () => {
80
+ await (0, create_1.generateDocspec)(".docspec/my-awesome-doc.docspec.md");
81
+ const filePath = path.join(tempDir, ".docspec", "my-awesome-doc.docspec.md");
82
+ const content = await fs.readFile(filePath, "utf-8");
83
+ expect(content).toContain("# DOCSPEC: [my-awesome-doc.md](/my-awesome-doc.md)");
84
+ });
85
+ it("should handle kebab-case markdown filenames", async () => {
86
+ await (0, create_1.generateDocspec)("api-reference.md");
87
+ const filePath = path.join(tempDir, ".docspec", "api-reference.docspec.md");
88
+ const content = await fs.readFile(filePath, "utf-8");
89
+ expect(content).toContain("# DOCSPEC: [api-reference.md](/api-reference.md)");
90
+ });
91
+ it("should handle snake_case markdown filenames", async () => {
92
+ await (0, create_1.generateDocspec)("user_guide.md");
93
+ const filePath = path.join(tempDir, ".docspec", "user_guide.docspec.md");
94
+ const content = await fs.readFile(filePath, "utf-8");
95
+ expect(content).toContain("# DOCSPEC: [user_guide.md](/user_guide.md)");
96
+ });
97
+ it("should create nested directories under .docspec/", async () => {
98
+ await (0, create_1.generateDocspec)("nested/deep/test.md");
99
+ const filePath = path.join(tempDir, ".docspec", "nested", "deep", "test.docspec.md");
100
+ const exists = await fs.access(filePath).then(() => true).catch(() => false);
101
+ expect(exists).toBe(true);
102
+ });
103
+ it("should generate valid markdown content", async () => {
104
+ await (0, create_1.generateDocspec)("test.md");
105
+ const filePath = path.join(tempDir, ".docspec", "test.docspec.md");
106
+ const content = await fs.readFile(filePath, "utf-8");
107
+ expect(content).toContain("# DOCSPEC:");
108
+ expect(content).toContain("## 1.");
109
+ expect(content).toContain("## 5.");
110
+ expect(content).toContain("[test.md](/test.md)");
111
+ });
112
+ it("should include all required sections in generated file", async () => {
113
+ await (0, create_1.generateDocspec)("test.md");
114
+ const filePath = path.join(tempDir, ".docspec", "test.docspec.md");
115
+ const content = await fs.readFile(filePath, "utf-8");
116
+ constants_1.REQUIRED_SECTIONS.forEach((section) => {
117
+ expect(content).toContain(section);
118
+ });
119
+ });
120
+ });
121
+ });
122
+ //# sourceMappingURL=create.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.test.js","sourceRoot":"","sources":["../../src/__tests__/create.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/generate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
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 generate_1 = require("../generate");
40
+ describe("generate", () => {
41
+ let tempDir;
42
+ let originalCwd;
43
+ beforeEach(async () => {
44
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "docspec-generate-test-"));
45
+ originalCwd = process.cwd();
46
+ process.chdir(tempDir);
47
+ });
48
+ afterEach(async () => {
49
+ process.chdir(originalCwd);
50
+ await fs.rm(tempDir, { recursive: true, force: true });
51
+ });
52
+ it("throws when markdown file does not exist", async () => {
53
+ await expect((0, generate_1.buildDocspecGeneratePrompts)({
54
+ markdownPath: "missing.md",
55
+ repoRoot: tempDir,
56
+ })).rejects.toThrow("Markdown file not found");
57
+ });
58
+ it("creates docspec and returns plan and impl prompts", async () => {
59
+ await fs.writeFile(path.join(tempDir, "README.md"), "# Hello World", "utf-8");
60
+ const result = await (0, generate_1.buildDocspecGeneratePrompts)({
61
+ markdownPath: "README.md",
62
+ repoRoot: tempDir,
63
+ });
64
+ expect(result.planPrompt).toContain("<markdown path=\"README.md\">");
65
+ expect(result.planPrompt).toContain("# Hello World");
66
+ expect(result.planPrompt).toContain("<docspec path=\".docspec/README.docspec.md\">");
67
+ expect(result.implPrompt).toContain("{{PLAN}}");
68
+ expect(result.implPrompt).toContain("README.md");
69
+ expect(result.implPrompt).toContain(".docspec/README.docspec.md");
70
+ const docspecPath = path.join(tempDir, ".docspec", "README.docspec.md");
71
+ const docspecExists = await fs.access(docspecPath).then(() => true).catch(() => false);
72
+ expect(docspecExists).toBe(true);
73
+ });
74
+ it("throws when docspec exists and overwrite is false", async () => {
75
+ await fs.mkdir(path.join(tempDir, ".docspec"), { recursive: true });
76
+ await fs.writeFile(path.join(tempDir, "README.md"), "# Hi", "utf-8");
77
+ await fs.writeFile(path.join(tempDir, ".docspec", "README.docspec.md"), "existing", "utf-8");
78
+ await expect((0, generate_1.buildDocspecGeneratePrompts)({
79
+ markdownPath: "README.md",
80
+ repoRoot: tempDir,
81
+ overwrite: false,
82
+ })).rejects.toThrow("Docspec file already exists");
83
+ });
84
+ it("overwrites docspec when overwrite is true", async () => {
85
+ await fs.mkdir(path.join(tempDir, ".docspec"), { recursive: true });
86
+ await fs.writeFile(path.join(tempDir, "README.md"), "# Hi", "utf-8");
87
+ await fs.writeFile(path.join(tempDir, ".docspec", "README.docspec.md"), "old content", "utf-8");
88
+ await (0, generate_1.buildDocspecGeneratePrompts)({
89
+ markdownPath: "README.md",
90
+ repoRoot: tempDir,
91
+ overwrite: true,
92
+ });
93
+ const content = await fs.readFile(path.join(tempDir, ".docspec", "README.docspec.md"), "utf-8");
94
+ expect(content).toContain("# DOCSPEC:");
95
+ expect(content).not.toBe("old content");
96
+ });
97
+ it("writes prompts to output paths when provided", async () => {
98
+ await fs.writeFile(path.join(tempDir, "doc.md"), "# Doc", "utf-8");
99
+ const result = await (0, generate_1.buildDocspecGeneratePrompts)({
100
+ markdownPath: "doc.md",
101
+ repoRoot: tempDir,
102
+ outputPromptPath: "prompt.txt",
103
+ outputPlanPath: "plan.txt",
104
+ });
105
+ expect(result.outputPromptPath).toBe(path.join(tempDir, "prompt.txt"));
106
+ expect(result.outputPlanPath).toBe(path.join(tempDir, "plan.txt"));
107
+ const promptContent = await fs.readFile(path.join(tempDir, "prompt.txt"), "utf-8");
108
+ const planContent = await fs.readFile(path.join(tempDir, "plan.txt"), "utf-8");
109
+ expect(promptContent).toBe(result.implPrompt);
110
+ expect(planContent).toBe(result.planPrompt);
111
+ });
112
+ });
113
+ //# sourceMappingURL=generate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.test.js","sourceRoot":"","sources":["../../src/__tests__/generate.test.ts"],"names":[],"mappings":"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"}
@@ -38,12 +38,17 @@ const path = __importStar(require("path"));
38
38
  const os = __importStar(require("os"));
39
39
  const generator_1 = require("../generator");
40
40
  const constants_1 = require("../constants");
41
+ const path_utils_1 = require("../path-utils");
41
42
  describe("generator", () => {
42
43
  let tempDir;
44
+ let originalCwd;
43
45
  beforeEach(async () => {
44
46
  tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "docspec-test-"));
47
+ originalCwd = process.cwd();
48
+ process.chdir(tempDir);
45
49
  });
46
50
  afterEach(async () => {
51
+ process.chdir(originalCwd);
47
52
  await fs.rm(tempDir, { recursive: true, force: true });
48
53
  });
49
54
  describe("generateDocspecContent", () => {
@@ -59,55 +64,54 @@ describe("generator", () => {
59
64
  });
60
65
  });
61
66
  describe("generateDocspec", () => {
62
- it("should generate a file at the specified path", async () => {
63
- const filePath = path.join(tempDir, "test.docspec.md");
64
- await (0, generator_1.generateDocspec)(filePath);
67
+ it("should generate a file under .docspec/ for markdown path", async () => {
68
+ await (0, generator_1.generateDocspec)("test.md");
69
+ const filePath = path.join(tempDir, ".docspec", "test.docspec.md");
65
70
  const exists = await fs.access(filePath).then(() => true).catch(() => false);
66
71
  expect(exists).toBe(true);
67
72
  });
68
73
  it("should generate link to target markdown file", async () => {
69
- const filePath = path.join(tempDir, "test.docspec.md");
70
- await (0, generator_1.generateDocspec)(filePath);
74
+ await (0, generator_1.generateDocspec)("test.md");
75
+ const filePath = path.join(tempDir, (0, path_utils_1.markdownToDocspecPath)("test.md"));
71
76
  const content = await fs.readFile(filePath, "utf-8");
72
77
  expect(content).toContain("# DOCSPEC: [test.md](/test.md)");
73
78
  });
74
- it("should extract target filename from docspec path", async () => {
75
- const filePath = path.join(tempDir, "my-awesome-doc.docspec.md");
76
- await (0, generator_1.generateDocspec)(filePath);
79
+ it("should accept docspec path under .docspec/", async () => {
80
+ await (0, generator_1.generateDocspec)(".docspec/my-awesome-doc.docspec.md");
81
+ const filePath = path.join(tempDir, ".docspec", "my-awesome-doc.docspec.md");
77
82
  const content = await fs.readFile(filePath, "utf-8");
78
83
  expect(content).toContain("# DOCSPEC: [my-awesome-doc.md](/my-awesome-doc.md)");
79
84
  });
80
- it("should handle kebab-case filenames", async () => {
81
- const filePath = path.join(tempDir, "api-reference.docspec.md");
82
- await (0, generator_1.generateDocspec)(filePath);
85
+ it("should handle kebab-case markdown filenames", async () => {
86
+ await (0, generator_1.generateDocspec)("api-reference.md");
87
+ const filePath = path.join(tempDir, ".docspec", "api-reference.docspec.md");
83
88
  const content = await fs.readFile(filePath, "utf-8");
84
89
  expect(content).toContain("# DOCSPEC: [api-reference.md](/api-reference.md)");
85
90
  });
86
- it("should handle snake_case filenames", async () => {
87
- const filePath = path.join(tempDir, "user_guide.docspec.md");
88
- await (0, generator_1.generateDocspec)(filePath);
91
+ it("should handle snake_case markdown filenames", async () => {
92
+ await (0, generator_1.generateDocspec)("user_guide.md");
93
+ const filePath = path.join(tempDir, ".docspec", "user_guide.docspec.md");
89
94
  const content = await fs.readFile(filePath, "utf-8");
90
95
  expect(content).toContain("# DOCSPEC: [user_guide.md](/user_guide.md)");
91
96
  });
92
- it("should create parent directories if they don't exist", async () => {
93
- const filePath = path.join(tempDir, "nested", "deep", "test.docspec.md");
94
- await (0, generator_1.generateDocspec)(filePath);
97
+ it("should create nested directories under .docspec/", async () => {
98
+ await (0, generator_1.generateDocspec)("nested/deep/test.md");
99
+ const filePath = path.join(tempDir, ".docspec", "nested", "deep", "test.docspec.md");
95
100
  const exists = await fs.access(filePath).then(() => true).catch(() => false);
96
101
  expect(exists).toBe(true);
97
102
  });
98
103
  it("should generate valid markdown content", async () => {
99
- const filePath = path.join(tempDir, "test.docspec.md");
100
- await (0, generator_1.generateDocspec)(filePath);
104
+ await (0, generator_1.generateDocspec)("test.md");
105
+ const filePath = path.join(tempDir, ".docspec", "test.docspec.md");
101
106
  const content = await fs.readFile(filePath, "utf-8");
102
- // Check structure
103
107
  expect(content).toContain("# DOCSPEC:");
104
108
  expect(content).toContain("## 1.");
105
109
  expect(content).toContain("## 5.");
106
110
  expect(content).toContain("[test.md](/test.md)");
107
111
  });
108
112
  it("should include all required sections in generated file", async () => {
109
- const filePath = path.join(tempDir, "test.docspec.md");
110
- await (0, generator_1.generateDocspec)(filePath);
113
+ await (0, generator_1.generateDocspec)("test.md");
114
+ const filePath = path.join(tempDir, ".docspec", "test.docspec.md");
111
115
  const content = await fs.readFile(filePath, "utf-8");
112
116
  constants_1.REQUIRED_SECTIONS.forEach((section) => {
113
117
  expect(content).toContain(section);
@@ -1 +1 @@
1
- {"version":3,"file":"generator.test.js","sourceRoot":"","sources":["../../src/__tests__/generator.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.test.js","sourceRoot":"","sources":["../../src/__tests__/generator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=path-utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/path-utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path_utils_1 = require("../path-utils");
4
+ describe("path-utils", () => {
5
+ describe("markdownToDocspecPath", () => {
6
+ it("converts README.md to .docspec/README.docspec.md", () => {
7
+ expect((0, path_utils_1.markdownToDocspecPath)("README.md")).toBe(".docspec/README.docspec.md");
8
+ });
9
+ it("converts path without .md suffix by appending .docspec.md", () => {
10
+ expect((0, path_utils_1.markdownToDocspecPath)("README")).toBe(".docspec/README.docspec.md");
11
+ });
12
+ it("converts nested path docs/deploy.md", () => {
13
+ expect((0, path_utils_1.markdownToDocspecPath)("docs/deploy.md")).toBe(".docspec/docs/deploy.docspec.md");
14
+ });
15
+ it("normalizes backslashes to forward slashes", () => {
16
+ expect((0, path_utils_1.markdownToDocspecPath)("docs\\deploy.md")).toBe(".docspec/docs/deploy.docspec.md");
17
+ });
18
+ it("maps absolute paths to .docspec/<basename>.docspec.md to avoid .docspec/var/...", () => {
19
+ const absolute = "/var/folders/6n/xyz/T/docspec-test-abc/boilerplate.docspec.md";
20
+ expect((0, path_utils_1.markdownToDocspecPath)(absolute)).toBe(".docspec/boilerplate.docspec.docspec.md");
21
+ });
22
+ });
23
+ describe("docspecToMarkdownPath", () => {
24
+ it("converts .docspec/README.docspec.md to README.md", () => {
25
+ expect((0, path_utils_1.docspecToMarkdownPath)(".docspec/README.docspec.md")).toBe("README.md");
26
+ });
27
+ it("converts nested docspec path to markdown path", () => {
28
+ expect((0, path_utils_1.docspecToMarkdownPath)(".docspec/docs/deploy.docspec.md")).toBe("docs/deploy.md");
29
+ });
30
+ it("returns path as-is when not under .docspec/ or not .docspec.md", () => {
31
+ expect((0, path_utils_1.docspecToMarkdownPath)("README.md")).toBe("README.md");
32
+ expect((0, path_utils_1.docspecToMarkdownPath)(".docspec/other.md")).toBe(".docspec/other.md");
33
+ });
34
+ });
35
+ describe("isDocspecPath", () => {
36
+ it("returns true for paths under .docspec/ ending in .docspec.md", () => {
37
+ expect((0, path_utils_1.isDocspecPath)(".docspec/README.docspec.md")).toBe(true);
38
+ expect((0, path_utils_1.isDocspecPath)(".docspec/docs/deploy.docspec.md")).toBe(true);
39
+ });
40
+ it("returns false for paths not under .docspec/", () => {
41
+ expect((0, path_utils_1.isDocspecPath)("README.md")).toBe(false);
42
+ expect((0, path_utils_1.isDocspecPath)("docs/README.docspec.md")).toBe(false);
43
+ });
44
+ it("returns false for .docspec paths not ending in .docspec.md", () => {
45
+ expect((0, path_utils_1.isDocspecPath)(".docspec/README.md")).toBe(false);
46
+ });
47
+ });
48
+ });
49
+ //# sourceMappingURL=path-utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.test.js","sourceRoot":"","sources":["../../src/__tests__/path-utils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=template.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/template.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,95 @@
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 template_1 = require("../template");
40
+ describe("template", () => {
41
+ let tempDir;
42
+ let originalCwd;
43
+ beforeEach(async () => {
44
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "docspec-template-test-"));
45
+ originalCwd = process.cwd();
46
+ process.chdir(tempDir);
47
+ });
48
+ afterEach(async () => {
49
+ process.chdir(originalCwd);
50
+ await fs.rm(tempDir, { recursive: true, force: true });
51
+ });
52
+ describe("getFormatFilePath", () => {
53
+ it("returns path to .docspec/docspec.md when it exists", async () => {
54
+ await fs.mkdir(path.join(tempDir, ".docspec"), { recursive: true });
55
+ await fs.writeFile(path.join(tempDir, ".docspec", "docspec.md"), "# Template", "utf-8");
56
+ const formatPath = (0, template_1.getFormatFilePath)();
57
+ expect(path.resolve(formatPath)).toBe(path.resolve(process.cwd(), ".docspec", "docspec.md"));
58
+ });
59
+ it("seeds .docspec/docspec.md from default when missing", () => {
60
+ const formatPath = (0, template_1.getFormatFilePath)();
61
+ expect(path.resolve(formatPath)).toBe(path.resolve(process.cwd(), ".docspec", "docspec.md"));
62
+ const content = require("fs").readFileSync(path.join(process.cwd(), ".docspec", "docspec.md"), "utf-8");
63
+ expect(content).toContain("Document Purpose");
64
+ expect(content).toContain("{{TARGET_FILE}}");
65
+ });
66
+ });
67
+ describe("parseFormatFile", () => {
68
+ it("parses template content into sections and template string", async () => {
69
+ const templatePath = path.join(tempDir, "format.md");
70
+ await fs.writeFile(templatePath, `# DOCSPEC: [{{TARGET_FILE}}](/{{TARGET_FILE}})
71
+
72
+ ## 1. Document Purpose
73
+ Describe the document.
74
+
75
+ ## 2. Update Triggers
76
+ When to update.
77
+ `, "utf-8");
78
+ const parsed = (0, template_1.parseFormatFile)(templatePath);
79
+ expect(parsed.sections).toHaveLength(2);
80
+ expect(parsed.sections[0].name).toBe("Document Purpose");
81
+ expect(parsed.sections[0].number).toBe(1);
82
+ expect(parsed.sections[0].boilerplate).toContain("Describe the document.");
83
+ expect(parsed.sections[1].name).toBe("Update Triggers");
84
+ expect(parsed.template).toContain("{{AGENT_INSTRUCTIONS}}");
85
+ expect(parsed.template).toContain("{{SECTIONS}}");
86
+ expect(parsed.template).toContain("{{TARGET_FILE}}");
87
+ });
88
+ it("throws when no section headers found", async () => {
89
+ const templatePath = path.join(tempDir, "empty.md");
90
+ await fs.writeFile(templatePath, "Just some text\nNo sections\n", "utf-8");
91
+ expect(() => (0, template_1.parseFormatFile)(templatePath)).toThrow("No section headers found");
92
+ });
93
+ });
94
+ });
95
+ //# sourceMappingURL=template.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.test.js","sourceRoot":"","sources":["../../src/__tests__/template.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface DocspecChangedOptions {
2
+ /** List of changed file paths (repo-relative). If not set, base and merge must be set. */
3
+ changedFiles?: string[];
4
+ /** Base SHA for git diff (e.g. PR base). */
5
+ base?: string;
6
+ /** Merge SHA for git diff (e.g. PR merge commit). */
7
+ merge?: string;
8
+ /** Max number of docspecs to include. */
9
+ maxDocspecs?: number;
10
+ /** Max characters of diff to include. */
11
+ maxDiffChars?: number;
12
+ /** Repo root (default process.cwd()). */
13
+ repoRoot?: string;
14
+ }
15
+ /**
16
+ * Build the changed prompt (sync markdown with docspecs from PR changes) and return it.
17
+ * If options.outputPath is set, writes the prompt to that file.
18
+ */
19
+ export declare function buildDocspecChangedPrompt(options: DocspecChangedOptions & {
20
+ outputPath?: string;
21
+ }): Promise<{
22
+ prompt: string;
23
+ outputPath: string | null;
24
+ }>;
25
+ //# sourceMappingURL=changed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changed.d.ts","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,qBAAqB;IACpC,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiHD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,qBAAqB,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAmGxD"}