@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.
Files changed (29) hide show
  1. package/defaults/teams/research/roles/researcher.md +29 -0
  2. package/defaults/teams/research/team.yaml +7 -0
  3. package/defaults/teams/software/roles/architect.md +31 -0
  4. package/defaults/teams/software/roles/dev-lead.md +32 -0
  5. package/defaults/teams/software/roles/developer.md +30 -0
  6. package/defaults/teams/software/roles/product-manager.md +32 -0
  7. package/defaults/teams/software/roles/product-owner.md +30 -0
  8. package/defaults/teams/software/roles/qa.md +35 -0
  9. package/defaults/teams/software/routing.yaml +28 -0
  10. package/defaults/teams/software/team.yaml +24 -0
  11. package/defaults/teams/solo/roles/developer.md +28 -0
  12. package/defaults/teams/solo/team.yaml +7 -0
  13. package/defaults/templates/plan.md +17 -0
  14. package/defaults/templates/review.md +11 -0
  15. package/defaults/templates/story.md +13 -0
  16. package/defaults/templates/task.md +11 -0
  17. package/defaults/workflows/team-software.yaml +153 -0
  18. package/dist/{agents-AKSUXQHN.js → agents-PSIOQEYH.js} +3 -3
  19. package/dist/{change-context-REE7UKU7.js → change-context-EZJMSGSP.js} +1 -1
  20. package/dist/{chunk-4PIRWYRA.js → chunk-26YG6A4M.js} +166 -81
  21. package/dist/{chunk-LHSR7JG2.js → chunk-2FJBFYVJ.js} +306 -31
  22. package/dist/{chunk-QGP43XCN.js → chunk-H55RFAEI.js} +1 -1
  23. package/dist/{chunk-QHV5KZKX.js → chunk-HG7TPW5V.js} +93 -8
  24. package/dist/{chunk-44LQ5BKZ.js → chunk-TGRV6WGS.js} +812 -4
  25. package/dist/{gather-ZNV2NAUN.js → gather-7TSVKQO2.js} +1 -1
  26. package/dist/{greenfield-I5S5OS2D.js → greenfield-QFA5WVHE.js} +3 -3
  27. package/dist/index.d.ts +804 -10
  28. package/dist/index.js +2765 -524
  29. 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
- const files = await listFiles(dir);
219
- return files.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).map((f) => f.replace(/\.ya?ml$/, "")).sort();
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 = join(dir, file);
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
- throw new Error(
235
- `Workflow "${name}" not found in ${dir}. Available: ${(await listWorkflowNames(projectRoot)).join(", ") || "(none)"}`
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
- `Workflow "${opts.preferred}" is not available. Available: ${available.join(", ") || "(none)"}`
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,