@specforge/mcp 3.0.7 → 3.1.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.
- package/dist/cli/commands/index.d.ts +2 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +2 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +184 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.types.d.ts +37 -0
- package/dist/cli/commands/init.types.d.ts.map +1 -1
- package/dist/cli/commands/init.types.js +18 -0
- package/dist/cli/commands/init.types.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +18 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +154 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/plan.types.d.ts +60 -0
- package/dist/cli/commands/plan.types.d.ts.map +1 -0
- package/dist/cli/commands/plan.types.js +8 -0
- package/dist/cli/commands/plan.types.js.map +1 -0
- package/dist/cli/commands/spec-activate.d.ts +29 -0
- package/dist/cli/commands/spec-activate.d.ts.map +1 -0
- package/dist/cli/commands/spec-activate.js +155 -0
- package/dist/cli/commands/spec-activate.js.map +1 -0
- package/dist/cli/commands/spec-activate.types.d.ts +24 -0
- package/dist/cli/commands/spec-activate.types.d.ts.map +1 -0
- package/dist/cli/commands/spec-activate.types.js +8 -0
- package/dist/cli/commands/spec-activate.types.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +89 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/status.types.d.ts +2 -0
- package/dist/cli/commands/status.types.d.ts.map +1 -1
- package/dist/cli/commands/status.types.js.map +1 -1
- package/dist/cli/config/agent-teams.types.d.ts +194 -0
- package/dist/cli/config/agent-teams.types.d.ts.map +1 -0
- package/dist/cli/config/agent-teams.types.js +36 -0
- package/dist/cli/config/agent-teams.types.js.map +1 -0
- package/dist/cli/config/index.d.ts +2 -0
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -0
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/config/loader.d.ts +36 -2
- package/dist/cli/config/loader.d.ts.map +1 -1
- package/dist/cli/config/loader.js +65 -0
- package/dist/cli/config/loader.js.map +1 -1
- package/dist/cli/config/validation.d.ts +69 -0
- package/dist/cli/config/validation.d.ts.map +1 -0
- package/dist/cli/config/validation.js +295 -0
- package/dist/cli/config/validation.js.map +1 -0
- package/dist/cli/config/writer.d.ts +39 -0
- package/dist/cli/config/writer.d.ts.map +1 -1
- package/dist/cli/config/writer.js +58 -0
- package/dist/cli/config/writer.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +3 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/monorepo-detector.d.ts +31 -0
- package/dist/lib/monorepo-detector.d.ts.map +1 -0
- package/dist/lib/monorepo-detector.js +271 -0
- package/dist/lib/monorepo-detector.js.map +1 -0
- package/dist/lib/prompt-generator.d.ts +65 -0
- package/dist/lib/prompt-generator.d.ts.map +1 -0
- package/dist/lib/prompt-generator.js +172 -0
- package/dist/lib/prompt-generator.js.map +1 -0
- package/dist/lib/strategy-analyzer.d.ts +59 -0
- package/dist/lib/strategy-analyzer.d.ts.map +1 -0
- package/dist/lib/strategy-analyzer.js +137 -0
- package/dist/lib/strategy-analyzer.js.map +1 -0
- package/dist/tools/core/context-helper.d.ts +22 -0
- package/dist/tools/core/context-helper.d.ts.map +1 -1
- package/dist/tools/core/context-helper.js +37 -1
- package/dist/tools/core/context-helper.js.map +1 -1
- package/dist/tools/core/workspace-files.d.ts +49 -0
- package/dist/tools/core/workspace-files.d.ts.map +1 -0
- package/dist/tools/core/workspace-files.js +259 -0
- package/dist/tools/core/workspace-files.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +147 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +3 -2
- package/src/cli/templates/agents/content/core/sfag-implementer.ts +113 -0
- package/src/cli/templates/agents/content/core/sfag-orchestrator.ts +107 -0
- package/src/cli/templates/agents/content/core/sfag-spec-creator.ts +126 -0
- package/src/cli/templates/agents/content/core/sfag-ticket-implementer.ts +132 -0
- package/src/cli/templates/agents/content/research/sfag-package-researcher.ts +153 -0
- package/src/cli/templates/agents/content/task-type/sfag-api-implementer.ts +132 -0
- package/src/cli/templates/agents/content/task-type/sfag-docs-writer.ts +183 -0
- package/src/cli/templates/agents/content/task-type/sfag-frontend-builder.ts +141 -0
- package/src/cli/templates/agents/content/task-type/sfag-infra-architect.ts +149 -0
- package/src/cli/templates/agents/content/task-type/sfag-schema-designer.ts +132 -0
- package/src/cli/templates/agents/content/task-type/sfag-test-writer.ts +171 -0
- package/src/cli/templates/agents/index.ts +74 -0
- package/src/cli/templates/commands.ts +179 -0
- package/src/cli/templates/content/sf-autonomous.ts +78 -0
- package/src/cli/templates/content/sf-blockers.ts +68 -0
- package/src/cli/templates/content/sf-commit.ts +78 -0
- package/src/cli/templates/content/sf-context.ts +64 -0
- package/src/cli/templates/content/sf-create-epics.ts +129 -0
- package/src/cli/templates/content/sf-create-spec.ts +136 -0
- package/src/cli/templates/content/sf-create-tickets.ts +148 -0
- package/src/cli/templates/content/sf-epic.ts +69 -0
- package/src/cli/templates/content/sf-help.ts +61 -0
- package/src/cli/templates/content/sf-import.ts +88 -0
- package/src/cli/templates/content/sf-init.ts +61 -0
- package/src/cli/templates/content/sf-next.ts +67 -0
- package/src/cli/templates/content/sf-reset.ts +78 -0
- package/src/cli/templates/content/sf-review.ts +67 -0
- package/src/cli/templates/content/sf-search.ts +64 -0
- package/src/cli/templates/content/sf-status.ts +67 -0
- package/src/cli/templates/content/sf-ticket.ts +76 -0
- package/src/cli/templates/content/sf-validate.ts +78 -0
- package/src/cli/templates/index.ts +16 -0
- package/src/cli/templates/skills/specforge-conventions.md +109 -0
- package/src/cli/templates/skills/specforge-orchestrator.md +401 -0
- package/src/cli/templates/skills/specforge-validator.md +122 -0
- package/src/cli/templates/skills/specforge-worker.md +378 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monorepo Detection Utility
|
|
3
|
+
*
|
|
4
|
+
* Detects monorepo setups by checking for tool-specific config files.
|
|
5
|
+
* Returns the detected tool, workspace globs, resolved workspace paths,
|
|
6
|
+
* and package manager. Returns null for single-project repos.
|
|
7
|
+
*
|
|
8
|
+
* Detection priority: turborepo → nx → lerna → pnpm → npm → yarn
|
|
9
|
+
*
|
|
10
|
+
* This runs locally (MCP stdio transport only). For SSE/cloud transport
|
|
11
|
+
* the caller should skip detection and return null.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'node:fs';
|
|
14
|
+
import * as path from 'node:path';
|
|
15
|
+
import { minimatch } from 'minimatch';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Public API
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Detect monorepo configuration from a project root directory.
|
|
21
|
+
*
|
|
22
|
+
* @param projectRoot Absolute or relative path to the project root.
|
|
23
|
+
* @returns MonorepoInfo if a monorepo setup is detected, null otherwise.
|
|
24
|
+
*/
|
|
25
|
+
export function detectMonorepo(projectRoot) {
|
|
26
|
+
if (!fs.existsSync(projectRoot)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const rootStats = fs.statSync(projectRoot);
|
|
30
|
+
if (!rootStats.isDirectory()) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
// Try each detector in priority order.
|
|
34
|
+
const detectors = [
|
|
35
|
+
() => detectTurborepo(projectRoot),
|
|
36
|
+
() => detectNx(projectRoot),
|
|
37
|
+
() => detectLerna(projectRoot),
|
|
38
|
+
() => detectPnpmWorkspaces(projectRoot),
|
|
39
|
+
() => detectNpmYarnWorkspaces(projectRoot),
|
|
40
|
+
];
|
|
41
|
+
for (const detect of detectors) {
|
|
42
|
+
const result = detect();
|
|
43
|
+
if (result !== null) {
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Detectors
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
function detectTurborepo(root) {
|
|
53
|
+
const turboPath = path.join(root, 'turbo.json');
|
|
54
|
+
if (!fs.existsSync(turboPath))
|
|
55
|
+
return null;
|
|
56
|
+
// Turborepo reads workspaces from package.json, not turbo.json.
|
|
57
|
+
const workspaces = readPackageJsonWorkspaces(root);
|
|
58
|
+
if (workspaces.length === 0)
|
|
59
|
+
return null;
|
|
60
|
+
return {
|
|
61
|
+
type: 'turborepo',
|
|
62
|
+
workspaces,
|
|
63
|
+
resolvedPaths: resolveWorkspaceGlobs(root, workspaces),
|
|
64
|
+
packageManager: detectPackageManager(root),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function detectNx(root) {
|
|
68
|
+
const nxPath = path.join(root, 'nx.json');
|
|
69
|
+
if (!fs.existsSync(nxPath))
|
|
70
|
+
return null;
|
|
71
|
+
// Nx can use package.json workspaces or its own project structure.
|
|
72
|
+
let workspaces = readPackageJsonWorkspaces(root);
|
|
73
|
+
// If no workspaces in package.json, check for common Nx patterns.
|
|
74
|
+
if (workspaces.length === 0) {
|
|
75
|
+
const defaults = ['packages/*', 'apps/*', 'libs/*'];
|
|
76
|
+
const existing = defaults.filter(g => {
|
|
77
|
+
const prefix = g.replace('/*', '');
|
|
78
|
+
return fs.existsSync(path.join(root, prefix));
|
|
79
|
+
});
|
|
80
|
+
if (existing.length === 0)
|
|
81
|
+
return null;
|
|
82
|
+
workspaces = existing;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
type: 'nx',
|
|
86
|
+
workspaces,
|
|
87
|
+
resolvedPaths: resolveWorkspaceGlobs(root, workspaces),
|
|
88
|
+
packageManager: detectPackageManager(root),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function detectLerna(root) {
|
|
92
|
+
const lernaPath = path.join(root, 'lerna.json');
|
|
93
|
+
if (!fs.existsSync(lernaPath))
|
|
94
|
+
return null;
|
|
95
|
+
try {
|
|
96
|
+
const lernaConfig = JSON.parse(fs.readFileSync(lernaPath, 'utf-8'));
|
|
97
|
+
let workspaces = lernaConfig.packages ?? [];
|
|
98
|
+
// Fallback to package.json workspaces if lerna.json has no packages.
|
|
99
|
+
if (workspaces.length === 0) {
|
|
100
|
+
workspaces = readPackageJsonWorkspaces(root);
|
|
101
|
+
}
|
|
102
|
+
if (workspaces.length === 0) {
|
|
103
|
+
// Lerna default
|
|
104
|
+
workspaces = ['packages/*'];
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
type: 'lerna',
|
|
108
|
+
workspaces,
|
|
109
|
+
resolvedPaths: resolveWorkspaceGlobs(root, workspaces),
|
|
110
|
+
packageManager: detectPackageManager(root),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function detectPnpmWorkspaces(root) {
|
|
118
|
+
const yamlPath = path.join(root, 'pnpm-workspace.yaml');
|
|
119
|
+
if (!fs.existsSync(yamlPath))
|
|
120
|
+
return null;
|
|
121
|
+
try {
|
|
122
|
+
const content = fs.readFileSync(yamlPath, 'utf-8');
|
|
123
|
+
const workspaces = parsePnpmWorkspaceYaml(content);
|
|
124
|
+
if (workspaces.length === 0)
|
|
125
|
+
return null;
|
|
126
|
+
return {
|
|
127
|
+
type: 'pnpm',
|
|
128
|
+
workspaces,
|
|
129
|
+
resolvedPaths: resolveWorkspaceGlobs(root, workspaces),
|
|
130
|
+
packageManager: 'pnpm',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function detectNpmYarnWorkspaces(root) {
|
|
138
|
+
const workspaces = readPackageJsonWorkspaces(root);
|
|
139
|
+
if (workspaces.length === 0)
|
|
140
|
+
return null;
|
|
141
|
+
const isYarn = fs.existsSync(path.join(root, 'yarn.lock'));
|
|
142
|
+
return {
|
|
143
|
+
type: isYarn ? 'yarn' : 'npm',
|
|
144
|
+
workspaces,
|
|
145
|
+
resolvedPaths: resolveWorkspaceGlobs(root, workspaces),
|
|
146
|
+
packageManager: isYarn ? 'yarn' : 'npm',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
// Helpers
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
/**
|
|
153
|
+
* Read the "workspaces" field from root package.json.
|
|
154
|
+
* Handles both array format and object format ({ packages: [...] }).
|
|
155
|
+
*/
|
|
156
|
+
function readPackageJsonWorkspaces(root) {
|
|
157
|
+
try {
|
|
158
|
+
const pkgPath = path.join(root, 'package.json');
|
|
159
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
160
|
+
const workspaces = pkg.workspaces;
|
|
161
|
+
if (Array.isArray(workspaces)) {
|
|
162
|
+
return workspaces;
|
|
163
|
+
}
|
|
164
|
+
if (workspaces && Array.isArray(workspaces.packages)) {
|
|
165
|
+
return workspaces.packages;
|
|
166
|
+
}
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Parse pnpm-workspace.yaml without a YAML library.
|
|
175
|
+
* Extracts entries under the `packages:` key.
|
|
176
|
+
*
|
|
177
|
+
* Expected format:
|
|
178
|
+
* packages:
|
|
179
|
+
* - 'packages/*'
|
|
180
|
+
* - 'apps/*'
|
|
181
|
+
*/
|
|
182
|
+
function parsePnpmWorkspaceYaml(content) {
|
|
183
|
+
const lines = content.split('\n');
|
|
184
|
+
const workspaces = [];
|
|
185
|
+
let inPackages = false;
|
|
186
|
+
for (const line of lines) {
|
|
187
|
+
const trimmed = line.trim();
|
|
188
|
+
if (trimmed === 'packages:') {
|
|
189
|
+
inPackages = true;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
// Exit the packages block on a new top-level key.
|
|
193
|
+
if (inPackages && trimmed.length > 0 && !trimmed.startsWith('-') && !trimmed.startsWith('#')) {
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
if (inPackages && trimmed.startsWith('-')) {
|
|
197
|
+
// Strip "- ", then strip surrounding quotes.
|
|
198
|
+
const value = trimmed
|
|
199
|
+
.slice(1)
|
|
200
|
+
.trim()
|
|
201
|
+
.replace(/^['"]/, '')
|
|
202
|
+
.replace(/['"]$/, '');
|
|
203
|
+
if (value) {
|
|
204
|
+
workspaces.push(value);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return workspaces;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Resolve workspace glob patterns to actual directory paths.
|
|
212
|
+
* Uses minimatch for pattern matching against directory entries.
|
|
213
|
+
*/
|
|
214
|
+
function resolveWorkspaceGlobs(root, globs) {
|
|
215
|
+
const resolved = [];
|
|
216
|
+
for (const glob of globs) {
|
|
217
|
+
// Skip negated patterns (e.g., "!packages/internal").
|
|
218
|
+
if (glob.startsWith('!'))
|
|
219
|
+
continue;
|
|
220
|
+
// Simple case: "packages/*" → list dirs in "packages/".
|
|
221
|
+
const parts = glob.split('/');
|
|
222
|
+
const prefix = parts.slice(0, -1).join('/');
|
|
223
|
+
const prefixDir = prefix ? path.join(root, prefix) : root;
|
|
224
|
+
if (!fs.existsSync(prefixDir) || !fs.statSync(prefixDir).isDirectory()) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
const entries = fs.readdirSync(prefixDir, { withFileTypes: true });
|
|
229
|
+
for (const entry of entries) {
|
|
230
|
+
if (!entry.isDirectory())
|
|
231
|
+
continue;
|
|
232
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
233
|
+
if (minimatch(relativePath, glob)) {
|
|
234
|
+
resolved.push(relativePath);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Skip unreadable directories.
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return resolved.sort();
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Detect the package manager from lockfiles or the package.json
|
|
246
|
+
* "packageManager" field.
|
|
247
|
+
*/
|
|
248
|
+
function detectPackageManager(root) {
|
|
249
|
+
// Check package.json "packageManager" field first (corepack).
|
|
250
|
+
try {
|
|
251
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));
|
|
252
|
+
if (typeof pkg.packageManager === 'string') {
|
|
253
|
+
// Format: "pnpm@9.0.0" → extract name.
|
|
254
|
+
const name = pkg.packageManager.split('@')[0];
|
|
255
|
+
if (name)
|
|
256
|
+
return name;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
// Ignore.
|
|
261
|
+
}
|
|
262
|
+
// Lockfile detection.
|
|
263
|
+
if (fs.existsSync(path.join(root, 'pnpm-lock.yaml')))
|
|
264
|
+
return 'pnpm';
|
|
265
|
+
if (fs.existsSync(path.join(root, 'yarn.lock')))
|
|
266
|
+
return 'yarn';
|
|
267
|
+
if (fs.existsSync(path.join(root, 'bun.lockb')))
|
|
268
|
+
return 'bun';
|
|
269
|
+
return 'npm';
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=monorepo-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monorepo-detector.js","sourceRoot":"","sources":["../../src/lib/monorepo-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAmBtC,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uCAAuC;IACvC,MAAM,SAAS,GAAqC;QAClD,GAAG,EAAE,CAAC,eAAe,CAAC,WAAW,CAAC;QAClC,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC3B,GAAG,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC;QAC9B,GAAG,EAAE,CAAC,oBAAoB,CAAC,WAAW,CAAC;QACvC,GAAG,EAAE,CAAC,uBAAuB,CAAC,WAAW,CAAC;KAC3C,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,gEAAgE;IAChE,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,UAAU;QACV,aAAa,EAAE,qBAAqB,CAAC,IAAI,EAAE,UAAU,CAAC;QACtD,cAAc,EAAE,oBAAoB,CAAC,IAAI,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,mEAAmE;IACnE,IAAI,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAEjD,kEAAkE;IAClE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACnC,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACnC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACvC,UAAU,GAAG,QAAQ,CAAC;IACxB,CAAC;IAED,OAAO;QACL,IAAI,EAAE,IAAI;QACV,UAAU;QACV,aAAa,EAAE,qBAAqB,CAAC,IAAI,EAAE,UAAU,CAAC;QACtD,cAAc,EAAE,oBAAoB,CAAC,IAAI,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QACpE,IAAI,UAAU,GAAa,WAAW,CAAC,QAAQ,IAAI,EAAE,CAAC;QAEtD,qEAAqE;QACrE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,gBAAgB;YAChB,UAAU,GAAG,CAAC,YAAY,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO;YACL,IAAI,EAAE,OAAO;YACb,UAAU;YACV,aAAa,EAAE,qBAAqB,CAAC,IAAI,EAAE,UAAU,CAAC;YACtD,cAAc,EAAE,oBAAoB,CAAC,IAAI,CAAC;SAC3C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEzC,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,UAAU;YACV,aAAa,EAAE,qBAAqB,CAAC,IAAI,EAAE,UAAU,CAAC;YACtD,cAAc,EAAE,MAAM;SACvB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAY;IAC3C,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAC3D,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;QAC7B,UAAU;QACV,aAAa,EAAE,qBAAqB,CAAC,IAAI,EAAE,UAAU,CAAC;QACtD,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;KACxC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,yBAAyB,CAAC,IAAY;IAC7C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1D,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QAElC,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,IAAI,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,OAAO,UAAU,CAAC,QAAQ,CAAC;QAC7B,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,sBAAsB,CAAC,OAAe;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,UAAU,GAAG,IAAI,CAAC;YAClB,SAAS;QACX,CAAC;QAED,kDAAkD;QAClD,IAAI,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7F,MAAM;QACR,CAAC;QAED,IAAI,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,6CAA6C;YAC7C,MAAM,KAAK,GAAG,OAAO;iBAClB,KAAK,CAAC,CAAC,CAAC;iBACR,IAAI,EAAE;iBACN,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;iBACpB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACxB,IAAI,KAAK,EAAE,CAAC;gBACV,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAAC,IAAY,EAAE,KAAe;IAC1D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,sDAAsD;QACtD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAEnC,wDAAwD;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACvE,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACnE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBAAE,SAAS;gBAEnC,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;gBACrE,IAAI,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC;oBAClC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACxC,8DAA8D;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QAClF,IAAI,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;YAC3C,uCAAuC;YACvC,MAAM,IAAI,GAAG,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,UAAU;IACZ,CAAC;IAED,sBAAsB;IACtB,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9D,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace-Scoped Worker Prompt Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates context-rich prompts for Agent Teams workers and validators.
|
|
5
|
+
* Follows the Worker Initial Prompt and Validation Watcher Prompt templates
|
|
6
|
+
* from the design doc.
|
|
7
|
+
*
|
|
8
|
+
* Prompts are kept concise (~2000-4000 tokens) for worker context efficiency.
|
|
9
|
+
* Sections with no data are omitted entirely.
|
|
10
|
+
*/
|
|
11
|
+
export interface TicketContext {
|
|
12
|
+
id: string;
|
|
13
|
+
ticketNumber: number;
|
|
14
|
+
title: string;
|
|
15
|
+
description: string;
|
|
16
|
+
implementation?: {
|
|
17
|
+
steps?: string[];
|
|
18
|
+
filesToCreate?: string[];
|
|
19
|
+
filesToModify?: string[];
|
|
20
|
+
} | null;
|
|
21
|
+
acceptanceCriteria?: Array<{
|
|
22
|
+
description: string;
|
|
23
|
+
}> | null;
|
|
24
|
+
technicalDetails?: Record<string, unknown> | null;
|
|
25
|
+
}
|
|
26
|
+
export interface EpicContext {
|
|
27
|
+
title: string;
|
|
28
|
+
objective?: string | null;
|
|
29
|
+
}
|
|
30
|
+
export interface SpecContext {
|
|
31
|
+
title: string;
|
|
32
|
+
techStack?: string[] | null;
|
|
33
|
+
codeStandards?: string | null;
|
|
34
|
+
}
|
|
35
|
+
export interface WorkspaceContext {
|
|
36
|
+
/** Relative path from project root (e.g., "apps/web") */
|
|
37
|
+
path: string;
|
|
38
|
+
/** Detected framework (e.g., "Next.js", "Express") */
|
|
39
|
+
framework?: string | null;
|
|
40
|
+
/** Package name from package.json */
|
|
41
|
+
name?: string | null;
|
|
42
|
+
/** Key dependency names */
|
|
43
|
+
dependencies?: string[] | null;
|
|
44
|
+
}
|
|
45
|
+
export interface ConventionsContext {
|
|
46
|
+
/** Free-form conventions text (e.g., from CLAUDE.md) */
|
|
47
|
+
content?: string | null;
|
|
48
|
+
}
|
|
49
|
+
export interface ValidationCommands {
|
|
50
|
+
test?: string | null;
|
|
51
|
+
lint?: string | null;
|
|
52
|
+
typeCheck?: string | null;
|
|
53
|
+
build?: string | null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generate a context-rich prompt for an Agent Teams worker.
|
|
57
|
+
*
|
|
58
|
+
* Omits entire sections when the corresponding data is missing.
|
|
59
|
+
*/
|
|
60
|
+
export declare function generateWorkerPrompt(ticket: TicketContext, epic: EpicContext, spec: SpecContext, workspace?: WorkspaceContext | null, conventions?: ConventionsContext | null): string;
|
|
61
|
+
/**
|
|
62
|
+
* Generate a prompt for an Agent Teams validation watcher.
|
|
63
|
+
*/
|
|
64
|
+
export declare function generateValidatorPrompt(epic: EpicContext, validationCommands?: ValidationCommands | null, workspace?: WorkspaceContext | null): string;
|
|
65
|
+
//# sourceMappingURL=prompt-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-generator.d.ts","sourceRoot":"","sources":["../../src/lib/prompt-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,kBAAkB,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAC3D,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,WAAW,EACjB,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,EACnC,WAAW,CAAC,EAAE,kBAAkB,GAAG,IAAI,GACtC,MAAM,CA+GR;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,WAAW,EACjB,kBAAkB,CAAC,EAAE,kBAAkB,GAAG,IAAI,EAC9C,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAClC,MAAM,CAiER"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace-Scoped Worker Prompt Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates context-rich prompts for Agent Teams workers and validators.
|
|
5
|
+
* Follows the Worker Initial Prompt and Validation Watcher Prompt templates
|
|
6
|
+
* from the design doc.
|
|
7
|
+
*
|
|
8
|
+
* Prompts are kept concise (~2000-4000 tokens) for worker context efficiency.
|
|
9
|
+
* Sections with no data are omitted entirely.
|
|
10
|
+
*/
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Worker prompt
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/**
|
|
15
|
+
* Generate a context-rich prompt for an Agent Teams worker.
|
|
16
|
+
*
|
|
17
|
+
* Omits entire sections when the corresponding data is missing.
|
|
18
|
+
*/
|
|
19
|
+
export function generateWorkerPrompt(ticket, epic, spec, workspace, conventions) {
|
|
20
|
+
const sections = [];
|
|
21
|
+
// Header
|
|
22
|
+
sections.push(`# SpecForge Worker: Implementing E-T${ticket.ticketNumber}`, '', `**Epic:** ${epic.title}`, `**Spec:** ${spec.title}`, '');
|
|
23
|
+
// Ticket details
|
|
24
|
+
sections.push(`## Ticket: ${ticket.title}`, '');
|
|
25
|
+
sections.push('### Description', ticket.description, '');
|
|
26
|
+
// Implementation guide
|
|
27
|
+
const impl = ticket.implementation;
|
|
28
|
+
if (impl) {
|
|
29
|
+
const hasSteps = impl.steps && impl.steps.length > 0;
|
|
30
|
+
const hasCreate = impl.filesToCreate && impl.filesToCreate.length > 0;
|
|
31
|
+
const hasModify = impl.filesToModify && impl.filesToModify.length > 0;
|
|
32
|
+
if (hasSteps || hasCreate || hasModify) {
|
|
33
|
+
sections.push('### Implementation Guide', '');
|
|
34
|
+
if (hasSteps) {
|
|
35
|
+
sections.push(...impl.steps.map((step, i) => `${i + 1}. ${step}`), '');
|
|
36
|
+
}
|
|
37
|
+
if (hasCreate) {
|
|
38
|
+
sections.push('**Files to create:**');
|
|
39
|
+
sections.push(...impl.filesToCreate.map(f => `- \`${f}\``), '');
|
|
40
|
+
}
|
|
41
|
+
if (hasModify) {
|
|
42
|
+
sections.push('**Files to modify:**');
|
|
43
|
+
sections.push(...impl.filesToModify.map(f => `- \`${f}\``), '');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Acceptance criteria
|
|
48
|
+
if (ticket.acceptanceCriteria && ticket.acceptanceCriteria.length > 0) {
|
|
49
|
+
sections.push('### Acceptance Criteria');
|
|
50
|
+
sections.push(...ticket.acceptanceCriteria.map(ac => `- [ ] ${ac.description}`), '');
|
|
51
|
+
}
|
|
52
|
+
// Technical details
|
|
53
|
+
if (ticket.technicalDetails && Object.keys(ticket.technicalDetails).length > 0) {
|
|
54
|
+
sections.push('### Technical Details');
|
|
55
|
+
sections.push(formatTechnicalDetails(ticket.technicalDetails), '');
|
|
56
|
+
}
|
|
57
|
+
// Tech stack from spec
|
|
58
|
+
if (spec.techStack && spec.techStack.length > 0) {
|
|
59
|
+
sections.push('### Tech Stack');
|
|
60
|
+
sections.push(spec.techStack.join(', '), '');
|
|
61
|
+
}
|
|
62
|
+
// Workspace info (monorepo)
|
|
63
|
+
if (workspace) {
|
|
64
|
+
sections.push('### Workspace');
|
|
65
|
+
sections.push(`- **Path:** ${workspace.path}`);
|
|
66
|
+
if (workspace.name) {
|
|
67
|
+
sections.push(`- **Package:** ${workspace.name}`);
|
|
68
|
+
}
|
|
69
|
+
if (workspace.framework) {
|
|
70
|
+
sections.push(`- **Framework:** ${workspace.framework}`);
|
|
71
|
+
}
|
|
72
|
+
if (workspace.dependencies && workspace.dependencies.length > 0) {
|
|
73
|
+
sections.push(`- **Key dependencies:** ${workspace.dependencies.join(', ')}`);
|
|
74
|
+
}
|
|
75
|
+
sections.push('');
|
|
76
|
+
}
|
|
77
|
+
// Conventions
|
|
78
|
+
if (conventions?.content) {
|
|
79
|
+
sections.push('### Conventions', conventions.content, '');
|
|
80
|
+
}
|
|
81
|
+
// Code standards from spec
|
|
82
|
+
if (spec.codeStandards) {
|
|
83
|
+
sections.push('### Code Standards', spec.codeStandards, '');
|
|
84
|
+
}
|
|
85
|
+
// Rules
|
|
86
|
+
sections.push('### Rules');
|
|
87
|
+
const rules = [
|
|
88
|
+
'Only modify files listed in the implementation guide unless necessary',
|
|
89
|
+
"Follow the project's coding conventions",
|
|
90
|
+
'Write tests for new functionality',
|
|
91
|
+
'Update ticket status via SpecForge MCP after each milestone',
|
|
92
|
+
'Report any blockers or discoveries to team-lead immediately',
|
|
93
|
+
];
|
|
94
|
+
if (workspace) {
|
|
95
|
+
rules.unshift(`Only modify files within \`${workspace.path}/\` unless the ticket explicitly requires cross-workspace changes`);
|
|
96
|
+
}
|
|
97
|
+
sections.push(...rules.map(r => `- ${r}`), '');
|
|
98
|
+
return sections.join('\n').trimEnd();
|
|
99
|
+
}
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// Validator prompt
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
/**
|
|
104
|
+
* Generate a prompt for an Agent Teams validation watcher.
|
|
105
|
+
*/
|
|
106
|
+
export function generateValidatorPrompt(epic, validationCommands, workspace) {
|
|
107
|
+
const sections = [];
|
|
108
|
+
sections.push(`# SpecForge Validator: ${epic.title}`, '');
|
|
109
|
+
sections.push('## Your Role');
|
|
110
|
+
sections.push('You are the validation watcher for this epic.', 'After each teammate reports a ticket as complete:', '');
|
|
111
|
+
// Validation commands
|
|
112
|
+
const steps = [];
|
|
113
|
+
steps.push('1. Pull their changes');
|
|
114
|
+
if (validationCommands?.test) {
|
|
115
|
+
steps.push(`2. Run tests: \`${validationCommands.test}\``);
|
|
116
|
+
}
|
|
117
|
+
if (validationCommands?.lint) {
|
|
118
|
+
steps.push(`${steps.length + 1}. Run lint: \`${validationCommands.lint}\``);
|
|
119
|
+
}
|
|
120
|
+
if (validationCommands?.typeCheck) {
|
|
121
|
+
steps.push(`${steps.length + 1}. Run type check: \`${validationCommands.typeCheck}\``);
|
|
122
|
+
}
|
|
123
|
+
if (validationCommands?.build) {
|
|
124
|
+
steps.push(`${steps.length + 1}. Run build: \`${validationCommands.build}\``);
|
|
125
|
+
}
|
|
126
|
+
steps.push(`${steps.length + 1}. Report results to team-lead`);
|
|
127
|
+
sections.push(...steps, '');
|
|
128
|
+
// Workspace scope
|
|
129
|
+
if (workspace) {
|
|
130
|
+
sections.push('## Workspace');
|
|
131
|
+
sections.push(`- **Path:** ${workspace.path}`);
|
|
132
|
+
if (workspace.framework) {
|
|
133
|
+
sections.push(`- **Framework:** ${workspace.framework}`);
|
|
134
|
+
}
|
|
135
|
+
sections.push('');
|
|
136
|
+
}
|
|
137
|
+
// Rules
|
|
138
|
+
sections.push('## Rules');
|
|
139
|
+
sections.push('- Do NOT modify code yourself', '- If tests fail, message the worker with specific errors and file:line references', '- If all checks pass, confirm to team-lead', '- Run validations in the correct workspace directory', '');
|
|
140
|
+
// Reporting format
|
|
141
|
+
sections.push('## Reporting Format');
|
|
142
|
+
sections.push('**On success:**', '> Ticket E-T{n} validated. All checks passed.', '', '**On failure:**', '> Ticket E-T{n} failed validation:', '> - {check}: {error message} ({file}:{line})', '');
|
|
143
|
+
return sections.join('\n').trimEnd();
|
|
144
|
+
}
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// Helpers
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
/**
|
|
149
|
+
* Format technical details as a readable key-value list.
|
|
150
|
+
* Handles nested objects and arrays.
|
|
151
|
+
*/
|
|
152
|
+
function formatTechnicalDetails(details) {
|
|
153
|
+
const lines = [];
|
|
154
|
+
for (const [key, value] of Object.entries(details)) {
|
|
155
|
+
if (value === null || value === undefined)
|
|
156
|
+
continue;
|
|
157
|
+
const label = key.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase());
|
|
158
|
+
if (Array.isArray(value)) {
|
|
159
|
+
if (value.length > 0) {
|
|
160
|
+
lines.push(`- **${label}:** ${value.join(', ')}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (typeof value === 'object') {
|
|
164
|
+
lines.push(`- **${label}:** ${JSON.stringify(value)}`);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
lines.push(`- **${label}:** ${String(value)}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return lines.join('\n');
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=prompt-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-generator.js","sourceRoot":"","sources":["../../src/lib/prompt-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strategy Auto-Detection Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Pure function that determines the optimal Agent Teams strategy
|
|
5
|
+
* based on a specification's structure: epic count, ticket distribution,
|
|
6
|
+
* and cross-epic dependency density.
|
|
7
|
+
*
|
|
8
|
+
* Decision matrix (from design doc):
|
|
9
|
+
* - 1 epic, ≤3 tickets → single-session
|
|
10
|
+
* - 1 epic, >3 tickets → spec-as-team
|
|
11
|
+
* - N epics, 0 cross-deps → epic-as-team
|
|
12
|
+
* - N epics, >50% cross-deps → spec-as-team
|
|
13
|
+
* - N epics, moderate cross-deps → epic-as-team with merged pairs
|
|
14
|
+
*/
|
|
15
|
+
/** Tickets with cross-epic deps / total tickets. Above this → spec-as-team. */
|
|
16
|
+
export declare const CROSS_DEP_THRESHOLD = 0.5;
|
|
17
|
+
/** Max tickets for a single-session recommendation (single epic only). */
|
|
18
|
+
export declare const SINGLE_SESSION_MAX_TICKETS = 3;
|
|
19
|
+
export interface SpecSummary {
|
|
20
|
+
id: string;
|
|
21
|
+
title: string;
|
|
22
|
+
epicCount: number;
|
|
23
|
+
}
|
|
24
|
+
export interface EpicSummary {
|
|
25
|
+
id: string;
|
|
26
|
+
title: string;
|
|
27
|
+
ticketCount: number;
|
|
28
|
+
}
|
|
29
|
+
export interface TicketSummary {
|
|
30
|
+
id: string;
|
|
31
|
+
epicId: string;
|
|
32
|
+
dependencies: string[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A dependency edge between two tickets in different epics.
|
|
36
|
+
*/
|
|
37
|
+
export interface DependencyEdge {
|
|
38
|
+
fromEpicId: string;
|
|
39
|
+
toEpicId: string;
|
|
40
|
+
fromTicketId: string;
|
|
41
|
+
toTicketId: string;
|
|
42
|
+
}
|
|
43
|
+
export type Strategy = 'single-session' | 'spec-as-team' | 'epic-as-team';
|
|
44
|
+
export interface StrategyRecommendation {
|
|
45
|
+
strategy: Strategy;
|
|
46
|
+
reasoning: string;
|
|
47
|
+
/** Epic ID groups that should be merged into a single team (for moderate cross-deps). */
|
|
48
|
+
mergedEpics?: string[][];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Analyze a specification's structure and recommend an Agent Teams strategy.
|
|
52
|
+
*
|
|
53
|
+
* This is a **pure function** — no side effects, no API calls.
|
|
54
|
+
* All data must be pre-fetched and passed in.
|
|
55
|
+
*
|
|
56
|
+
* @throws {Error} If the specification has no epics or no tickets.
|
|
57
|
+
*/
|
|
58
|
+
export declare function analyzeStrategy(spec: SpecSummary, epics: EpicSummary[], ticketsByEpic: Map<string, TicketSummary[]>, dependencyEdges: DependencyEdge[]): StrategyRecommendation;
|
|
59
|
+
//# sourceMappingURL=strategy-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-analyzer.d.ts","sourceRoot":"","sources":["../../src/lib/strategy-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,0EAA0E;AAC1E,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAM5C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,MAAM,MAAM,QAAQ,GAAG,gBAAgB,GAAG,cAAc,GAAG,cAAc,CAAC;AAE1E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CAC1B;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,WAAW,EAAE,EACpB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,EAC3C,eAAe,EAAE,cAAc,EAAE,GAChC,sBAAsB,CA+DxB"}
|