@tiangong-lca/cli 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -2
- package/dist/src/cli.js +553 -4
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-command.js +11 -0
- package/dist/src/lib/dataset-command.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-flow-identity-approval-claim.js +175 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-approval-claim.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-capture.js +511 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-capture.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-command.js +26 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-command.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-contract.js +784 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-contract.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-execution-contract.js +1317 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-execution-contract.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-freeze.js +342 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-freeze.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-plan.js +900 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-plan.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-recovery.js +688 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-recovery.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-run.js +1369 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-run.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-seal.js +144 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-seal.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-verify.js +377 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-verify.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-wire.js +178 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-wire.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-remote.js +156 -10
- package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
- package/dist/src/lib/dataset-save-draft-run.js +667 -0
- package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
- package/dist/src/lib/http.js.map +1 -1
- package/dist/src/lib/lca-release.js +683 -0
- package/dist/src/lib/lca-release.js.map +1 -0
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -39,6 +39,7 @@ import { runFlowReviewedPublishData, } from './lib/flow-publish-reviewed-data.js
|
|
|
39
39
|
import { runFlowBuildAliasMap, } from './lib/flow-build-alias-map.js';
|
|
40
40
|
import { runFlowApplyProcessFlowRepairs, runFlowPlanProcessFlowRepairs, runFlowRegenProduct, runFlowScanProcessFlowRefs, runFlowValidateProcesses, } from './lib/flow-regen-product.js';
|
|
41
41
|
import { executeRemoteCommand, getRemoteCommandHelp } from './lib/remote.js';
|
|
42
|
+
import { LCA_RELEASE_ACTIONS, renderLcaReleaseReport, runLcaRelease, } from './lib/lca-release.js';
|
|
42
43
|
import { runValidation, } from './lib/validation.js';
|
|
43
44
|
import { runDatasetValidate, } from './lib/dataset-validate.js';
|
|
44
45
|
import { runDatasetCurationQueueBuild, runDatasetCurationQueueNext, runDatasetCurationQueueVerify, } from './lib/dataset-curation-queue.js';
|
|
@@ -60,6 +61,13 @@ import { freezeDatasetMaintenanceProtected } from './lib/dataset-maintenance-pro
|
|
|
60
61
|
import { runDatasetMaintenanceProtected } from './lib/dataset-maintenance-protected-run.js';
|
|
61
62
|
import { sealDatasetMaintenanceProtectedApproval } from './lib/dataset-maintenance-protected-seal.js';
|
|
62
63
|
import { runDatasetMaintenanceVerify } from './lib/dataset-maintenance-verify.js';
|
|
64
|
+
import { runFlowIdentityPlanFromFiles } from './lib/dataset-maintenance-flow-identity-command.js';
|
|
65
|
+
import { captureFlowIdentity } from './lib/dataset-maintenance-flow-identity-capture.js';
|
|
66
|
+
import { freezeFlowIdentity } from './lib/dataset-maintenance-flow-identity-freeze.js';
|
|
67
|
+
import { sealFlowIdentityApproval } from './lib/dataset-maintenance-flow-identity-seal.js';
|
|
68
|
+
import { freezeFlowIdentityRecovery, sealFlowIdentityRecoveryApproval, } from './lib/dataset-maintenance-flow-identity-recovery.js';
|
|
69
|
+
import { runFlowIdentity } from './lib/dataset-maintenance-flow-identity-run.js';
|
|
70
|
+
import { verifyFlowIdentity } from './lib/dataset-maintenance-flow-identity-verify.js';
|
|
63
71
|
import { runDatasetSourceUploadAttachments, } from './lib/dataset-source-upload-attachments.js';
|
|
64
72
|
function renderMainHelp(dotEnvStatus) {
|
|
65
73
|
return `TianGong LCA CLI
|
|
@@ -80,12 +88,13 @@ Implemented Commands:
|
|
|
80
88
|
doctor show environment diagnostics
|
|
81
89
|
search flow | process | lifecyclemodel
|
|
82
90
|
process get | list | identity-preflight | build-plan | scope-statistics | dedup-review | auto-build | resume-build | publish-build | complete-required-fields | save-draft | batch-build | refresh-references | verify-rows
|
|
83
|
-
dataset contract get | context-pack | classification children/path/audit/apply | curation-queue build/next/verify | import-lca convert | author | patch apply | save-draft | source upload-attachments | validate | verify-remote | bilingual extract/apply/validate | evidence-search plan/run | references rewrite/refresh-remote | maintenance clear-account/plan/apply/verify
|
|
91
|
+
dataset contract get | context-pack | classification children/path/audit/apply | curation-queue build/next/verify | import-lca convert | author | patch apply | save-draft | source upload-attachments | validate | verify-remote | bilingual extract/apply/validate | evidence-search plan/run | references rewrite/refresh-remote | maintenance clear-account/plan/apply/verify/flow-identity
|
|
84
92
|
flow get | list | identity-preflight | build-plan | 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
|
|
85
93
|
lifecyclemodel auto-build | validate-build | publish-build | save-draft | graph | build-resulting-process | publish-resulting-process | orchestrate
|
|
86
94
|
qa process | flow | lifecyclemodel
|
|
87
95
|
publish run
|
|
88
96
|
validation run
|
|
97
|
+
release prepare | upload | finalize | approve | publish | readback-verify | unpublish | status | current | calculation-bundle | calculation-artifact | artifact-download
|
|
89
98
|
admin embedding-run
|
|
90
99
|
|
|
91
100
|
Planned Surface (not implemented yet):
|
|
@@ -163,6 +172,8 @@ Examples:
|
|
|
163
172
|
tiangong-lca qa lifecyclemodel --rows-file ./lifecyclemodels.jsonl --out-dir ./lifecyclemodel-qa
|
|
164
173
|
tiangong-lca publish run --input ./publish-request.json --dry-run
|
|
165
174
|
tiangong-lca validation run --input-dir ./package --engine auto
|
|
175
|
+
tiangong-lca release status --release-run-id <run-id> --json
|
|
176
|
+
tiangong-lca release calculation-bundle --package-id <package-id> --output ./calculation-bundle.json
|
|
166
177
|
tiangong-lca admin embedding-run --input ./jobs.json
|
|
167
178
|
|
|
168
179
|
Environment:
|
|
@@ -226,6 +237,58 @@ Runtime note:
|
|
|
226
237
|
and sends the resolved access token to Edge Functions.
|
|
227
238
|
`.trim();
|
|
228
239
|
}
|
|
240
|
+
function renderLcaReleaseHelp() {
|
|
241
|
+
return `Usage:
|
|
242
|
+
tiangong-lca release <action> [options]
|
|
243
|
+
|
|
244
|
+
Workflow actions:
|
|
245
|
+
prepare register an immutable publish plan from --input
|
|
246
|
+
upload verify four local ZIPs, upload them, and write --output receipt
|
|
247
|
+
finalize bind a Release Manifest and uploaded artifact refs from --input
|
|
248
|
+
approve create a durable manager approval from --input
|
|
249
|
+
publish publish an approved release from --input; credential fingerprint is derived locally
|
|
250
|
+
readback-verify record independent artifact readback hashes from --input
|
|
251
|
+
unpublish unpublish the current release from --input
|
|
252
|
+
|
|
253
|
+
Read and download actions:
|
|
254
|
+
status read --release-run-id
|
|
255
|
+
current read the current public release
|
|
256
|
+
calculation-bundle verify/sign bundle manifest and chunks for --package-id; requires --output
|
|
257
|
+
calculation-artifact download one exact --artifact-path from --package-id; requires --output
|
|
258
|
+
artifact-download download one release ZIP by --artifact-id; requires --output
|
|
259
|
+
|
|
260
|
+
Options:
|
|
261
|
+
--input <file> JSON command or upload request
|
|
262
|
+
--output <path> Durable JSON receipt/projection or downloaded bytes
|
|
263
|
+
--release-run-id <uuid> Release run for status
|
|
264
|
+
--package-id <uuid> LCIA result package for Calculation Bundle reads
|
|
265
|
+
--artifact-id <uuid> Published release artifact to download
|
|
266
|
+
--artifact-path <path> Exact path from a Calculation Bundle manifest
|
|
267
|
+
--force Replace an existing output file
|
|
268
|
+
--dry-run Validate and print the masked planned request without network writes
|
|
269
|
+
--json Print the stable compact JSON report; otherwise print Summary and Next
|
|
270
|
+
--api-key <key> Override TIANGONG_LCA_API_KEY; environment use is preferred
|
|
271
|
+
--base-url <url> Override TIANGONG_LCA_API_BASE_URL
|
|
272
|
+
--timeout-ms <n> Request timeout in milliseconds (default 60000)
|
|
273
|
+
-h, --help
|
|
274
|
+
|
|
275
|
+
Required environment:
|
|
276
|
+
TIANGONG_LCA_API_BASE_URL
|
|
277
|
+
TIANGONG_LCA_API_KEY
|
|
278
|
+
TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY
|
|
279
|
+
|
|
280
|
+
Authorization and safety:
|
|
281
|
+
The User API key is exchanged for a user session. Database RPCs then check that the live account
|
|
282
|
+
has data_product_manager. The service-role key never enters this CLI. Large bundle projections,
|
|
283
|
+
ZIPs, and chunks are written to files and verified against exact byte size and SHA-256.
|
|
284
|
+
|
|
285
|
+
Examples:
|
|
286
|
+
tiangong-lca release prepare --input ./release-prepare.json --json
|
|
287
|
+
tiangong-lca release upload --input ./release-upload.json --output ./upload-receipt.json
|
|
288
|
+
tiangong-lca release calculation-bundle --package-id 11111111-1111-4111-8111-111111111111 --output ./calculation-bundle.json
|
|
289
|
+
tiangong-lca release calculation-artifact --package-id 11111111-1111-4111-8111-111111111111 --artifact-path chunks/lci-00000.jsonl.gz --output ./lci-00000.jsonl.gz
|
|
290
|
+
`.trim();
|
|
291
|
+
}
|
|
229
292
|
function renderPublishHelp() {
|
|
230
293
|
return `Usage:
|
|
231
294
|
tiangong-lca publish run --input <file> [options]
|
|
@@ -292,6 +355,7 @@ Implemented Subcommands:
|
|
|
292
355
|
maintenance seal-protected-approval Record byte-exact human approval entirely offline
|
|
293
356
|
maintenance run-protected Run or inspect one sealed, one-shot production maintenance execution
|
|
294
357
|
maintenance verify Read back affected rows and references against the immutable plan
|
|
358
|
+
maintenance flow-identity Dedicated Step 3 capture/plan/freeze/approval/serial-run/verify workflow
|
|
295
359
|
|
|
296
360
|
Examples:
|
|
297
361
|
tiangong-lca dataset contract get --type process --include schema,methodology,ruleset --out-dir ./contract --help
|
|
@@ -321,11 +385,12 @@ Examples:
|
|
|
321
385
|
tiangong-lca dataset maintenance freeze-protected --help
|
|
322
386
|
tiangong-lca dataset maintenance seal-protected-approval --help
|
|
323
387
|
tiangong-lca dataset maintenance run-protected --help
|
|
388
|
+
tiangong-lca dataset maintenance flow-identity --help
|
|
324
389
|
`.trim();
|
|
325
390
|
}
|
|
326
391
|
function renderDatasetMaintenanceHelp() {
|
|
327
392
|
return `Usage:
|
|
328
|
-
tiangong-lca dataset maintenance <clear-account|plan|apply|freeze-protected|seal-protected-approval|run-protected|verify> [options]
|
|
393
|
+
tiangong-lca dataset maintenance <clear-account|plan|apply|freeze-protected|seal-protected-approval|run-protected|verify|flow-identity> [options]
|
|
329
394
|
|
|
330
395
|
Actions:
|
|
331
396
|
clear-account Dry-run or delete current authenticated account-owned lifecyclemodels, processes, flows, sources, and contacts.
|
|
@@ -335,6 +400,7 @@ Actions:
|
|
|
335
400
|
seal-protected-approval Record a byte-exact human response into an approval artifact with no authentication or network access.
|
|
336
401
|
run-protected Run or inspect one sealed production execution with one-shot admission and terminal derivative proof.
|
|
337
402
|
verify Re-fetch rows, references, or derivative request state and report passed, pending, or failed independently of apply.
|
|
403
|
+
flow-identity Run the dedicated Step 3 capture/plan/freeze/seal-approval/serial-run/independent-verify workflow.
|
|
338
404
|
|
|
339
405
|
Safety:
|
|
340
406
|
plan, verify, and freeze-protected are read-only; seal-protected-approval is local-only.
|
|
@@ -343,6 +409,7 @@ Safety:
|
|
|
343
409
|
freeze-protected is production-only and never calls preflight, gate, admission, execution, or mutation RPCs.
|
|
344
410
|
seal-protected-approval only records the exact human-approved bytes; it never authenticates, connects, or submits execution.
|
|
345
411
|
run-protected is production-only: authenticated owner context plus server-side actor/user_id/state_code=0 and exact-plan closure fences protect writes; RLS remains a defense on public and independent-read surfaces. It never falls back to dev, a legacy alias RPC, or a second admission POST.
|
|
412
|
+
flow-identity never reuses the Step 2 runner. Process writes are strictly ordinal and ambiguous responses permit read-only recovery, never automatic process replay.
|
|
346
413
|
|
|
347
414
|
Required Artifact Contract:
|
|
348
415
|
- maintenance-plan.json
|
|
@@ -364,6 +431,72 @@ Examples:
|
|
|
364
431
|
tiangong-lca dataset maintenance seal-protected-approval --freeze ./protected-freeze/protected-execution-freeze.json --approval-request ./protected-freeze/protected-approval-request.json --human-approval ./human-approval.txt --approve-freeze-file <sha256> --approve-request <sha256> --approve-text <sha256> --confirm bafudata@126.com --approved-at <iso> --out-dir ./protected-approval
|
|
365
432
|
tiangong-lca dataset maintenance run-protected --plan ./maintenance-plan.json --freeze ./protected-execution-seal.json --approval ./protected-approval.json --out-dir ./protected-run --status-only
|
|
366
433
|
tiangong-lca dataset maintenance verify --plan ./dataset-maintenance/maintenance-plan.json --out-dir ./dataset-maintenance/verify
|
|
434
|
+
tiangong-lca dataset maintenance flow-identity --help
|
|
435
|
+
`.trim();
|
|
436
|
+
}
|
|
437
|
+
function renderDatasetMaintenanceFlowIdentityHelp() {
|
|
438
|
+
return `Usage:
|
|
439
|
+
tiangong-lca dataset maintenance flow-identity <capture|plan|freeze|seal-approval|run|freeze-recovery|seal-recovery-approval|run-recovery|verify> [options]
|
|
440
|
+
|
|
441
|
+
Actions:
|
|
442
|
+
capture Authenticated production census and one database attestation; performs zero scope/preflight/rewrite/finalize calls.
|
|
443
|
+
plan Build immutable Step 3 reference-only process templates from an approved v3 review ledger and fresh post-Step2/post-#29 live capture.
|
|
444
|
+
freeze Offline-bind one production plan/toolchain/receipt and generate this execution's byte-exact approval request.
|
|
445
|
+
seal-approval Offline-record byte-exact human approval; performs zero authentication, network, or database calls.
|
|
446
|
+
run Create/read one guarded scope, serially submit only its durable next ordinal, then wait read-only for derivative readiness before at most one finalize POST. Ambiguous responses are never retried in the same invocation.
|
|
447
|
+
freeze-recovery Authenticated read-only scope snapshot that freezes a new exact continuation approval after the prior in-memory permit was lost.
|
|
448
|
+
seal-recovery-approval Offline-record byte-exact human approval for only that frozen durable-scope baseline.
|
|
449
|
+
run-recovery Consume that recovery approval once, obtain a fresh memory-only rotating permit, and continue the same durable scope.
|
|
450
|
+
verify Independently re-read the terminal scope, all 305 source rows, public/support rows, exact affected processes, and the complete owner-draft process reference closure.
|
|
451
|
+
|
|
452
|
+
Plan:
|
|
453
|
+
--policy <file> --review-ledger <file> --live-capture <file> --out-dir <dir>
|
|
454
|
+
|
|
455
|
+
Capture:
|
|
456
|
+
--policy <file> --review-ledger <file> --prerequisites <file> --toolchain-evidence <file>
|
|
457
|
+
--request-id <uuid> --operation-id <value> --expected-project-ref <ref> --confirm <email>
|
|
458
|
+
--sdk-version <value> --out-dir <dir>
|
|
459
|
+
[--page-size <n>] [--read-concurrency <n>] [--timeout-ms <n>]
|
|
460
|
+
|
|
461
|
+
Freeze:
|
|
462
|
+
--plan <file> --toolchain-evidence <file> --approved-at <iso> --expected-project-ref <ref> --confirm <email> --out-dir <dir>
|
|
463
|
+
|
|
464
|
+
Seal approval:
|
|
465
|
+
--plan <file> --freeze <file> --approval-request <file> --human-approval <file>
|
|
466
|
+
--approve-freeze-file <sha256> --approve-request <sha256> --approve-text <sha256>
|
|
467
|
+
--confirm <email> --approved-at <iso> --out-dir <dir>
|
|
468
|
+
|
|
469
|
+
Run:
|
|
470
|
+
--plan <file> --freeze <file> --approval <file> --out-dir <dir>
|
|
471
|
+
(--commit --approve-execution <sha256> --confirm <email> | --status-only)
|
|
472
|
+
[--wait-seconds <n>] [--poll-ms <n>] [--timeout-ms <n>]
|
|
473
|
+
|
|
474
|
+
Freeze recovery:
|
|
475
|
+
--plan <file> --freeze <original-file> --approval <original-file> --run-dir <prior-run-dir>
|
|
476
|
+
--toolchain-evidence <file> --approved-at <iso> --recovery-reason <reason>
|
|
477
|
+
--expected-project-ref <ref> --confirm <email> --out-dir <dir> [--timeout-ms <n>]
|
|
478
|
+
|
|
479
|
+
Seal recovery approval:
|
|
480
|
+
--recovery-freeze <file> --approval-request <file> --human-approval <file>
|
|
481
|
+
--approve-freeze-file <sha256> --approve-request <sha256> --approve-text <sha256>
|
|
482
|
+
--confirm <email> --approved-at <iso> --out-dir <dir>
|
|
483
|
+
|
|
484
|
+
Run recovery:
|
|
485
|
+
--plan <file> --freeze <original-file> --approval <original-file> --run-dir <prior-run-dir>
|
|
486
|
+
--recovery-freeze <file> --recovery-approval <file> --out-dir <dir>
|
|
487
|
+
--commit --approve-execution <recovery-identity-sha256> --confirm <email>
|
|
488
|
+
[--wait-seconds <n>] [--poll-ms <n>] [--timeout-ms <n>]
|
|
489
|
+
|
|
490
|
+
Verify:
|
|
491
|
+
--plan <file> --freeze <file> --approval <file> --run-dir <dir> --out-dir <dir>
|
|
492
|
+
[--page-size <n>] [--timeout-ms <n>]
|
|
493
|
+
|
|
494
|
+
Derivative failure boundary:
|
|
495
|
+
A failed/stale derivative will never retry a process. This command stops. Any derivative-only compensation requires a separate plan, new freeze, and new exact human approval.
|
|
496
|
+
|
|
497
|
+
Common:
|
|
498
|
+
--json
|
|
499
|
+
-h, --help
|
|
367
500
|
`.trim();
|
|
368
501
|
}
|
|
369
502
|
function renderDatasetMaintenancePlanHelp() {
|
|
@@ -812,6 +945,10 @@ Options:
|
|
|
812
945
|
--out-dir <dir> Artifact directory
|
|
813
946
|
--commit Execute remote save-draft writes
|
|
814
947
|
--dry-run Validate and plan without remote writes (default)
|
|
948
|
+
--execution-contract <file>
|
|
949
|
+
Execute a content-bound ordered owner-draft batch with append-only attempt/readback evidence (requires --commit)
|
|
950
|
+
--allow-account-local-support
|
|
951
|
+
Explicitly permit account-local Unit Group / Flow Property rows in the execution contract
|
|
815
952
|
--json Print compact JSON
|
|
816
953
|
-h, --help
|
|
817
954
|
|
|
@@ -820,6 +957,7 @@ Outputs written under --out-dir:
|
|
|
820
957
|
- outputs/dataset-save-draft/progress.jsonl
|
|
821
958
|
- outputs/dataset-save-draft/failures.jsonl
|
|
822
959
|
- outputs/dataset-save-draft/summary.json
|
|
960
|
+
- $XDG_STATE_HOME/tiangong-lca-cli/execution-ledgers/dataset-save-draft/v1/<owner-scope-sha256>/<action-identity-sha256>.events.jsonl (execution-contract mode; platform state directory fallback applies)
|
|
823
961
|
|
|
824
962
|
Contract:
|
|
825
963
|
This generic dataset path writes only mutable rows such as contact/source/flow/process. Unit group and flow property rows are reference-only; select existing database rows and rewrite references instead of creating My Data support rows.
|
|
@@ -2167,6 +2305,71 @@ function parseRemoteFlags(args) {
|
|
|
2167
2305
|
timeoutMs,
|
|
2168
2306
|
};
|
|
2169
2307
|
}
|
|
2308
|
+
function parseLcaReleaseFlags(args) {
|
|
2309
|
+
let values;
|
|
2310
|
+
try {
|
|
2311
|
+
({ values } = parseArgs({
|
|
2312
|
+
args,
|
|
2313
|
+
allowPositionals: false,
|
|
2314
|
+
strict: true,
|
|
2315
|
+
options: {
|
|
2316
|
+
help: { type: 'boolean', short: 'h' },
|
|
2317
|
+
json: { type: 'boolean' },
|
|
2318
|
+
'dry-run': { type: 'boolean' },
|
|
2319
|
+
force: { type: 'boolean' },
|
|
2320
|
+
input: { type: 'string' },
|
|
2321
|
+
output: { type: 'string' },
|
|
2322
|
+
'release-run-id': { type: 'string' },
|
|
2323
|
+
'package-id': { type: 'string' },
|
|
2324
|
+
'artifact-id': { type: 'string' },
|
|
2325
|
+
'artifact-path': { type: 'string' },
|
|
2326
|
+
'api-key': { type: 'string' },
|
|
2327
|
+
'base-url': { type: 'string' },
|
|
2328
|
+
'timeout-ms': { type: 'string' },
|
|
2329
|
+
},
|
|
2330
|
+
}));
|
|
2331
|
+
}
|
|
2332
|
+
catch (error) {
|
|
2333
|
+
throw new CliError(String(error), {
|
|
2334
|
+
code: 'INVALID_ARGS',
|
|
2335
|
+
exitCode: 2,
|
|
2336
|
+
});
|
|
2337
|
+
}
|
|
2338
|
+
const timeoutText = typeof values['timeout-ms'] === 'string' ? values['timeout-ms'] : undefined;
|
|
2339
|
+
const timeoutMs = timeoutText ? Number.parseInt(timeoutText, 10) : 60_000;
|
|
2340
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
|
|
2341
|
+
throw new CliError('Expected --timeout-ms to be a positive integer.', {
|
|
2342
|
+
code: 'INVALID_TIMEOUT',
|
|
2343
|
+
exitCode: 2,
|
|
2344
|
+
});
|
|
2345
|
+
}
|
|
2346
|
+
const optionalString = (value) => typeof value === 'string' ? value : null;
|
|
2347
|
+
return {
|
|
2348
|
+
help: Boolean(values.help),
|
|
2349
|
+
json: Boolean(values.json),
|
|
2350
|
+
dryRun: Boolean(values['dry-run']),
|
|
2351
|
+
force: Boolean(values.force),
|
|
2352
|
+
inputPath: optionalString(values.input),
|
|
2353
|
+
outputPath: optionalString(values.output),
|
|
2354
|
+
releaseRunId: optionalString(values['release-run-id']),
|
|
2355
|
+
packageId: optionalString(values['package-id']),
|
|
2356
|
+
artifactId: optionalString(values['artifact-id']),
|
|
2357
|
+
artifactPath: optionalString(values['artifact-path']),
|
|
2358
|
+
apiKey: optionalString(values['api-key']),
|
|
2359
|
+
apiBaseUrl: optionalString(values['base-url']),
|
|
2360
|
+
timeoutMs,
|
|
2361
|
+
};
|
|
2362
|
+
}
|
|
2363
|
+
function requireLcaReleaseAction(value) {
|
|
2364
|
+
if (!LCA_RELEASE_ACTIONS.includes(value)) {
|
|
2365
|
+
throw new CliError(`Unsupported release action: ${value}`, {
|
|
2366
|
+
code: 'LCA_RELEASE_ACTION_UNSUPPORTED',
|
|
2367
|
+
exitCode: 2,
|
|
2368
|
+
details: { actions: LCA_RELEASE_ACTIONS },
|
|
2369
|
+
});
|
|
2370
|
+
}
|
|
2371
|
+
return value;
|
|
2372
|
+
}
|
|
2170
2373
|
function parsePublishFlags(args) {
|
|
2171
2374
|
let values;
|
|
2172
2375
|
try {
|
|
@@ -2280,6 +2483,7 @@ function parseDatasetSaveDraftFlags(args) {
|
|
|
2280
2483
|
commit: { type: 'boolean' },
|
|
2281
2484
|
'dry-run': { type: 'boolean' },
|
|
2282
2485
|
'allow-account-local-support': { type: 'boolean' },
|
|
2486
|
+
'execution-contract': { type: 'string' },
|
|
2283
2487
|
},
|
|
2284
2488
|
}));
|
|
2285
2489
|
}
|
|
@@ -2303,6 +2507,7 @@ function parseDatasetSaveDraftFlags(args) {
|
|
|
2303
2507
|
outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : null,
|
|
2304
2508
|
commit: Boolean(values.commit),
|
|
2305
2509
|
allowReferenceOnlySupport: Boolean(values['allow-account-local-support']),
|
|
2510
|
+
executionContractPath: typeof values['execution-contract'] === 'string' ? values['execution-contract'] : null,
|
|
2306
2511
|
};
|
|
2307
2512
|
}
|
|
2308
2513
|
function parseDatasetSourceUploadAttachmentsFlags(args) {
|
|
@@ -3386,6 +3591,95 @@ function parseDatasetMaintenanceProtectedFlags(args) {
|
|
|
3386
3591
|
timeoutMs: parseDatasetMaintenancePositiveInteger(values['timeout-ms'], '--timeout-ms'),
|
|
3387
3592
|
};
|
|
3388
3593
|
}
|
|
3594
|
+
function parseDatasetMaintenanceFlowIdentityFlags(args) {
|
|
3595
|
+
let values;
|
|
3596
|
+
try {
|
|
3597
|
+
({ values } = parseArgs({
|
|
3598
|
+
args,
|
|
3599
|
+
allowPositionals: false,
|
|
3600
|
+
strict: true,
|
|
3601
|
+
options: {
|
|
3602
|
+
help: { type: 'boolean', short: 'h' },
|
|
3603
|
+
json: { type: 'boolean' },
|
|
3604
|
+
policy: { type: 'string' },
|
|
3605
|
+
'review-ledger': { type: 'string' },
|
|
3606
|
+
prerequisites: { type: 'string' },
|
|
3607
|
+
'live-capture': { type: 'string' },
|
|
3608
|
+
plan: { type: 'string' },
|
|
3609
|
+
'toolchain-evidence': { type: 'string' },
|
|
3610
|
+
'approval-text': { type: 'string' },
|
|
3611
|
+
'expected-project-ref': { type: 'string' },
|
|
3612
|
+
'request-id': { type: 'string' },
|
|
3613
|
+
'operation-id': { type: 'string' },
|
|
3614
|
+
'sdk-version': { type: 'string' },
|
|
3615
|
+
freeze: { type: 'string' },
|
|
3616
|
+
'approval-request': { type: 'string' },
|
|
3617
|
+
'human-approval': { type: 'string' },
|
|
3618
|
+
approval: { type: 'string' },
|
|
3619
|
+
'recovery-freeze': { type: 'string' },
|
|
3620
|
+
'recovery-approval': { type: 'string' },
|
|
3621
|
+
'recovery-reason': { type: 'string' },
|
|
3622
|
+
'approve-freeze-file': { type: 'string' },
|
|
3623
|
+
'approve-request': { type: 'string' },
|
|
3624
|
+
'approve-text': { type: 'string' },
|
|
3625
|
+
'approve-execution': { type: 'string' },
|
|
3626
|
+
confirm: { type: 'string' },
|
|
3627
|
+
'approved-at': { type: 'string' },
|
|
3628
|
+
'out-dir': { type: 'string' },
|
|
3629
|
+
'run-dir': { type: 'string' },
|
|
3630
|
+
commit: { type: 'boolean' },
|
|
3631
|
+
'status-only': { type: 'boolean' },
|
|
3632
|
+
'wait-seconds': { type: 'string' },
|
|
3633
|
+
'poll-ms': { type: 'string' },
|
|
3634
|
+
'page-size': { type: 'string' },
|
|
3635
|
+
'read-concurrency': { type: 'string' },
|
|
3636
|
+
'timeout-ms': { type: 'string' },
|
|
3637
|
+
},
|
|
3638
|
+
}));
|
|
3639
|
+
}
|
|
3640
|
+
catch (error) {
|
|
3641
|
+
throw new CliError(String(error), { code: 'INVALID_ARGS', exitCode: 2 });
|
|
3642
|
+
}
|
|
3643
|
+
const valueRecord = values;
|
|
3644
|
+
const string = (name) => typeof valueRecord[name] === 'string' ? String(valueRecord[name]) : '';
|
|
3645
|
+
return {
|
|
3646
|
+
help: Boolean(values.help),
|
|
3647
|
+
json: Boolean(values.json),
|
|
3648
|
+
policyPath: string('policy'),
|
|
3649
|
+
reviewLedgerPath: string('review-ledger'),
|
|
3650
|
+
prerequisitesPath: string('prerequisites'),
|
|
3651
|
+
liveCapturePath: string('live-capture'),
|
|
3652
|
+
planPath: string('plan'),
|
|
3653
|
+
toolchainEvidencePath: string('toolchain-evidence'),
|
|
3654
|
+
approvalTextPath: string('approval-text'),
|
|
3655
|
+
expectedProjectRef: string('expected-project-ref'),
|
|
3656
|
+
requestId: string('request-id'),
|
|
3657
|
+
operationId: string('operation-id'),
|
|
3658
|
+
sdkVersion: string('sdk-version'),
|
|
3659
|
+
freezePath: string('freeze'),
|
|
3660
|
+
approvalRequestPath: string('approval-request'),
|
|
3661
|
+
humanApprovalPath: string('human-approval'),
|
|
3662
|
+
approvalPath: string('approval'),
|
|
3663
|
+
recoveryFreezePath: string('recovery-freeze'),
|
|
3664
|
+
recoveryApprovalPath: string('recovery-approval'),
|
|
3665
|
+
recoveryReason: string('recovery-reason'),
|
|
3666
|
+
approveFreezeFile: string('approve-freeze-file'),
|
|
3667
|
+
approveRequest: string('approve-request'),
|
|
3668
|
+
approveText: string('approve-text'),
|
|
3669
|
+
approveExecution: string('approve-execution'),
|
|
3670
|
+
confirm: string('confirm'),
|
|
3671
|
+
approvedAtUtc: string('approved-at'),
|
|
3672
|
+
outDir: string('out-dir'),
|
|
3673
|
+
runDir: string('run-dir'),
|
|
3674
|
+
commit: Boolean(values.commit),
|
|
3675
|
+
statusOnly: Boolean(values['status-only']),
|
|
3676
|
+
waitSeconds: parseDatasetMaintenanceNonNegativeInteger(values['wait-seconds'], '--wait-seconds'),
|
|
3677
|
+
pollMs: parseDatasetMaintenancePositiveInteger(values['poll-ms'], '--poll-ms'),
|
|
3678
|
+
pageSize: parseDatasetMaintenancePositiveInteger(values['page-size'], '--page-size'),
|
|
3679
|
+
readConcurrency: parseDatasetMaintenancePositiveInteger(values['read-concurrency'], '--read-concurrency'),
|
|
3680
|
+
timeoutMs: parseDatasetMaintenancePositiveInteger(values['timeout-ms'], '--timeout-ms'),
|
|
3681
|
+
};
|
|
3682
|
+
}
|
|
3389
3683
|
function parseDatasetMaintenanceVerifyFlags(args) {
|
|
3390
3684
|
let values;
|
|
3391
3685
|
try {
|
|
@@ -5100,6 +5394,7 @@ export async function executeCli(argv, deps) {
|
|
|
5100
5394
|
const { flags, command, subcommand, commandArgs } = parseCommandLine(argv);
|
|
5101
5395
|
const publishImpl = deps.runPublishImpl ?? runPublish;
|
|
5102
5396
|
const validationImpl = deps.runValidationImpl ?? runValidation;
|
|
5397
|
+
const lcaReleaseImpl = deps.runLcaReleaseImpl ?? runLcaRelease;
|
|
5103
5398
|
const lifecyclemodelAutoBuildImpl = deps.runLifecyclemodelAutoBuildImpl ?? runLifecyclemodelAutoBuild;
|
|
5104
5399
|
const lifecyclemodelBuildImpl = deps.runLifecyclemodelBuildResultingProcessImpl ?? runLifecyclemodelBuildResultingProcess;
|
|
5105
5400
|
const lifecyclemodelPublishImpl = deps.runLifecyclemodelPublishResultingProcessImpl ?? runLifecyclemodelPublishResultingProcess;
|
|
@@ -5169,6 +5464,14 @@ export async function executeCli(argv, deps) {
|
|
|
5169
5464
|
const datasetMaintenanceProtectedImpl = deps.runDatasetMaintenanceProtectedImpl ?? runDatasetMaintenanceProtected;
|
|
5170
5465
|
const datasetMaintenanceProtectedApprovalSealImpl = deps.sealDatasetMaintenanceProtectedApprovalImpl ?? sealDatasetMaintenanceProtectedApproval;
|
|
5171
5466
|
const datasetMaintenanceVerifyImpl = deps.runDatasetMaintenanceVerifyImpl ?? runDatasetMaintenanceVerify;
|
|
5467
|
+
const flowIdentityPlanImpl = deps.runFlowIdentityPlanFromFilesImpl ?? runFlowIdentityPlanFromFiles;
|
|
5468
|
+
const flowIdentityCaptureImpl = deps.captureFlowIdentityImpl ?? captureFlowIdentity;
|
|
5469
|
+
const flowIdentityFreezeImpl = deps.freezeFlowIdentityImpl ?? freezeFlowIdentity;
|
|
5470
|
+
const flowIdentityApprovalSealImpl = deps.sealFlowIdentityApprovalImpl ?? sealFlowIdentityApproval;
|
|
5471
|
+
const flowIdentityRecoveryFreezeImpl = deps.freezeFlowIdentityRecoveryImpl ?? freezeFlowIdentityRecovery;
|
|
5472
|
+
const flowIdentityRecoveryApprovalSealImpl = deps.sealFlowIdentityRecoveryApprovalImpl ?? sealFlowIdentityRecoveryApproval;
|
|
5473
|
+
const flowIdentityRunImpl = deps.runFlowIdentityImpl ?? runFlowIdentity;
|
|
5474
|
+
const flowIdentityVerifyImpl = deps.verifyFlowIdentityImpl ?? verifyFlowIdentity;
|
|
5172
5475
|
const datasetSourceUploadAttachmentsImpl = deps.runDatasetSourceUploadAttachmentsImpl ?? runDatasetSourceUploadAttachments;
|
|
5173
5476
|
if (flags.version) {
|
|
5174
5477
|
return { exitCode: 0, stdout: `${loadCliPackageVersion(import.meta.url)}\n`, stderr: '' };
|
|
@@ -5554,11 +5857,12 @@ export async function executeCli(argv, deps) {
|
|
|
5554
5857
|
outDir: datasetFlags.outDir,
|
|
5555
5858
|
commit: datasetFlags.commit,
|
|
5556
5859
|
allowReferenceOnlySupport: datasetFlags.allowReferenceOnlySupport,
|
|
5860
|
+
executionContractPath: datasetFlags.executionContractPath,
|
|
5557
5861
|
env: deps.env,
|
|
5558
5862
|
fetchImpl: deps.fetchImpl,
|
|
5559
5863
|
});
|
|
5560
5864
|
return {
|
|
5561
|
-
exitCode: report.status === '
|
|
5865
|
+
exitCode: report.status === 'completed' ? 0 : 1,
|
|
5562
5866
|
stdout: stringifyJson(report, datasetFlags.json),
|
|
5563
5867
|
stderr: '',
|
|
5564
5868
|
};
|
|
@@ -5753,6 +6057,215 @@ export async function executeCli(argv, deps) {
|
|
|
5753
6057
|
if (!action || action === '--help' || action === '-h') {
|
|
5754
6058
|
return { exitCode: 0, stdout: `${renderDatasetMaintenanceHelp()}\n`, stderr: '' };
|
|
5755
6059
|
}
|
|
6060
|
+
if (action === 'flow-identity') {
|
|
6061
|
+
const flowAction = commandArgs[1] ?? '';
|
|
6062
|
+
if (!flowAction || flowAction === '--help' || flowAction === '-h') {
|
|
6063
|
+
return {
|
|
6064
|
+
exitCode: 0,
|
|
6065
|
+
stdout: `${renderDatasetMaintenanceFlowIdentityHelp()}\n`,
|
|
6066
|
+
stderr: '',
|
|
6067
|
+
};
|
|
6068
|
+
}
|
|
6069
|
+
const datasetFlags = parseDatasetMaintenanceFlowIdentityFlags(commandArgs.slice(2));
|
|
6070
|
+
if (datasetFlags.help) {
|
|
6071
|
+
return {
|
|
6072
|
+
exitCode: 0,
|
|
6073
|
+
stdout: `${renderDatasetMaintenanceFlowIdentityHelp()}\n`,
|
|
6074
|
+
stderr: '',
|
|
6075
|
+
};
|
|
6076
|
+
}
|
|
6077
|
+
const required = (value, flag) => {
|
|
6078
|
+
if (!value) {
|
|
6079
|
+
throw new CliError(`dataset maintenance flow-identity ${flowAction} requires ${flag}.`, {
|
|
6080
|
+
code: 'DATASET_FLOW_IDENTITY_ARGUMENT_REQUIRED',
|
|
6081
|
+
exitCode: 2,
|
|
6082
|
+
});
|
|
6083
|
+
}
|
|
6084
|
+
return value;
|
|
6085
|
+
};
|
|
6086
|
+
if (flowAction === 'capture') {
|
|
6087
|
+
const report = await flowIdentityCaptureImpl({
|
|
6088
|
+
policyPath: required(datasetFlags.policyPath, '--policy'),
|
|
6089
|
+
reviewLedgerPath: required(datasetFlags.reviewLedgerPath, '--review-ledger'),
|
|
6090
|
+
prerequisitesPath: required(datasetFlags.prerequisitesPath, '--prerequisites'),
|
|
6091
|
+
toolchainEvidencePath: required(datasetFlags.toolchainEvidencePath, '--toolchain-evidence'),
|
|
6092
|
+
requestId: required(datasetFlags.requestId, '--request-id'),
|
|
6093
|
+
operationId: required(datasetFlags.operationId, '--operation-id'),
|
|
6094
|
+
expectedProjectRef: required(datasetFlags.expectedProjectRef, '--expected-project-ref'),
|
|
6095
|
+
confirm: required(datasetFlags.confirm, '--confirm'),
|
|
6096
|
+
cliVersion: loadCliPackageVersion(import.meta.url),
|
|
6097
|
+
sdkVersion: required(datasetFlags.sdkVersion, '--sdk-version'),
|
|
6098
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6099
|
+
pageSize: datasetFlags.pageSize,
|
|
6100
|
+
readConcurrency: datasetFlags.readConcurrency,
|
|
6101
|
+
timeoutMs: datasetFlags.timeoutMs,
|
|
6102
|
+
env: deps.env,
|
|
6103
|
+
fetchImpl: deps.fetchImpl,
|
|
6104
|
+
});
|
|
6105
|
+
return { exitCode: 0, stdout: stringifyJson(report, datasetFlags.json), stderr: '' };
|
|
6106
|
+
}
|
|
6107
|
+
if (flowAction === 'plan') {
|
|
6108
|
+
const plan = await flowIdentityPlanImpl({
|
|
6109
|
+
policyPath: required(datasetFlags.policyPath, '--policy'),
|
|
6110
|
+
reviewLedgerPath: required(datasetFlags.reviewLedgerPath, '--review-ledger'),
|
|
6111
|
+
liveCapturePath: required(datasetFlags.liveCapturePath, '--live-capture'),
|
|
6112
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6113
|
+
});
|
|
6114
|
+
return { exitCode: 0, stdout: stringifyJson(plan, datasetFlags.json), stderr: '' };
|
|
6115
|
+
}
|
|
6116
|
+
if (flowAction === 'freeze') {
|
|
6117
|
+
const report = await flowIdentityFreezeImpl({
|
|
6118
|
+
planPath: required(datasetFlags.planPath, '--plan'),
|
|
6119
|
+
toolchainEvidencePath: required(datasetFlags.toolchainEvidencePath, '--toolchain-evidence'),
|
|
6120
|
+
approvedAtUtc: required(datasetFlags.approvedAtUtc, '--approved-at'),
|
|
6121
|
+
expectedProjectRef: required(datasetFlags.expectedProjectRef, '--expected-project-ref'),
|
|
6122
|
+
confirm: required(datasetFlags.confirm, '--confirm'),
|
|
6123
|
+
cliVersion: loadCliPackageVersion(import.meta.url),
|
|
6124
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6125
|
+
});
|
|
6126
|
+
return { exitCode: 0, stdout: stringifyJson(report, datasetFlags.json), stderr: '' };
|
|
6127
|
+
}
|
|
6128
|
+
if (flowAction === 'seal-approval') {
|
|
6129
|
+
const report = await flowIdentityApprovalSealImpl({
|
|
6130
|
+
planPath: required(datasetFlags.planPath, '--plan'),
|
|
6131
|
+
freezePath: required(datasetFlags.freezePath, '--freeze'),
|
|
6132
|
+
approvalRequestPath: required(datasetFlags.approvalRequestPath, '--approval-request'),
|
|
6133
|
+
humanApprovalPath: required(datasetFlags.humanApprovalPath, '--human-approval'),
|
|
6134
|
+
approveFreezeFile: required(datasetFlags.approveFreezeFile, '--approve-freeze-file'),
|
|
6135
|
+
approveRequest: required(datasetFlags.approveRequest, '--approve-request'),
|
|
6136
|
+
approveText: required(datasetFlags.approveText, '--approve-text'),
|
|
6137
|
+
confirm: required(datasetFlags.confirm, '--confirm'),
|
|
6138
|
+
approvedAtUtc: required(datasetFlags.approvedAtUtc, '--approved-at'),
|
|
6139
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6140
|
+
});
|
|
6141
|
+
return { exitCode: 0, stdout: stringifyJson(report, datasetFlags.json), stderr: '' };
|
|
6142
|
+
}
|
|
6143
|
+
if (flowAction === 'freeze-recovery') {
|
|
6144
|
+
const recoveryReason = required(datasetFlags.recoveryReason, '--recovery-reason');
|
|
6145
|
+
if (![
|
|
6146
|
+
'wrapper_exited_without_permit',
|
|
6147
|
+
'process_response_ambiguous',
|
|
6148
|
+
'process_domain_rejected',
|
|
6149
|
+
'finalize_response_ambiguous',
|
|
6150
|
+
'derivatives_became_ready_after_wrapper_exit',
|
|
6151
|
+
].includes(recoveryReason)) {
|
|
6152
|
+
throw new CliError('flow-identity recovery reason is not allowed.', {
|
|
6153
|
+
code: 'DATASET_FLOW_IDENTITY_RECOVERY_REASON_INVALID',
|
|
6154
|
+
exitCode: 2,
|
|
6155
|
+
});
|
|
6156
|
+
}
|
|
6157
|
+
const report = await flowIdentityRecoveryFreezeImpl({
|
|
6158
|
+
planPath: required(datasetFlags.planPath, '--plan'),
|
|
6159
|
+
freezePath: required(datasetFlags.freezePath, '--freeze'),
|
|
6160
|
+
approvalPath: required(datasetFlags.approvalPath, '--approval'),
|
|
6161
|
+
runDir: required(datasetFlags.runDir, '--run-dir'),
|
|
6162
|
+
toolchainEvidencePath: required(datasetFlags.toolchainEvidencePath, '--toolchain-evidence'),
|
|
6163
|
+
expectedProjectRef: required(datasetFlags.expectedProjectRef, '--expected-project-ref'),
|
|
6164
|
+
confirm: required(datasetFlags.confirm, '--confirm'),
|
|
6165
|
+
approvedAtUtc: required(datasetFlags.approvedAtUtc, '--approved-at'),
|
|
6166
|
+
recoveryReason: recoveryReason,
|
|
6167
|
+
cliVersion: loadCliPackageVersion(import.meta.url),
|
|
6168
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6169
|
+
timeoutMs: datasetFlags.timeoutMs,
|
|
6170
|
+
env: deps.env,
|
|
6171
|
+
fetchImpl: deps.fetchImpl,
|
|
6172
|
+
});
|
|
6173
|
+
return { exitCode: 0, stdout: stringifyJson(report, datasetFlags.json), stderr: '' };
|
|
6174
|
+
}
|
|
6175
|
+
if (flowAction === 'seal-recovery-approval') {
|
|
6176
|
+
const report = flowIdentityRecoveryApprovalSealImpl({
|
|
6177
|
+
recoveryFreezePath: required(datasetFlags.recoveryFreezePath, '--recovery-freeze'),
|
|
6178
|
+
approvalRequestPath: required(datasetFlags.approvalRequestPath, '--approval-request'),
|
|
6179
|
+
humanApprovalPath: required(datasetFlags.humanApprovalPath, '--human-approval'),
|
|
6180
|
+
approveFreezeFile: required(datasetFlags.approveFreezeFile, '--approve-freeze-file'),
|
|
6181
|
+
approveRequest: required(datasetFlags.approveRequest, '--approve-request'),
|
|
6182
|
+
approveText: required(datasetFlags.approveText, '--approve-text'),
|
|
6183
|
+
confirm: required(datasetFlags.confirm, '--confirm'),
|
|
6184
|
+
approvedAtUtc: required(datasetFlags.approvedAtUtc, '--approved-at'),
|
|
6185
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6186
|
+
});
|
|
6187
|
+
return { exitCode: 0, stdout: stringifyJson(report, datasetFlags.json), stderr: '' };
|
|
6188
|
+
}
|
|
6189
|
+
if (flowAction === 'run-recovery') {
|
|
6190
|
+
if (!datasetFlags.commit || datasetFlags.statusOnly) {
|
|
6191
|
+
throw new CliError('flow-identity run-recovery requires --commit only.', {
|
|
6192
|
+
code: 'DATASET_FLOW_IDENTITY_RECOVERY_RUN_MODE_INVALID',
|
|
6193
|
+
exitCode: 2,
|
|
6194
|
+
});
|
|
6195
|
+
}
|
|
6196
|
+
const report = await flowIdentityRunImpl({
|
|
6197
|
+
planPath: required(datasetFlags.planPath, '--plan'),
|
|
6198
|
+
freezePath: required(datasetFlags.freezePath, '--freeze'),
|
|
6199
|
+
approvalPath: required(datasetFlags.approvalPath, '--approval'),
|
|
6200
|
+
recoveryRunDir: required(datasetFlags.runDir, '--run-dir'),
|
|
6201
|
+
recoveryFreezePath: required(datasetFlags.recoveryFreezePath, '--recovery-freeze'),
|
|
6202
|
+
recoveryApprovalPath: required(datasetFlags.recoveryApprovalPath, '--recovery-approval'),
|
|
6203
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6204
|
+
commit: true,
|
|
6205
|
+
statusOnly: false,
|
|
6206
|
+
approveExecution: required(datasetFlags.approveExecution, '--approve-execution'),
|
|
6207
|
+
confirm: required(datasetFlags.confirm, '--confirm'),
|
|
6208
|
+
waitSeconds: datasetFlags.waitSeconds,
|
|
6209
|
+
pollMs: datasetFlags.pollMs,
|
|
6210
|
+
timeoutMs: datasetFlags.timeoutMs,
|
|
6211
|
+
env: deps.env,
|
|
6212
|
+
fetchImpl: deps.fetchImpl,
|
|
6213
|
+
});
|
|
6214
|
+
return {
|
|
6215
|
+
exitCode: report.status === 'passed' ? 0 : 1,
|
|
6216
|
+
stdout: stringifyJson(report, datasetFlags.json),
|
|
6217
|
+
stderr: '',
|
|
6218
|
+
};
|
|
6219
|
+
}
|
|
6220
|
+
if (flowAction === 'run') {
|
|
6221
|
+
if (datasetFlags.commit === datasetFlags.statusOnly) {
|
|
6222
|
+
throw new CliError('flow-identity run requires exactly one of --commit or --status-only.', { code: 'DATASET_FLOW_IDENTITY_RUN_MODE_INVALID', exitCode: 2 });
|
|
6223
|
+
}
|
|
6224
|
+
if (datasetFlags.commit) {
|
|
6225
|
+
required(datasetFlags.approveExecution, '--approve-execution');
|
|
6226
|
+
required(datasetFlags.confirm, '--confirm');
|
|
6227
|
+
}
|
|
6228
|
+
const report = await flowIdentityRunImpl({
|
|
6229
|
+
planPath: required(datasetFlags.planPath, '--plan'),
|
|
6230
|
+
freezePath: required(datasetFlags.freezePath, '--freeze'),
|
|
6231
|
+
approvalPath: required(datasetFlags.approvalPath, '--approval'),
|
|
6232
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6233
|
+
commit: datasetFlags.commit,
|
|
6234
|
+
statusOnly: datasetFlags.statusOnly,
|
|
6235
|
+
approveExecution: datasetFlags.approveExecution || undefined,
|
|
6236
|
+
confirm: datasetFlags.confirm || undefined,
|
|
6237
|
+
waitSeconds: datasetFlags.waitSeconds,
|
|
6238
|
+
pollMs: datasetFlags.pollMs,
|
|
6239
|
+
timeoutMs: datasetFlags.timeoutMs,
|
|
6240
|
+
env: deps.env,
|
|
6241
|
+
fetchImpl: deps.fetchImpl,
|
|
6242
|
+
});
|
|
6243
|
+
return {
|
|
6244
|
+
exitCode: report.status === 'passed' ? 0 : 1,
|
|
6245
|
+
stdout: stringifyJson(report, datasetFlags.json),
|
|
6246
|
+
stderr: '',
|
|
6247
|
+
};
|
|
6248
|
+
}
|
|
6249
|
+
if (flowAction === 'verify') {
|
|
6250
|
+
const report = await flowIdentityVerifyImpl({
|
|
6251
|
+
planPath: required(datasetFlags.planPath, '--plan'),
|
|
6252
|
+
freezePath: required(datasetFlags.freezePath, '--freeze'),
|
|
6253
|
+
approvalPath: required(datasetFlags.approvalPath, '--approval'),
|
|
6254
|
+
runDir: required(datasetFlags.runDir, '--run-dir'),
|
|
6255
|
+
outDir: required(datasetFlags.outDir, '--out-dir'),
|
|
6256
|
+
pageSize: datasetFlags.pageSize,
|
|
6257
|
+
timeoutMs: datasetFlags.timeoutMs,
|
|
6258
|
+
env: deps.env,
|
|
6259
|
+
fetchImpl: deps.fetchImpl,
|
|
6260
|
+
});
|
|
6261
|
+
return {
|
|
6262
|
+
exitCode: report.status === 'passed' ? 0 : 1,
|
|
6263
|
+
stdout: stringifyJson(report, datasetFlags.json),
|
|
6264
|
+
stderr: '',
|
|
6265
|
+
};
|
|
6266
|
+
}
|
|
6267
|
+
throw new CliError("dataset maintenance flow-identity action must be 'capture', 'plan', 'freeze', 'seal-approval', 'run', 'freeze-recovery', 'seal-recovery-approval', 'run-recovery', or 'verify'.", { code: 'DATASET_FLOW_IDENTITY_ACTION_INVALID', exitCode: 2 });
|
|
6268
|
+
}
|
|
5756
6269
|
if (action === 'clear-account') {
|
|
5757
6270
|
const datasetFlags = parseDatasetMaintenanceClearAccountFlags(commandArgs.slice(1));
|
|
5758
6271
|
if (datasetFlags.help) {
|
|
@@ -6125,7 +6638,7 @@ export async function executeCli(argv, deps) {
|
|
|
6125
6638
|
stderr: '',
|
|
6126
6639
|
};
|
|
6127
6640
|
}
|
|
6128
|
-
throw new CliError("dataset maintenance action must be 'clear-account', 'plan', 'apply', 'freeze-protected', 'seal-protected-approval', 'run-protected', or '
|
|
6641
|
+
throw new CliError("dataset maintenance action must be 'clear-account', 'plan', 'apply', 'freeze-protected', 'seal-protected-approval', 'run-protected', 'verify', or 'flow-identity'.", {
|
|
6129
6642
|
code: 'DATASET_MAINTENANCE_ACTION_INVALID',
|
|
6130
6643
|
exitCode: 2,
|
|
6131
6644
|
});
|
|
@@ -6969,6 +7482,42 @@ export async function executeCli(argv, deps) {
|
|
|
6969
7482
|
stderr: '',
|
|
6970
7483
|
};
|
|
6971
7484
|
}
|
|
7485
|
+
if (command === 'release' && !subcommand) {
|
|
7486
|
+
return { exitCode: 0, stdout: `${renderLcaReleaseHelp()}\n`, stderr: '' };
|
|
7487
|
+
}
|
|
7488
|
+
if (command === 'release' && subcommand) {
|
|
7489
|
+
const releaseFlags = parseLcaReleaseFlags(commandArgs);
|
|
7490
|
+
if (releaseFlags.help) {
|
|
7491
|
+
return { exitCode: 0, stdout: `${renderLcaReleaseHelp()}\n`, stderr: '' };
|
|
7492
|
+
}
|
|
7493
|
+
const action = requireLcaReleaseAction(subcommand);
|
|
7494
|
+
const env = { ...deps.env };
|
|
7495
|
+
if (releaseFlags.apiKey !== null) {
|
|
7496
|
+
env.TIANGONG_LCA_API_KEY = releaseFlags.apiKey;
|
|
7497
|
+
}
|
|
7498
|
+
if (releaseFlags.apiBaseUrl !== null) {
|
|
7499
|
+
env.TIANGONG_LCA_API_BASE_URL = releaseFlags.apiBaseUrl;
|
|
7500
|
+
}
|
|
7501
|
+
const report = await lcaReleaseImpl({
|
|
7502
|
+
action,
|
|
7503
|
+
inputPath: releaseFlags.inputPath,
|
|
7504
|
+
outputPath: releaseFlags.outputPath,
|
|
7505
|
+
releaseRunId: releaseFlags.releaseRunId,
|
|
7506
|
+
packageId: releaseFlags.packageId,
|
|
7507
|
+
artifactId: releaseFlags.artifactId,
|
|
7508
|
+
artifactPath: releaseFlags.artifactPath,
|
|
7509
|
+
env,
|
|
7510
|
+
timeoutMs: releaseFlags.timeoutMs,
|
|
7511
|
+
dryRun: releaseFlags.dryRun,
|
|
7512
|
+
force: releaseFlags.force,
|
|
7513
|
+
fetchImpl: deps.fetchImpl,
|
|
7514
|
+
});
|
|
7515
|
+
return {
|
|
7516
|
+
exitCode: 0,
|
|
7517
|
+
stdout: releaseFlags.json ? stringifyJson(report, true) : renderLcaReleaseReport(report),
|
|
7518
|
+
stderr: '',
|
|
7519
|
+
};
|
|
7520
|
+
}
|
|
6972
7521
|
if (command === 'admin' && !subcommand && commandArgs.includes('--help')) {
|
|
6973
7522
|
return { exitCode: 0, stdout: `${renderAdminHelp()}\n`, stderr: '' };
|
|
6974
7523
|
}
|