@deksden-com/dd-flow-cli 0.2.0 → 0.3.1

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 (47) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +76 -5
  3. package/dist/build-info.json +10 -6
  4. package/dist/cli/help.js +165 -20
  5. package/dist/cli/run-cli.js +427 -17
  6. package/dist/schemas/compatibility.schema.json +105 -0
  7. package/dist/schemas/engine-manifest.schema.json +61 -0
  8. package/dist/schemas/flow-guidance.schema.json +90 -0
  9. package/dist/schemas/flow-run-index.schema.json +30 -4
  10. package/dist/schemas/global-dashboard-data.schema.json +126 -0
  11. package/dist/schemas/mb-sdlc-review-report.schema.json +242 -0
  12. package/dist/schemas/mb-upgrade-migration-report.schema.json +93 -0
  13. package/dist/schemas/plan-stage-report.schema.json +83 -0
  14. package/dist/schemas/project-dashboard-data.schema.json +122 -0
  15. package/dist/schemas/project-flow-pack-manifest.schema.json +5 -1
  16. package/dist/schemas/project-summary.schema.json +73 -0
  17. package/dist/schemas/protocol-dashboard-data.schema.json +112 -0
  18. package/dist/schemas/status-report.schema.json +38 -2
  19. package/dist/schemas/version-report.schema.json +22 -0
  20. package/dist/services/build-info.js +26 -3
  21. package/dist/services/canon.js +93 -22
  22. package/dist/services/cleanup.js +45 -1
  23. package/dist/services/cli-operation-classifier.js +104 -0
  24. package/dist/services/compatibility-preflight.js +124 -0
  25. package/dist/services/config.js +31 -0
  26. package/dist/services/dashboard-targets.js +95 -0
  27. package/dist/services/dashboard.js +972 -10
  28. package/dist/services/engines.js +532 -0
  29. package/dist/services/flow-guidance.js +221 -0
  30. package/dist/services/hooks.js +1 -1
  31. package/dist/services/ids.js +106 -0
  32. package/dist/services/lanes.js +333 -1
  33. package/dist/services/merge-queue.js +106 -16
  34. package/dist/services/merge-worker.js +67 -4
  35. package/dist/services/migrations.js +231 -0
  36. package/dist/services/project-summary.js +122 -0
  37. package/dist/services/projects.js +44 -3
  38. package/dist/services/protocol-lifecycle.js +144 -0
  39. package/dist/services/protocols.js +660 -7
  40. package/dist/services/runs.js +98 -21
  41. package/dist/services/schema-validation.js +84 -4
  42. package/dist/services/sessions.js +21 -4
  43. package/dist/services/status.js +199 -1
  44. package/dist/services/version-status.js +59 -9
  45. package/dist/storage/database.js +31 -0
  46. package/dist/storage/paths.js +33 -0
  47. package/package.json +3 -2
