@pixel613/spec 1.0.1

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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -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 +79 -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/implement.d.ts +9 -0
  25. package/dist/src/commands/implement.js +244 -0
  26. package/dist/src/commands/implement.js.map +1 -0
  27. package/dist/src/commands/init.d.ts +6 -0
  28. package/dist/src/commands/init.js +177 -0
  29. package/dist/src/commands/init.js.map +1 -0
  30. package/dist/src/commands/new.d.ts +5 -0
  31. package/dist/src/commands/new.js +143 -0
  32. package/dist/src/commands/new.js.map +1 -0
  33. package/dist/src/commands/refine.d.ts +8 -0
  34. package/dist/src/commands/refine.js +158 -0
  35. package/dist/src/commands/refine.js.map +1 -0
  36. package/dist/src/commands/review.d.ts +4 -0
  37. package/dist/src/commands/review.js +70 -0
  38. package/dist/src/commands/review.js.map +1 -0
  39. package/dist/src/commands/status.d.ts +1 -0
  40. package/dist/src/commands/status.js +53 -0
  41. package/dist/src/commands/status.js.map +1 -0
  42. package/dist/src/discovery/project.d.ts +7 -0
  43. package/dist/src/discovery/project.js +90 -0
  44. package/dist/src/discovery/project.js.map +1 -0
  45. package/dist/src/git/operations.d.ts +10 -0
  46. package/dist/src/git/operations.js +56 -0
  47. package/dist/src/git/operations.js.map +1 -0
  48. package/dist/src/parsers/arguments.d.ts +18 -0
  49. package/dist/src/parsers/arguments.js +43 -0
  50. package/dist/src/parsers/arguments.js.map +1 -0
  51. package/dist/src/parsers/plan.d.ts +23 -0
  52. package/dist/src/parsers/plan.js +117 -0
  53. package/dist/src/parsers/plan.js.map +1 -0
  54. package/dist/src/parsers/spec.d.ts +10 -0
  55. package/dist/src/parsers/spec.js +46 -0
  56. package/dist/src/parsers/spec.js.map +1 -0
  57. package/dist/src/state/manager.d.ts +24 -0
  58. package/dist/src/state/manager.js +103 -0
  59. package/dist/src/state/manager.js.map +1 -0
  60. package/dist/src/state/types.d.ts +47 -0
  61. package/dist/src/state/types.js +21 -0
  62. package/dist/src/state/types.js.map +1 -0
  63. package/dist/src/utils/display.d.ts +7 -0
  64. package/dist/src/utils/display.js +42 -0
  65. package/dist/src/utils/display.js.map +1 -0
  66. package/dist/src/utils/prompt.d.ts +31 -0
  67. package/dist/src/utils/prompt.js +81 -0
  68. package/dist/src/utils/prompt.js.map +1 -0
  69. package/package.json +52 -0
  70. package/templates/agents-md-snippet.md +20 -0
  71. package/templates/architectures/clean/csharp-aspnet.md +56 -0
  72. package/templates/architectures/clean/go-gin.md +50 -0
  73. package/templates/architectures/clean/go-std.md +49 -0
  74. package/templates/architectures/clean/python-fastapi.md +49 -0
  75. package/templates/architectures/clean/typescript-express.md +60 -0
  76. package/templates/architectures/clean/typescript-nestjs.md +61 -0
  77. package/templates/architectures/ddd/csharp-aspnet.md +55 -0
  78. package/templates/architectures/ddd/go-gin.md +53 -0
  79. package/templates/architectures/ddd/python-fastapi.md +52 -0
  80. package/templates/architectures/ddd/typescript-nestjs.md +62 -0
  81. package/templates/architectures/hexagonal/csharp-aspnet.md +45 -0
  82. package/templates/architectures/hexagonal/go-gin.md +47 -0
  83. package/templates/architectures/hexagonal/python-fastapi.md +43 -0
  84. package/templates/architectures/hexagonal/typescript-nestjs.md +44 -0
  85. package/templates/architectures/layered/csharp-aspnet.md +45 -0
  86. package/templates/architectures/layered/go-gin.md +41 -0
  87. package/templates/architectures/layered/python-fastapi.md +42 -0
  88. package/templates/architectures/layered/typescript-nestjs.md +48 -0
  89. package/templates/architectures/modular/csharp-aspnet.md +45 -0
  90. package/templates/architectures/modular/go-gin.md +47 -0
  91. package/templates/architectures/modular/python-fastapi.md +45 -0
  92. package/templates/architectures/modular/typescript-nestjs.md +48 -0
  93. package/templates/claude-commands/sf.clarify.md +18 -0
  94. package/templates/claude-commands/sf.implement.md +79 -0
  95. package/templates/claude-commands/sf.new.md +22 -0
  96. package/templates/claude-commands/sf.refine.md +47 -0
  97. package/templates/claude-commands/sf.review.md +17 -0
  98. package/templates/claude-commands/sf.status.md +12 -0
  99. package/templates/workflow/config.yaml +17 -0
  100. package/templates/workflow/prompts/clarify.md +39 -0
  101. package/templates/workflow/prompts/final-review.md +30 -0
  102. package/templates/workflow/prompts/implement-tdd.md +35 -0
  103. package/templates/workflow/prompts/implement.md +43 -0
  104. package/templates/workflow/prompts/refine.md +52 -0
  105. package/templates/workflow/prompts/review.md +34 -0
  106. package/templates/workflow/prompts/test.md +14 -0
  107. package/templates/workflow/templates/spec-template.md +13 -0
