@tiangong-lca/cli 0.0.6 → 0.0.7

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 (58) hide show
  1. package/README.md +73 -30
  2. package/dist/src/cli.js +912 -113
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/lib/dataset-local.js +231 -0
  5. package/dist/src/lib/dataset-local.js.map +1 -0
  6. package/dist/src/lib/dataset-references-rewrite.js +214 -0
  7. package/dist/src/lib/dataset-references-rewrite.js.map +1 -0
  8. package/dist/src/lib/dataset-validate.js +191 -0
  9. package/dist/src/lib/dataset-validate.js.map +1 -0
  10. package/dist/src/lib/flow-regen-product.js +2 -10
  11. package/dist/src/lib/flow-regen-product.js.map +1 -1
  12. package/dist/src/lib/flow-remediate.js +4 -8
  13. package/dist/src/lib/flow-remediate.js.map +1 -1
  14. package/dist/src/lib/lifecyclemodel-auto-build.js +11 -8
  15. package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
  16. package/dist/src/lib/lifecyclemodel-graph.js +248 -0
  17. package/dist/src/lib/lifecyclemodel-graph.js.map +1 -0
  18. package/dist/src/lib/lifecyclemodel-publish-build.js +1 -1
  19. package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -1
  20. package/dist/src/lib/lifecyclemodel-save-draft-run.js +245 -0
  21. package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -0
  22. package/dist/src/lib/lifecyclemodel-validate-build.js +1 -1
  23. package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
  24. package/dist/src/lib/process-auto-build.js +11 -8
  25. package/dist/src/lib/process-auto-build.js.map +1 -1
  26. package/dist/src/lib/process-batch-build.js +6 -3
  27. package/dist/src/lib/process-batch-build.js.map +1 -1
  28. package/dist/src/lib/process-dedup-review.js +870 -0
  29. package/dist/src/lib/process-dedup-review.js.map +1 -0
  30. package/dist/src/lib/process-payload-validation.js +50 -0
  31. package/dist/src/lib/process-payload-validation.js.map +1 -0
  32. package/dist/src/lib/process-publish-build.js +4 -6
  33. package/dist/src/lib/process-publish-build.js.map +1 -1
  34. package/dist/src/lib/process-refresh-references.js +1028 -0
  35. package/dist/src/lib/process-refresh-references.js.map +1 -0
  36. package/dist/src/lib/process-resume-build.js +4 -6
  37. package/dist/src/lib/process-resume-build.js.map +1 -1
  38. package/dist/src/lib/process-save-draft-run.js +31 -12
  39. package/dist/src/lib/process-save-draft-run.js.map +1 -1
  40. package/dist/src/lib/process-scope-statistics.js +859 -0
  41. package/dist/src/lib/process-scope-statistics.js.map +1 -0
  42. package/dist/src/lib/process-verify-rows.js +250 -0
  43. package/dist/src/lib/process-verify-rows.js.map +1 -0
  44. package/dist/src/lib/publish.js +1 -1
  45. package/dist/src/lib/publish.js.map +1 -1
  46. package/dist/src/lib/remote.js +4 -4
  47. package/dist/src/lib/remote.js.map +1 -1
  48. package/dist/src/lib/review-lifecyclemodel.js +2 -2
  49. package/dist/src/lib/review-lifecyclemodel.js.map +1 -1
  50. package/dist/src/lib/tidas-sdk-package-validator.js +28 -9
  51. package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
  52. package/dist/src/lib/tidas-sdk-validation.js +96 -0
  53. package/dist/src/lib/tidas-sdk-validation.js.map +1 -0
  54. package/dist/src/lib/user-api-key.js +1 -1
  55. package/dist/src/lib/user-api-key.js.map +1 -1
  56. package/package.json +4 -4
  57. /package/bin/{tiangong.d.ts → tiangong-lca.d.ts} +0 -0
  58. /package/bin/{tiangong.js → tiangong-lca.js} +0 -0
package/dist/src/cli.js CHANGED
@@ -8,14 +8,20 @@ import { runLifecyclemodelBuildResultingProcess, } from './lib/lifecyclemodel-re
8
8
  import { runLifecyclemodelPublishResultingProcess, } from './lib/lifecyclemodel-publish-resulting-process.js';
9
9
  import { runLifecyclemodelValidateBuild, } from './lib/lifecyclemodel-validate-build.js';
10
10
  import { runLifecyclemodelPublishBuild, } from './lib/lifecyclemodel-publish-build.js';
11
+ import { runLifecyclemodelSaveDraft, } from './lib/lifecyclemodel-save-draft-run.js';
12
+ import { runLifecyclemodelGraph, } from './lib/lifecyclemodel-graph.js';
11
13
  import { runLifecyclemodelOrchestrate, } from './lib/lifecyclemodel-orchestrate.js';
12
14
  import { runProcessAutoBuild, } from './lib/process-auto-build.js';
13
15
  import { runProcessGet, } from './lib/process-get.js';
14
16
  import { runProcessList, } from './lib/process-list.js';
15
17
  import { runProcessBatchBuild, } from './lib/process-batch-build.js';
18
+ import { runProcessScopeStatistics, } from './lib/process-scope-statistics.js';
19
+ import { runProcessRefreshReferences, } from './lib/process-refresh-references.js';
20
+ import { runProcessDedupReview, } from './lib/process-dedup-review.js';
16
21
  import { runProcessResumeBuild, } from './lib/process-resume-build.js';
17
22
  import { runProcessPublishBuild, } from './lib/process-publish-build.js';
18
23
  import { runProcessSaveDraft, } from './lib/process-save-draft-run.js';
24
+ import { runProcessVerifyRows, } from './lib/process-verify-rows.js';
19
25
  import { runPublish } from './lib/publish.js';
20
26
  import { runProcessReview, } from './lib/review-process.js';
21
27
  import { runFlowReview, } from './lib/review-flow.js';
@@ -31,6 +37,8 @@ import { runFlowBuildAliasMap, } from './lib/flow-build-alias-map.js';
31
37
  import { runFlowApplyProcessFlowRepairs, runFlowPlanProcessFlowRepairs, runFlowRegenProduct, runFlowScanProcessFlowRefs, runFlowValidateProcesses, } from './lib/flow-regen-product.js';
32
38
  import { executeRemoteCommand, getRemoteCommandHelp } from './lib/remote.js';
33
39
  import { runValidation, } from './lib/validation.js';
