@xenonbyte/da-vinci-workflow 0.2.4 → 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.
@@ -66,9 +66,21 @@ These commands do not replace route selection, but they support design execution
66
66
  - `da-vinci generate-sidecars --project <path> [--change <id>] [--json]`
67
67
  - explicitly generates deterministic planning sidecars: `spec.index.json`, `tasks.index.json`, `page-map.index.json`, `bindings.index.json`
68
68
  - this is the only write surface for planning sidecars; lint/status/verify surfaces should not silently rewrite them
69
- - `da-vinci verify-bindings|verify-implementation|verify-structure|verify-coverage --project <path> [--change <id>] [--strict] [--json]`
70
- - verifies code landings, planned-state implementation evidence, and structural consistency against bindings
71
- - `verify-structure` reports whether checks used markup-backed analysis or heuristic fallback and exposes confidence
69
+ - `da-vinci verify-bindings --project <path> [--change <id>] [--strict] [--json]`
70
+ - validates implementation landing resolution from `pencil-bindings.md`
71
+ - `da-vinci verify-implementation --project <path> [--change <id>] [--changed-files <csv>] [--strict] [--json]`
72
+ - verifies planned-state/task-group implementation evidence with per-check `mode` + `confidence` metadata
73
+ - JS/TS checks are syntax-aware and do not count comment-only or string-literal-only matches as normal coverage
74
+ - when `--changed-files` is used, the run is explicit incremental scope (partial semantics) and reports selected/scanned/filtered file counts
75
+ - `da-vinci verify-structure --project <path> [--change <id>] [--changed-files <csv>] [--strict] [--json]`
76
+ - verifies structural consistency against bindings and reports `markup` vs `heuristic` confidence surfaces
77
+ - when `--changed-files` is used, unmatched or irrelevant entries stay visible instead of silently widening to full scan
78
+ - `da-vinci verify-coverage --project <path> [--change <id>] [--changed-files <csv>] [--strict] [--json]`
79
+ - aggregates upstream verification surfaces and marks incremental upstream results as partial freshness
80
+ - `da-vinci scaffold --project <path> [--change <id>] [--output <path>] [--json]`
81
+ - generates reviewable TODO scaffold templates with framework-aware shape (`next`/`react`/`vue`/`svelte`/`html`)
82
+ - keeps known implementation landing extension/route shape when a concrete landing already exists
83
+ - unknown/ambiguous framework detection falls back to HTML with explicit warning; traversal/output-root safety remains enforced
72
84
  - `da-vinci task-execution --project <path> --change <id> --task-group <id> --status <DONE|DONE_WITH_CONCERNS|NEEDS_CONTEXT|BLOCKED> --summary <text> [--changed-files <csv>] [--test-evidence <csv>] [--concerns <csv>] [--blockers <csv>] [--json]`
73
85
  - persists normalized implementer-status envelopes into execution signals
74
86
  - use this to keep resume routing machine-readable when implementation is blocked or concerns remain
@@ -71,6 +71,7 @@ Continuation precedence:
71
71
  - run `da-vinci scope-check --project <path> [--change <id>]` when page or state propagation across planning artifacts is uncertain
72
72
  - run `da-vinci lint-tasks --project <path> [--change <id>]` before routing into `build` when task metadata quality is uncertain
73
73
  - run `da-vinci verify-bindings --project <path> [--change <id>]` and `da-vinci verify-coverage --project <path> [--change <id>]` before terminal completion routing
74
+ - if using `--changed-files` with `verify-implementation`/`verify-structure`/`verify-coverage`, treat results as explicit incremental partial evidence, not full-project freshness
74
75
  - run `da-vinci diff-spec --project <path> [--change <id>]` after planning edits when continuation must reason about changed requirement slices
75
76
  - determine routing from artifact and checkpoint truth first
76
77
  - use contextual checkpoint deltas only as auxiliary recovery context