@@ -0,0 +1,158 @@
1
+ import fs from 'node:fs';
2
+ import inquirer from 'inquirer';
3
+ import { StateManager } from '../state/manager.js';
4
+ import { createBackend } from '../backends/factory.js';
5
+ import { assemblePrompt } from '../utils/prompt.js';
6
+ import { parsePlan } from '../parsers/plan.js';
7
+ import * as display from '../utils/display.js';
8
+ export async function refineCommand(name, args, options) {
9
+ const state = new StateManager();
10
+ state.ensureWorkflow();
11
+ state.checkPhaseGuard('refine', name);
12
+ const specPath = state.specPath(name);
13
+ if (!fs.existsSync(specPath)) {
14
+ display.error(`Spec "${name}" not found. Run \`pxs new ${name}\` first.`);
15
+ return;
16
+ }
17
+ const config = state.readConfig();
18
+ const backend = createBackend(config.backend.default);
19
+ if (!(await backend.isAvailable())) {
20
+ display.error(`Backend "${config.backend.default}" not available.`);
21
+ return;
22
+ }
23
+ let specContent = fs.readFileSync(specPath, 'utf-8');
24
+ const feature = state.getFeature(name);
25
+ let sessionId = feature.session?.id ?? '';
26
+ // Sub-flow 1: Clarify (unless skipped)
27
+ if (!options.skipClarify) {
28
+ display.heading('Phase 1: Requirement Clarification');
29
+ const clarifyPrompt = assemblePrompt({
30
+ templateName: 'clarify',
31
+ vars: { spec_content: specContent },
32
+ agents: args.agents,
33
+ skills: args.skills,
34
+ extraText: args.text,
35
+ });
36
+ const clarifyResult = sessionId
37
+ ? await backend.resume(sessionId, clarifyPrompt)
38
+ : await backend.execute(clarifyPrompt);
39
+ sessionId = clarifyResult.sessionId;
40
+ console.log('\n' + clarifyResult.output);
41
+ feature.phase = 'clarifying';
42
+ feature.session = { backend: config.backend.default, id: sessionId };
43
+ state.upsertFeature(feature);
44
+ // Wait for user to answer questions (in CLI mode, AI handles the conversation)
45
+ const { proceed } = await inquirer.prompt([
46
+ {
47
+ type: 'confirm',
48
+ name: 'proceed',
49
+ message: 'Proceed to spec refinement?',
50
+ default: true,
51
+ },
52
+ ]);
53
+ if (!proceed) {
54
+ display.info('Paused. Run `pxs refine` again when ready.');
55
+ return;
56
+ }
57
+ }
58
+ // Sub-flow 2: Refine spec
59
+ display.heading('Phase 2: Refine Spec');
60
+ specContent = fs.readFileSync(specPath, 'utf-8');
61
+ const refinePrompt = assemblePrompt({
62
+ templateName: 'refine',
63
+ vars: { spec_content: specContent },
64
+ agents: args.agents,
65
+ skills: args.skills,
66
+ extraText: args.text,
67
+ });
68
+ const refineResult = sessionId
69
+ ? await backend.resume(sessionId, refinePrompt)
70
+ : await backend.execute(refinePrompt);
71
+ sessionId = refineResult.sessionId;
72
+ // Save refined spec
73
+ fs.writeFileSync(specPath, refineResult.output, 'utf-8');
74
+ display.success(`Refined spec saved to ${specPath}`);
75
+ console.log('\n' + refineResult.output.slice(0, 500) + '...\n');
76
+ feature.phase = 'spec_approved';
77
+ feature.session = { backend: config.backend.default, id: sessionId };
78
+ state.upsertFeature(feature);
79
+ const { approveSpec } = await inquirer.prompt([
80
+ {
81
+ type: 'list',
82
+ name: 'approveSpec',
83
+ message: 'Spec refinement:',
84
+ choices: ['approve', 'edit'],
85
+ },
86
+ ]);
87
+ if (approveSpec === 'edit') {
88
+ display.info(`Edit ${specPath} and run \`pxs refine ${name} --skip-clarify\``);
89
+ return;
90
+ }
91
+ // Sub-flow 3: Decompose plan
92
+ display.heading('Phase 3: Decompose Plan');
93
+ specContent = fs.readFileSync(specPath, 'utf-8');
94
+ const planPrompt = `Decompose the following refined spec into an implementation plan with discrete tasks.
95
+
96
+ ${specContent}
97
+
98
+ Output the plan in this exact format:
99
+ # Implementation Plan: ${name}
100
+
101
+ > type: feat
102
+ > branch: feat/${name}
103
+ > total_tasks: N
104
+
105
+ ## Task 1: <title>
106
+ - **Files**:
107
+ - \`path/to/file\` (new|modify)
108
+ - **Description**: What to implement
109
+ - **Depends on**: None | Task N
110
+ - **Complexity**: Low | Medium | High
111
+ - **Acceptance**: Definition of done
112
+
113
+ (repeat for each task)`;
114
+ const planResult = sessionId
115
+ ? await backend.resume(sessionId, planPrompt)
116
+ : await backend.execute(planPrompt);
117
+ sessionId = planResult.sessionId;
118
+ // Save plan
119
+ fs.mkdirSync(state.plansDir(), { recursive: true });
120
+ const planPath = state.planPath(name);
121
+ fs.writeFileSync(planPath, planResult.output, 'utf-8');
122
+ display.success(`Plan saved to ${planPath}`);
123
+ console.log('\n' + planResult.output + '\n');
124
+ // Parse plan for state
125
+ const plan = parsePlan(planResult.output);
126
+ feature.phase = 'plan_pending_approval';
127
+ feature.session = { backend: config.backend.default, id: sessionId };
128
+ state.upsertFeature(feature);
129
+ const { approvePlan } = await inquirer.prompt([
130
+ {
131
+ type: 'list',
132
+ name: 'approvePlan',
133
+ message: 'Implementation plan:',
134
+ choices: ['approve', 'edit', 're-split'],
135
+ },
136
+ ]);
137
+ if (approvePlan === 'edit') {
138
+ display.info(`Edit ${planPath} and run \`pxs refine ${name} --skip-clarify\``);
139
+ return;
140
+ }
141
+ if (approvePlan === 're-split') {
142
+ display.info('Re-splitting not yet implemented. Edit the plan manually.');
143
+ return;
144
+ }
145
+ // Approve: update state
146
+ feature.type = plan.type;
147
+ feature.branch = plan.branch || `${plan.type}/${name}`;
148
+ feature.phase = 'ready_to_implement';
149
+ feature.total_tasks = plan.tasks.length;
150
+ feature.current_task = 0;
151
+ feature.tasks = plan.tasks.map((t) => ({
152
+ name: t.title,
153
+ status: 'pending',
154
+ }));
155
+ state.upsertFeature(feature);
156
+ display.success('Plan approved! Run `pxs implement ' + name + '` to start.');
157
+ }
158
+ //# sourceMappingURL=refine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refine.js","sourceRoot":"","sources":["../../../src/commands/refine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function reviewCommand(name: string, options: {
2
+ step?: number;
3
+ summary?: boolean;
4
+ }): Promise<void>;
@@ -0,0 +1,70 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { StateManager } from '../state/manager.js';
4
+ import * as display from '../utils/display.js';
5
+ export async function reviewCommand(name, options) {
6
+ const state = new StateManager();
7
+ state.ensureWorkflow();
8
+ state.checkPhaseGuard('review', name);
9
+ const feature = state.getFeature(name);
10
+ if (!feature) {
11
+ display.error(`Feature "${name}" not found.`);
12
+ return;
13
+ }
14
+ if (options.summary) {
15
+ display.heading(`Review Summary: ${name}`);
16
+ for (let i = 0; i < feature.tasks.length; i++) {
17
+ const t = feature.tasks[i];
18
+ const reviewPath = state.reviewPath(name, i + 1);
19
+ const hasReview = fs.existsSync(reviewPath);
20
+ console.log(` ${i + 1}. ${display.taskIcon(t.status)} ${t.name} ${hasReview ? '(reviewed)' : ''}`);
21
+ }
22
+ // Show final review status
23
+ const finalReviewPath = path.join(state.reviewsDir(), `${name}-final.md`);
24
+ if (fs.existsSync(finalReviewPath)) {
25
+ console.log(`\n Final branch review: exists`);
26
+ }
27
+ return;
28
+ }
29
+ if (options.step !== undefined) {
30
+ const reviewPath = state.reviewPath(name, options.step);
31
+ if (!fs.existsSync(reviewPath)) {
32
+ display.error(`Review for task ${options.step} not found.`);
33
+ return;
34
+ }
35
+ const content = fs.readFileSync(reviewPath, 'utf-8');
36
+ display.heading(`Review: ${name} - Task ${options.step}`);
37
+ console.log(content);
38
+ return;
39
+ }
40
+ // Default: if completed, show final review first
41
+ if (feature.phase === 'completed' || feature.phase === 'merged') {
42
+ const finalReviewPath = path.join(state.reviewsDir(), `${name}-final.md`);
43
+ if (fs.existsSync(finalReviewPath)) {
44
+ display.heading(`Final Branch Review: ${name}`);
45
+ console.log(fs.readFileSync(finalReviewPath, 'utf-8'));
46
+ return;
47
+ }
48
+ }
49
+ // Show most recent or pending review
50
+ const pendingIdx = feature.tasks.findIndex((t) => t.status === 'review_pending');
51
+ if (pendingIdx >= 0) {
52
+ const reviewPath = state.reviewPath(name, pendingIdx + 1);
53
+ if (fs.existsSync(reviewPath)) {
54
+ display.heading(`Pending Review: Task ${pendingIdx + 1}`);
55
+ console.log(fs.readFileSync(reviewPath, 'utf-8'));
56
+ return;
57
+ }
58
+ }
59
+ // Show last completed task's review
60
+ for (let i = feature.tasks.length - 1; i >= 0; i--) {
61
+ const reviewPath = state.reviewPath(name, i + 1);
62
+ if (fs.existsSync(reviewPath)) {
63
+ display.heading(`Latest Review: Task ${i + 1}`);
64
+ console.log(fs.readFileSync(reviewPath, 'utf-8'));
65
+ return;
66
+ }
67
+ }
68
+ display.info('No reviews found.');
69
+ }
70
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/commands/review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function statusCommand(name?: string): Promise<void>;
@@ -0,0 +1,53 @@
1
+ import { StateManager } from '../state/manager.js';
2
+ import * as display from '../utils/display.js';
3
+ export async function statusCommand(name) {
4
+ const state = new StateManager();
5
+ if (!state.workflowExists()) {
6
+ display.error('Workflow not initialized. Run `pxs init` first.');
7
+ return;
8
+ }
9
+ const workflowState = state.readState();
10
+ if (!name) {
11
+ // List all features
12
+ if (workflowState.features.length === 0) {
13
+ display.info('No features tracked. Run `pxs new <name>` to start.');
14
+ return;
15
+ }
16
+ display.heading('Workflow Status');
17
+ display.table(['Feature', 'Type', 'Phase', 'Tasks', 'Branch'], workflowState.features.map((f) => {
18
+ const completedTasks = f.tasks.filter((t) => t.status === 'complete').length;
19
+ return [
20
+ f.feature,
21
+ f.type,
22
+ f.phase,
23
+ `${completedTasks}/${f.total_tasks}`,
24
+ f.branch || '-',
25
+ ];
26
+ }));
27
+ }
28
+ else {
29
+ // Show specific feature
30
+ const feature = state.getFeature(name);
31
+ if (!feature) {
32
+ display.error(`Feature "${name}" not found.`);
33
+ return;
34
+ }
35
+ display.heading(`Feature: ${feature.feature}`);
36
+ console.log(` Type: ${feature.type}`);
37
+ console.log(` Branch: ${feature.branch || '-'}`);
38
+ console.log(` Phase: ${feature.phase}`);
39
+ if (feature.session) {
40
+ console.log(` Backend: ${feature.session.backend}`);
41
+ console.log(` Session: ${feature.session.id}`);
42
+ }
43
+ if (feature.tasks.length > 0) {
44
+ console.log('\n Tasks:');
45
+ for (let i = 0; i < feature.tasks.length; i++) {
46
+ const t = feature.tasks[i];
47
+ const icon = display.taskIcon(t.status);
48
+ console.log(` ${i + 1}. ${icon} ${t.name} (${t.status})`);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAa;IAC/C,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;IAEjC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;IAExC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,oBAAoB;QACpB,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACnC,OAAO,CAAC,KAAK,CACX,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAC/C,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/B,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;YAC7E,OAAO;gBACL,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,KAAK;gBACP,GAAG,cAAc,IAAI,CAAC,CAAC,WAAW,EAAE;gBACpC,CAAC,CAAC,MAAM,IAAI,GAAG;aAChB,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,wBAAwB;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,cAAc,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,YAAY,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface ProjectInfo {
2
+ name: string;
3
+ language: string;
4
+ framework: string;
5
+ lang_framework: string;
6
+ }
7
+ export declare function detectProject(cwd?: string): ProjectInfo;
@@ -0,0 +1,90 @@
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
+ // Node.js / TypeScript
11
+ const pkgPath = path.join(cwd, 'package.json');
12
+ if (fs.existsSync(pkgPath)) {
13
+ try {
14
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
15
+ info.name = pkg.name || info.name;
16
+ info.language = 'typescript';
17
+ info.framework = 'node';
18
+ info.lang_framework = detectNodeFramework(pkg);
19
+ }
20
+ catch {
21
+ // ignore parse error
22
+ }
23
+ return info;
24
+ }
25
+ // Go
26
+ const goModPath = path.join(cwd, 'go.mod');
27
+ if (fs.existsSync(goModPath)) {
28
+ const content = fs.readFileSync(goModPath, 'utf-8');
29
+ const moduleMatch = content.match(/^module\s+(.+)$/m);
30
+ if (moduleMatch) {
31
+ info.name = moduleMatch[1].trim();
32
+ }
33
+ info.language = 'go';
34
+ info.framework = 'go';
35
+ info.lang_framework = detectGoFramework(content);
36
+ return info;
37
+ }
38
+ // Python
39
+ const reqPath = path.join(cwd, 'requirements.txt');
40
+ if (fs.existsSync(reqPath)) {
41
+ const content = fs.readFileSync(reqPath, 'utf-8');
42
+ info.language = 'python';
43
+ info.framework = 'python';
44
+ info.lang_framework = detectPythonFramework(content);
45
+ return info;
46
+ }
47
+ // C# / .NET
48
+ const csprojFiles = fs.readdirSync(cwd).filter((f) => f.endsWith('.csproj'));
49
+ if (csprojFiles.length > 0) {
50
+ info.name = csprojFiles[0].replace('.csproj', '');
51
+ info.language = 'csharp';
52
+ info.framework = 'dotnet';
53
+ const content = fs.readFileSync(path.join(cwd, csprojFiles[0]), 'utf-8');
54
+ info.lang_framework = detectCsharpFramework(content);
55
+ return info;
56
+ }
57
+ return info;
58
+ }
59
+ function detectNodeFramework(pkg) {
60
+ const deps = {
61
+ ...pkg.dependencies,
62
+ ...pkg.devDependencies,
63
+ };
64
+ if (deps['@nestjs/core'])
65
+ return 'typescript-nestjs';
66
+ if (deps['express'])
67
+ return 'typescript-express';
68
+ return 'typescript-express';
69
+ }
70
+ function detectGoFramework(goMod) {
71
+ if (goMod.includes('github.com/gin-gonic/gin'))
72
+ return 'go-gin';
73
+ if (goMod.includes('github.com/go-chi/chi'))
74
+ return 'go-chi';
75
+ return 'go-std';
76
+ }
77
+ function detectPythonFramework(requirements) {
78
+ const lower = requirements.toLowerCase();
79
+ if (lower.includes('fastapi'))
80
+ return 'python-fastapi';
81
+ if (lower.includes('django'))
82
+ return 'python-django';
83
+ return 'python-std';
84
+ }
85
+ function detectCsharpFramework(csproj) {
86
+ if (csproj.includes('Microsoft.AspNetCore'))
87
+ return 'csharp-aspnet';
88
+ return 'csharp-dotnet';
89
+ }
90
+ //# 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;