@@ -0,0 +1,144 @@
1
+ import { defaultFlowContract, flowContractForState, normalizeStage } from "../domain/flow-contract.js";
2
+ export function normalizeProtocolLifecycle(input) {
3
+ const source = input.state ? "runtime_state" : input.rawStage || input.rawStatus ? "protocol_record" : "missing";
4
+ const contract = input.flowContract ?? (input.state ? flowContractForState(input.state) : defaultFlowContract);
5
+ const rawStage = nonEmpty(input.state?.stage) ?? nonEmpty(input.rawStage) ?? "unregistered";
6
+ const rawStatus = nonEmpty(input.state?.status) ?? nonEmpty(input.rawStatus) ?? "unknown";
7
+ const normalizedRawStage = safeNormalizeStage(rawStage, contract);
8
+ const diagnostics = [];
9
+ const mapped = mapLegacyLifecycle(normalizedRawStage, rawStatus, input.queueStatus ?? null, contract);
10
+ if (normalizedRawStage !== rawStage) {
11
+ diagnostics.push({
12
+ code: "lifecycle_legacy_alias_normalized",
13
+ severity: "info",
14
+ raw_stage: rawStage,
15
+ normalized_stage: normalizedRawStage
16
+ });
17
+ }
18
+ if (mapped.stage === "unknown") {
19
+ diagnostics.push({
20
+ code: "lifecycle_stage_unknown",
21
+ severity: "warning",
22
+ raw_stage: rawStage,
23
+ raw_status: rawStatus
24
+ });
25
+ }
26
+ if (["blocked", "waiting_for_user"].includes(normalizedRawStage) && !mapped.status_reason) {
27
+ diagnostics.push({
28
+ code: "lifecycle_return_stage_missing",
29
+ severity: "warning",
30
+ raw_stage: rawStage,
31
+ summary: `${normalizedRawStage} is a status-like legacy stage without explicit return_to_stage metadata.`
32
+ });
33
+ }
34
+ return {
35
+ flow: nonEmpty(input.flow) ?? "mb_sdlc",
36
+ stage: mapped.stage,
37
+ substage: mapped.substage,
38
+ status: mapped.status,
39
+ status_reason: mapped.status_reason,
40
+ terminal: mapped.terminal,
41
+ legacy_stage: mapped.legacy_stage,
42
+ legacy_status: mapped.legacy_status,
43
+ raw_stage: rawStage,
44
+ raw_status: rawStatus,
45
+ queue_status: input.queueStatus ?? null,
46
+ source,
47
+ diagnostics
48
+ };
49
+ }
50
+ export function lifecycleIsTerminalSuccess(lifecycle) {
51
+ return lifecycle.terminal && lifecycle.status === "done";
52
+ }
53
+ export function lifecycleIsTerminalFailure(lifecycle) {
54
+ return lifecycle.terminal && ["cancelled", "failed"].includes(lifecycle.status);
55
+ }
56
+ export function lifecycleLegacyStage(lifecycle) {
57
+ return lifecycle.legacy_stage ?? lifecycle.raw_stage;
58
+ }
59
+ function mapLegacyLifecycle(stage, rawStatus, queueStatus, contract) {
60
+ if (stage === "registered") {
61
+ return mapped("protocol", null, "registered", "registered", rawStatus, false);
62
+ }
63
+ if (stage === "priming" || stage === "prime") {
64
+ return mapped("specify", "priming", statusFromRaw(rawStatus, "in_progress"), stage, rawStatus, false);
65
+ }
66
+ if (stage === "specify") {
67
+ return mapped("specify", null, statusFromRaw(rawStatus, "in_progress"), null, null, false);
68
+ }
69
+ if (stage === "plan") {
70
+ return mapped("plan", null, statusFromRaw(rawStatus, "in_progress"), null, null, false);
71
+ }
72
+ if (stage === "implementation") {
73
+ return mapped("code", "implementation", statusFromRaw(rawStatus, "in_progress"), "implementation", rawStatus, false);
74
+ }
75
+ if (stage === "readiness") {
76
+ return mapped("code", "readiness", rawStatus === "running" ? "readiness" : statusFromRaw(rawStatus, "readiness"), "readiness", rawStatus, false);
77
+ }
78
+ if (stage === "ready_for_merge") {
79
+ const status = queueStatus && ["ready", "requeued"].includes(queueStatus) ? "ready_for_merge" : "ready_for_merge";
80
+ return mapped("code", null, status, "ready_for_merge", rawStatus, false);
81
+ }
82
+ if (stage === "queued_for_merge") {
83
+ return mapped("merge", null, queueStatus === "claimed" ? "claimed" : "queued", "queued_for_merge", rawStatus, false);
84
+ }
85
+ if (stage === "integration") {
86
+ return mapped("merge", "integration", queueStatus === "claimed" ? "in_progress" : statusFromRaw(rawStatus, "in_progress"), "integration", rawStatus, false);
87
+ }
88
+ if (stage === "blocked") {
89
+ return mapped("unknown", null, "blocked", "blocked", rawStatus, false);
90
+ }
91
+ if (stage === "waiting_for_user") {
92
+ return mapped("unknown", null, "waiting_for_user", "waiting_for_user", rawStatus, false);
93
+ }
94
+ if (stage === "closed") {
95
+ return mapped("closed", null, "done", "closed", rawStatus, true);
96
+ }
97
+ if (stage === "cancelled") {
98
+ return mapped("closed", null, "cancelled", "cancelled", rawStatus, true);
99
+ }
100
+ if (contract.stages[stage]?.terminal) {
101
+ return mapped(stage, null, statusFromRaw(rawStatus, "done"), stage, rawStatus, true);
102
+ }
103
+ if (contract.stages[stage]) {
104
+ return mapped(stage, null, statusFromRaw(rawStatus, "in_progress"), null, null, false);
105
+ }
106
+ return mapped("unknown", null, statusFromRaw(rawStatus, "unknown"), stage, rawStatus, false);
107
+ }
108
+ function mapped(stage, substage, status, legacyStage, legacyStatus, terminal) {
109
+ return {
110
+ stage,
111
+ substage,
112
+ status,
113
+ status_reason: null,
114
+ terminal,
115
+ legacy_stage: legacyStage,
116
+ legacy_status: legacyStatus
117
+ };
118
+ }
119
+ function statusFromRaw(rawStatus, fallback) {
120
+ if (rawStatus === "running")
121
+ return fallback;
122
+ if (rawStatus === "closed")
123
+ return "done";
124
+ if (rawStatus === "registered")
125
+ return "registered";
126
+ if (rawStatus === "waiting_user")
127
+ return "waiting_for_user";
128
+ if (rawStatus === "active")
129
+ return "in_progress";
130
+ if (rawStatus === "unknown")
131
+ return fallback;
132
+ return rawStatus || fallback;
133
+ }
134
+ function safeNormalizeStage(stage, contract) {
135
+ try {
136
+ return normalizeStage(stage, contract);
137
+ }
138
+ catch {
139
+ return stage;
140
+ }
141
+ }
142
+ function nonEmpty(value) {
143
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
144
+ }