@@ -0,0 +1,14 @@
1
+ # SKILL Contract Maintenance
2
+
3
+ Use this policy when editing workflow guidance:
4
+
5
+ 1. Keep invariant route/execution truth in `SKILL.md` only.
6
+ 2. Keep stage-specific procedure in one owned reference file.
7
+ 3. Ensure `SKILL.md` `Load References On Demand` map points to that owner.
8
+ 4. Avoid duplicate prose across `SKILL.md`, `references/`, and generated command assets unless tests explicitly require duplication.
9
+ 5. Update `references/skill-workflow-detail.md` move map when relocating sections.
10
+
11
+ Boundary rule:
12
+
13
+ - If a rule changes workflow truth, route semantics, or execution policy, edit core.
14
+ - If a rule is tactical for one stage (design/build/review/scaffold), edit reference docs.
@@ -68,9 +68,21 @@ Da Vinci 期望它们遵循工作流状态。
68
68
  - `da-vinci generate-sidecars --project <path> [--change <id>] [--json]`
69
69
  - 显式生成确定性的 planning sidecars:`spec.index.json`、`tasks.index.json`、`page-map.index.json`、`bindings.index.json`
70
70
  - sidecar 只允许通过这个命令写入;lint/status/verify 不应静默重写
71
- - `da-vinci verify-bindings|verify-implementation|verify-structure|verify-coverage --project <path> [--change <id>] [--strict] [--json]`
72
- - 校验代码落点、计划状态实现证据、以及绑定驱动的结构一致性
73
- - `verify-structure` 会明确报告是 markup-backed 还是 heuristic fallback,并给出置信度
71
+ - `da-vinci verify-bindings --project <path> [--change <id>] [--strict] [--json]`
72
+ - 校验 `pencil-bindings.md` 的实现落点能否被正确解析
73
+ - `da-vinci verify-implementation --project <path> [--change <id>] [--changed-files <csv>] [--strict] [--json]`
74
+ - 以每个检查项的 `mode` + `confidence` 证据模型校验状态/任务组实现覆盖
75
+ - JS/TS 会走语法感知检查,不把“仅注释命中”或“仅字符串字面量命中”当作正常覆盖
76
+ - 使用 `--changed-files` 时会进入显式增量模式(partial 语义),并输出 selected/scanned/filtered 统计
77
+ - `da-vinci verify-structure --project <path> [--change <id>] [--changed-files <csv>] [--strict] [--json]`
78
+ - 校验 bindings 驱动的结构一致性,并显式报告 `markup`/`heuristic` 置信度
79
+ - 使用 `--changed-files` 时,不相关条目会被显式报告,不会静默扩展成全量扫描
80
+ - `da-vinci verify-coverage --project <path> [--change <id>] [--changed-files <csv>] [--strict] [--json]`
81
+ - 聚合上游 verify surface,并在上游是增量验证时明确标记 partial freshness
82
+ - `da-vinci scaffold --project <path> [--change <id>] [--output <path>] [--json]`
83
+ - 生成 framework-aware 的 TODO 可审查骨架(`next`/`react`/`vue`/`svelte`/`html`)
84
+ - 若已存在明确实现落点,会优先保留该落点的扩展名与路由形状
85
+ - 框架未知或冲突时显式告警并回退 HTML;同时继续严格执行 traversal/output-root 安全约束
74
86
  - `da-vinci task-execution --project <path> --change <id> --task-group <id> --status <DONE|DONE_WITH_CONCERNS|NEEDS_CONTEXT|BLOCKED> --summary <text> [--changed-files <csv>] [--test-evidence <csv>] [--concerns <csv>] [--blockers <csv>] [--json]`
75
87
  - 持久化结构化 implementer 执行结果包,作为 task 级执行证据
76
88
  - `da-vinci task-review --project <path> --change <id> --task-group <id> --stage <spec|quality> --status <PASS|WARN|BLOCK> --summary <text> [--issues <csv>] [--reviewer <name>] [--write-verification] [--json]`
@@ -72,6 +72,7 @@
72
72
  - 如果页面或状态在规划工件中的传播关系不确定,进入 `build` 前先运行 `da-vinci scope-check --project <path> [--change <id>]`
73
73
  - 如果任务拆解质量不确定,进入 `build` 前先运行 `da-vinci lint-tasks --project <path> [--change <id>]`
74
74
  - 进入终态前先运行 `da-vinci verify-bindings --project <path> [--change <id>]` 与 `da-vinci verify-coverage --project <path> [--change <id>]`
