@pixelcraft-tw/spec 1.0.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 (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/bin/pxs.d.ts +2 -0
  4. package/dist/bin/pxs.js +5 -0
  5. package/dist/bin/pxs.js.map +1 -0
  6. package/dist/src/backends/claude.d.ts +9 -0
  7. package/dist/src/backends/claude.js +80 -0
  8. package/dist/src/backends/claude.js.map +1 -0
  9. package/dist/src/backends/codex.d.ts +9 -0
  10. package/dist/src/backends/codex.js +72 -0
  11. package/dist/src/backends/codex.js.map +1 -0
  12. package/dist/src/backends/factory.d.ts +2 -0
  13. package/dist/src/backends/factory.js +14 -0
  14. package/dist/src/backends/factory.js.map +1 -0
  15. package/dist/src/backends/interface.d.ts +15 -0
  16. package/dist/src/backends/interface.js +2 -0
  17. package/dist/src/backends/interface.js.map +1 -0
  18. package/dist/src/cli.d.ts +2 -0
  19. package/dist/src/cli.js +94 -0
  20. package/dist/src/cli.js.map +1 -0
  21. package/dist/src/commands/clarify.d.ts +5 -0
  22. package/dist/src/commands/clarify.js +46 -0
  23. package/dist/src/commands/clarify.js.map +1 -0
  24. package/dist/src/commands/diff.d.ts +1 -0
  25. package/dist/src/commands/diff.js +81 -0
  26. package/dist/src/commands/diff.js.map +1 -0
  27. package/dist/src/commands/implement.d.ts +9 -0
  28. package/dist/src/commands/implement.js +247 -0
  29. package/dist/src/commands/implement.js.map +1 -0
  30. package/dist/src/commands/init.d.ts +6 -0
  31. package/dist/src/commands/init.js +183 -0
  32. package/dist/src/commands/init.js.map +1 -0
  33. package/dist/src/commands/new.d.ts +5 -0
  34. package/dist/src/commands/new.js +186 -0
  35. package/dist/src/commands/new.js.map +1 -0
  36. package/dist/src/commands/refine.d.ts +8 -0
  37. package/dist/src/commands/refine.js +158 -0
  38. package/dist/src/commands/refine.js.map +1 -0
  39. package/dist/src/commands/reset.d.ts +3 -0
  40. package/dist/src/commands/reset.js +44 -0
  41. package/dist/src/commands/reset.js.map +1 -0
  42. package/dist/src/commands/review.d.ts +4 -0
  43. package/dist/src/commands/review.js +70 -0
  44. package/dist/src/commands/review.js.map +1 -0
  45. package/dist/src/commands/status.d.ts +1 -0
  46. package/dist/src/commands/status.js +53 -0
  47. package/dist/src/commands/status.js.map +1 -0
  48. package/dist/src/discovery/project.d.ts +7 -0
  49. package/dist/src/discovery/project.js +135 -0
  50. package/dist/src/discovery/project.js.map +1 -0
  51. package/dist/src/git/operations.d.ts +10 -0
  52. package/dist/src/git/operations.js +56 -0
  53. package/dist/src/git/operations.js.map +1 -0
  54. package/dist/src/parsers/arguments.d.ts +18 -0
  55. package/dist/src/parsers/arguments.js +43 -0
  56. package/dist/src/parsers/arguments.js.map +1 -0
  57. package/dist/src/parsers/plan.d.ts +23 -0
  58. package/dist/src/parsers/plan.js +117 -0
  59. package/dist/src/parsers/plan.js.map +1 -0
  60. package/dist/src/parsers/spec.d.ts +10 -0
  61. package/dist/src/parsers/spec.js +46 -0
  62. package/dist/src/parsers/spec.js.map +1 -0
  63. package/dist/src/state/manager.d.ts +24 -0
  64. package/dist/src/state/manager.js +103 -0
  65. package/dist/src/state/manager.js.map +1 -0
  66. package/dist/src/state/types.d.ts +48 -0
  67. package/dist/src/state/types.js +20 -0
  68. package/dist/src/state/types.js.map +1 -0
  69. package/dist/src/utils/display.d.ts +7 -0
  70. package/dist/src/utils/display.js +42 -0
  71. package/dist/src/utils/display.js.map +1 -0
  72. package/dist/src/utils/prompt.d.ts +15 -0
  73. package/dist/src/utils/prompt.js +139 -0
  74. package/dist/src/utils/prompt.js.map +1 -0
  75. package/package.json +52 -0
  76. package/templates/agents-md-snippet.md +20 -0
  77. package/templates/architectures/clean/csharp-aspnet.md +56 -0
  78. package/templates/architectures/clean/dart-flutter.md +73 -0
  79. package/templates/architectures/clean/go-gin.md +50 -0
  80. package/templates/architectures/clean/go-std.md +49 -0
  81. package/templates/architectures/clean/kotlin-android.md +70 -0
  82. package/templates/architectures/clean/python-fastapi.md +49 -0
  83. package/templates/architectures/clean/swift-ios.md +69 -0
  84. package/templates/architectures/clean/typescript-express.md +60 -0
  85. package/templates/architectures/clean/typescript-nestjs.md +61 -0
  86. package/templates/architectures/ddd/csharp-aspnet.md +55 -0
  87. package/templates/architectures/ddd/go-gin.md +53 -0
  88. package/templates/architectures/ddd/python-fastapi.md +52 -0
  89. package/templates/architectures/ddd/typescript-nestjs.md +62 -0
  90. package/templates/architectures/hexagonal/csharp-aspnet.md +45 -0
  91. package/templates/architectures/hexagonal/go-gin.md +47 -0
  92. package/templates/architectures/hexagonal/python-fastapi.md +43 -0
  93. package/templates/architectures/hexagonal/typescript-nestjs.md +44 -0
  94. package/templates/architectures/layered/csharp-aspnet.md +45 -0
  95. package/templates/architectures/layered/go-gin.md +41 -0
  96. package/templates/architectures/layered/python-fastapi.md +42 -0
  97. package/templates/architectures/layered/typescript-nestjs.md +48 -0
  98. package/templates/architectures/modular/csharp-aspnet.md +45 -0
  99. package/templates/architectures/modular/dart-flutter.md +64 -0
  100. package/templates/architectures/modular/go-gin.md +47 -0
  101. package/templates/architectures/modular/kotlin-android.md +68 -0
  102. package/templates/architectures/modular/python-fastapi.md +45 -0
  103. package/templates/architectures/modular/swift-ios.md +55 -0
  104. package/templates/architectures/modular/typescript-nestjs.md +48 -0
  105. package/templates/architectures/mvvm/dart-flutter.md +69 -0
  106. package/templates/architectures/mvvm/kotlin-android.md +79 -0
  107. package/templates/architectures/mvvm/swift-ios.md +66 -0
  108. package/templates/claude-commands/sf.clarify.md +18 -0
  109. package/templates/claude-commands/sf.implement.md +80 -0
  110. package/templates/claude-commands/sf.new.md +22 -0
  111. package/templates/claude-commands/sf.refine.md +47 -0
  112. package/templates/claude-commands/sf.review.md +17 -0
  113. package/templates/claude-commands/sf.status.md +12 -0
  114. package/templates/workflow/config.yaml +17 -0
  115. package/templates/workflow/prompts/clarify.md +39 -0
  116. package/templates/workflow/prompts/final-review.md +30 -0
  117. package/templates/workflow/prompts/implement-tdd.md +35 -0
  118. package/templates/workflow/prompts/implement.md +43 -0
  119. package/templates/workflow/prompts/refine.md +52 -0
  120. package/templates/workflow/prompts/review.md +33 -0
  121. package/templates/workflow/prompts/test.md +14 -0
  122. package/templates/workflow/templates/spec-template.md +13 -0
@@ -0,0 +1,135 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export function detectProject(cwd = process.cwd()) {
4
+ const info = {
5
+ name: path.basename(cwd),
6
+ language: '',
7
+ framework: '',
8
+ lang_framework: '',
9
+ };
10
+ // Flutter (must come before Node.js — Flutter uses pubspec.yaml, not package.json)
11
+ const pubspecPath = path.join(cwd, 'pubspec.yaml');
12
+ if (fs.existsSync(pubspecPath)) {
13
+ const content = fs.readFileSync(pubspecPath, 'utf-8');
14
+ if (content.includes('flutter:') || content.includes('sdk: flutter')) {
15
+ const nameMatch = content.match(/^name:\s*(.+)$/m);
16
+ if (nameMatch) {
17
+ info.name = nameMatch[1].trim();
18
+ }
19
+ info.language = 'dart';
20
+ info.framework = 'flutter';
21
+ info.lang_framework = 'dart-flutter';
22
+ return info;
23
+ }
24
+ }
25
+ // Node.js / TypeScript
26
+ const pkgPath = path.join(cwd, 'package.json');
27
+ if (fs.existsSync(pkgPath)) {
28
+ try {
29
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
30
+ info.name = pkg.name || info.name;
31
+ info.language = 'typescript';
32
+ info.framework = 'node';
33
+ info.lang_framework = detectNodeFramework(pkg);
34
+ }
35
+ catch {
36
+ // ignore parse error
37
+ }
38
+ return info;
39
+ }
40
+ // Go
41
+ const goModPath = path.join(cwd, 'go.mod');
42
+ if (fs.existsSync(goModPath)) {
43
+ const content = fs.readFileSync(goModPath, 'utf-8');
44
+ const moduleMatch = content.match(/^module\s+(.+)$/m);
45
+ if (moduleMatch) {
46
+ info.name = moduleMatch[1].trim();
47
+ }
48
+ info.language = 'go';
49
+ info.framework = 'go';
50
+ info.lang_framework = detectGoFramework(content);
51
+ return info;
52
+ }
53
+ // Python
54
+ const reqPath = path.join(cwd, 'requirements.txt');
55
+ if (fs.existsSync(reqPath)) {
56
+ const content = fs.readFileSync(reqPath, 'utf-8');
57
+ info.language = 'python';
58
+ info.framework = 'python';
59
+ info.lang_framework = detectPythonFramework(content);
60
+ return info;
61
+ }
62
+ // C# / .NET
63
+ const csprojFiles = fs.readdirSync(cwd).filter((f) => f.endsWith('.csproj'));
64
+ if (csprojFiles.length > 0) {
65
+ info.name = csprojFiles[0].replace('.csproj', '');
66
+ info.language = 'csharp';
67
+ info.framework = 'dotnet';
68
+ const content = fs.readFileSync(path.join(cwd, csprojFiles[0]), 'utf-8');
69
+ info.lang_framework = detectCsharpFramework(content);
70
+ return info;
71
+ }
72
+ // iOS (*.xcodeproj directory at root)
73
+ const entries = fs.readdirSync(cwd);
74
+ const xcodeprojDir = entries.find((e) => e.endsWith('.xcodeproj'));
75
+ if (xcodeprojDir) {
76
+ const stat = fs.statSync(path.join(cwd, xcodeprojDir));
77
+ if (stat.isDirectory()) {
78
+ info.name = xcodeprojDir.replace('.xcodeproj', '');
79
+ info.language = 'swift';
80
+ info.framework = 'ios';
81
+ info.lang_framework = 'swift-ios';
82
+ return info;
83
+ }
84
+ }
85
+ // Android (build.gradle.kts or build.gradle with android plugin)
86
+ const gradleKts = path.join(cwd, 'build.gradle.kts');
87
+ const gradleGroovy = path.join(cwd, 'build.gradle');
88
+ const gradlePath = fs.existsSync(gradleKts) ? gradleKts : fs.existsSync(gradleGroovy) ? gradleGroovy : null;
89
+ if (gradlePath) {
90
+ const content = fs.readFileSync(gradlePath, 'utf-8');
91
+ if (content.includes('com.android.application') || content.includes('com.android.library')) {
92
+ const nameMatch = content.match(/namespace\s*=?\s*["']([^"']+)["']/);
93
+ if (nameMatch) {
94
+ info.name = nameMatch[1].split('.').pop() || info.name;
95
+ }
96
+ info.language = 'kotlin';
97
+ info.framework = 'android';
98
+ info.lang_framework = 'kotlin-android';
99
+ return info;
100
+ }
101
+ }
102
+ return info;
103
+ }
104
+ function detectNodeFramework(pkg) {
105
+ const deps = {
106
+ ...pkg.dependencies,
107
+ ...pkg.devDependencies,
108
+ };
109
+ if (deps['@nestjs/core'])
110
+ return 'typescript-nestjs';
111
+ if (deps['express'])
112
+ return 'typescript-express';
113
+ return 'typescript-express';
114
+ }
115
+ function detectGoFramework(goMod) {
116
+ if (goMod.includes('github.com/gin-gonic/gin'))
117
+ return 'go-gin';
118
+ if (goMod.includes('github.com/go-chi/chi'))
119
+ return 'go-chi';
120
+ return 'go-std';
121
+ }
122
+ function detectPythonFramework(requirements) {
123
+ const lower = requirements.toLowerCase();
124
+ if (lower.includes('fastapi'))
125
+ return 'python-fastapi';
126
+ if (lower.includes('django'))
127
+ return 'python-django';
128
+ return 'python-std';
129
+ }
130
+ function detectCsharpFramework(csproj) {
131
+ if (csproj.includes('Microsoft.AspNetCore'))
132
+ return 'csharp-aspnet';
133
+ return 'csharp-dotnet';
134
+ }
135
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/discovery/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare function gitBranch(branchName: string, cwd?: string): void;
2
+ export declare function gitCheckout(branchName: string, cwd?: string): void;
3
+ export declare function gitCurrentBranch(cwd?: string): string;
4
+ export declare function gitCommit(message: string, cwd?: string): void;
5
+ export declare function gitDiff(from?: string, to?: string, cwd?: string): string;
6
+ export declare function gitStatus(cwd?: string): string;
7
+ export declare function gitMerge(branch: string, squash?: boolean, cwd?: string): void;
8
+ export declare function gitLog(n?: number, cwd?: string): string;
9
+ export declare function gitDiffBranch(base?: string, cwd?: string): string;
10
+ export declare function isGitRepo(cwd?: string): boolean;
@@ -0,0 +1,56 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ function run(cmd, args, cwd) {
3
+ return execFileSync(cmd, args, {
4
+ cwd: cwd ?? process.cwd(),
5
+ encoding: 'utf-8',
6
+ }).trim();
7
+ }
8
+ export function gitBranch(branchName, cwd) {
9
+ run('git', ['checkout', '-b', branchName], cwd);
10
+ }
11
+ export function gitCheckout(branchName, cwd) {
12
+ run('git', ['checkout', branchName], cwd);
13
+ }
14
+ export function gitCurrentBranch(cwd) {
15
+ return run('git', ['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
16
+ }
17
+ export function gitCommit(message, cwd) {
18
+ run('git', ['add', '-A'], cwd);
19
+ run('git', ['commit', '-m', message], cwd);
20
+ }
21
+ export function gitDiff(from, to, cwd) {
22
+ if (from && to) {
23
+ return run('git', ['diff', `${from}..${to}`], cwd);
24
+ }
25
+ if (from) {
26
+ return run('git', ['diff', from], cwd);
27
+ }
28
+ return run('git', ['diff', 'HEAD~1'], cwd);
29
+ }
30
+ export function gitStatus(cwd) {
31
+ return run('git', ['status', '--short'], cwd);
32
+ }
33
+ export function gitMerge(branch, squash = false, cwd) {
34
+ const args = ['merge'];
35
+ if (squash)
36
+ args.push('--squash');
37
+ args.push(branch);
38
+ run('git', args, cwd);
39
+ }
40
+ export function gitLog(n = 5, cwd) {
41
+ return run('git', ['log', '--oneline', `-${n}`], cwd);
42
+ }
43
+ export function gitDiffBranch(base = 'main', cwd) {
44
+ const mergeBase = run('git', ['merge-base', base, 'HEAD'], cwd);
45
+ return run('git', ['diff', mergeBase], cwd);
46
+ }
47
+ export function isGitRepo(cwd) {
48
+ try {
49
+ run('git', ['rev-parse', '--is-inside-work-tree'], cwd);
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../../src/git/operations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface ParsedArgs {
2
+ name: string;
3
+ agents: string[];
4
+ skills: string[];
5
+ text: string;
6
+ options: Record<string, string | boolean | string[]>;
7
+ }
8
+ /**
9
+ * Parse variadic CLI arguments into structured parts.
10
+ *
11
+ * Rules:
12
+ * - First word not starting with @, /, or -- is <name>
13
+ * - Words starting with @ are agent references (e.g., @architect)
14
+ * - Words starting with / are skill/MCP references (e.g., /mysql)
15
+ * - Words starting with -- are options (handled by commander, but we parse leftovers)
16
+ * - Remaining text is supplementary instructions
17
+ */
18
+ export declare function parseArgs(args: string[]): ParsedArgs;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Parse variadic CLI arguments into structured parts.
3
+ *
4
+ * Rules:
5
+ * - First word not starting with @, /, or -- is <name>
6
+ * - Words starting with @ are agent references (e.g., @architect)
7
+ * - Words starting with / are skill/MCP references (e.g., /mysql)
8
+ * - Words starting with -- are options (handled by commander, but we parse leftovers)
9
+ * - Remaining text is supplementary instructions
10
+ */
11
+ export function parseArgs(args) {
12
+ const result = {
13
+ name: '',
14
+ agents: [],
15
+ skills: [],
16
+ text: '',
17
+ options: {},
18
+ };
19
+ const textParts = [];
20
+ let nameFound = false;
21
+ for (const arg of args) {
22
+ if (arg.startsWith('@')) {
23
+ result.agents.push(arg.slice(1));
24
+ }
25
+ else if (arg.startsWith('/')) {
26
+ result.skills.push(arg.slice(1));
27
+ }
28
+ else if (arg.startsWith('--')) {
29
+ // Skip option flags (handled by commander)
30
+ continue;
31
+ }
32
+ else if (!nameFound) {
33
+ result.name = arg;
34
+ nameFound = true;
35
+ }
36
+ else {
37
+ textParts.push(arg);
38
+ }
39
+ }
40
+ result.text = textParts.join(' ');
41
+ return result;
42
+ }
43
+ //# sourceMappingURL=arguments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arguments.js","sourceRoot":"","sources":["../../../src/parsers/arguments.ts"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,MAAM,GAAe;QACzB,IAAI,EAAE,EAAE;QACR,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,EAAE;QACR,OAAO,EAAE,EAAE;KACZ,CAAC;IAEF,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,2CAA2C;YAC3C,SAAS;QACX,CAAC;aAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC;YAClB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { FeatureType } from '../state/types.js';
2
+ export interface PlanTask {
3
+ number: number;
4
+ title: string;
5
+ files: string[];
6
+ description: string;
7
+ dependsOn: string;
8
+ complexity: string;
9
+ acceptance: string;
10
+ raw: string;
11
+ }
12
+ export interface ParsedPlan {
13
+ name: string;
14
+ type: FeatureType;
15
+ branch: string;
16
+ totalTasks: number;
17
+ tasks: PlanTask[];
18
+ raw: string;
19
+ }
20
+ /**
21
+ * Parse a plan markdown file into structured tasks.
22
+ */
23
+ export declare function parsePlan(content: string): ParsedPlan;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Parse a plan markdown file into structured tasks.
3
+ */
4
+ export function parsePlan(content) {
5
+ const result = {
6
+ name: '',
7
+ type: 'feat',
8
+ branch: '',
9
+ totalTasks: 0,
10
+ tasks: [],
11
+ raw: content,
12
+ };
13
+ const lines = content.split('\n');
14
+ // Extract metadata from blockquotes at top
15
+ for (const line of lines) {
16
+ const typeMatch = line.match(/^>\s*type:\s*(.+)/);
17
+ if (typeMatch) {
18
+ result.type = typeMatch[1].trim();
19
+ }
20
+ const branchMatch = line.match(/^>\s*branch:\s*(.+)/);
21
+ if (branchMatch) {
22
+ result.branch = branchMatch[1].trim();
23
+ }
24
+ const totalMatch = line.match(/^>\s*total_tasks:\s*(\d+)/);
25
+ if (totalMatch) {
26
+ result.totalTasks = parseInt(totalMatch[1], 10);
27
+ }
28
+ const titleMatch = line.match(/^#\s+Implementation Plan:\s*(.+)/);
29
+ if (titleMatch) {
30
+ result.name = titleMatch[1].trim();
31
+ }
32
+ }
33
+ // Split into task sections by H2
34
+ const taskRegex = /^##\s+Task\s+(\d+):\s*(.+)/;
35
+ let currentTask = null;
36
+ const taskLines = [];
37
+ for (const line of lines) {
38
+ const taskMatch = line.match(taskRegex);
39
+ if (taskMatch) {
40
+ if (currentTask) {
41
+ currentTask.raw = taskLines.join('\n').trim();
42
+ parseTaskFields(currentTask, taskLines);
43
+ result.tasks.push(currentTask);
44
+ }
45
+ currentTask = {
46
+ number: parseInt(taskMatch[1], 10),
47
+ title: taskMatch[2].trim(),
48
+ files: [],
49
+ description: '',
50
+ dependsOn: 'None',
51
+ complexity: 'Medium',
52
+ acceptance: '',
53
+ raw: '',
54
+ };
55
+ taskLines.length = 0;
56
+ }
57
+ else if (currentTask) {
58
+ taskLines.push(line);
59
+ }
60
+ }
61
+ // Flush last task
62
+ if (currentTask) {
63
+ currentTask.raw = taskLines.join('\n').trim();
64
+ parseTaskFields(currentTask, taskLines);
65
+ result.tasks.push(currentTask);
66
+ }
67
+ if (result.totalTasks === 0) {
68
+ result.totalTasks = result.tasks.length;
69
+ }
70
+ return result;
71
+ }
72
+ function parseTaskFields(task, lines) {
73
+ let currentField = '';
74
+ const fieldLines = [];
75
+ for (const line of lines) {
76
+ const fieldMatch = line.match(/^-\s+\*\*(\w[\w\s]*)\*\*:\s*(.*)/);
77
+ if (fieldMatch) {
78
+ flushField(task, currentField, fieldLines);
79
+ currentField = fieldMatch[1].trim();
80
+ fieldLines.length = 0;
81
+ const value = fieldMatch[2].trim();
82
+ if (value)
83
+ fieldLines.push(value);
84
+ }
85
+ else if (currentField && line.match(/^\s+-\s+/)) {
86
+ // Sub-list items (like file paths)
87
+ fieldLines.push(line.replace(/^\s+-\s+/, '').trim());
88
+ }
89
+ else if (currentField && line.trim()) {
90
+ fieldLines.push(line.trim());
91
+ }
92
+ }
93
+ flushField(task, currentField, fieldLines);
94
+ }
95
+ function flushField(task, field, lines) {
96
+ if (!field)
97
+ return;
98
+ const value = lines.join('\n').trim();
99
+ switch (field.toLowerCase()) {
100
+ case 'files':
101
+ task.files = lines.map((l) => l.replace(/`/g, '').replace(/\s*\(.*\)$/, '').trim());
102
+ break;
103
+ case 'description':
104
+ task.description = value;
105
+ break;
106
+ case 'depends on':
107
+ task.dependsOn = value || 'None';
108
+ break;
109
+ case 'complexity':
110
+ task.complexity = value;
111
+ break;
112
+ case 'acceptance':
113
+ task.acceptance = value;
114
+ break;
115
+ }
116
+ }
117
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/parsers/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface ParsedSpec {
2
+ title: string;
3
+ source?: string;
4
+ sections: Record<string, string>;
5
+ raw: string;
6
+ }
7
+ /**
8
+ * Parse a spec markdown file into structured sections.
9
+ */
10
+ export declare function parseSpec(content: string): ParsedSpec;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Parse a spec markdown file into structured sections.
3
+ */
4
+ export function parseSpec(content) {
5
+ const lines = content.split('\n');
6
+ const result = {
7
+ title: '',
8
+ sections: {},
9
+ raw: content,
10
+ };
11
+ let currentSection = '';
12
+ const sectionLines = [];
13
+ for (const line of lines) {
14
+ // Extract title from first H1
15
+ const h1Match = line.match(/^#\s+(?:Feature:\s*)?(.+)/);
16
+ if (h1Match && !result.title) {
17
+ result.title = h1Match[1].trim();
18
+ continue;
19
+ }
20
+ // Extract source from blockquote
21
+ const sourceMatch = line.match(/^>\s*source:\s*(.+)/);
22
+ if (sourceMatch) {
23
+ result.source = sourceMatch[1].trim();
24
+ continue;
25
+ }
26
+ // Detect H2 sections
27
+ const h2Match = line.match(/^##\s+(.+)/);
28
+ if (h2Match) {
29
+ if (currentSection && sectionLines.length > 0) {
30
+ result.sections[currentSection] = sectionLines.join('\n').trim();
31
+ }
32
+ currentSection = h2Match[1].trim();
33
+ sectionLines.length = 0;
34
+ continue;
35
+ }
36
+ if (currentSection) {
37
+ sectionLines.push(line);
38
+ }
39
+ }
40
+ // Flush last section
41
+ if (currentSection && sectionLines.length > 0) {
42
+ result.sections[currentSection] = sectionLines.join('\n').trim();
43
+ }
44
+ return result;
45
+ }
46
+ //# sourceMappingURL=spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../src/parsers/spec.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAe;QACzB,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,EAAE;QACZ,GAAG,EAAE,OAAO;KACb,CAAC;IAEF,IAAI,cAAc,GAAG,EAAE,CAAC;IACxB,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,8BAA8B;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACxD,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACjC,SAAS;QACX,CAAC;QAED,iCAAiC;QACjC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACtD,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QAED,qBAAqB;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACzC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,cAAc,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACnE,CAAC;YACD,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACnC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;YACxB,SAAS;QACX,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACnB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,IAAI,cAAc,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type WorkflowState, type FeatureState, type ProjectConfig } from './types.js';
2
+ export declare class StateManager {
3
+ private cwd;
4
+ private workflowDir;
5
+ constructor(cwd?: string);
6
+ get statePath(): string;
7
+ get configPath(): string;
8
+ workflowExists(): boolean;
9
+ ensureWorkflow(): void;
10
+ readState(): WorkflowState;
11
+ writeState(state: WorkflowState): void;
12
+ getFeature(name: string): FeatureState | undefined;
13
+ upsertFeature(feature: FeatureState): void;
14
+ checkPhaseGuard(command: string, featureName: string): void;
15
+ readConfig(): ProjectConfig;
16
+ specsDir(): string;
17
+ plansDir(): string;
18
+ reviewsDir(): string;
19
+ promptsDir(): string;
20
+ templatesDir(): string;
21
+ specPath(name: string): string;
22
+ planPath(name: string): string;
23
+ reviewPath(name: string, taskN: number): string;
24
+ }
@@ -0,0 +1,103 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import yaml from 'js-yaml';
4
+ import { PHASE_GUARDS, } from './types.js';
5
+ const WORKFLOW_DIR = '.workflow';
6
+ const STATE_FILE = 'state.yaml';
7
+ const CONFIG_FILE = 'config.yaml';
8
+ export class StateManager {
9
+ cwd;
10
+ workflowDir;
11
+ constructor(cwd = process.cwd()) {
12
+ this.cwd = cwd;
13
+ this.workflowDir = path.join(cwd, WORKFLOW_DIR);
14
+ }
15
+ get statePath() {
16
+ return path.join(this.workflowDir, STATE_FILE);
17
+ }
18
+ get configPath() {
19
+ return path.join(this.workflowDir, CONFIG_FILE);
20
+ }
21
+ workflowExists() {
22
+ return fs.existsSync(this.workflowDir);
23
+ }
24
+ ensureWorkflow() {
25
+ if (!this.workflowExists()) {
26
+ throw new Error('Workflow not initialized. Run `pxs init` first.');
27
+ }
28
+ }
29
+ readState() {
30
+ if (!fs.existsSync(this.statePath)) {
31
+ return { features: [] };
32
+ }
33
+ const content = fs.readFileSync(this.statePath, 'utf-8');
34
+ const data = yaml.load(content);
35
+ return data ?? { features: [] };
36
+ }
37
+ writeState(state) {
38
+ this.ensureWorkflow();
39
+ const content = yaml.dump(state, { lineWidth: -1, noRefs: true });
40
+ fs.writeFileSync(this.statePath, content, 'utf-8');
41
+ }
42
+ getFeature(name) {
43
+ const state = this.readState();
44
+ return state.features.find((f) => f.feature === name);
45
+ }
46
+ upsertFeature(feature) {
47
+ const state = this.readState();
48
+ const idx = state.features.findIndex((f) => f.feature === feature.feature);
49
+ if (idx >= 0) {
50
+ state.features[idx] = feature;
51
+ }
52
+ else {
53
+ state.features.push(feature);
54
+ }
55
+ this.writeState(state);
56
+ }
57
+ checkPhaseGuard(command, featureName) {
58
+ const allowedPhases = PHASE_GUARDS[command];
59
+ if (!allowedPhases || allowedPhases.length === 0)
60
+ return; // any phase allowed
61
+ const feature = this.getFeature(featureName);
62
+ if (!feature) {
63
+ throw new Error(`Feature "${featureName}" not found in state. Run \`pxs new ${featureName}\` first.`);
64
+ }
65
+ if (!allowedPhases.includes(feature.phase)) {
66
+ throw new Error(`Command "pxs ${command}" cannot run in phase "${feature.phase}". ` +
67
+ `Allowed phases: ${allowedPhases.join(', ')}`);
68
+ }
69
+ }
70
+ readConfig() {
71
+ if (!fs.existsSync(this.configPath)) {
72
+ throw new Error('Config not found. Run `pxs init` first.');
73
+ }
74
+ const content = fs.readFileSync(this.configPath, 'utf-8');
75
+ return yaml.load(content);
76
+ }
77
+ // Helper paths
78
+ specsDir() {
79
+ return path.join(this.workflowDir, 'specs');
80
+ }
81
+ plansDir() {
82
+ return path.join(this.workflowDir, 'plans');
83
+ }
84
+ reviewsDir() {
85
+ return path.join(this.workflowDir, 'reviews');
86
+ }
87
+ promptsDir() {
88
+ return path.join(this.workflowDir, 'prompts');
89
+ }
90
+ templatesDir() {
91
+ return path.join(this.workflowDir, 'templates');
92
+ }
93
+ specPath(name) {
94
+ return path.join(this.specsDir(), `${name}.md`);
95
+ }
96
+ planPath(name) {
97
+ return path.join(this.plansDir(), `${name}.md`);
98
+ }
99
+ reviewPath(name, taskN) {
100
+ return path.join(this.reviewsDir(), `${name}-task-${taskN}.md`);
101
+ }
102
+ }
103
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/state/manager.ts"],"names":[],"mappings":"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"}