40
+ import { runDatasetValidate, } from './lib/dataset-validate.js';
41
+ import { runDatasetReferencesRewrite, } from './lib/dataset-references-rewrite.js';
34
42
  function renderMainHelp(dotEnvStatus) {
35
43
  return `TianGong LCA CLI
36
44
 
@@ -43,15 +51,16 @@ Design principles:
43
51
  - file-first input and JSON-first output
44
52
 
45
53
  Usage:
46
- tiangong <command> [subcommand] [options]
54
+ tiangong-lca <command> [subcommand] [options]
47
55
 
48
56
  Commands:
49
57
  Implemented Commands:
50
58
  doctor show environment diagnostics
51
59
  search flow | process | lifecyclemodel
52
- process get | list | auto-build | resume-build | publish-build | save-draft | batch-build
60
+ process get | list | scope-statistics | dedup-review | auto-build | resume-build | publish-build | save-draft | batch-build | refresh-references | verify-rows
61
+ dataset validate | references rewrite
53
62
  flow get | list | fetch-rows | materialize-decisions | remediate | publish-version | publish-reviewed-data | build-alias-map | scan-process-flow-refs | plan-process-flow-repairs | apply-process-flow-repairs | regen-product | validate-processes
54
- lifecyclemodel auto-build | validate-build | publish-build | build-resulting-process | publish-resulting-process | orchestrate
63
+ lifecyclemodel auto-build | validate-build | publish-build | save-draft | graph | build-resulting-process | publish-resulting-process | orchestrate
55
64
  review process | flow | lifecyclemodel
56
65
  publish run
57
66
  validation run
@@ -64,40 +73,48 @@ Planned Surface (not implemented yet):
64
73
  Planned commands currently print an explicit "not implemented yet" message and exit with code 2.
65
74
 
66
75
  Examples:
67
- tiangong doctor
68
- tiangong search flow --input ./request.json
69
- tiangong search process --input ./request.json --dry-run
70
- tiangong process get --id <process-id>
71
- tiangong process list --state-code 100 --limit 20
72
- tiangong process auto-build --input ./pff-request.json
73
- tiangong process resume-build --run-id <id>
74
- tiangong process publish-build --run-id <id>
75
- tiangong process save-draft --input ./patched-processes.jsonl --dry-run
76
- tiangong process batch-build --input ./batch-request.json
77
- tiangong lifecyclemodel auto-build --input ./lifecyclemodel-auto-build.request.json
78
- tiangong lifecyclemodel validate-build --run-dir ./artifacts/lifecyclemodel_auto_build/<run_id>
79
- tiangong lifecyclemodel publish-build --run-dir ./artifacts/lifecyclemodel_auto_build/<run_id>
80
- tiangong lifecyclemodel orchestrate plan --input ./lifecyclemodel-orchestrate.request.json --out-dir ./artifacts/lifecyclemodel_recursive/run-001
81
- tiangong flow get --id <flow-id> --version <version>
82
- tiangong flow list --id <flow-id> --state-code 100 --limit 20
83
- tiangong flow fetch-rows --refs-file ./flow-refs.json --out-dir ./flow-fetch
84
- tiangong flow materialize-decisions --decision-file ./approved-decisions.json --flow-rows-file ./review-input-rows.jsonl --out-dir ./flow-decisions
85
- tiangong flow remediate --input-file ./invalid-flows.jsonl --out-dir ./flow-remediation
86
- tiangong flow publish-version --input-file ./ready-flows.jsonl --out-dir ./flow-publish --commit
87
- tiangong flow publish-reviewed-data --flow-rows-file ./reviewed-flows.jsonl --original-flow-rows-file ./original-flows.jsonl --out-dir ./flow-publish-review
88
- tiangong flow build-alias-map --old-flow-file ./old-flows.jsonl --new-flow-file ./new-flows.jsonl --out-dir ./flow-alias-map
89
- tiangong flow scan-process-flow-refs --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-scan
90
- tiangong flow plan-process-flow-repairs --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-repair-plan
91
- tiangong flow apply-process-flow-repairs --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-repair-apply
92
- tiangong flow regen-product --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-regeneration --apply
93
- tiangong flow validate-processes --original-processes-file ./before.jsonl --patched-processes-file ./after.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-validation
94
- tiangong review process --rows-file ./processes.jsonl --out-dir ./review
95
- tiangong review process --run-root ./artifacts/process_from_flow/<run_id> --run-id <run_id> --out-dir ./review
96
- tiangong review flow --rows-file ./flows.json --out-dir ./review
97
- tiangong review lifecyclemodel --run-dir ./artifacts/lifecyclemodel_auto_build/<run_id> --out-dir ./lifecyclemodel-review
98
- tiangong publish run --input ./publish-request.json --dry-run
99
- tiangong validation run --input-dir ./package --engine auto
100
- tiangong admin embedding-run --input ./jobs.json
76
+ tiangong-lca doctor
77
+ tiangong-lca search flow --input ./request.json
78
+ tiangong-lca search process --input ./request.json --dry-run
79
+ tiangong-lca process get --id <process-id>
80
+ tiangong-lca process list --state-code 100 --limit 20
81
+ tiangong-lca process scope-statistics --out-dir /abs/path/to/process-scope --state-code 0 --state-code 100
82
+ tiangong-lca process dedup-review --input ./duplicate-groups.json --out-dir /abs/path/to/process-dedup
83
+ tiangong-lca process auto-build --input ./pff-request.json --out-dir /abs/path/to/process-run
84
+ tiangong-lca process resume-build --run-dir /abs/path/to/process-run
85
+ tiangong-lca process publish-build --run-dir /abs/path/to/process-run
86
+ tiangong-lca process save-draft --input ./patched-processes.jsonl --out-dir /abs/path/to/process-save-draft --dry-run
87
+ tiangong-lca process batch-build --input ./batch-request.json --out-dir /abs/path/to/process-batch
88
+ tiangong-lca process refresh-references --out-dir /abs/path/to/process-refresh --dry-run
89
+ tiangong-lca process verify-rows --rows-file ./process-list-report.json --out-dir /abs/path/to/process-verify
90
+ tiangong-lca dataset validate --input ./rows.jsonl --type auto --out-dir /abs/path/to/dataset-validate
91
+ tiangong-lca dataset references rewrite --input ./rows.jsonl --from flow:<old-id>@<old-version> --to flow:<new-id>@<new-version> --out-dir /abs/path/to/dataset-rewrite
92
+ tiangong-lca lifecyclemodel auto-build --input ./lifecyclemodel-auto-build.request.json --out-dir /abs/path/to/lifecyclemodel-run
93
+ tiangong-lca lifecyclemodel validate-build --run-dir /abs/path/to/lifecyclemodel-run
94
+ tiangong-lca lifecyclemodel publish-build --run-dir /abs/path/to/lifecyclemodel-run
95
+ tiangong-lca lifecyclemodel save-draft --input ./lifecyclemodels.jsonl --out-dir /abs/path/to/lifecyclemodel-save-draft --dry-run
96
+ tiangong-lca lifecyclemodel graph --input ./lifecyclemodels.jsonl --out-dir /abs/path/to/lifecyclemodel-graph --format all
97
+ tiangong-lca lifecyclemodel orchestrate plan --input ./lifecyclemodel-orchestrate.request.json --out-dir /abs/path/to/lifecyclemodel-recursive-run
98
+ tiangong-lca flow get --id <flow-id> --version <version>
99
+ tiangong-lca flow list --id <flow-id> --state-code 100 --limit 20
100
+ tiangong-lca flow fetch-rows --refs-file ./flow-refs.json --out-dir ./flow-fetch
101
+ tiangong-lca flow materialize-decisions --decision-file ./approved-decisions.json --flow-rows-file ./review-input-rows.jsonl --out-dir ./flow-decisions
102
+ tiangong-lca flow remediate --input-file ./invalid-flows.jsonl --out-dir ./flow-remediation
103
+ tiangong-lca flow publish-version --input-file ./ready-flows.jsonl --out-dir ./flow-publish --commit
104
+ tiangong-lca flow publish-reviewed-data --flow-rows-file ./reviewed-flows.jsonl --original-flow-rows-file ./original-flows.jsonl --out-dir ./flow-publish-review
105
+ tiangong-lca flow build-alias-map --old-flow-file ./old-flows.jsonl --new-flow-file ./new-flows.jsonl --out-dir ./flow-alias-map
106
+ tiangong-lca flow scan-process-flow-refs --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-scan
107
+ tiangong-lca flow plan-process-flow-repairs --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-repair-plan
108
+ tiangong-lca flow apply-process-flow-repairs --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-repair-apply
109
+ tiangong-lca flow regen-product --processes-file ./processes.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-regeneration --apply
110
+ tiangong-lca flow validate-processes --original-processes-file ./before.jsonl --patched-processes-file ./after.jsonl --scope-flow-file ./flows.jsonl --out-dir ./flow-validation
111
+ tiangong-lca review process --rows-file ./processes.jsonl --out-dir ./review
112
+ tiangong-lca review process --run-root /abs/path/to/process-run --run-id <run_id> --out-dir ./review
113
+ tiangong-lca review flow --rows-file ./flows.json --out-dir ./review
114
+ tiangong-lca review lifecyclemodel --run-dir /abs/path/to/lifecyclemodel-run --out-dir ./lifecyclemodel-review
115
+ tiangong-lca publish run --input ./publish-request.json --dry-run
116
+ tiangong-lca validation run --input-dir ./package --engine auto
117
+ tiangong-lca admin embedding-run --input ./jobs.json
101
118
 
102
119
  Environment:
103
120
  .env loaded: ${dotEnvStatus.loaded ? `yes (${dotEnvStatus.path}, ${dotEnvStatus.count} keys)` : 'no'}
@@ -105,7 +122,7 @@ Environment:
105
122
  }
106
123
  function renderDoctorHelp() {
107
124
  return `Usage:
108
- tiangong doctor [--json]
125
+ tiangong-lca doctor [--json]
109
126
 
110
127
  Options:
111
128
  --json Print structured environment diagnostics
@@ -114,7 +131,7 @@ Options:
114
131
  }
115
132
  function renderSearchHelp() {
116
133
  return `Usage:
117
- tiangong search <flow|process|lifecyclemodel> --input <file> [options]
134
+ tiangong-lca search <flow|process|lifecyclemodel> --input <file> [options]
118
135
 
119
136
  Options:
120
137
  --input <file> JSON request file
@@ -139,7 +156,7 @@ Runtime note:
139
156
  }
140
157
  function renderAdminHelp() {
141
158
  return `Usage:
142
- tiangong admin embedding-run --input <file> [options]
159
+ tiangong-lca admin embedding-run --input <file> [options]
143
160
 
144
161
  Options:
145
162
  --input <file> JSON request file
@@ -162,7 +179,7 @@ Runtime note:
162
179
  }
