@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.
- package/CHANGELOG.md +32 -0
- package/README.md +32 -7
- package/README.zh-CN.md +151 -7
- package/SKILL.md +45 -704
- package/commands/claude/dv/build.md +5 -0
- package/commands/claude/dv/continue.md +4 -0
- package/commands/claude/dv/tasks.md +6 -0
- package/commands/claude/dv/verify.md +2 -0
- package/commands/codex/prompts/dv-build.md +5 -0
- package/commands/codex/prompts/dv-continue.md +4 -0
- package/commands/codex/prompts/dv-tasks.md +6 -0
- package/commands/codex/prompts/dv-verify.md +2 -0
- package/commands/gemini/dv/build.toml +5 -0
- package/commands/gemini/dv/continue.toml +4 -0
- package/commands/gemini/dv/tasks.toml +6 -0
- package/commands/gemini/dv/verify.toml +2 -0
- package/commands/templates/dv-continue.shared.md +4 -0
- package/docs/discipline-and-orchestration-upgrade.md +83 -0
- package/docs/dv-command-reference.md +33 -5
- package/docs/execution-chain-migration.md +23 -0
- package/docs/prompt-entrypoints.md +6 -0
- package/docs/skill-contract-maintenance.md +14 -0
- package/docs/skill-usage.md +16 -0
- package/docs/workflow-overview.md +17 -0
- package/docs/zh-CN/dv-command-reference.md +31 -5
- package/docs/zh-CN/execution-chain-migration.md +23 -0
- package/docs/zh-CN/prompt-entrypoints.md +6 -0
- package/docs/zh-CN/skill-usage.md +16 -0
- package/docs/zh-CN/workflow-overview.md +17 -0
- package/lib/audit-parsers.js +148 -1
- package/lib/cli/helpers.js +43 -0
- package/lib/cli/lint-family.js +56 -0
- package/lib/cli/verify-family.js +79 -0
- package/lib/cli.js +123 -145
- package/lib/execution-profile.js +143 -0
- package/lib/execution-signals.js +19 -1
- package/lib/lint-tasks.js +86 -2
- package/lib/planning-parsers.js +263 -19
- package/lib/scaffold.js +454 -23
- package/lib/supervisor-review.js +2 -1
- package/lib/task-execution.js +160 -0
- package/lib/task-review.js +197 -0
- package/lib/utils.js +19 -0
- package/lib/verify.js +1308 -85
- package/lib/workflow-state.js +452 -30
- package/lib/worktree-preflight.js +214 -0
- package/package.json +1 -1
- package/references/artifact-templates.md +56 -6
- package/references/skill-workflow-detail.md +66 -0
package/lib/planning-parsers.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const crypto = require("crypto");
|
|
4
|
-
const {
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|