@structured-vibe-coding/core 0.18.0 → 0.19.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/defaults/teams/research/roles/researcher.md +29 -0
- package/defaults/teams/research/team.yaml +7 -0
- package/defaults/teams/software/roles/architect.md +31 -0
- package/defaults/teams/software/roles/dev-lead.md +32 -0
- package/defaults/teams/software/roles/developer.md +30 -0
- package/defaults/teams/software/roles/product-manager.md +32 -0
- package/defaults/teams/software/roles/product-owner.md +30 -0
- package/defaults/teams/software/roles/qa.md +35 -0
- package/defaults/teams/software/routing.yaml +28 -0
- package/defaults/teams/software/team.yaml +24 -0
- package/defaults/teams/solo/roles/developer.md +28 -0
- package/defaults/teams/solo/team.yaml +7 -0
- package/defaults/templates/plan.md +17 -0
- package/defaults/templates/review.md +11 -0
- package/defaults/templates/story.md +13 -0
- package/defaults/templates/task.md +11 -0
- package/defaults/workflows/team-software.yaml +153 -0
- package/dist/{agents-AKSUXQHN.js → agents-PSIOQEYH.js} +3 -3
- package/dist/{change-context-REE7UKU7.js → change-context-EZJMSGSP.js} +1 -1
- package/dist/{chunk-4PIRWYRA.js → chunk-26YG6A4M.js} +166 -81
- package/dist/{chunk-LHSR7JG2.js → chunk-2FJBFYVJ.js} +306 -31
- package/dist/{chunk-QGP43XCN.js → chunk-H55RFAEI.js} +1 -1
- package/dist/{chunk-QHV5KZKX.js → chunk-HG7TPW5V.js} +93 -8
- package/dist/{chunk-44LQ5BKZ.js → chunk-TGRV6WGS.js} +812 -4
- package/dist/{gather-ZNV2NAUN.js → gather-7TSVKQO2.js} +1 -1
- package/dist/{greenfield-I5S5OS2D.js → greenfield-QFA5WVHE.js} +3 -3
- package/dist/index.d.ts +804 -10
- package/dist/index.js +2765 -524
- package/package.json +2 -2
|
@@ -21,6 +21,8 @@ var GateSchema = z.object({
|
|
|
21
21
|
type: z.enum(["none", "soft", "hard"]).default("soft"),
|
|
22
22
|
mode: z.enum(["none", "human_approval", "checklist"]).default("checklist"),
|
|
23
23
|
checklist: z.array(z.string()).default([]),
|
|
24
|
+
/** Role names, or human for a person listed on the team. */
|
|
25
|
+
approvers: z.array(z.string().trim().min(1)).optional(),
|
|
24
26
|
overridable: z.boolean().default(true)
|
|
25
27
|
});
|
|
26
28
|
var ArtifactDefSchema = z.object({
|
|
@@ -46,6 +48,15 @@ var StageSchema = z.object({
|
|
|
46
48
|
kind: z.enum(["standard", "brainstorm", "clarify"]).default("standard"),
|
|
47
49
|
/** When true, stage is optional (skippable); agents may skip if not needed */
|
|
48
50
|
optional: z.boolean().default(false),
|
|
51
|
+
/** Role that produces this stage. */
|
|
52
|
+
owner: z.string().trim().min(1).optional(),
|
|
53
|
+
/** Roles who work with the owner on this stage. */
|
|
54
|
+
collaborates: z.array(z.string().trim().min(1)).optional(),
|
|
55
|
+
/**
|
|
56
|
+
* One item per matching file when the stage starts.
|
|
57
|
+
* A directory, a slash, and one star in the file name: tasks/T-*.md
|
|
58
|
+
*/
|
|
59
|
+
items_from: z.string().regex(/^(?!.*\.\.)[A-Za-z0-9._-]+\/[A-Za-z0-9._-]*\*[A-Za-z0-9._-]*$/).optional(),
|
|
49
60
|
artifacts: z.array(ArtifactDefSchema).default([]),
|
|
50
61
|
gate: GateSchema.default({}),
|
|
51
62
|
skippable: z.boolean().default(true),
|
|
@@ -212,17 +223,75 @@ function uniqueChangeDirName(base, taken) {
|
|
|
212
223
|
}
|
|
213
224
|
|
|
214
225
|
// src/workflow.ts
|
|
215
|
-
import { join } from "pathe";
|
|
226
|
+
import { join as join2 } from "pathe";
|
|
227
|
+
|
|
228
|
+
// src/defaults.ts
|
|
229
|
+
import { existsSync } from "fs";
|
|
230
|
+
import { fileURLToPath } from "url";
|
|
231
|
+
import { dirname, join } from "pathe";
|
|
232
|
+
function defaultsRoot() {
|
|
233
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
234
|
+
const candidates = [
|
|
235
|
+
join(here, "..", "defaults"),
|
|
236
|
+
// npm package: dist/../defaults
|
|
237
|
+
join(here, "defaults"),
|
|
238
|
+
// same-dir defaults if present
|
|
239
|
+
join(here, "..", "..", "defaults")
|
|
240
|
+
// src/ during some test runners
|
|
241
|
+
];
|
|
242
|
+
for (const c of candidates) {
|
|
243
|
+
if (existsSync(c)) return c;
|
|
244
|
+
}
|
|
245
|
+
return candidates[0];
|
|
246
|
+
}
|
|
247
|
+
function defaultWorkflowsDir() {
|
|
248
|
+
return join(defaultsRoot(), "workflows");
|
|
249
|
+
}
|
|
250
|
+
function defaultTeamsDir() {
|
|
251
|
+
return join(defaultsRoot(), "teams");
|
|
252
|
+
}
|
|
253
|
+
function defaultTemplatesDir() {
|
|
254
|
+
return join(defaultsRoot(), "templates");
|
|
255
|
+
}
|
|
256
|
+
function defaultMemoryDir() {
|
|
257
|
+
return join(defaultsRoot(), "memory");
|
|
258
|
+
}
|
|
259
|
+
function defaultMcpYamlPath() {
|
|
260
|
+
return join(defaultsRoot(), "mcp.yaml");
|
|
261
|
+
}
|
|
262
|
+
function defaultPricesYamlPath() {
|
|
263
|
+
return join(defaultsRoot(), "prices.yaml");
|
|
264
|
+
}
|
|
265
|
+
function defaultSearchYamlPath() {
|
|
266
|
+
return join(defaultsRoot(), "search.yaml");
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/workflow.ts
|
|
270
|
+
function workflowNamesIn(files) {
|
|
271
|
+
return files.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).map((f) => f.replace(/\.ya?ml$/, "")).sort();
|
|
272
|
+
}
|
|
216
273
|
async function listWorkflowNames(projectRoot) {
|
|
217
274
|
const dir = workflowsDir(projectRoot);
|
|
218
|
-
|
|
219
|
-
|
|
275
|
+
return workflowNamesIn(await listFiles(dir));
|
|
276
|
+
}
|
|
277
|
+
async function listBundledWorkflowNames() {
|
|
278
|
+
return workflowNamesIn(await listFiles(defaultWorkflowsDir()));
|
|
279
|
+
}
|
|
280
|
+
async function missingBundledWorkflows(projectRoot) {
|
|
281
|
+
const present = new Set(await listWorkflowNames(projectRoot));
|
|
282
|
+
return (await listBundledWorkflowNames()).filter((name) => !present.has(name));
|
|
283
|
+
}
|
|
284
|
+
function workflowUnavailableMessage(name, available, bundled) {
|
|
285
|
+
const listed = available.join(", ") || "(none)";
|
|
286
|
+
const base = `Workflow "${name}" is not available. Available: ${listed}`;
|
|
287
|
+
if (!bundled.includes(name)) return base;
|
|
288
|
+
return `${base}. This CLI ships ${name}. Run \`sdd init --here --force\` to copy new defaults.`;
|
|
220
289
|
}
|
|
221
290
|
async function loadWorkflow(projectRoot, name) {
|
|
222
291
|
const dir = workflowsDir(projectRoot);
|
|
223
292
|
const candidates = [`${name}.yaml`, `${name}.yml`];
|
|
224
293
|
for (const file of candidates) {
|
|
225
|
-
const path =
|
|
294
|
+
const path = join2(dir, file);
|
|
226
295
|
if (await pathExists(path)) {
|
|
227
296
|
const raw = await readYaml(path);
|
|
228
297
|
const workflow = WorkflowSchema.parse(raw);
|
|
@@ -231,9 +300,14 @@ async function loadWorkflow(projectRoot, name) {
|
|
|
231
300
|
return workflow;
|
|
232
301
|
}
|
|
233
302
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
);
|
|
303
|
+
const available = await listWorkflowNames(projectRoot);
|
|
304
|
+
const bundled = await listBundledWorkflowNames();
|
|
305
|
+
const listed = available.join(", ") || "(none)";
|
|
306
|
+
let message = `Workflow "${name}" not found in ${dir}. Available: ${listed}`;
|
|
307
|
+
if (bundled.includes(name)) {
|
|
308
|
+
message += `. This CLI ships ${name}. Run \`sdd init --here --force\` to copy new defaults.`;
|
|
309
|
+
}
|
|
310
|
+
throw new Error(message);
|
|
237
311
|
}
|
|
238
312
|
function resolveStages(workflow, meta) {
|
|
239
313
|
const base = [...workflow.stages];
|
|
@@ -314,7 +388,7 @@ async function recommendWorkflow(projectRoot, title, config, opts) {
|
|
|
314
388
|
if (opts?.preferred) {
|
|
315
389
|
if (!available.includes(opts.preferred)) {
|
|
316
390
|
throw new Error(
|
|
317
|
-
|
|
391
|
+
workflowUnavailableMessage(opts.preferred, available, await listBundledWorkflowNames())
|
|
318
392
|
);
|
|
319
393
|
}
|
|
320
394
|
if (config.allowed_workflows?.length && !config.allowed_workflows.includes(opts.preferred)) {
|
|
@@ -460,7 +534,18 @@ export {
|
|
|
460
534
|
nowIso,
|
|
461
535
|
changeDirName,
|
|
462
536
|
uniqueChangeDirName,
|
|
537
|
+
defaultsRoot,
|
|
538
|
+
defaultWorkflowsDir,
|
|
539
|
+
defaultTeamsDir,
|
|
540
|
+
defaultTemplatesDir,
|
|
541
|
+
defaultMemoryDir,
|
|
542
|
+
defaultMcpYamlPath,
|
|
543
|
+
defaultPricesYamlPath,
|
|
544
|
+
defaultSearchYamlPath,
|
|
463
545
|
listWorkflowNames,
|
|
546
|
+
listBundledWorkflowNames,
|
|
547
|
+
missingBundledWorkflows,
|
|
548
|
+
workflowUnavailableMessage,
|
|
464
549
|
loadWorkflow,
|
|
465
550
|
resolveStages,
|
|
466
551
|
isStageSkipped,
|