163
180
  function renderPublishHelp() {
164
181
  return `Usage:
165
- tiangong publish run --input <file> [options]
182
+ tiangong-lca publish run --input <file> [options]
166
183
 
167
184
  Options:
168
185
  --input <file> JSON publish request file
@@ -178,7 +195,7 @@ Path rule:
178
195
  }
179
196
  function renderValidationHelp() {
180
197
  return `Usage:
181
- tiangong validation run --input-dir <dir> [options]
198
+ tiangong-lca validation run --input-dir <dir> [options]
182
199
 
183
200
  Options:
184
201
  --input-dir <dir> TIDAS package directory
@@ -188,9 +205,67 @@ Options:
188
205
  -h, --help
189
206
  `.trim();
190
207
  }
208
+ function renderDatasetHelp() {
209
+ return `Usage:
210
+ tiangong-lca dataset <subcommand> [options]
211
+
212
+ Implemented Subcommands:
213
+ validate Validate local flow / process / lifecyclemodel rows with the TIDAS SDK
214
+ references rewrite Rewrite flow references in local process and lifecyclemodel rows
215
+
216
+ Examples:
217
+ tiangong-lca dataset validate --input ./rows.jsonl --type auto --out-dir ./dataset-validate --help
218
+ tiangong-lca dataset references rewrite --input ./rows.jsonl --from flow:<old-id>@<old-version> --to flow:<new-id>@<new-version> --out-dir ./dataset-rewrite --help
219
+ `.trim();
220
+ }
221
+ function renderDatasetValidateHelp() {
222
+ return `Usage:
223
+ tiangong-lca dataset validate --input <file> [options]
224
+
225
+ Options:
226
+ --input <file> Local rows as JSON or JSONL; objects with rows[] are also accepted
227
+ --type <type> auto | flow | process | lifecyclemodel (default: auto)
228
+ --out-dir <dir> Optional artifact directory for validation report and row splits
229
+ --json Print compact JSON
230
+ -h, --help
231
+
232
+ Outputs written under --out-dir:
233
+ - outputs/validation-report.json
234
+ - outputs/valid-rows.jsonl
235
+ - outputs/invalid-rows.jsonl
236
+ `.trim();
237
+ }
238
+ function renderDatasetReferencesHelp() {
239
+ return `Usage:
240
+ tiangong-lca dataset references rewrite --input <file> --from flow:<id>[@<version>] --to flow:<id>[@<version>] [options]
241
+
242
+ Options:
243
+ --input <file> Local rows as JSON or JSONL; process and lifecyclemodel rows are supported
244
+ --from <ref> Source flow reference, for example flow:<old-id>@01.00.000
245
+ --to <ref> Target flow reference, for example flow:<new-id>@01.01.000
246
+ --type <type> Repeatable row type filter: process | lifecyclemodel (default: both)
247
+ --types <csv> Comma-separated alias for one or more row types
248
+ --scope <label> Optional artifact label for the already-frozen input scope
249
+ --out-dir <dir> Artifact directory for rewrite plan and patched rows
250
+ --commit Execute state-aware save-draft writes for patched rows
251
+ --dry-run Keep the command local-only (default)
252
+ --json Print compact JSON
253
+ -h, --help
254
+
255
+ Environment:
256
+ none for local dry-run
257
+ TIANGONG_LCA_API_BASE_URL, TIANGONG_LCA_API_KEY, and TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY
258
+ when --commit executes remote writes
259
+
260
+ Outputs written under --out-dir:
261
+ - outputs/patched-rows.jsonl
262
+ - outputs/rewrite-plan.json
263
+ - outputs/summary.json
264
+ `.trim();
265
+ }
191
266
  function renderFlowHelp() {
192
267
  return `Usage:
193
- tiangong flow <subcommand> [options]
268
+ tiangong-lca flow <subcommand> [options]
194
269
 
195
270
  Implemented Subcommands:
196
271
  get Load one flow dataset by identifier through direct Supabase access
@@ -208,25 +283,25 @@ Implemented Subcommands:
208
283
  validate-processes Validate locally patched process rows against allowed flow-reference-only changes
209
284
 
210
285
  Examples:
211
- tiangong flow --help
212
- tiangong flow get --help
213
- tiangong flow list --help
214
- tiangong flow fetch-rows --help
215
- tiangong flow materialize-decisions --help
216
- tiangong flow remediate --help
217
- tiangong flow publish-version --help
218
- tiangong flow publish-reviewed-data --help
219
- tiangong flow build-alias-map --help
220
- tiangong flow scan-process-flow-refs --help
221
- tiangong flow plan-process-flow-repairs --help
222
- tiangong flow apply-process-flow-repairs --help
223
- tiangong flow regen-product --help
224
- tiangong flow validate-processes --help
286
+ tiangong-lca flow --help
287
+ tiangong-lca flow get --help
288
+ tiangong-lca flow list --help
289
+ tiangong-lca flow fetch-rows --help
290
+ tiangong-lca flow materialize-decisions --help
291
+ tiangong-lca flow remediate --help
292
+ tiangong-lca flow publish-version --help
293
+ tiangong-lca flow publish-reviewed-data --help
294
+ tiangong-lca flow build-alias-map --help
295
+ tiangong-lca flow scan-process-flow-refs --help
296
+ tiangong-lca flow plan-process-flow-repairs --help
297
+ tiangong-lca flow apply-process-flow-repairs --help
298
+ tiangong-lca flow regen-product --help
299
+ tiangong-lca flow validate-processes --help
225
300
  `.trim();
226
301
  }
227
302
  function renderFlowGetHelp() {
228
303
  return `Usage:
229
- tiangong flow get --id <flow-id> [options]
304
+ tiangong-lca flow get --id <flow-id> [options]
230
305
 
231
306
  Options:
232
307
  --id <flow-id> Flow UUID
@@ -248,7 +323,7 @@ Runtime note:
248
323
  }
249
324
  function renderFlowListHelp() {
250
325
  return `Usage:
251
- tiangong flow list [options]
326
+ tiangong-lca flow list [options]
252
327
 
253
328
  Options:
254
329
  --id <flow-id> Repeatable exact flow UUID filter
@@ -276,7 +351,7 @@ Runtime note:
276
351
  }
277
352
  function renderFlowRemediateHelp() {
278
353
  return `Usage:
279
- tiangong flow remediate --input-file <file> --out-dir <dir> [options]
354
+ tiangong-lca flow remediate --input-file <file> --out-dir <dir> [options]
280
355
 
281
356
  Options:
282
357
  --input-file <file> Invalid flow rows as JSON or JSONL
@@ -295,7 +370,7 @@ Outputs written under --out-dir:
295
370
  }
296
371
  function renderFlowFetchRowsHelp() {
297
372
  return `Usage:
298
- tiangong flow fetch-rows --refs-file <file> --out-dir <dir> [options]
373
+ tiangong-lca flow fetch-rows --refs-file <file> --out-dir <dir> [options]
299
374
 
300
375
  Options:
301
376
  --refs-file <file> Flow refs as JSON or JSONL
@@ -320,7 +395,7 @@ Outputs written under --out-dir:
320
395
  }
321
396
  function renderFlowMaterializeDecisionsHelp() {
322
397
  return `Usage:
323
- tiangong flow materialize-decisions --decision-file <file> --flow-rows-file <file> --out-dir <dir> [options]
398
+ tiangong-lca flow materialize-decisions --decision-file <file> --flow-rows-file <file> --out-dir <dir> [options]
324
399
 
325
400
  Options:
326
401
  --decision-file <file> Approved cluster decisions as JSON or JSONL
@@ -339,7 +414,7 @@ Outputs written under --out-dir:
339
414
  }
340
415
  function renderFlowPublishVersionHelp() {
341
416
  return `Usage:
342
- tiangong flow publish-version --input-file <file> --out-dir <dir> [options]
417
+ tiangong-lca flow publish-version --input-file <file> --out-dir <dir> [options]
343
418
 
344
419
  Options:
345
420
  --input-file <file> Ready-for-publish flow rows as JSON or JSONL
@@ -365,7 +440,7 @@ Outputs written under --out-dir:
365
440
  }
366
441
  function renderFlowPublishReviewedDataHelp() {
367
442
  return `Usage:
368
- tiangong flow publish-reviewed-data --out-dir <dir> [--flow-rows-file <file>] [--process-rows-file <file>] [options]
443
+ tiangong-lca flow publish-reviewed-data --out-dir <dir> [--flow-rows-file <file>] [--process-rows-file <file>] [options]
369
444
 
370
445
  Options:
371
446
  --flow-rows-file <file> Reviewed flow rows as JSON or JSONL
@@ -400,7 +475,7 @@ Outputs written under --out-dir:
400
475
  }
401
476
  function renderFlowBuildAliasMapHelp() {
402
477
  return `Usage:
403
- tiangong flow build-alias-map --old-flow-file <file> --new-flow-file <file> --out-dir <dir> [options]
478
+ tiangong-lca flow build-alias-map --old-flow-file <file> --new-flow-file <file> --out-dir <dir> [options]
404
479
 
405
480
  Options:
406
481
  --old-flow-file <file> Repeatable pre-governance flow snapshot as JSON or JSONL
@@ -420,7 +495,7 @@ Outputs written under --out-dir:
420
495
  }
421
496
  function renderFlowScanProcessFlowRefsHelp() {
422
497
  return `Usage:
423
- tiangong flow scan-process-flow-refs --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
498
+ tiangong-lca flow scan-process-flow-refs --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
424
499
 
425
500
  Options:
426
501
  --processes-file <file> Process rows as JSON or JSONL
@@ -441,7 +516,7 @@ Outputs written under --out-dir:
441
516
  }
442
517
  function renderFlowPlanProcessFlowRepairsHelp() {
443
518
  return `Usage:
444
- tiangong flow plan-process-flow-repairs --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
519
+ tiangong-lca flow plan-process-flow-repairs --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
445
520
 
446
521
  Options:
447
522
  --processes-file <file> Process rows as JSON or JSONL
@@ -462,7 +537,7 @@ Outputs written under --out-dir:
462
537
  }
463
538
  function renderFlowApplyProcessFlowRepairsHelp() {
464
539
  return `Usage:
465
- tiangong flow apply-process-flow-repairs --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
540
+ tiangong-lca flow apply-process-flow-repairs --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
466
541
 
467
542
  Options:
468
543
  --processes-file <file> Process rows as JSON or JSONL
@@ -486,7 +561,7 @@ Outputs written under --out-dir:
486
561
  }
487
562
  function renderFlowRegenProductHelp() {
488
563
  return `Usage:
489
- tiangong flow regen-product --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
564
+ tiangong-lca flow regen-product --processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
490
565
 
491
566
  Options:
492
567
  --processes-file <file> Process rows as JSON or JSONL
@@ -512,7 +587,7 @@ Outputs written under --out-dir:
512
587
  }
513
588
  function renderFlowValidateProcessesHelp() {
514
589
  return `Usage:
515
- tiangong flow validate-processes --original-processes-file <file> --patched-processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
590
+ tiangong-lca flow validate-processes --original-processes-file <file> --patched-processes-file <file> --scope-flow-file <file> --out-dir <dir> [options]
516
591
 
517
592
  Options:
518
593
  --original-processes-file <file> Original process rows before repair as JSON or JSONL
@@ -530,7 +605,7 @@ Outputs written under --out-dir:
530
605
  }
531
606
  function renderReviewHelp() {
532
607
  return `Usage:
533
- tiangong review <subcommand> [options]
608
+ tiangong-lca review <subcommand> [options]
534
609
 
535
610
  Implemented Subcommands:
536
611
  process Review process build runs or rows-file snapshots and emit artifact-first findings
@@ -538,15 +613,15 @@ Implemented Subcommands:
538
613
  lifecyclemodel Review one local lifecyclemodel build run and emit artifact-first findings
539
614
 
540
615
  Examples:
541
- tiangong review --help
542
- tiangong review process --help
543
- tiangong review flow --help
544
- tiangong review lifecyclemodel --help
616
+ tiangong-lca review --help
617
+ tiangong-lca review process --help
618
+ tiangong-lca review flow --help
619
+ tiangong-lca review lifecyclemodel --help
545
620
  `.trim();
546
621
  }
