@sudocode-ai/integration-speckit 0.1.14

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 (53) hide show
  1. package/dist/id-generator.d.ts +149 -0
  2. package/dist/id-generator.d.ts.map +1 -0
  3. package/dist/id-generator.js +197 -0
  4. package/dist/id-generator.js.map +1 -0
  5. package/dist/index.d.ts +33 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +1017 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/parser/index.d.ts +11 -0
  10. package/dist/parser/index.d.ts.map +1 -0
  11. package/dist/parser/index.js +16 -0
  12. package/dist/parser/index.js.map +1 -0
  13. package/dist/parser/markdown-utils.d.ts +138 -0
  14. package/dist/parser/markdown-utils.d.ts.map +1 -0
  15. package/dist/parser/markdown-utils.js +283 -0
  16. package/dist/parser/markdown-utils.js.map +1 -0
  17. package/dist/parser/plan-parser.d.ts +97 -0
  18. package/dist/parser/plan-parser.d.ts.map +1 -0
  19. package/dist/parser/plan-parser.js +286 -0
  20. package/dist/parser/plan-parser.js.map +1 -0
  21. package/dist/parser/spec-parser.d.ts +95 -0
  22. package/dist/parser/spec-parser.d.ts.map +1 -0
  23. package/dist/parser/spec-parser.js +250 -0
  24. package/dist/parser/spec-parser.js.map +1 -0
  25. package/dist/parser/supporting-docs.d.ts +119 -0
  26. package/dist/parser/supporting-docs.d.ts.map +1 -0
  27. package/dist/parser/supporting-docs.js +324 -0
  28. package/dist/parser/supporting-docs.js.map +1 -0
  29. package/dist/parser/tasks-parser.d.ts +171 -0
  30. package/dist/parser/tasks-parser.d.ts.map +1 -0
  31. package/dist/parser/tasks-parser.js +281 -0
  32. package/dist/parser/tasks-parser.js.map +1 -0
  33. package/dist/relationship-mapper.d.ts +165 -0
  34. package/dist/relationship-mapper.d.ts.map +1 -0
  35. package/dist/relationship-mapper.js +238 -0
  36. package/dist/relationship-mapper.js.map +1 -0
  37. package/dist/watcher.d.ts +137 -0
  38. package/dist/watcher.d.ts.map +1 -0
  39. package/dist/watcher.js +599 -0
  40. package/dist/watcher.js.map +1 -0
  41. package/dist/writer/index.d.ts +8 -0
  42. package/dist/writer/index.d.ts.map +1 -0
  43. package/dist/writer/index.js +10 -0
  44. package/dist/writer/index.js.map +1 -0
  45. package/dist/writer/spec-writer.d.ts +70 -0
  46. package/dist/writer/spec-writer.d.ts.map +1 -0
  47. package/dist/writer/spec-writer.js +261 -0
  48. package/dist/writer/spec-writer.js.map +1 -0
  49. package/dist/writer/tasks-writer.d.ts +47 -0
  50. package/dist/writer/tasks-writer.d.ts.map +1 -0
  51. package/dist/writer/tasks-writer.js +161 -0
  52. package/dist/writer/tasks-writer.js.map +1 -0
  53. package/package.json +42 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Spec Writer for Spec-Kit Integration
