@xenonbyte/da-vinci-workflow 0.2.3 → 0.2.5

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 (49) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +32 -7
  3. package/README.zh-CN.md +151 -7
  4. package/SKILL.md +45 -704
  5. package/commands/claude/dv/build.md +5 -0
  6. package/commands/claude/dv/continue.md +4 -0
  7. package/commands/claude/dv/tasks.md +6 -0
  8. package/commands/claude/dv/verify.md +2 -0
  9. package/commands/codex/prompts/dv-build.md +5 -0
  10. package/commands/codex/prompts/dv-continue.md +4 -0
  11. package/commands/codex/prompts/dv-tasks.md +6 -0
  12. package/commands/codex/prompts/dv-verify.md +2 -0
  13. package/commands/gemini/dv/build.toml +5 -0
  14. package/commands/gemini/dv/continue.toml +4 -0
  15. package/commands/gemini/dv/tasks.toml +6 -0
  16. package/commands/gemini/dv/verify.toml +2 -0
  17. package/commands/templates/dv-continue.shared.md +4 -0
  18. package/docs/discipline-and-orchestration-upgrade.md +83 -0
  19. package/docs/dv-command-reference.md +33 -5
  20. package/docs/execution-chain-migration.md +23 -0
  21. package/docs/prompt-entrypoints.md +6 -0
  22. package/docs/skill-contract-maintenance.md +14 -0
  23. package/docs/skill-usage.md +16 -0
  24. package/docs/workflow-overview.md +17 -0
  25. package/docs/zh-CN/dv-command-reference.md +31 -5
  26. package/docs/zh-CN/execution-chain-migration.md +23 -0
  27. package/docs/zh-CN/prompt-entrypoints.md +6 -0
  28. package/docs/zh-CN/skill-usage.md +16 -0
  29. package/docs/zh-CN/workflow-overview.md +17 -0
  30. package/lib/audit-parsers.js +148 -1
  31. package/lib/cli/helpers.js +43 -0
  32. package/lib/cli/lint-family.js +56 -0
  33. package/lib/cli/verify-family.js +79 -0
  34. package/lib/cli.js +123 -145
  35. package/lib/execution-profile.js +143 -0
  36. package/lib/execution-signals.js +19 -1
  37. package/lib/lint-tasks.js +86 -2
  38. package/lib/planning-parsers.js +263 -19
  39. package/lib/scaffold.js +454 -23
  40. package/lib/supervisor-review.js +2 -1
  41. package/lib/task-execution.js +160 -0
  42. package/lib/task-review.js +197 -0
  43. package/lib/utils.js +19 -0
  44. package/lib/verify.js +1308 -85
  45. package/lib/workflow-state.js +452 -30
  46. package/lib/worktree-preflight.js +214 -0
  47. package/package.json +1 -1
  48. package/references/artifact-templates.md +56 -6
  49. package/references/skill-workflow-detail.md +66 -0
@@ -1,7 +1,11 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
3
  const crypto = require("crypto");
4
- const { getMarkdownSection } = require("./audit-parsers");
4
+ const {
5
+ getMarkdownSection,
6
+ parseDisciplineMarkers,
7
+ DISCIPLINE_MARKER_NAMES
8
+ } = require("./audit-parsers");
5
9
  const { parseRuntimeSpecMarkdown } = require("./artifact-parsers");
6
10
  const { pathExists, readTextIfExists } = require("./utils");
7
11
 
@@ -62,7 +66,7 @@ function unique(values) {
62
66
  }
63
67
 