547
622
  function renderReviewProcessHelp() {
548
623
  return `Usage:
549
- tiangong review process (--rows-file <file> | --run-root <dir>) --out-dir <dir> [options]
624
+ tiangong-lca review process (--rows-file <file> | --run-root <dir>) --out-dir <dir> [options]
550
625
 
551
626
  Options:
552
627
  --rows-file <file> Process rows JSON/JSONL file; full process list reports with rows[] are also accepted
@@ -565,7 +640,7 @@ Options:
565
640
  }
566
641
  function renderReviewFlowHelp() {
567
642
  return `Usage:
568
- tiangong review flow (--rows-file <file> | --flows-dir <dir> | --run-root <dir>) --out-dir <dir> [options]
643
+ tiangong-lca review flow (--rows-file <file> | --flows-dir <dir> | --run-root <dir>) --out-dir <dir> [options]
569
644
 
570
645
  Options:
571
646
  --rows-file <file> Flow rows JSON / JSONL file; the CLI materializes review-input/flows automatically
@@ -588,7 +663,7 @@ Options:
588
663
  }
589
664
  function renderReviewLifecyclemodelHelp() {
590
665
  return `Usage:
591
- tiangong review lifecyclemodel --run-dir <dir> --out-dir <dir> [options]
666
+ tiangong-lca review lifecyclemodel --run-dir <dir> --out-dir <dir> [options]
592
667
 
593
668
  Options:
594
669
  --run-dir <dir> Existing lifecyclemodel auto-build run directory
@@ -607,7 +682,7 @@ This command:
607
682
  }
608
683
  function renderLifecyclemodelBuildResultingProcessHelp() {
609
684
  return `Usage:
610
- tiangong lifecyclemodel build-resulting-process --input <file> [options]
685
+ tiangong-lca lifecyclemodel build-resulting-process --input <file> [options]
611
686
 
612
687
  Options:
613
688
  --input <file> JSON request file
@@ -623,7 +698,7 @@ Remote lookup env (only when process_sources.allow_remote_lookup=true):
623
698
  }
624
699
  function renderLifecyclemodelPublishResultingProcessHelp() {
625
700
  return `Usage:
626
- tiangong lifecyclemodel publish-resulting-process --run-dir <dir> [options]
701
+ tiangong-lca lifecyclemodel publish-resulting-process --run-dir <dir> [options]
627
702
 
628
703
  Options:
629
704
  --run-dir <dir> Existing lifecyclemodel resulting-process run directory
@@ -633,30 +708,83 @@ Options:
633
708
  -h, --help
634
709
  `.trim();
635
710
  }
711
+ function renderLifecyclemodelSaveDraftHelp() {
712
+ return `Usage:
713
+ tiangong-lca lifecyclemodel save-draft --input <file> [options]
714
+
715
+ Options:
716
+ --input <file> Lifecyclemodel rows JSON/JSONL file or publish-request.json
717
+ --out-dir <dir> Run root written relative to cwd when a relative path is passed
718
+ --commit Execute remote save-draft writes
719
+ --dry-run Keep the command local-only (default)
720
+ --json Print compact JSON
721
+ -h, --help
722
+
723
+ Environment:
724
+ none for local dry-run
725
+ TIANGONG_LCA_API_BASE_URL, TIANGONG_LCA_API_KEY, and TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY
726
+ when --commit executes remote writes
727
+
728
+ Local gate:
729
+ canonical lifecyclemodel payloads are validated against LifeCycleModelSchema before any remote write;
730
+ schema-invalid rows stay in failures.jsonl instead of being committed
731
+
732
+ Outputs written under --out-dir:
733
+ - inputs/normalized-input.json
734
+ - outputs/save-draft-bundle/selected-lifecyclemodels.jsonl
735
+ - outputs/save-draft-bundle/progress.jsonl
736
+ - outputs/save-draft-bundle/failures.jsonl
737
+ - outputs/save-draft-bundle/summary.json
738
+ `.trim();
739
+ }
740
+ function renderLifecyclemodelGraphHelp() {
741
+ return `Usage:
742
+ tiangong-lca lifecyclemodel graph --input <file> [options]
743
+
744
+ Options:
745
+ --input <file> Lifecyclemodel rows JSON/JSONL file
746
+ --out-dir <dir> Artifact directory for graph files and findings
747
+ --format <format> json | dot | svg | all (default: all)
748
+ --check-connections Fail when process-instance links are missing or unresolved
749
+ --json Print compact JSON
750
+ -h, --help
751
+
752
+ Outputs written under --out-dir:
753
+ - outputs/graph-report.json
754
+ - outputs/findings.jsonl
755
+ - graphs/*.json
756
+ - graphs/*.dot
757
+ - graphs/*.svg
758
+ `.trim();
759
+ }
636
760
  function renderLifecyclemodelHelp() {
637
761
  return `Usage:
638
- tiangong lifecyclemodel <subcommand> [options]
762
+ tiangong-lca lifecyclemodel <subcommand> [options]
639
763
 
640
764
  Implemented Subcommands:
641
765
  auto-build Build native lifecyclemodel json_ordered artifacts from local process run exports
642
766
  validate-build Re-run local validation on one lifecyclemodel build run
643
767
  publish-build Prepare lifecyclemodel publish handoff artifacts from one local build run
768
+ save-draft Save canonical lifecyclemodel datasets through the bundle save path
769
+ graph Derive lifecyclemodel graph artifacts and connection findings
644
770
  build-resulting-process Deterministically aggregate a lifecycle model into a resulting process bundle
645
771
  publish-resulting-process Prepare publish-bundle.json and publish-intent.json from a prior resulting-process run
646
772
  orchestrate Plan, execute, or publish a recursive lifecyclemodel assembly run
647
773
 
648
774
  Examples:
649
- tiangong lifecyclemodel --help
650
- tiangong lifecyclemodel auto-build --help
651
- tiangong lifecyclemodel validate-build --help
652
- tiangong lifecyclemodel publish-build --help
653
- tiangong lifecyclemodel build-resulting-process --help
654
- tiangong lifecyclemodel orchestrate --help
775
+ tiangong-lca lifecyclemodel --help
776
+ tiangong-lca lifecyclemodel auto-build --help
777
+ tiangong-lca lifecyclemodel validate-build --help
778
+ tiangong-lca lifecyclemodel publish-build --help
779
+ tiangong-lca lifecyclemodel save-draft --help
780
+ tiangong-lca lifecyclemodel graph --help
781
+ tiangong-lca lifecyclemodel build-resulting-process --help
782
+ tiangong-lca lifecyclemodel orchestrate --help
655
783
  `.trim();
656
784
  }
657
785
  function renderLifecyclemodelOrchestrateHelp() {
658
786
  return `Usage:
659
- tiangong lifecyclemodel orchestrate <plan|execute|publish> [options]
787
+ tiangong-lca lifecyclemodel orchestrate <plan|execute|publish> [options]
660
788
 
661
789
  Plan / execute options:
662
790
  --input <file> JSON request file
@@ -682,11 +810,11 @@ This command:
682
810
  }
683
811
  function renderLifecyclemodelAutoBuildHelp() {
684
812
  return `Usage:
685
- tiangong lifecyclemodel auto-build --input <file> [options]
813
+ tiangong-lca lifecyclemodel auto-build --input <file> [options]
686
814
 
687
815
  Options:
688
816
  --input <file> JSON request file
689
- --out-dir <dir> Override the default lifecyclemodel build run root
817
+ --out-dir <dir> Explicit run root; otherwise request.out_dir is required
690
818
  --json Print compact JSON
691
819
  -h, --help
692
820
 
@@ -696,6 +824,7 @@ Minimal request contract:
696
824
  }
697
825
 
698
826
  This first CLI slice is local-only and read-only:
827
+ - applies no implicit repo-local ./artifacts fallback; callers must provide a run root
699
828
  - loads local process build run directories
700
829
  - infers the process graph from shared flow UUIDs
701
830
  - emits native lifecyclemodel json_ordered artifacts
@@ -704,7 +833,7 @@ This first CLI slice is local-only and read-only:
704
833
  }
705
834
  function renderLifecyclemodelValidateBuildHelp() {
706
835
  return `Usage:
707
- tiangong lifecyclemodel validate-build --run-dir <dir> [options]
836
+ tiangong-lca lifecyclemodel validate-build --run-dir <dir> [options]
708
837
 
709
838
  Options:
710
839
  --run-dir <dir> Existing lifecyclemodel auto-build run directory
@@ -720,7 +849,7 @@ This command:
720
849
  }
721
850
  function renderLifecyclemodelPublishBuildHelp() {
722
851
  return `Usage:
723
- tiangong lifecyclemodel publish-build --run-dir <dir> [options]
852
+ tiangong-lca lifecyclemodel publish-build --run-dir <dir> [options]
724
853
 
725
854
  Options:
726
855
  --run-dir <dir> Existing lifecyclemodel auto-build run directory
@@ -730,24 +859,26 @@ Options:
730
859
  This command:
731
860
  - collects native lifecyclemodel json_ordered payloads from one local build run
732
861
  - writes publish-bundle.json, publish-request.json, and publish-intent.json
733
- - keeps actual dry-run / commit execution in tiangong publish run
862
+ - keeps actual dry-run / commit execution in tiangong-lca publish run
734
863
  - routes lifecyclemodel commit through save_lifecycle_model_bundle internally
735
864
  `.trim();
736
865
  }
737
866
  function renderProcessAutoBuildHelp() {
738
867
  return `Usage:
739
- tiangong process auto-build --input <file> [options]
868
+ tiangong-lca process auto-build --input <file> [options]
740
869
 
741
870
  Options:
742
871
  --input <file> JSON request file
743
- --out-dir <dir> Override the default run root directory
872
+ --out-dir <dir> Explicit run root; otherwise request.workspace_run_root is required
744
873
  --json Print compact JSON
745
874
  -h, --help
875
+
876
+ This command applies no implicit repo-local ./artifacts fallback.
746
877
  `.trim();
747
878
  }
748
879
  function renderProcessGetHelp() {
749
880
  return `Usage:
750
- tiangong process get --id <process-id> [options]
881
+ tiangong-lca process get --id <process-id> [options]
751
882
 
752
883
  Options:
753
884
  --id <process-id> Process UUID
@@ -767,7 +898,7 @@ Runtime note:
767
898
  }
