@zhuan-ai/zhuanspec 2.11.2 → 2.11.3

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.
@@ -209,6 +209,23 @@ export class ProgressCommand {
209
209
  wave: currentWave,
210
210
  description: description.split('@')[0].trim(), // Remove @skill/@depends tags
211
211
  });
212
+ continue;
213
+ }
214
+ // Match "Task X.Y" format: #### Task 1.0: description or #### Task 1.1: description
215
+ const taskXYMatch = line.match(/^####\s*Task\s+(\d+\.\d+)\s*:\s*(.+)$/i);
216
+ if (taskXYMatch) {
217
+ const taskId = taskXYMatch[1];
218
+ const rawDescription = taskXYMatch[2].trim();
219
+ const isCompleted = rawDescription.endsWith('✅');
220
+ const description = isCompleted
221
+ ? rawDescription.slice(0, -1).trim()
222
+ : rawDescription;
223
+ tasks.push({
224
+ taskId,
225
+ status: isCompleted ? 'completed' : 'pending',
226
+ wave: currentWave,
227
+ description: description.split('@')[0].trim(),
228
+ });
212
229
  }
213
230
  }
214
231
  return tasks;
@@ -542,11 +542,17 @@ async function runRecordProgress(filePath, toolName, success, stdinData) {
542
542
  if (await FileSystemUtils.fileExists(tasksPath)) {
543
543
  try {
544
544
  const tasksContent = await FileSystemUtils.readFile(tasksPath);
545
- const totalTaskMatches = tasksContent.match(/^- \[[ x]\] .+$/gm) || [];
546
- const completedTaskMatches = tasksContent.match(/^- \[x\] .+$/gm) || [];
545
+ // Match checkbox format: - [ ] or - [x], and also #### Task X.Y: format
546
+ const checkboxTasks = tasksContent.match(/^- \[[ x]\] .+$/gm) || [];
547
+ const taskHeaderTasks = tasksContent.match(/^####\s*Task\s+\d+\.\d+\s*:.+$/gm) || [];
548
+ const legacyHeaderTasks = tasksContent.match(/^####\s*T\d+\s*:.+$/gm) || [];
549
+ const totalTaskMatches = checkboxTasks.length > 0 ? checkboxTasks : (taskHeaderTasks.length > 0 ? taskHeaderTasks : legacyHeaderTasks);
550
+ const completedCheckbox = tasksContent.match(/^- \[x\] .+$/gm) || [];
551
+ const completedHeaders = (taskHeaderTasks.length > 0 ? taskHeaderTasks : legacyHeaderTasks).filter(t => t.endsWith('\u2705'));
552
+ const completedTaskMatches = checkboxTasks.length > 0 ? completedCheckbox : completedHeaders;
547
553
  progress.totalTasks = totalTaskMatches.length;
548
554
  // Update completedTasks array with completed task descriptions
549
- const completedDescriptions = completedTaskMatches.map(t => t.replace(/^- \[x\] /, '').trim());
555
+ const completedDescriptions = completedTaskMatches.map(t => t.replace(/^- \[x\] /, '').replace(/^####\s*(?:Task\s+\d+\.\d+|T\d+)\s*:\s*/, '').replace(/\u2705$/, '').trim());
550
556
  if (completedDescriptions.length > 0) {
551
557
  progress.completedTasks = completedDescriptions;
552
558
  }
@@ -2,6 +2,8 @@ import { promises as fs } from 'fs';
2
2
  import path from 'path';
3
3
  const TASK_PATTERN = /^[-*]\s+\[[\sx]\]/i;
4
4
  const COMPLETED_TASK_PATTERN = /^[-*]\s+\[x\]/i;
5
+ const TASK_HEADER_PATTERN = /^####\s*(?:Task\s+\d+\.\d+|T\d+)\s*:/;
6
+ const COMPLETED_HEADER_PATTERN = /^####\s*(?:Task\s+\d+\.\d+|T\d+)\s*:.*\u2705\s*$/;
5
7
  export function countTasksFromContent(content) {
6
8
  const lines = content.split('\n');
7
9
  let total = 0;
@@ -13,6 +15,12 @@ export function countTasksFromContent(content) {
13
15
  completed++;
14
16
  }
15
17
  }
18
+ else if (line.match(TASK_HEADER_PATTERN)) {
19
+ total++;
20
+ if (line.match(COMPLETED_HEADER_PATTERN)) {
21
+ completed++;
22
+ }
23
+ }
16
24
  }
17
25
  return { total, completed };
18
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhuan-ai/zhuanspec",
3
- "version": "2.11.2",
3
+ "version": "2.11.3",
4
4
  "description": "AI-native system for spec-driven development",
5
5
  "keywords": [
6
6
  "zhuanspec",
@@ -39,26 +39,6 @@
39
39
  "!dist/**/__tests__",
40
40
  "!dist/**/*.map"
41
41
  ],
42
- "scripts": {
43
- "lint": "eslint src/",
44
- "build": "node build.js",
45
- "dev": "tsc --watch",
46
- "dev:cli": "pnpm build && node bin/zhuanspec.js",
47
- "test": "vitest run",
48
- "test:watch": "vitest",
49
- "test:ui": "vitest --ui",
50
- "test:coverage": "vitest --coverage",
51
- "test:postinstall": "node scripts/postinstall.js",
52
- "prepare": "npm run build",
53
- "prepublishOnly": "npm run build",
54
- "postinstall": "node scripts/postinstall.js",
55
- "check:pack-version": "node scripts/pack-version-check.mjs",
56
- "diagnose:cursor": "node scripts/diagnose-cursor-commands.js",
57
- "release": "pnpm run release:ci",
58
- "release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
59
- "release:local": "pnpm exec changeset version && pnpm run check:pack-version && pnpm exec changeset publish",
60
- "changeset": "changeset"
61
- },
62
42
  "engines": {
63
43
  "node": ">=20.19.0"
64
44
  },
@@ -80,5 +60,23 @@
80
60
  "ora": "^8.2.0",
81
61
  "yaml": "^2.8.2",
82
62
  "zod": "^4.0.17"
63
+ },
64
+ "scripts": {
65
+ "lint": "eslint src/",
66
+ "build": "node build.js",
67
+ "dev": "tsc --watch",
68
+ "dev:cli": "pnpm build && node bin/zhuanspec.js",
69
+ "test": "vitest run",
70
+ "test:watch": "vitest",
71
+ "test:ui": "vitest --ui",
72
+ "test:coverage": "vitest --coverage",
73
+ "test:postinstall": "node scripts/postinstall.js",
74
+ "postinstall": "node scripts/postinstall.js",
75
+ "check:pack-version": "node scripts/pack-version-check.mjs",
76
+ "diagnose:cursor": "node scripts/diagnose-cursor-commands.js",
77
+ "release": "pnpm run release:ci",
78
+ "release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
79
+ "release:local": "pnpm exec changeset version && pnpm run check:pack-version && pnpm exec changeset publish",
80
+ "changeset": "changeset"
83
81
  }
84
- }
82
+ }