75
+ - 若在 `verify-implementation`/`verify-structure`/`verify-coverage` 使用 `--changed-files`,要把结果视为显式增量 partial 证据,而不是全量 fresh 验证
75
76
  - 当规划切片有改动且需要恢复判断时,运行 `da-vinci diff-spec --project <path> [--change <id>]`
76
77
  - 先根据工件和 checkpoint 真相决定路由
77
78
  - Context Delta 只用于恢复和解释,不用于覆盖选路
@@ -0,0 +1,43 @@
1
+ const { writeExecutionSignal } = require("../execution-signals");
2
+
3
+ function emitOrThrowOnStatus(status, blockedStatuses, output, continueOnError) {
4
+ if (!Array.isArray(blockedStatuses) || !blockedStatuses.includes(status)) {
5
+ return false;
6
+ }
7
+ if (continueOnError) {
8
+ console.log(output);
9
+ return true;
10
+ }
11
+ throw new Error(output);
12
+ }
13
+
14
+ function persistExecutionSignal(projectPath, changeId, surface, result, strict = false) {
15
+ try {
16
+ writeExecutionSignal(projectPath, {
17
+ changeId: changeId || "global",
18
+ surface,
19
+ status: result.status,
20
+ advisory: strict ? false : true,
21
+ strict,
22
+ failures: result.failures || [],
23
+ warnings: result.warnings || [],
24
+ notes: result.notes || []
25
+ });
26
+ } catch (error) {
27
+ // Signals are advisory metadata and should not break command execution.
28
+ const code = error && error.code ? String(error.code).toUpperCase() : "";
29
+ if (code === "EACCES" || code === "ENOSPC") {
30
+ return;
31
+ }
32
+
33
+ const message = error && error.message ? error.message : String(error);
34
+ console.error(
35
+ `Warning: failed to persist execution signal (${surface}) for change ${changeId || "global"}: ${message}`
36
+ );
37
+ }
38
+ }
39
+
40
+ module.exports = {
41
+ emitOrThrowOnStatus,
42
+ persistExecutionSignal
43
+ };
@@ -0,0 +1,56 @@
1
+ function handleLintFamilyCommand(command, context) {
2
+ const lintCommands = new Set(["lint-spec", "scope-check", "lint-tasks", "lint-bindings"]);
3
+ if (!lintCommands.has(command)) {
4
+ return false;
5
+ }
6
+
7
+ const {
8
+ argv,
9
+ positionalArgs,
10
+ continueOnError,
11
+ getOption,
12
+ lintRuntimeSpecs,
13
+ formatLintSpecReport,
14
+ runScopeCheck,
15
+ formatScopeCheckReport,
16
+ lintTasks,
17
+ formatLintTasksReport,
18
+ lintBindings,
19
+ formatLintBindingsReport,
20
+ emitOrThrowOnStatus,
21
+ persistExecutionSignal
22
+ } = context;
23
+
24
+ const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
25
+ const changeId = getOption(argv, "--change");
26
+ const strict = argv.includes("--strict");
27
+ const useJson = argv.includes("--json");
28
+
29
+ let result;
30
+ let output = "";
31
+ let surface = command;
32
+ if (command === "lint-spec") {
33
+ result = lintRuntimeSpecs(projectPath, { changeId, strict });
34
+ output = useJson ? JSON.stringify(result, null, 2) : formatLintSpecReport(result);
35
+ } else if (command === "scope-check") {
36
+ result = runScopeCheck(projectPath, { changeId, strict });
37
+ output = useJson ? JSON.stringify(result, null, 2) : formatScopeCheckReport(result);
38
+ } else if (command === "lint-tasks") {
39
+ result = lintTasks(projectPath, { changeId, strict });
40
+ output = useJson ? JSON.stringify(result, null, 2) : formatLintTasksReport(result);
41
+ } else {
42
+ result = lintBindings(projectPath, { changeId, strict });
43
+ output = useJson ? JSON.stringify(result, null, 2) : formatLintBindingsReport(result);
44
+ }
45
+
46
+ persistExecutionSignal(projectPath, result.changeId || changeId, surface, result, strict);
47
+ if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
48
+ return true;
49
+ }
50
+ console.log(output);
51
+ return true;
52
+ }
53
+
54
+ module.exports = {
55
+ handleLintFamilyCommand
56
+ };
@@ -0,0 +1,79 @@
1
+ function handleVerifyFamilyCommand(command, context) {
2
+ const verifyCommands = new Set([
3
+ "verify-bindings",
4
+ "verify-implementation",
5
+ "verify-structure",
6
+ "verify-coverage"
7
+ ]);
8
+ if (!verifyCommands.has(command)) {
9
+ return false;
10
+ }
11
+
12
+ const {
13
+ argv,
14
+ positionalArgs,
15
+ continueOnError,
16
+ getOption,
17
+ getCommaSeparatedOptionValues,
18
+ collectOptionEntries,
19
+ verifyBindings,
20
+ verifyImplementation,
21
+ verifyStructure,
22
+ verifyCoverage,
23
+ formatVerifyReport,
24
+ emitOrThrowOnStatus,
25
+ persistExecutionSignal
26
+ } = context;
27
+
28
+ const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
29
+ const changeId = getOption(argv, "--change");
30
+ const strict = argv.includes("--strict");
31
+ const useJson = argv.includes("--json");
32
+ const changedFilesProvided = collectOptionEntries(argv, "--changed-files").length > 0;
33
+ const changedFiles = changedFilesProvided
34
+ ? getCommaSeparatedOptionValues(argv, "--changed-files")
35
+ : undefined;
36
+
37
+ let result;
38
+ let title = "Da Vinci verify";
39
+ if (command === "verify-bindings") {
40
+ result = verifyBindings(projectPath, { changeId, strict });
41
+ title = "Da Vinci verify-bindings";
42
+ } else if (command === "verify-implementation") {
43
+ result = verifyImplementation(projectPath, {
44
+ changeId,
45
+ strict,
46
+ changedFiles,
47
+ changedFilesProvided
48
+ });
49
+ title = "Da Vinci verify-implementation";
50
+ } else if (command === "verify-structure") {
51
+ result = verifyStructure(projectPath, {
52
+ changeId,
53
+ strict,
54
+ changedFiles,
55
+ changedFilesProvided
56
+ });
57
+ title = "Da Vinci verify-structure";
58
+ } else {
59
+ result = verifyCoverage(projectPath, {
60
+ changeId,
61
+ strict,
62
+ changedFiles,
63
+ changedFilesProvided
64
+ });
65
+ title = "Da Vinci verify-coverage";
66
+ }
67
+
68
+ persistExecutionSignal(projectPath, result.changeId || changeId, command, result, strict);
69
+ const output = useJson ? JSON.stringify(result, null, 2) : formatVerifyReport(result, title);
70
+ if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
71
+ return true;
72
+ }
73
+ console.log(output);
74
+ return true;
75
+ }
76
+
77
+ module.exports = {
78
+ handleVerifyFamilyCommand
79
+ };
package/lib/cli.js CHANGED
@@ -78,7 +78,9 @@ const {
78
78
  } = require("./verify");