768
899
  function renderProcessListHelp() {
769
900
  return `Usage:
770
- tiangong process list [options]
901
+ tiangong-lca process list [options]
771
902
 
772
903
  Options:
773
904
  --id <process-id> Repeatable exact process UUID filter
@@ -792,31 +923,102 @@ Runtime note:
792
923
  and authenticates that client with the resolved user access token.
793
924
  `.trim();
794
925
  }
926
+ function renderProcessScopeStatisticsHelp() {
927
+ return `Usage:
928
+ tiangong-lca process scope-statistics --out-dir <dir> [options]
929
+
930
+ Options:
931
+ --out-dir <dir> Artifact root to write inputs/outputs/reports
932
+ --scope <name> visible | current-user (default: visible)
933
+ --state-code <code> Repeatable non-negative integer state code filter
934
+ --state-codes <csv> Comma-separated alias for one or more state codes
935
+ --page-size <n> Remote page size (default: 200)
936
+ --reuse-snapshot Reuse inputs/processes.snapshot.rows.jsonl instead of refetching
937
+ --json Print compact JSON
938
+ -h, --help
939
+
940
+ Outputs written under --out-dir:
941
+ - inputs/processes.snapshot.manifest.json
942
+ - inputs/processes.snapshot.rows.jsonl
943
+ - outputs/process-scope-summary.json
944
+ - outputs/domain-summary.json
945
+ - outputs/craft-summary.json
946
+ - outputs/product-summary.json
947
+ - outputs/type-of-dataset-summary.json
948
+ - reports/process-scope-statistics.md
949
+ - reports/process-scope-statistics.zh-CN.md
950
+ `.trim();
951
+ }
952
+ function renderProcessDedupReviewHelp() {
953
+ return `Usage:
954
+ tiangong-lca process dedup-review --input <file> --out-dir <dir> [options]
955
+
956
+ Options:
957
+ --input <file> Grouped duplicate-candidate JSON input
958
+ --out-dir <dir> Artifact root to write inputs/outputs
959
+ --skip-remote Skip optional TianGong remote enrichment and reference scans
960
+ --json Print compact JSON
961
+ -h, --help
962
+
963
+ Input contract:
964
+ {
965
+ "source_label": "duplicate-processes-export",
966
+ "groups": [
967
+ {
968
+ "group_id": 1,
969
+ "processes": [
970
+ {
971
+ "process_id": "proc-1",
972
+ "version": "01.00.000",
973
+ "name_en": "Example",
974
+ "name_zh": "示例",
975
+ "sheet_exchange_rows": [
976
+ {
977
+ "flow_id": "flow-1",
978
+ "direction": "Input",
979
+ "mean_amount": "1",
980
+ "resulting_amount": "1"
981
+ }
982
+ ]
983
+ }
984
+ ]
985
+ }
986
+ ]
987
+ }
988
+
989
+ Outputs written under --out-dir:
990
+ - inputs/dedup-input.manifest.json
991
+ - inputs/processes.remote-metadata.json (when remote enrichment succeeds)
992
+ - outputs/duplicate-groups.json
993
+ - outputs/delete-plan.json
994
+ - outputs/current-user-reference-scan.json (when reference scan succeeds)
995
+ `.trim();
996
+ }
795
997
  function renderProcessResumeBuildHelp() {
796
998
  return `Usage:
797
- tiangong process resume-build [--run-id <id>] [--run-dir <dir>] [options]
999
+ tiangong-lca process resume-build --run-dir <dir> [options]
798
1000
 
799
1001
  Options:
800
- --run-id <id> Existing process build run id
801
1002
  --run-dir <dir> Existing process build run directory
1003
+ --run-id <id> Optional run id consistency check
802
1004
  --json Print compact JSON
803
1005
  -h, --help
804
1006
  `.trim();
805
1007
  }
806
1008
  function renderProcessPublishBuildHelp() {
807
1009
  return `Usage:
808
- tiangong process publish-build [--run-id <id>] [--run-dir <dir>] [options]
1010
+ tiangong-lca process publish-build --run-dir <dir> [options]
809
1011
 
810
1012
  Options:
811
- --run-id <id> Existing process build run id
812
1013
  --run-dir <dir> Existing process build run directory
1014
+ --run-id <id> Optional run id consistency check
813
1015
  --json Print compact JSON
814
1016
  -h, --help
815
1017
  `.trim();
816
1018
  }
817
1019
  function renderProcessSaveDraftHelp() {
818
1020
  return `Usage:
819
- tiangong process save-draft --input <file> [options]
1021
+ tiangong-lca process save-draft --input <file> [options]
820
1022
 
821
1023
  Options:
822
1024
  --input <file> Process rows JSON/JSONL file or publish-request.json
@@ -831,6 +1033,10 @@ Environment:
831
1033
  TIANGONG_LCA_API_BASE_URL, TIANGONG_LCA_API_KEY, and TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY
832
1034
  when --commit executes remote writes
833
1035
 
1036
+ Local gate:
1037
+ canonical process payloads are validated against ProcessSchema before any remote write;
1038
+ schema-invalid rows stay in failures.jsonl instead of being committed
1039
+
834
1040
  Outputs written under --out-dir:
835
1041
  - inputs/normalized-input.json
836
1042
  - outputs/save-draft-rpc/selected-processes.jsonl
@@ -839,39 +1045,99 @@ Outputs written under --out-dir:
839
1045
  - outputs/save-draft-rpc/summary.json
840
1046
  `.trim();
841
1047
  }
1048
+ function renderProcessRefreshReferencesHelp() {
1049
+ return `Usage:
1050
+ tiangong-lca process refresh-references --out-dir <dir> [options]
1051
+
1052
+ Options:
1053
+ --out-dir <dir> Artifact root for manifest, progress, blockers, and reports
1054
+ --apply Commit state-aware draft writes after local validation passes
1055
+ --dry-run Refresh references locally only (default)
1056
+ --reuse-manifest Reuse inputs/processes.manifest.json instead of refetching the owner snapshot
1057
+ --limit <n> Process at most n manifest rows
1058
+ --page-size <n> Snapshot page size (default: 500)
1059
+ --concurrency <n> Parallel row workers (default: 1, max: 8)
1060
+ --json Print compact JSON
1061
+ -h, --help
1062
+
1063
+ Required env:
1064
+ TIANGONG_LCA_API_BASE_URL
1065
+ TIANGONG_LCA_API_KEY
1066
+ TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY
1067
+
1068
+ Guardrails:
1069
+ - refresh only the current authenticated user's process snapshot
1070
+ - skip rows with state_code >= 20 instead of forcing an unsupported write path
1071
+ - block remote writes when ProcessSchema validation fails or references stay unresolved
1072
+ - never requires raw SUPABASE_EMAIL / SUPABASE_PASSWORD in the skill layer
1073
+
1074
+ Outputs written under --out-dir:
1075
+ - inputs/processes.manifest.json
1076
+ - outputs/progress.jsonl
1077
+ - outputs/errors.jsonl
1078
+ - outputs/validation-blockers.jsonl
1079
+ - outputs/summary.json
1080
+ - reports/process-refresh-references.md
1081
+ `.trim();
1082
+ }
1083
+ function renderProcessVerifyRowsHelp() {
1084
+ return `Usage:
1085
+ tiangong-lca process verify-rows --rows-file <file> --out-dir <dir> [options]
1086
+
1087
+ Options:
1088
+ --rows-file <file> Raw process rows JSON/JSONL file; full process list reports with rows[] are also accepted
1089
+ --out-dir <dir> Output directory for summary and verification JSONL artifacts
1090
+ --json Print compact JSON
1091
+ -h, --help
1092
+
1093
+ Outputs written under --out-dir:
1094
+ - outputs/summary.json
1095
+ - outputs/verification.jsonl
1096
+ `.trim();
1097
+ }
842
1098
  function renderProcessBatchBuildHelp() {
843
1099
  return `Usage:
844
- tiangong process batch-build --input <file> [options]
1100
+ tiangong-lca process batch-build --input <file> [options]
845
1101
 
846
1102
  Options:
847
1103
  --input <file> JSON batch manifest file
848
- --out-dir <dir> Override the batch artifact output directory
1104
+ --out-dir <dir> Explicit batch root; otherwise request.out_dir is required
849
1105
  --json Print compact JSON
850
1106
  -h, --help
1107
+
1108
+ This command applies no implicit repo-local ./artifacts fallback.
851
1109
  `.trim();
852
1110
  }
853
1111
  function renderProcessHelp() {
854
1112
  return `Usage:
855
- tiangong process <subcommand> [options]
1113
+ tiangong-lca process <subcommand> [options]
856
1114
 
857
1115
  Implemented Subcommands:
858
1116
  get Load one process dataset by identifier through direct Supabase access
859
1117
  list List visible process rows through direct Supabase access
1118
+ scope-statistics Count repeatable coverage statistics from visible or owner-filtered process snapshots
1119
+ dedup-review Review grouped duplicate process candidates and emit keep/delete evidence
860
1120
  auto-build Prepare a local process-from-flow run scaffold and artifact workspace
861
1121
  resume-build Prepare a local resume handoff from one existing process build run
862
1122
  publish-build Prepare publish handoff artifacts from one existing process build run
863
1123
  save-draft Save canonical process datasets through the state-aware draft-maintenance path
864
1124
  batch-build Run multiple process auto-build requests through one batch-oriented CLI surface
1125
+ refresh-references Refresh current-user process references to the latest reachable dataset versions
1126
+ verify-rows Re-validate fetched process rows and required naming fields locally
865
1127
 
866
1128
  Examples:
867
- tiangong process --help
868
- tiangong process get --id <process-id>
869
- tiangong process list --state-code 100 --limit 20 --help
870
- tiangong process auto-build --help
871
- tiangong process resume-build --run-id <id> --help
872
- tiangong process publish-build --run-id <id> --help
873
- tiangong process save-draft --input ./patched-processes.jsonl --help
874
- tiangong process batch-build --input ./batch-request.json --help
1129
+ tiangong-lca process --help
1130
+ tiangong-lca process get --id <process-id>
1131
+ tiangong-lca process list --state-code 100 --limit 20 --help
1132
+ tiangong-lca process scope-statistics --out-dir ./process-scope --state-code 0 --state-code 100 --help
1133
+ tiangong-lca process dedup-review --input ./duplicate-groups.json --out-dir ./process-dedup --help
1134
+ tiangong-lca process auto-build --help
1135
+ tiangong-lca process resume-build --run-dir /abs/path/to/process-run --help
1136
+ tiangong-lca process publish-build --run-dir /abs/path/to/process-run --help
1137
+ tiangong-lca process save-draft --input ./patched-processes.jsonl --help
1138
+ tiangong-lca process batch-build --input ./batch-request.json --help
1139
+ tiangong-lca process refresh-references --out-dir ./process-refresh --help
1140
+ tiangong-lca process verify-rows --rows-file ./process-list-report.json --out-dir ./process-verify --help
875
1141
  `.trim();
876
1142
  }