64
68
  function resolveImplementationLanding(projectRoot, implementationToken) {
65
- const knownExtensions = [".html", ".tsx", ".jsx", ".ts", ".js"];
69
+ const knownExtensions = [".html", ".tsx", ".jsx", ".ts", ".js", ".vue", ".svelte"];
66
70
  const seen = new Set();
67
71
  const candidates = [];
68
72
  const addCandidate = (relativePath) => {
@@ -89,6 +93,9 @@ function resolveImplementationLanding(projectRoot, implementationToken) {
89
93
  addCandidate(path.join(dirPath, `page${extension}`));
90
94
  }
91
95
  };
96
+ const addSvelteRoutePageCandidate = (dirPath) => {
97
+ addCandidate(path.join(dirPath, "+page.svelte"));
98
+ };
92
99
  const resolveFileCandidate = (relativePath) => {
93
100
  const absolutePath = path.join(projectRoot, relativePath);
94
101
  try {
@@ -114,6 +121,8 @@ function resolveImplementationLanding(projectRoot, implementationToken) {
114
121
  addPageCandidates("app");
115
122
  addFileCandidates(path.join("src", "app", "page"));
116
123
  addPageCandidates(path.join("src", "app"));
124
+ addSvelteRoutePageCandidate(path.join("src", "routes"));
125
+ addSvelteRoutePageCandidate("routes");
117
126
  } else {
118
127
  const routePath = normalized.replace(/^\//, "").replace(/\/+$/, "");
119
128
  addFileCandidates(routePath);
@@ -131,6 +140,8 @@ function resolveImplementationLanding(projectRoot, implementationToken) {
131
140
  addPageCandidates(path.join("app", routePath));
132
141
  addFileCandidates(path.join("src", "app", routePath, "page"));
133
142
  addPageCandidates(path.join("src", "app", routePath));
143
+ addSvelteRoutePageCandidate(path.join("src", "routes", routePath));
144
+ addSvelteRoutePageCandidate(path.join("routes", routePath));
134
145
  }
135
146
 
136
147
  for (const candidate of candidates) {
@@ -350,33 +361,239 @@ function parsePageMapArtifact(text) {
350
361
  };
351
362
  }
352
363
 
364
+ function parseInlineCodeTokens(line) {
365
+ const tokens = [];
366
+ const matches = String(line || "").matchAll(/`([^`]+)`/g);
367
+ for (const match of matches) {
368
+ const token = String(match[1] || "").trim();
369
+ if (token) {
370
+ tokens.push(token);
371
+ }
372
+ }
373
+ return tokens;
374
+ }
375
+
376
+ function normalizeExecutionIntent(text) {
377
+ const normalized = normalizeText(text);
378
+ if (!normalized) {
379
+ return "";
380
+ }
381
+ if (/bounded parallel|parallel bounded|parallel-safe/.test(normalized)) {
382
+ return "bounded_parallel";
383
+ }
384
+ if (/serial|sequential|one by one/.test(normalized)) {
385
+ return "serial";
386
+ }
387
+ if (/review required|review-required|review heavy|spec review|quality review/.test(normalized)) {
388
+ return "review_required";
389
+ }
390
+ return "";
391
+ }
392
+
393
+ function hasVerificationIntent(text) {
394
+ return /verify|verification|coverage|assert|validate|smoke/i.test(String(text || ""));
395
+ }
396
+
397
+ function hasTestingIntent(text) {
398
+ return /(?:^|\b)(test|tests|unit test|integration test|e2e|regression|tdd|coverage)(?:\b|$)/i.test(
399
+ String(text || "")
400
+ );
401
+ }
402
+
403
+ function hasReviewIntent(text) {
404
+ return /review|reviewer|spec review|quality review|qa|audit/i.test(String(text || ""));
405
+ }
406
+
407
+ function looksLikeCodeChange(text) {
408
+ return /implement|modify|update|add|create|refactor|fix|remove|rename|rewrite|harden|extend/i.test(
409
+ String(text || "")
410
+ );
411
+ }
412
+
413
+ function isPlaceholderText(text) {
414
+ return /\b(TBD|TODO|implement later|later fill|to be decided)\b/i.test(String(text || ""));
415
+ }
416
+
417
+ function extractFileReferences(text) {
418
+ const references = [];
419
+ const seen = new Set();
420
+ const addReference = (value) => {
421
+ const candidate = String(value || "")
422
+ .replace(/[`"'(),]/g, "")
423
+ .trim();
424
+ if (!candidate) {
425
+ return;
426
+ }
427
+ if (!/[./]/.test(candidate)) {
428
+ return;
429
+ }
430
+ if (candidate.length < 3) {
431
+ return;
432
+ }
433
+ if (seen.has(candidate)) {
434
+ return;
435
+ }
436
+ seen.add(candidate);
437
+ references.push(candidate);
438
+ };
439
+
440
+ for (const token of parseInlineCodeTokens(text)) {
441
+ addReference(token);
442
+ }
443
+ const plainMatches = String(text || "").matchAll(/(?:^|[\s(])([A-Za-z0-9._/-]+(?:\.[A-Za-z0-9_*.-]+|\/))(?:$|[\s),])/g);
444
+ for (const match of plainMatches) {
445
+ addReference(match[1]);
446
+ }
447
+ return references;
448
+ }
449
+
450
+ function extractVerificationCommands(text) {
451
+ const commands = [];
452
+ const supportedCommandPattern =
453
+ /^(?:da-vinci\s+verify-(?:bindings|implementation|structure|coverage)|npm|pnpm|yarn|bun|node|npx|pytest|go test|cargo test|dotnet test|mvn test|gradle test|make test|vitest|jest)\b/i;
454
+ const addCommand = (value) => {
455
+ const command = String(value || "").trim();
456
+ if (!command) {
457
+ return;
458
+ }
459
+ if (!/\s/.test(command)) {
460
+ return;
461
+ }
462
+ if (!supportedCommandPattern.test(command)) {
463
+ return;
464
+ }
465
+ commands.push(command);
466
+ };
467
+ for (const token of parseInlineCodeTokens(text)) {
468
+ addCommand(token);
469
+ }
470
+ return unique(commands);
471
+ }
472
+
473
+ function analyzeTaskGroup(section) {
474
+ const targetFiles = [];
475
+ const verificationActions = [];
476
+ const verificationCommands = [];
477
+ const placeholderItems = [];
478
+ const rawFileReferences = [];
479
+ const executionHints = [];
480
+
481
+ const lines = Array.isArray(section.lines) ? section.lines : [];
482
+ for (let index = 0; index < lines.length; index += 1) {
483
+ const line = String(lines[index] || "");
484
+ rawFileReferences.push(...extractFileReferences(line));
485
+ if (isPlaceholderText(line)) {
486
+ placeholderItems.push(line.trim());
487
+ }
488
+ if (hasVerificationIntent(line)) {
489
+ verificationActions.push(line.trim());
490
+ }
491
+ verificationCommands.push(...extractVerificationCommands(line));
492
+ const executionIntent = normalizeExecutionIntent(line);
493
+ if (executionIntent) {
494
+ executionHints.push(executionIntent);
495
+ }
496
+
497
+ if (/^\s*target files\s*:\s*$/i.test(line)) {
498
+ for (let cursor = index + 1; cursor < lines.length; cursor += 1) {
499
+ const followLine = String(lines[cursor] || "");
500
+ if (/^\s*$/.test(followLine)) {
501
+ continue;
502
+ }
503
+ if (/^\s{0,3}##\s+/.test(followLine)) {
504
+ break;
505
+ }
506
+ if (/^\s*[A-Za-z][A-Za-z0-9 _-]{0,80}\s*:\s*$/.test(followLine)) {
507
+ break;
508
+ }
509
+ const itemMatch = followLine.match(/^\s*-\s+(.+)$/);
510
+ if (!itemMatch) {
511
+ break;
512
+ }
513
+ const entry = String(itemMatch[1] || "").trim();
514
+ if (!entry) {
515
+ continue;
516
+ }
517
+ targetFiles.push(...extractFileReferences(entry));
518
+ }
519
+ }
520
+ }
521
+
522
+ for (const item of section.checklistItems) {
523
+ rawFileReferences.push(...extractFileReferences(item.text));
524
+ if (isPlaceholderText(item.text)) {
525
+ placeholderItems.push(item.text);
526
+ }
527
+ if (hasVerificationIntent(item.text)) {
528
+ verificationActions.push(item.text);
529
+ }
530
+ verificationCommands.push(...extractVerificationCommands(item.text));
531
+ const executionIntent = normalizeExecutionIntent(item.text);
532
+ if (executionIntent) {
533
+ executionHints.push(executionIntent);
534
+ }
535
+ }
536
+
537
+ const mergedFileReferences = unique([...targetFiles, ...rawFileReferences]);
538
+ const titleExecutionIntent = normalizeExecutionIntent(section.title);
539
+ if (titleExecutionIntent) {
540
+ executionHints.push(titleExecutionIntent);
541
+ }
542
+
543
+ const joinedContent = [section.title, ...lines, ...section.checklistItems.map((item) => item.text)].join("\n");
544
+ return {
545
+ ...section,
546
+ targetFiles: unique(targetFiles),
547
+ fileReferences: mergedFileReferences,
548
+ verificationActions: unique(verificationActions.filter(Boolean)),
549
+ verificationCommands: unique(verificationCommands),
550
+ executionIntent: unique(executionHints),
551
+ reviewIntent: hasReviewIntent(joinedContent),
552
+ testingIntent: hasTestingIntent(joinedContent),
553
+ codeChangeLikely: looksLikeCodeChange(joinedContent),
554
+ placeholderItems: unique(placeholderItems.filter(Boolean))
555
+ };
556
+ }
557
+
353
558
  function parseTasksArtifact(text) {
354
559
  const lines = String(text || "").replace(/\r\n?/g, "\n").split("\n");
355
560
  const taskGroups = [];
356
561
  const checklistItems = [];
357
562
  const checkpointItems = [];
358
563
  const sections = [];
564
+ const markers = parseDisciplineMarkers(text);
359
565
  let currentSection = null;
360
566
 
361
- for (const line of lines) {
567
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
568
+ const line = lines[lineIndex];
362
569
  const groupMatch = line.match(/^\s{0,3}##\s+(\d+(?:\.\d+)*)\.\s+(.+)$/);
363
570
  if (groupMatch) {
364
571
  const group = {
365
572
  id: groupMatch[1],
366
- title: String(groupMatch[2] || "").trim()
573
+ title: String(groupMatch[2] || "").trim(),
574
+ startLine: lineIndex + 1
367
575
  };
368
576
  taskGroups.push(group);
369
577
  if (currentSection) {
370
- sections.push(currentSection);
578
+ currentSection.endLine = lineIndex;
579
+ sections.push(analyzeTaskGroup(currentSection));
371
580
  }
372
581
  currentSection = {
373
582
  id: group.id,
374
583
  title: group.title,
375
- checklistItems: []
584
+ startLine: lineIndex + 1,
585
+ endLine: lineIndex + 1,
586
+ checklistItems: [],
587
+ lines: []
376
588
  };
377
589
  continue;
378
590
  }
379
591
 
592
+ if (currentSection) {
593
+ currentSection.lines.push(line);
594
+ currentSection.endLine = lineIndex + 1;
595
+ }
596
+
380
597
  const checklistMatch = line.match(/^\s*-\s*\[([ xX])\]\s+(.+)$/);
381
598
  if (checklistMatch) {
382
599
  const checked = String(checklistMatch[1] || "").toLowerCase() === "x";
@@ -384,33 +601,60 @@ function parseTasksArtifact(text) {
384
601
  if (!textValue) {
385
602
  continue;
386
603
  }
387
- checklistItems.push({
604
+ const item = {
388
605
  checked,
389
- text: textValue
390
- });
606
+ text: textValue,
607
+ line: lineIndex + 1
608
+ };
609
+ checklistItems.push(item);
391
610
  if (currentSection) {
392
- currentSection.checklistItems.push({
393
- checked,
394
- text: textValue
395
- });
611
+ currentSection.checklistItems.push(item);
396
612
  }
397
613
  if (/checkpoint/i.test(textValue)) {
398
- checkpointItems.push({
399
- checked,
400
- text: textValue
401
- });
614
+ checkpointItems.push(item);
402
615
  }
403
616
  }
404
617
  }
405
618
  if (currentSection) {
406
- sections.push(currentSection);
619
+ sections.push(analyzeTaskGroup(currentSection));
407
620
  }
408
621
 
622
+ const sectionById = new Map(sections.map((section) => [section.id, section]));
623
+ const normalizedTaskGroups = taskGroups.map((group) => {
624
+ const section = sectionById.get(group.id);
625
+ if (!section) {
626
+ return group;
627
+ }
628
+ return {
629
+ id: group.id,
630
+ title: group.title,
631
+ startLine: group.startLine,
632
+ endLine: section.endLine,
633
+ targetFiles: section.targetFiles,
634
+ fileReferences: section.fileReferences,
635
+ verificationActions: section.verificationActions,
636
+ verificationCommands: section.verificationCommands,
637
+ executionIntent: section.executionIntent,
638
+ reviewIntent: section.reviewIntent,
639
+ testingIntent: section.testingIntent,
640
+ codeChangeLikely: section.codeChangeLikely,
641
+ placeholderItems: section.placeholderItems,
642
+ checklistItems: section.checklistItems
643
+ };
644
+ });
645
+
409
646
  return {
410
- taskGroups,
647
+ taskGroups: normalizedTaskGroups,
411
648
  checklistItems,
412
649
  checkpointItems,
413
650
  sections,
651
+ markers,
652
+ markerSummary: {
653
+ hasDesignApproval: Boolean(markers.markers[DISCIPLINE_MARKER_NAMES.designApproval]),
654
+ hasPlanSelfReview: Boolean(markers.markers[DISCIPLINE_MARKER_NAMES.planSelfReview]),
655
+ hasOperatorReviewAck: Boolean(markers.markers[DISCIPLINE_MARKER_NAMES.operatorReviewAck]),
656
+ malformedCount: markers.malformed.length
657
+ },
414
658
  text: String(text || "")
415
659
  };
416
660
  }