3
+ *
4
+ * Updates spec.md and plan.md content while preserving document structure.
5
+ * Handles title updates in headers and status line updates.
6
+ */
7
+ /**
8
+ * Updates to apply to a spec file
9
+ */
10
+ export interface SpecUpdates {
11
+ /** New title (will update # header) */
12
+ title?: string;
13
+ /** New status (will update **Status**: line) */
14
+ status?: string;
15
+ /** New content (will replace everything after frontmatter/header) */
16
+ content?: string;
17
+ }
18
+ /**
19
+ * Result of a spec update operation
20
+ */
21
+ export interface SpecUpdateResult {
22
+ success: boolean;
23
+ error?: string;
24
+ changes: {
25
+ title?: {
26
+ from: string;
27
+ to: string;
28
+ };
29
+ status?: {
30
+ from: string;
31
+ to: string;
32
+ };
33
+ content?: boolean;
34
+ };
35
+ }
36
+ /**
37
+ * Update spec content while preserving document structure
38
+ *
39
+ * @param specFilePath - Absolute path to the spec.md or plan.md file
40
+ * @param updates - Updates to apply (title, status, content)
41
+ * @returns Result of the update operation
42
+ *
43
+ * @example
44
+ * // Update just the status
45
+ * updateSpecContent("/project/.specify/specs/001-auth/spec.md", {
46
+ * status: "In Progress"
47
+ * });
48
+ *
49
+ * // Update title and status
50
+ * updateSpecContent("/project/.specify/specs/001-auth/spec.md", {
51
+ * title: "Authentication System",
52
+ * status: "Complete"
53
+ * });
54
+ */
55
+ export declare function updateSpecContent(specFilePath: string, updates: SpecUpdates): SpecUpdateResult;
56
+ /**
57
+ * Get the current title from a spec file
58
+ *
59
+ * @param specFilePath - Absolute path to the spec file
60
+ * @returns The title or null if not found
61
+ */
62
+ export declare function getSpecTitle(specFilePath: string): string | null;
63
+ /**
64
+ * Get the current status from a spec file
65
+ *
66
+ * @param specFilePath - Absolute path to the spec file
67
+ * @returns The status or null if not found
68
+ */
69
+ export declare function getSpecStatus(specFilePath: string): string | null;
70
+ //# sourceMappingURL=spec-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-writer.d.ts","sourceRoot":"","sources":["../../src/writer/spec-writer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QACP,KAAK,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;QACrC,MAAM,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;QACtC,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AA6BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,WAAW,GACnB,gBAAgB,CAsGlB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWhE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWjE"}
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Spec Writer for Spec-Kit Integration
3
+ *
4
+ * Updates spec.md and plan.md content while preserving document structure.
5
+ * Handles title updates in headers and status line updates.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, renameSync } from "fs";
8
+ import { dirname } from "path";
9
+ import { mkdirSync } from "fs";
10
+ /**
11
+ * Regex patterns for spec-kit markdown structure
12
+ */
13
+ const TITLE_REGEX = /^#\s+(.+)$/;
14
+ const STATUS_REGEX = /^\*\*Status\*\*:\s*(.*)$/i;
15
+ const METADATA_LINE_REGEX = /^\*\*[^*]+\*\*:/;
16
+ /**
17
+ * Update spec content while preserving document structure
18
+ *
19
+ * @param specFilePath - Absolute path to the spec.md or plan.md file
20
+ * @param updates - Updates to apply (title, status, content)
21
+ * @returns Result of the update operation
22
+ *
23
+ * @example
24
+ * // Update just the status
25
+ * updateSpecContent("/project/.specify/specs/001-auth/spec.md", {
26
+ * status: "In Progress"
27
+ * });
28
+ *
29
+ * // Update title and status
30
+ * updateSpecContent("/project/.specify/specs/001-auth/spec.md", {
31
+ * title: "Authentication System",
32
+ * status: "Complete"
33
+ * });
34
+ */
35
+ export function updateSpecContent(specFilePath, updates) {
36
+ const result = {
37
+ success: false,
38
+ changes: {},
39
+ };
40
+ // Validate inputs
41
+ if (!specFilePath) {
42
+ result.error = "Spec file path is required";
43
+ return result;
44
+ }
45
+ if (!updates.title && !updates.status && updates.content === undefined) {
46
+ result.error = "At least one update (title, status, or content) is required";
47
+ return result;
48
+ }
49
+ // Check if file exists
50
+ if (!existsSync(specFilePath)) {
51
+ result.error = `Spec file not found: ${specFilePath}`;
52
+ return result;
53
+ }
54
+ try {
55
+ // Parse the file
56
+ const parsed = parseSpecFile(specFilePath);
57
+ const lines = [...parsed.lines];
58
+ // Apply title update
59
+ if (updates.title !== undefined && updates.title !== parsed.currentTitle) {
60
+ if (parsed.titleLineIndex !== null) {
61
+ lines[parsed.titleLineIndex] = `# ${updates.title}`;
62
+ result.changes.title = {
63
+ from: parsed.currentTitle || "",
64
+ to: updates.title,
65
+ };
66
+ }
67
+ else {
68
+ // No title found, prepend one
69
+ lines.unshift(`# ${updates.title}`, "");
70
+ result.changes.title = {
71
+ from: "",
72
+ to: updates.title,
73
+ };
74
+ }
75
+ }
76
+ // Apply status update
77
+ if (updates.status !== undefined && updates.status !== parsed.currentStatus) {
78
+ if (parsed.statusLineIndex !== null) {
79
+ lines[parsed.statusLineIndex] = `**Status**: ${updates.status}`;
80
+ result.changes.status = {
81
+ from: parsed.currentStatus || "",
82
+ to: updates.status,
83
+ };
84
+ }
85
+ else {
86
+ // No status found, insert after title or at start
87
+ const insertIndex = parsed.titleLineIndex !== null ? parsed.titleLineIndex + 1 : 0;
88
+ // Make sure there's a blank line before status if inserting after title
89
+ if (parsed.titleLineIndex !== null && lines[insertIndex]?.trim() !== "") {
90
+ lines.splice(insertIndex, 0, "");
91
+ }
92
+ lines.splice(insertIndex + 1, 0, `**Status**: ${updates.status}`);
93
+ result.changes.status = {
94
+ from: "",
95
+ to: updates.status,
96
+ };
97
+ }
98
+ }
99
+ // Apply content update
100
+ if (updates.content !== undefined) {
101
+ // Recalculate content start after possible line shifts
102
+ const recalculated = recalculateContentStart(lines);
103
+ // Remove everything from content start
104
+ lines.splice(recalculated.contentStartIndex);
105
+ // Add new content with proper spacing
106
+ if (recalculated.contentStartIndex > 0 && !lines[lines.length - 1]?.trim()) {
107
+ // Already has blank line
108
+ }
109
+ else {
110
+ lines.push("");
111
+ }
112
+ // Add the new content
113
+ lines.push(updates.content);
114
+ result.changes.content = true;
115
+ }
116
+ // Write the updated content atomically
117
+ const updatedContent = lines.join("\n");
118
+ writeFileAtomic(specFilePath, updatedContent);
119
+ result.success = true;
120
+ return result;
121
+ }
122
+ catch (error) {
123
+ result.error = `Failed to update spec: ${error instanceof Error ? error.message : String(error)}`;
124
+ return result;
125
+ }
126
+ }
127
+ /**
128
+ * Get the current title from a spec file
129
+ *
130
+ * @param specFilePath - Absolute path to the spec file
131
+ * @returns The title or null if not found
132
+ */
133
+ export function getSpecTitle(specFilePath) {
134
+ if (!existsSync(specFilePath)) {
135
+ return null;
136
+ }
137
+ try {
138
+ const parsed = parseSpecFile(specFilePath);
139
+ return parsed.currentTitle;
140
+ }
141
+ catch {
142
+ return null;
143
+ }
144
+ }
145
+ /**
146
+ * Get the current status from a spec file
147
+ *
148
+ * @param specFilePath - Absolute path to the spec file
149
+ * @returns The status or null if not found
150
+ */
151
+ export function getSpecStatus(specFilePath) {
152
+ if (!existsSync(specFilePath)) {
153
+ return null;
154
+ }
155
+ try {
156
+ const parsed = parseSpecFile(specFilePath);
157
+ return parsed.currentStatus;
158
+ }
159
+ catch {
160
+ return null;
161
+ }
162
+ }
163
+ /**
164
+ * Parse a spec-kit markdown file to extract structure
165
+ */
166
+ function parseSpecFile(filePath) {
167
+ const raw = readFileSync(filePath, "utf-8");
168
+ const lines = raw.split("\n");
169
+ let titleLineIndex = null;
170
+ let currentTitle = null;
171
+ let statusLineIndex = null;
172
+ let currentStatus = null;
173
+ let contentStartIndex = 0;
174
+ let foundFirstContent = false;
175
+ for (let i = 0; i < lines.length; i++) {
176
+ const line = lines[i];
177
+ // Look for title (# header)
178
+ if (titleLineIndex === null) {
179
+ const titleMatch = line.match(TITLE_REGEX);
180
+ if (titleMatch) {
181
+ titleLineIndex = i;
182
+ currentTitle = titleMatch[1].trim();
183
+ continue;
184
+ }
185
+ }
186
+ // Look for status line
187
+ if (statusLineIndex === null) {
188
+ const statusMatch = line.match(STATUS_REGEX);
189
+ if (statusMatch) {
190
+ statusLineIndex = i;
191
+ currentStatus = statusMatch[1].trim();
192
+ continue;
193
+ }
194
+ }
195
+ // Track metadata section (lines starting with **Key**:)
196
+ if (METADATA_LINE_REGEX.test(line)) {
197
+ continue;
198
+ }
199
+ // Track where content starts (first non-empty, non-metadata line after title)
200
+ if (!foundFirstContent && titleLineIndex !== null && line.trim() !== "") {
201
+ // Skip if this is still in metadata section
202
+ if (!METADATA_LINE_REGEX.test(line)) {
203
+ contentStartIndex = i;
204
+ foundFirstContent = true;
205
+ }
206
+ }
207
+ }
208
+ // If no content found, start after metadata
209
+ if (!foundFirstContent) {
210
+ contentStartIndex = lines.length;
211
+ }
212
+ return {
213
+ raw,
214
+ lines,
215
+ titleLineIndex,
216
+ currentTitle,
217
+ statusLineIndex,
218
+ currentStatus,
219
+ contentStartIndex,
220
+ };
221
+ }
222
+ /**
223
+ * Recalculate content start index after modifications
224
+ */
225
+ function recalculateContentStart(lines) {
226
+ let titleLineIndex = null;
227
+ let lastMetadataIndex = -1;
228
+ for (let i = 0; i < lines.length; i++) {
229
+ const line = lines[i];
230
+ // Find title
231
+ if (titleLineIndex === null && TITLE_REGEX.test(line)) {
232
+ titleLineIndex = i;
233
+ }
234
+ // Track metadata lines
235
+ if (METADATA_LINE_REGEX.test(line)) {
236
+ lastMetadataIndex = i;
237
+ }
238
+ }
239
+ // Content starts after the last metadata line (or after title if no metadata)
240
+ // Skip any blank lines too
241
+ let contentStartIndex = Math.max(titleLineIndex !== null ? titleLineIndex + 1 : 0, lastMetadataIndex + 1);
242
+ // Skip blank lines after metadata
243
+ while (contentStartIndex < lines.length && lines[contentStartIndex]?.trim() === "") {
244
+ contentStartIndex++;
245
+ }
246
+ return { contentStartIndex };
247
+ }
248
+ /**
249
+ * Write file atomically using temp file + rename pattern
250
+ */
251
+ function writeFileAtomic(filePath, content) {
252
+ const dir = dirname(filePath);
253
+ if (!existsSync(dir)) {
254
+ mkdirSync(dir, { recursive: true });
255
+ }
256
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
257
+ writeFileSync(tempPath, content, "utf-8");
258
+ // Rename is atomic on most file systems
259
+ renameSync(tempPath, filePath);
260
+ }
261
+ //# sourceMappingURL=spec-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-writer.js","sourceRoot":"","sources":["../../src/writer/spec-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Tasks Writer for Spec-Kit Integration
3
+ *
4
+ * Updates task checkbox status in tasks.md files.
5
+ * Tasks are formatted as: `- [ ] T001: Task description` or `- [x] T001: Task description`
6
+ */
7
+ /**
8
+ * Result of a task status update operation
9
+ */
10
+ export interface TaskUpdateResult {
11
+ success: boolean;
12
+ error?: string;
13
+ previousStatus?: boolean;
14
+ newStatus?: boolean;
15
+ }
16
+ /**
17
+ * Update a task's checkbox status in a tasks.md file
18
+ *
19
+ * @param tasksFilePath - Absolute path to the tasks.md file
20
+ * @param taskId - Task identifier (e.g., "T001")
21
+ * @param completed - Whether the task should be marked as completed
22
+ * @returns Result of the update operation
23
+ *
24
+ * @example
25
+ * updateTaskStatus("/project/.specify/specs/001-auth/tasks.md", "T001", true);
26
+ * // Changes `- [ ] T001: Setup auth` to `- [x] T001: Setup auth`
27
+ *
28
+ * updateTaskStatus("/project/.specify/specs/001-auth/tasks.md", "T001", false);
29
+ * // Changes `- [x] T001: Setup auth` to `- [ ] T001: Setup auth`
30
+ */
31
+ export declare function updateTaskStatus(tasksFilePath: string, taskId: string, completed: boolean): TaskUpdateResult;
32
+ /**
33
+ * Get the current status of a task
34
+ *
35
+ * @param tasksFilePath - Absolute path to the tasks.md file
36
+ * @param taskId - Task identifier (e.g., "T001")
37
+ * @returns The task's completion status, or null if not found
38
+ */
39
+ export declare function getTaskStatus(tasksFilePath: string, taskId: string): boolean | null;
40
+ /**
41
+ * Get all tasks and their statuses from a tasks.md file
42
+ *
43
+ * @param tasksFilePath - Absolute path to the tasks.md file
44
+ * @returns Map of task IDs to their completion status
45
+ */
46
+ export declare function getAllTaskStatuses(tasksFilePath: string): Map<string, boolean>;
47
+ //# sourceMappingURL=tasks-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks-writer.d.ts","sourceRoot":"","sources":["../../src/writer/tasks-writer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAaD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,GACjB,gBAAgB,CAiElB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,GAAG,IAAI,CAoBhB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,GACpB,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAwBtB"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Tasks Writer for Spec-Kit Integration
3
+ *
4
+ * Updates task checkbox status in tasks.md files.
5
+ * Tasks are formatted as: `- [ ] T001: Task description` or `- [x] T001: Task description`
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, renameSync } from "fs";
8
+ import { dirname } from "path";
9
+ import { mkdirSync } from "fs";
10
+ /**
11
+ * Regex pattern to match task lines in tasks.md
12
+ * Matches: `- [ ] T001: description` or `- [x] T001: description`
13
+ * Captures:
14
+ * - Group 1: Leading whitespace and bullet
15
+ * - Group 2: Checkbox state (space or x)
16
+ * - Group 3: Task ID (e.g., T001)
17
+ * - Group 4: Rest of line (description)
18
+ */
19
+ const TASK_LINE_REGEX = /^(\s*-\s*)\[([ xX])\]\s*(T\d+)(.*)$/;
20
+ /**
21
+ * Update a task's checkbox status in a tasks.md file
22
+ *
23
+ * @param tasksFilePath - Absolute path to the tasks.md file
24
+ * @param taskId - Task identifier (e.g., "T001")
25
+ * @param completed - Whether the task should be marked as completed
26
+ * @returns Result of the update operation
27
+ *
28
+ * @example
29
+ * updateTaskStatus("/project/.specify/specs/001-auth/tasks.md", "T001", true);
30
+ * // Changes `- [ ] T001: Setup auth` to `- [x] T001: Setup auth`
31
+ *
32
+ * updateTaskStatus("/project/.specify/specs/001-auth/tasks.md", "T001", false);
33
+ * // Changes `- [x] T001: Setup auth` to `- [ ] T001: Setup auth`
34
+ */
35
+ export function updateTaskStatus(tasksFilePath, taskId, completed) {
36
+ // Validate inputs
37
+ if (!tasksFilePath) {
38
+ return { success: false, error: "Tasks file path is required" };
39
+ }
40
+ if (!taskId || !/^T\d+$/.test(taskId)) {
41
+ return {
42
+ success: false,
43
+ error: `Invalid task ID format: ${taskId}. Expected format: T001, T002, etc.`,
44
+ };
45
+ }
46
+ // Check if file exists
47
+ if (!existsSync(tasksFilePath)) {
48
+ return { success: false, error: `Tasks file not found: ${tasksFilePath}` };
49
+ }
50
+ try {
51
+ // Read the file
52
+ const content = readFileSync(tasksFilePath, "utf-8");
53
+ const lines = content.split("\n");
54
+ let taskFound = false;
55
+ let previousStatus;
56
+ const newCheckbox = completed ? "x" : " ";
57
+ // Process each line
58
+ const updatedLines = lines.map((line) => {
59
+ const match = line.match(TASK_LINE_REGEX);
60
+ if (match && match[3] === taskId) {
61
+ taskFound = true;
62
+ const [, prefix, currentCheckbox, id, rest] = match;
63
+ previousStatus = currentCheckbox.toLowerCase() === "x";
64
+ // Return updated line with new checkbox state
65
+ return `${prefix}[${newCheckbox}] ${id}${rest}`;
66
+ }
67
+ return line;
68
+ });
69
+ if (!taskFound) {
70
+ return {
71
+ success: false,
72
+ error: `Task ${taskId} not found in ${tasksFilePath}`,
73
+ };
74
+ }
75
+ // Write the updated content atomically
76
+ const updatedContent = updatedLines.join("\n");
77
+ writeFileAtomic(tasksFilePath, updatedContent);
78
+ return {
79
+ success: true,
80
+ previousStatus,
81
+ newStatus: completed,
82
+ };
83
+ }
84
+ catch (error) {
85
+ return {
86
+ success: false,
87
+ error: `Failed to update task status: ${error instanceof Error ? error.message : String(error)}`,
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * Get the current status of a task
93
+ *
94
+ * @param tasksFilePath - Absolute path to the tasks.md file
95
+ * @param taskId - Task identifier (e.g., "T001")
96
+ * @returns The task's completion status, or null if not found
97
+ */
98
+ export function getTaskStatus(tasksFilePath, taskId) {
99
+ if (!existsSync(tasksFilePath)) {
100
+ return null;
101
+ }
102
+ try {
103
+ const content = readFileSync(tasksFilePath, "utf-8");
104
+ const lines = content.split("\n");
105
+ for (const line of lines) {
106
+ const match = line.match(TASK_LINE_REGEX);
107
+ if (match && match[3] === taskId) {
108
+ return match[2].toLowerCase() === "x";
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ /**
118
+ * Get all tasks and their statuses from a tasks.md file
119
+ *
120
+ * @param tasksFilePath - Absolute path to the tasks.md file
121
+ * @returns Map of task IDs to their completion status
122
+ */
123
+ export function getAllTaskStatuses(tasksFilePath) {
124
+ const statuses = new Map();
125
+ if (!existsSync(tasksFilePath)) {
126
+ return statuses;
127
+ }
128
+ try {
129
+ const content = readFileSync(tasksFilePath, "utf-8");
130
+ const lines = content.split("\n");
131
+ for (const line of lines) {
132
+ const match = line.match(TASK_LINE_REGEX);
133
+ if (match) {
134
+ const taskId = match[3];
135
+ const isCompleted = match[2].toLowerCase() === "x";
136
+ statuses.set(taskId, isCompleted);
137
+ }
138
+ }
139
+ }
140
+ catch {
141
+ // Return empty map on error
142
+ }
143
+ return statuses;
144
+ }
145
+ /**
146
+ * Write file atomically using temp file + rename pattern
147
+ *
148
+ * @param filePath - Target file path
149
+ * @param content - Content to write
150
+ */
151
+ function writeFileAtomic(filePath, content) {
152
+ const dir = dirname(filePath);
153
+ if (!existsSync(dir)) {
154
+ mkdirSync(dir, { recursive: true });
155
+ }
156
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
157
+ writeFileSync(tempPath, content, "utf-8");
158
+ // Rename is atomic on most file systems
159
+ renameSync(tempPath, filePath);
160
+ }
161
+ //# sourceMappingURL=tasks-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks-writer.js","sourceRoot":"","sources":["../../src/writer/tasks-writer.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@sudocode-ai/integration-speckit",
3
+ "version": "0.1.14",
4
+ "description": "Spec-kit integration plugin for sudocode",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "test": "vitest --run",
20
+ "clean": "rm -rf dist"
21
+ },
22
+ "keywords": [
23
+ "sudocode",
24
+ "integration",
25
+ "spec-kit",
26
+ "plugin"
27
+ ],
28
+ "author": "sudocode-ai",
29
+ "license": "Apache-2.0",
30
+ "dependencies": {
31
+ "chokidar": "^4.0.3"
32
+ },
33
+ "peerDependencies": {
34
+ "@sudocode-ai/types": "^0.1.14"
35
+ },
36
+ "devDependencies": {
37
+ "@sudocode-ai/types": "*",
38
+ "@types/node": "^22.10.2",
39
+ "typescript": "^5.8.3",
40
+ "vitest": "^3.2.4"
41
+ }
42
+ }