877
1143
  function renderDoctorText(report) {
@@ -1079,6 +1345,89 @@ function parseValidationFlags(args) {
1079
1345
  reportFile: typeof values['report-file'] === 'string' ? values['report-file'] : null,
1080
1346
  };
1081
1347
  }
1348
+ function parseDatasetValidateFlags(args) {
1349
+ let values;
1350
+ try {
1351
+ ({ values } = parseArgs({
1352
+ args,
1353
+ allowPositionals: false,
1354
+ strict: true,
1355
+ options: {
1356
+ help: { type: 'boolean', short: 'h' },
1357
+ json: { type: 'boolean' },
1358
+ input: { type: 'string' },
1359
+ type: { type: 'string' },
1360
+ 'out-dir': { type: 'string' },
1361
+ },
1362
+ }));
1363
+ }
1364
+ catch (error) {
1365
+ throw new CliError(String(error), {
1366
+ code: 'INVALID_ARGS',
1367
+ exitCode: 2,
1368
+ });
1369
+ }
1370
+ return {
1371
+ help: Boolean(values.help),
1372
+ json: Boolean(values.json),
1373
+ inputPath: typeof values.input === 'string' ? values.input : '',
1374
+ type: typeof values.type === 'string' ? values.type : undefined,
1375
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : null,
1376
+ };
1377
+ }
1378
+ function parseDatasetReferencesRewriteFlags(args) {
1379
+ let values;
1380
+ try {
1381
+ ({ values } = parseArgs({
1382
+ args,
1383
+ allowPositionals: false,
1384
+ strict: true,
1385
+ options: {
1386
+ help: { type: 'boolean', short: 'h' },
1387
+ json: { type: 'boolean' },
1388
+ input: { type: 'string' },
1389
+ from: { type: 'string' },
1390
+ to: { type: 'string' },
1391
+ type: { type: 'string', multiple: true },
1392
+ types: { type: 'string', multiple: true },
1393
+ scope: { type: 'string' },
1394
+ 'out-dir': { type: 'string' },
1395
+ commit: { type: 'boolean' },
1396
+ 'dry-run': { type: 'boolean' },
1397
+ },
1398
+ }));
1399
+ }
1400
+ catch (error) {
1401
+ throw new CliError(String(error), {
1402
+ code: 'INVALID_ARGS',
1403
+ exitCode: 2,
1404
+ });
1405
+ }
1406
+ if (values.commit && values['dry-run']) {
1407
+ throw new CliError('Cannot pass both --commit and --dry-run.', {
1408
+ code: 'DATASET_REFERENCES_REWRITE_MODE_CONFLICT',
1409
+ exitCode: 2,
1410
+ });
1411
+ }
1412
+ return {
1413
+ help: Boolean(values.help),
1414
+ json: Boolean(values.json),
1415
+ inputPath: typeof values.input === 'string' ? values.input : '',
1416
+ from: typeof values.from === 'string' ? values.from : '',
1417
+ to: typeof values.to === 'string' ? values.to : '',
1418
+ types: [
1419
+ ...(Array.isArray(values.type)
1420
+ ? values.type.filter((value) => typeof value === 'string')
1421
+ : []),
1422
+ ...(Array.isArray(values.types)
1423
+ ? values.types.filter((value) => typeof value === 'string')
1424
+ : []),
1425
+ ],
1426
+ scope: typeof values.scope === 'string' ? values.scope : null,
1427
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
1428
+ commit: Boolean(values.commit),
1429
+ };
1430
+ }
1082
1431
  function parseFlowRemediateFlags(args) {
1083
1432
  let values;
1084
1433
  try {
@@ -1998,6 +2347,75 @@ function parseLifecyclemodelPublishBuildFlags(args) {
1998
2347
  runDir: typeof values['run-dir'] === 'string' ? values['run-dir'] : '',
1999
2348
  };
2000
2349
  }
2350
+ function parseLifecyclemodelSaveDraftFlags(args) {
2351
+ let values;
2352
+ try {
2353
+ ({ values } = parseArgs({
2354
+ args,
2355
+ allowPositionals: false,
2356
+ strict: true,
2357
+ options: {
2358
+ help: { type: 'boolean', short: 'h' },
2359
+ json: { type: 'boolean' },
2360
+ input: { type: 'string' },
2361
+ 'out-dir': { type: 'string' },
2362
+ commit: { type: 'boolean' },
2363
+ 'dry-run': { type: 'boolean' },
2364
+ },
2365
+ }));
2366
+ }
2367
+ catch (error) {
2368
+ throw new CliError(String(error), {
2369
+ code: 'INVALID_ARGS',
2370
+ exitCode: 2,
2371
+ });
2372
+ }
2373
+ if (values.commit && values['dry-run']) {
2374
+ throw new CliError('Cannot pass both --commit and --dry-run.', {
2375
+ code: 'INVALID_LIFECYCLEMODEL_SAVE_DRAFT_MODE',
2376
+ exitCode: 2,
2377
+ });
2378
+ }
2379
+ return {
2380
+ help: Boolean(values.help),
2381
+ json: Boolean(values.json),
2382
+ inputPath: typeof values.input === 'string' ? values.input : '',
2383
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : null,
2384
+ commit: Boolean(values.commit),
2385
+ };
2386
+ }
2387
+ function parseLifecyclemodelGraphFlags(args) {
2388
+ let values;
2389
+ try {
2390
+ ({ values } = parseArgs({
2391
+ args,
2392
+ allowPositionals: false,
2393
+ strict: true,
2394
+ options: {
2395
+ help: { type: 'boolean', short: 'h' },
2396
+ json: { type: 'boolean' },
2397
+ input: { type: 'string' },
2398
+ 'out-dir': { type: 'string' },
2399
+ format: { type: 'string' },
2400
+ 'check-connections': { type: 'boolean' },
2401
+ },
2402
+ }));
2403
+ }
2404
+ catch (error) {
2405
+ throw new CliError(String(error), {
2406
+ code: 'INVALID_ARGS',
2407
+ exitCode: 2,
2408
+ });
2409
+ }
2410
+ return {
2411
+ help: Boolean(values.help),
2412
+ json: Boolean(values.json),
2413
+ inputPath: typeof values.input === 'string' ? values.input : '',
2414
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
2415
+ format: typeof values.format === 'string' ? values.format : undefined,
2416
+ checkConnections: Boolean(values['check-connections']),
2417
+ };
2418
+ }
2001
2419
  function parseLifecyclemodelBuildFlags(args) {
2002
2420
  let values;
2003
2421
  try {
@@ -2214,6 +2632,111 @@ function parseProcessListFlags(args) {
2214
2632
  order: typeof values.order === 'string' ? values.order : null,
2215
2633
  };
2216
2634
  }
2635
+ function parseProcessScopeStatisticsFlags(args) {
2636
+ let values;
2637
+ try {
2638
+ ({ values } = parseArgs({
2639
+ args,
2640
+ allowPositionals: false,
2641
+ strict: true,
2642
+ options: {
2643
+ help: { type: 'boolean', short: 'h' },
2644
+ json: { type: 'boolean' },
2645
+ 'out-dir': { type: 'string' },
2646
+ scope: { type: 'string' },
2647
+ 'state-code': { type: 'string', multiple: true },
2648
+ 'state-codes': { type: 'string' },
2649
+ 'page-size': { type: 'string' },
2650
+ 'reuse-snapshot': { type: 'boolean' },
2651
+ },
2652
+ }));
2653
+ }
2654
+ catch (error) {
2655
+ throw new CliError(String(error), {
2656
+ code: 'INVALID_ARGS',
2657
+ exitCode: 2,
2658
+ });
2659
+ }
2660
+ const parseStateCode = (value) => {
2661
+ const parsed = Number.parseInt(value, 10);
2662
+ if (!Number.isInteger(parsed) || parsed < 0) {
2663
+ throw new CliError('Expected --state-code to be a non-negative integer.', {
2664
+ code: 'INVALID_PROCESS_SCOPE_STATE_CODE',
2665
+ exitCode: 2,
2666
+ });
2667
+ }
2668
+ return parsed;
2669
+ };
2670
+ const stateCodes = [
2671
+ ...(Array.isArray(values['state-code'])
2672
+ ? values['state-code'].map((value) => parseStateCode(String(value)))
2673
+ : []),
2674
+ ...(typeof values['state-codes'] === 'string' ? values['state-codes'].split(',') : [])
2675
+ .map((value) => value.trim())
2676
+ .filter(Boolean)
2677
+ .map((value) => parseStateCode(value)),
2678
+ ];
2679
+ let pageSize = null;
2680
+ if (typeof values['page-size'] === 'string') {
2681
+ const parsed = Number.parseInt(values['page-size'], 10);
2682
+ if (!Number.isInteger(parsed) || parsed <= 0) {
2683
+ throw new CliError('Expected --page-size to be a positive integer.', {
2684
+ code: 'INVALID_PROCESS_SCOPE_PAGE_SIZE',
2685
+ exitCode: 2,
2686
+ });
2687
+ }
2688
+ pageSize = parsed;
2689
+ }
2690
+ let scope;
2691
+ if (typeof values.scope === 'string') {
2692
+ if (values.scope !== 'visible' && values.scope !== 'current-user') {
2693
+ throw new CliError("Expected --scope to be either 'visible' or 'current-user'.", {
2694
+ code: 'INVALID_PROCESS_SCOPE_SCOPE',
2695
+ exitCode: 2,
2696
+ });
2697
+ }
2698
+ scope = values.scope;
2699
+ }
2700
+ return {
2701
+ help: Boolean(values.help),
2702
+ json: Boolean(values.json),
2703
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
2704
+ scope,
2705
+ stateCodes,
2706
+ pageSize,
2707
+ reuseSnapshot: Boolean(values['reuse-snapshot']),
2708
+ };
2709
+ }
2710
+ function parseProcessDedupReviewFlags(args) {
2711
+ let values;
2712
+ try {
2713
+ ({ values } = parseArgs({
2714
+ args,
2715
+ allowPositionals: false,
2716
+ strict: true,
2717
+ options: {
2718
+ help: { type: 'boolean', short: 'h' },
2719
+ json: { type: 'boolean' },
2720
+ input: { type: 'string' },
2721
+ 'out-dir': { type: 'string' },
2722
+ 'skip-remote': { type: 'boolean' },
2723
+ },
2724
+ }));
2725
+ }
2726
+ catch (error) {
2727
+ throw new CliError(String(error), {
2728
+ code: 'INVALID_ARGS',
2729
+ exitCode: 2,
2730
+ });
2731
+ }
2732
+ return {
2733
+ help: Boolean(values.help),
2734
+ json: Boolean(values.json),
2735
+ inputPath: typeof values.input === 'string' ? values.input : '',
2736
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
2737
+ skipRemote: Boolean(values['skip-remote']),
2738
+ };
2739
+ }
2217
2740
  function parseProcessResumeBuildFlags(args) {
2218
2741
  let values;
2219
2742
  try {
@@ -2307,6 +2830,90 @@ function parseProcessSaveDraftFlags(args) {
2307
2830
  commit: Boolean(values.commit),
2308
2831
  };
2309
2832
  }
2833
+ function parseProcessRefreshReferencesFlags(args) {
2834
+ let values;
2835
+ try {
2836
+ ({ values } = parseArgs({
2837
+ args,
2838
+ allowPositionals: false,
2839
+ strict: true,
2840
+ options: {
2841
+ help: { type: 'boolean', short: 'h' },
2842
+ json: { type: 'boolean' },
2843
+ 'out-dir': { type: 'string' },
2844
+ apply: { type: 'boolean' },
2845
+ 'dry-run': { type: 'boolean' },
2846
+ 'reuse-manifest': { type: 'boolean' },
2847
+ limit: { type: 'string' },
2848
+ 'page-size': { type: 'string' },
2849
+ concurrency: { type: 'string' },
2850
+ },
2851
+ }));
2852
+ }
2853
+ catch (error) {
2854
+ throw new CliError(String(error), {
2855
+ code: 'INVALID_ARGS',
2856
+ exitCode: 2,
2857
+ });
2858
+ }
2859
+ if (values.apply && values['dry-run']) {
2860
+ throw new CliError('Cannot pass both --apply and --dry-run.', {
2861
+ code: 'PROCESS_REFRESH_MODE_CONFLICT',
2862
+ exitCode: 2,
2863
+ });
2864
+ }
2865
+ const parseOptionalPositiveIntegerFlag = (value, label, code) => {
2866
+ if (typeof value !== 'string') {
2867
+ return null;
2868
+ }
2869
+ const parsed = Number.parseInt(value, 10);
2870
+ if (!Number.isInteger(parsed) || parsed <= 0) {
2871
+ throw new CliError(`Expected ${label} to be a positive integer.`, {
2872
+ code,
2873
+ exitCode: 2,
2874
+ });
2875
+ }
2876
+ return parsed;
2877
+ };
2878
+ return {
2879
+ help: Boolean(values.help),
2880
+ json: Boolean(values.json),
2881
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
2882
+ apply: Boolean(values.apply),
2883
+ reuseManifest: Boolean(values['reuse-manifest']),
2884
+ limit: parseOptionalPositiveIntegerFlag(values.limit, '--limit', 'INVALID_PROCESS_REFRESH_LIMIT'),
2885
+ pageSize: parseOptionalPositiveIntegerFlag(values['page-size'], '--page-size', 'INVALID_PROCESS_REFRESH_PAGE_SIZE'),
2886
+ concurrency: parseOptionalPositiveIntegerFlag(values.concurrency, '--concurrency', 'INVALID_PROCESS_REFRESH_CONCURRENCY'),
2887
+ };
2888
+ }
2889
+ function parseProcessVerifyRowsFlags(args) {
2890
+ let values;
2891
+ try {
2892
+ ({ values } = parseArgs({
2893
+ args,
2894
+ allowPositionals: false,
2895
+ strict: true,
2896
+ options: {
2897
+ help: { type: 'boolean', short: 'h' },
2898
+ json: { type: 'boolean' },
2899
+ 'rows-file': { type: 'string' },
2900
+ 'out-dir': { type: 'string' },
2901
+ },
2902
+ }));
2903
+ }
2904
+ catch (error) {
2905
+ throw new CliError(String(error), {
2906
+ code: 'INVALID_ARGS',
2907
+ exitCode: 2,
2908
+ });
2909
+ }
2910
+ return {
2911
+ help: Boolean(values.help),
2912
+ json: Boolean(values.json),
2913
+ rowsFile: typeof values['rows-file'] === 'string' ? values['rows-file'] : '',
2914
+ outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
2915
+ };
2916
+ }
2310
2917
  function parseProcessBatchBuildFlags(args) {
2311
2918
  let values;
2312
2919
  try {
@@ -2362,14 +2969,20 @@ export async function executeCli(argv, deps) {
2362
2969
  const lifecyclemodelPublishImpl = deps.runLifecyclemodelPublishResultingProcessImpl ?? runLifecyclemodelPublishResultingProcess;
2363
2970
  const lifecyclemodelValidateImpl = deps.runLifecyclemodelValidateBuildImpl ?? runLifecyclemodelValidateBuild;
2364
2971
  const lifecyclemodelPublishBuildImpl = deps.runLifecyclemodelPublishBuildImpl ?? runLifecyclemodelPublishBuild;
2972
+ const lifecyclemodelSaveDraftImpl = deps.runLifecyclemodelSaveDraftImpl ?? runLifecyclemodelSaveDraft;
2973
+ const lifecyclemodelGraphImpl = deps.runLifecyclemodelGraphImpl ?? runLifecyclemodelGraph;
2365
2974
  const lifecyclemodelOrchestrateImpl = deps.runLifecyclemodelOrchestrateImpl ?? runLifecyclemodelOrchestrate;
2366
2975
  const processGetImpl = deps.runProcessGetImpl ?? runProcessGet;
2367
2976
  const processListImpl = deps.runProcessListImpl ?? runProcessList;
2368
2977
  const processAutoBuildImpl = deps.runProcessAutoBuildImpl ?? runProcessAutoBuild;
2369
2978
  const processBatchBuildImpl = deps.runProcessBatchBuildImpl ?? runProcessBatchBuild;
2979
+ const processScopeStatisticsImpl = deps.runProcessScopeStatisticsImpl ?? runProcessScopeStatistics;
2980
+ const processRefreshReferencesImpl = deps.runProcessRefreshReferencesImpl ?? runProcessRefreshReferences;
2981
+ const processDedupReviewImpl = deps.runProcessDedupReviewImpl ?? runProcessDedupReview;
2370
2982
  const processResumeBuildImpl = deps.runProcessResumeBuildImpl ?? runProcessResumeBuild;
2371
2983
  const processPublishBuildImpl = deps.runProcessPublishBuildImpl ?? runProcessPublishBuild;
2372
2984
  const processSaveDraftImpl = deps.runProcessSaveDraftImpl ?? runProcessSaveDraft;
2985
+ const processVerifyRowsImpl = deps.runProcessVerifyRowsImpl ?? runProcessVerifyRows;
2373
2986
  const processReviewImpl = deps.runProcessReviewImpl ?? runProcessReview;
2374
2987
  const flowReviewImpl = deps.runFlowReviewImpl ?? runFlowReview;
2375
2988
  const lifecyclemodelReviewImpl = deps.runLifecyclemodelReviewImpl ?? runLifecyclemodelReview;
@@ -2386,6 +2999,8 @@ export async function executeCli(argv, deps) {
2386
2999
  const flowApplyProcessFlowRepairsImpl = deps.runFlowApplyProcessFlowRepairsImpl ?? runFlowApplyProcessFlowRepairs;
2387
3000
  const flowRegenProductImpl = deps.runFlowRegenProductImpl ?? runFlowRegenProduct;
2388
3001
  const flowValidateProcessesImpl = deps.runFlowValidateProcessesImpl ?? runFlowValidateProcesses;
3002
+ const datasetValidateImpl = deps.runDatasetValidateImpl ?? runDatasetValidate;
3003
+ const datasetReferencesRewriteImpl = deps.runDatasetReferencesRewriteImpl ?? runDatasetReferencesRewrite;
2389
3004
  if (flags.version) {
2390
3005
  return { exitCode: 0, stdout: `${loadCliPackageVersion(import.meta.url)}\n`, stderr: '' };
2391
3006
  }
@@ -2428,6 +3043,57 @@ export async function executeCli(argv, deps) {
2428
3043
  stderr: '',
2429
3044
  };
2430
3045
  }
3046
+ if (command === 'dataset' && !subcommand) {
3047
+ return { exitCode: 0, stdout: `${renderDatasetHelp()}\n`, stderr: '' };
3048
+ }
3049
+ if (command === 'dataset' && subcommand === 'validate') {
3050
+ const datasetFlags = parseDatasetValidateFlags(commandArgs);
3051
+ if (datasetFlags.help) {
3052
+ return { exitCode: 0, stdout: `${renderDatasetValidateHelp()}\n`, stderr: '' };
3053
+ }
3054
+ const report = await datasetValidateImpl({
3055
+ inputPath: datasetFlags.inputPath,
3056
+ type: datasetFlags.type,
3057
+ outDir: datasetFlags.outDir,
3058
+ });
3059
+ return {
3060
+ exitCode: report.counts.invalid > 0 ? 1 : 0,
3061
+ stdout: stringifyJson(report, datasetFlags.json),
3062
+ stderr: '',
3063
+ };
3064
+ }
3065
+ if (command === 'dataset' && subcommand === 'references') {
3066
+ const action = commandArgs[0] ?? '';
3067
+ if (!action || action === '--help' || action === '-h') {
3068
+ return { exitCode: 0, stdout: `${renderDatasetReferencesHelp()}\n`, stderr: '' };
3069
+ }
3070
+ if (action !== 'rewrite') {
3071
+ throw new CliError("dataset references action must be 'rewrite'.", {
3072
+ code: 'INVALID_ARGS',
3073
+ exitCode: 2,
3074
+ });
3075
+ }
3076
+ const datasetFlags = parseDatasetReferencesRewriteFlags(commandArgs.slice(1));
3077
+ if (datasetFlags.help) {
3078
+ return { exitCode: 0, stdout: `${renderDatasetReferencesHelp()}\n`, stderr: '' };
3079
+ }
3080
+ const report = await datasetReferencesRewriteImpl({
3081
+ inputPath: datasetFlags.inputPath,
3082
+ from: datasetFlags.from,
3083
+ to: datasetFlags.to,
3084
+ types: datasetFlags.types,
3085
+ scope: datasetFlags.scope,
3086
+ outDir: datasetFlags.outDir,
3087
+ commit: datasetFlags.commit,
3088
+ env: deps.env,
3089
+ fetchImpl: deps.fetchImpl,
3090
+ });
3091
+ return {
3092
+ exitCode: report.status === 'completed_with_failures' ? 1 : 0,
3093
+ stdout: stringifyJson(report, datasetFlags.json),
3094
+ stderr: '',
3095
+ };
3096
+ }
2431
3097
  if (command === 'lifecyclemodel' && !subcommand) {
2432
3098
  return { exitCode: 0, stdout: `${renderLifecyclemodelHelp()}\n`, stderr: '' };
2433
3099
  }
@@ -2531,6 +3197,49 @@ export async function executeCli(argv, deps) {
2531
3197
  stderr: '',
2532
3198
  };
2533
3199
  }
3200
+ if (command === 'lifecyclemodel' && subcommand === 'save-draft') {
3201
+ const lifecyclemodelFlags = parseLifecyclemodelSaveDraftFlags(commandArgs);
3202
+ if (lifecyclemodelFlags.help) {
3203
+ return {
3204
+ exitCode: 0,
3205
+ stdout: `${renderLifecyclemodelSaveDraftHelp()}\n`,
3206
+ stderr: '',
3207
+ };
3208
+ }
3209
+ const report = await lifecyclemodelSaveDraftImpl({
3210
+ inputPath: lifecyclemodelFlags.inputPath,
3211
+ outDir: lifecyclemodelFlags.outDir,
3212
+ commit: lifecyclemodelFlags.commit,
3213
+ env: deps.env,
3214
+ fetchImpl: deps.fetchImpl,
3215
+ });
3216
+ return {
3217
+ exitCode: report.status === 'completed_with_failures' ? 1 : 0,
3218
+ stdout: stringifyJson(report, lifecyclemodelFlags.json),
3219
+ stderr: '',
3220
+ };
3221
+ }
3222
+ if (command === 'lifecyclemodel' && subcommand === 'graph') {
3223
+ const lifecyclemodelFlags = parseLifecyclemodelGraphFlags(commandArgs);
3224
+ if (lifecyclemodelFlags.help) {
3225
+ return {
3226
+ exitCode: 0,
3227
+ stdout: `${renderLifecyclemodelGraphHelp()}\n`,
3228
+ stderr: '',
3229
+ };
3230
+ }
3231
+ const report = await lifecyclemodelGraphImpl({
3232
+ inputPath: lifecyclemodelFlags.inputPath,
3233
+ outDir: lifecyclemodelFlags.outDir,
3234
+ format: lifecyclemodelFlags.format,
3235
+ checkConnections: lifecyclemodelFlags.checkConnections,
3236
+ });
3237
+ return {
3238
+ exitCode: report.status === 'completed_with_findings' ? 1 : 0,
3239
+ stdout: stringifyJson(report, lifecyclemodelFlags.json),
3240
+ stderr: '',
3241
+ };
3242
+ }
2534
3243
  if (command === 'lifecyclemodel' && subcommand === 'orchestrate') {
2535
3244
  const lifecyclemodelFlags = parseLifecyclemodelOrchestrateFlags(commandArgs);
2536
3245
  if (lifecyclemodelFlags.help || !lifecyclemodelFlags.action) {
@@ -2618,6 +3327,52 @@ export async function executeCli(argv, deps) {
2618
3327
  stderr: '',
2619
3328
  };
2620
3329
  }
3330
+ if (command === 'process' && subcommand === 'scope-statistics') {
3331
+ const processFlags = parseProcessScopeStatisticsFlags(commandArgs);
3332
+ if (processFlags.help) {
3333
+ return {
3334
+ exitCode: 0,
3335
+ stdout: `${renderProcessScopeStatisticsHelp()}\n`,
3336
+ stderr: '',
3337
+ };
3338
+ }
3339
+ const report = await processScopeStatisticsImpl({
3340
+ outDir: processFlags.outDir,
3341
+ scope: processFlags.scope,
3342
+ stateCodes: processFlags.stateCodes,
3343
+ pageSize: processFlags.pageSize,
3344
+ reuseSnapshot: processFlags.reuseSnapshot,
3345
+ env: deps.env,
3346
+ fetchImpl: deps.fetchImpl,
3347
+ });
3348
+ return {
3349
+ exitCode: 0,
3350
+ stdout: stringifyJson(report, processFlags.json),
3351
+ stderr: '',
3352
+ };
3353
+ }
3354
+ if (command === 'process' && subcommand === 'dedup-review') {
3355
+ const processFlags = parseProcessDedupReviewFlags(commandArgs);
3356
+ if (processFlags.help) {
3357
+ return {
3358
+ exitCode: 0,
3359
+ stdout: `${renderProcessDedupReviewHelp()}\n`,
3360
+ stderr: '',
3361
+ };
3362
+ }
3363
+ const report = await processDedupReviewImpl({
3364
+ inputPath: processFlags.inputPath,
3365
+ outDir: processFlags.outDir,
3366
+ skipRemote: processFlags.skipRemote,
3367
+ env: deps.env,
3368
+ fetchImpl: deps.fetchImpl,
3369
+ });
3370
+ return {
3371
+ exitCode: 0,
3372
+ stdout: stringifyJson(report, processFlags.json),
3373
+ stderr: '',
3374
+ };
3375
+ }
2621
3376
  if (command === 'process' && subcommand === 'auto-build') {
2622
3377
  const processFlags = parseProcessAutoBuildFlags(commandArgs);
2623
3378
  if (processFlags.help) {
@@ -2697,6 +3452,50 @@ export async function executeCli(argv, deps) {
2697
3452
  stderr: '',
2698
3453
  };
2699
3454
  }
3455
+ if (command === 'process' && subcommand === 'refresh-references') {
3456
+ const processFlags = parseProcessRefreshReferencesFlags(commandArgs);
3457
+ if (processFlags.help) {
3458
+ return {
3459
+ exitCode: 0,
3460
+ stdout: `${renderProcessRefreshReferencesHelp()}\n`,
3461
+ stderr: '',
3462
+ };
3463
+ }
3464
+ const report = await processRefreshReferencesImpl({
3465
+ outDir: processFlags.outDir,
3466
+ apply: processFlags.apply,
3467
+ reuseManifest: processFlags.reuseManifest,
3468
+ limit: processFlags.limit,
3469
+ pageSize: processFlags.pageSize,
3470
+ concurrency: processFlags.concurrency,
3471
+ env: deps.env,
3472
+ fetchImpl: deps.fetchImpl,
3473
+ });
3474
+ return {
3475
+ exitCode: report.status === 'completed_process_reference_refresh_with_errors' ? 1 : 0,
3476
+ stdout: stringifyJson(report, processFlags.json),
3477
+ stderr: '',
3478
+ };
3479
+ }
3480
+ if (command === 'process' && subcommand === 'verify-rows') {
3481
+ const processFlags = parseProcessVerifyRowsFlags(commandArgs);
3482
+ if (processFlags.help) {
3483
+ return {
3484
+ exitCode: 0,
3485
+ stdout: `${renderProcessVerifyRowsHelp()}\n`,
3486
+ stderr: '',
3487
+ };
3488
+ }
3489
+ const report = await processVerifyRowsImpl({
3490
+ rowsFile: processFlags.rowsFile,
3491
+ outDir: processFlags.outDir,
3492
+ });
3493
+ return {
3494
+ exitCode: report.invalid_count > 0 ? 1 : 0,
3495
+ stdout: stringifyJson(report, processFlags.json),
3496
+ stderr: '',
3497
+ };
3498
+ }
2700
3499
  if (command === 'process' && subcommand === 'batch-build') {
2701
3500
  const processFlags = parseProcessBatchBuildFlags(commandArgs);
2702
3501
  if (processFlags.help) {