79
79
  const { diffSpec, formatDiffSpecReport } = require("./diff-spec");
80
80
  const { scaffoldFromBindings, formatScaffoldReport } = require("./scaffold");
81
- const { writeExecutionSignal } = require("./execution-signals");
81
+ const { emitOrThrowOnStatus, persistExecutionSignal } = require("./cli/helpers");
82
+ const { handleVerifyFamilyCommand } = require("./cli/verify-family");
83
+ const { handleLintFamilyCommand } = require("./cli/lint-family");
82
84
  const {
83
85
  writeTaskExecutionEnvelope,
84
86
  formatTaskExecutionReport
@@ -187,7 +189,10 @@ const HELP_OPTION_SPECS = [
187
189
  { flag: "--stage <value>", description: "task-review stage: spec or quality" },
188
190
  { flag: "--summary <text>", description: "task-execution/task-review summary text" },
189
191
  { flag: "--task-group <id>", description: "task group identifier for task-execution/task-review" },
190
- { flag: "--changed-files <csv>", description: "comma-separated changed files for task-execution" },
192
+ {
193
+ flag: "--changed-files <csv>",
194
+ description: "comma-separated changed files for verify-implementation/verify-structure/verify-coverage/task-execution"
195
+ },
191
196
  { flag: "--test-evidence <csv>", description: "comma-separated test evidence commands for task-execution" },
192
197
  { flag: "--concerns <csv>", description: "comma-separated concern text for task-execution" },
193
198
  { flag: "--blockers <csv>", description: "comma-separated blocker text for task-execution" },
@@ -379,17 +384,6 @@ function shouldContinueOnError(args) {
379
384
  return Array.isArray(args) && args.includes("--continue-on-error");
380
385
  }
381
386
 
382
- function emitOrThrowOnStatus(status, blockedStatuses, output, continueOnError) {
383
- if (!Array.isArray(blockedStatuses) || !blockedStatuses.includes(status)) {
384
- return false;
385
- }
386
- if (continueOnError) {
387
- console.log(output);
388
- return true;
389
- }
390
- throw new Error(output);
391
- }
392
-
393
387
  function getIntegerOption(args, name, options = {}) {
394
388
  const raw = getOption(args, name);
395
389
  if (raw === undefined) {
@@ -477,32 +471,6 @@ function appendStatusIssues(lines, label, missing = [], mismatched = [], unreada
477
471
  }
478
472
  }
479
473
 
480
- function persistExecutionSignal(projectPath, changeId, surface, result, strict = false) {
481
- try {
482
- writeExecutionSignal(projectPath, {
483
- changeId: changeId || "global",
484
- surface,
485
- status: result.status,
486
- advisory: strict ? false : true,
487
- strict,
488
- failures: result.failures || [],
489
- warnings: result.warnings || [],
490
- notes: result.notes || []
491
- });
492
- } catch (error) {
493
- // Signals are advisory metadata and should not break command execution.
494
- const code = error && error.code ? String(error.code).toUpperCase() : "";
495
- if (code === "EACCES" || code === "ENOSPC") {
496
- return;
497
- }
498
-
499
- const message = error && error.message ? error.message : String(error);
500
- console.error(
501
- `Warning: failed to persist execution signal (${surface}) for change ${changeId || "global"}: ${message}`
502
- );
503
- }
504
- }
505
-
506
474
  function printHelp() {
507
475
  const optionLines = HELP_OPTION_SPECS.map((optionSpec) => {
508
476
  const paddedFlag = optionSpec.flag.padEnd(30, " ");
@@ -526,9 +494,9 @@ function printHelp() {
526
494
  " da-vinci lint-bindings [--project <path>] [--change <id>] [--strict] [--json]",
527
495
  " da-vinci generate-sidecars [--project <path>] [--change <id>] [--json]",
528
496
  " da-vinci verify-bindings [--project <path>] [--change <id>] [--strict] [--json]",
529
- " da-vinci verify-implementation [--project <path>] [--change <id>] [--strict] [--json]",
530
- " da-vinci verify-structure [--project <path>] [--change <id>] [--strict] [--json]",
531
- " da-vinci verify-coverage [--project <path>] [--change <id>] [--strict] [--json]",
497
+ " da-vinci verify-implementation [--project <path>] [--change <id>] [--changed-files <csv>] [--strict] [--json]",
498
+ " da-vinci verify-structure [--project <path>] [--change <id>] [--changed-files <csv>] [--strict] [--json]",
499
+ " da-vinci verify-coverage [--project <path>] [--change <id>] [--changed-files <csv>] [--strict] [--json]",
532
500
  " da-vinci task-execution --project <path> --change <id> --task-group <id> --status <DONE|DONE_WITH_CONCERNS|NEEDS_CONTEXT|BLOCKED> --summary <text> [--changed-files <csv>] [--test-evidence <csv>] [--concerns <csv>] [--blockers <csv>] [--json]",
533
501
  " da-vinci task-review --project <path> --change <id> --task-group <id> --stage <spec|quality> --status <PASS|WARN|BLOCK> --summary <text> [--issues <csv>] [--reviewer <name>] [--write-verification] [--json]",
534
502
  " da-vinci worktree-preflight --project <path> [--change <id>] [--json]",
@@ -1056,71 +1024,24 @@ async function runCli(argv) {
1056
1024
  return;
1057
1025
  }
1058
1026
 
1059
- if (command === "lint-spec") {
1060
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1061
- const changeId = getOption(argv, "--change");
1062
- const strict = argv.includes("--strict");
1063
- const result = lintRuntimeSpecs(projectPath, { changeId, strict });
1064
- persistExecutionSignal(projectPath, result.changeId || changeId, "lint-spec", result, strict);
1065
- const useJson = argv.includes("--json");
1066
- const output = useJson ? JSON.stringify(result, null, 2) : formatLintSpecReport(result);
1067
-
1068
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1069
- return;
1070
- }
1071
-
1072
- console.log(output);
1073
- return;
1074
- }
1075
-
1076
- if (command === "scope-check") {
1077
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1078
- const changeId = getOption(argv, "--change");
1079
- const strict = argv.includes("--strict");
1080
- const result = runScopeCheck(projectPath, { changeId, strict });
1081
- persistExecutionSignal(projectPath, result.changeId || changeId, "scope-check", result, strict);
1082
- const useJson = argv.includes("--json");
1083
- const output = useJson ? JSON.stringify(result, null, 2) : formatScopeCheckReport(result);
1084
-
1085
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1086
- return;
1087
- }
1088
-
1089
- console.log(output);
1090
- return;
1091
- }
1092
-
1093
- if (command === "lint-tasks") {
1094
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1095
- const changeId = getOption(argv, "--change");
1096
- const strict = argv.includes("--strict");
1097
- const result = lintTasks(projectPath, { changeId, strict });
1098
- persistExecutionSignal(projectPath, result.changeId || changeId, "lint-tasks", result, strict);
1099
- const useJson = argv.includes("--json");
1100
- const output = useJson ? JSON.stringify(result, null, 2) : formatLintTasksReport(result);
1101
-
1102
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1103
- return;
1104
- }
1105
-
1106
- console.log(output);
1107
- return;
1108
- }
1109
-
1110
- if (command === "lint-bindings") {
1111
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1112
- const changeId = getOption(argv, "--change");
1113
- const strict = argv.includes("--strict");
1114
- const result = lintBindings(projectPath, { changeId, strict });
1115
- persistExecutionSignal(projectPath, result.changeId || changeId, "lint-bindings", result, strict);
1116
- const useJson = argv.includes("--json");
1117
- const output = useJson ? JSON.stringify(result, null, 2) : formatLintBindingsReport(result);
1118
-
1119
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1120
- return;
1121
- }
1122
-
1123
- console.log(output);
1027
+ if (
1028
+ handleLintFamilyCommand(command, {
1029
+ argv,
1030
+ positionalArgs,
1031
+ continueOnError,
1032
+ getOption,
1033
+ lintRuntimeSpecs,
1034
+ formatLintSpecReport,
1035
+ runScopeCheck,
1036
+ formatScopeCheckReport,
1037
+ lintTasks,
1038
+ formatLintTasksReport,
1039
+ lintBindings,
1040
+ formatLintBindingsReport,
1041
+ emitOrThrowOnStatus,
1042
+ persistExecutionSignal
1043
+ })
1044
+ ) {
1124
1045
  return;
1125
1046
  }
1126
1047
 
@@ -1140,71 +1061,23 @@ async function runCli(argv) {
1140
1061
  return;
1141
1062
  }
1142
1063
 
1143
- if (command === "verify-bindings") {
1144
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1145
- const changeId = getOption(argv, "--change");
1146
- const strict = argv.includes("--strict");
1147
- const result = verifyBindings(projectPath, { changeId, strict });
1148
- persistExecutionSignal(projectPath, result.changeId || changeId, "verify-bindings", result, strict);
1149
- const useJson = argv.includes("--json");
1150
- const output = useJson
1151
- ? JSON.stringify(result, null, 2)
1152
- : formatVerifyReport(result, "Da Vinci verify-bindings");
1153
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1154
- return;
1155
- }
1156
- console.log(output);
1157
- return;
1158
- }
1159
-
1160
- if (command === "verify-implementation") {
1161
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1162
- const changeId = getOption(argv, "--change");
1163
- const strict = argv.includes("--strict");
1164
- const result = verifyImplementation(projectPath, { changeId, strict });
1165
- persistExecutionSignal(projectPath, result.changeId || changeId, "verify-implementation", result, strict);
1166
- const useJson = argv.includes("--json");
1167
- const output = useJson
1168
- ? JSON.stringify(result, null, 2)
1169
- : formatVerifyReport(result, "Da Vinci verify-implementation");
1170
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1171
- return;
1172
- }
1173
- console.log(output);
1174
- return;
1175
- }
1176
-
1177
- if (command === "verify-structure") {
1178
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1179
- const changeId = getOption(argv, "--change");
1180
- const strict = argv.includes("--strict");
1181
- const result = verifyStructure(projectPath, { changeId, strict });
1182
- persistExecutionSignal(projectPath, result.changeId || changeId, "verify-structure", result, strict);
1183
- const useJson = argv.includes("--json");
1184
- const output = useJson
1185
- ? JSON.stringify(result, null, 2)
1186
- : formatVerifyReport(result, "Da Vinci verify-structure");
1187
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1188
- return;
1189
- }
1190
- console.log(output);
1191
- return;
1192
- }
1193
-
1194
- if (command === "verify-coverage") {
1195
- const projectPath = getOption(argv, "--project") || positionalArgs[0] || process.cwd();
1196
- const changeId = getOption(argv, "--change");
1197
- const strict = argv.includes("--strict");
1198
- const result = verifyCoverage(projectPath, { changeId, strict });
1199
- persistExecutionSignal(projectPath, result.changeId || changeId, "verify-coverage", result, strict);
1200
- const useJson = argv.includes("--json");
1201
- const output = useJson
1202
- ? JSON.stringify(result, null, 2)
1203
- : formatVerifyReport(result, "Da Vinci verify-coverage");
1204
- if (emitOrThrowOnStatus(result.status, ["BLOCK"], output, continueOnError)) {
1205
- return;
1206
- }
1207
- console.log(output);
1064
+ if (
1065
+ handleVerifyFamilyCommand(command, {
1066
+ argv,
1067
+ positionalArgs,
1068
+ continueOnError,
1069
+ getOption,
1070
+ getCommaSeparatedOptionValues,
1071
+ collectOptionEntries,
1072
+ verifyBindings,
1073
+ verifyImplementation,
1074
+ verifyStructure,
1075
+ verifyCoverage,
1076
+ formatVerifyReport,
1077
+ emitOrThrowOnStatus,
1078
+ persistExecutionSignal
1079
+ })
1080
+ ) {
1208
1081
  return;
1209
1082
  }
1210
1083
 
@@ -66,7 +66,7 @@ function unique(values) {
66
66
  }
67
67
 
68
68
  function resolveImplementationLanding(projectRoot, implementationToken) {
69
- const knownExtensions = [".html", ".tsx", ".jsx", ".ts", ".js"];
69
+ const knownExtensions = [".html", ".tsx", ".jsx", ".ts", ".js", ".vue", ".svelte"];
70
70
  const seen = new Set();
71
71
  const candidates = [];
72
72
  const addCandidate = (relativePath) => {
@@ -93,6 +93,9 @@ function resolveImplementationLanding(projectRoot, implementationToken) {
93
93
  addCandidate(path.join(dirPath, `page${extension}`));
94
94
  }
95
95
  };
96
+ const addSvelteRoutePageCandidate = (dirPath) => {
97
+ addCandidate(path.join(dirPath, "+page.svelte"));
98
+ };
96
99
  const resolveFileCandidate = (relativePath) => {
97
100
  const absolutePath = path.join(projectRoot, relativePath);
98
101
  try {
@@ -118,6 +121,8 @@ function resolveImplementationLanding(projectRoot, implementationToken) {
118
121
  addPageCandidates("app");
119
122
  addFileCandidates(path.join("src", "app", "page"));
120
123
  addPageCandidates(path.join("src", "app"));
124
+ addSvelteRoutePageCandidate(path.join("src", "routes"));
125
+ addSvelteRoutePageCandidate("routes");
121
126
  } else {
122
127
  const routePath = normalized.replace(/^\//, "").replace(/\/+$/, "");
123
128
  addFileCandidates(routePath);
@@ -135,6 +140,8 @@ function resolveImplementationLanding(projectRoot, implementationToken) {
135
140
  addPageCandidates(path.join("app", routePath));
136
141
  addFileCandidates(path.join("src", "app", routePath, "page"));
137
142
  addPageCandidates(path.join("src", "app", routePath));
143
+ addSvelteRoutePageCandidate(path.join("src", "routes", routePath));
144
+ addSvelteRoutePageCandidate(path.join("routes", routePath));
138
145
  }
139
146
 
140
147
  for (const candidate of candidates) {