@tiangong-lca/cli 0.0.33 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +61 -13
- package/assets/import-smoke/simapro.csv +20 -0
- package/bin/tiangong-lca.js +1 -1
- package/dist/src/cli.js +213 -64
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/auth-identity-receipt.js +634 -0
- package/dist/src/lib/auth-identity-receipt.js.map +1 -0
- package/dist/src/lib/dataset-bilingual.js.map +1 -1
- package/dist/src/lib/dataset-classification.js.map +1 -1
- package/dist/src/lib/dataset-contract.js.map +1 -1
- package/dist/src/lib/dataset-evidence-search.js.map +1 -1
- package/dist/src/lib/dataset-import-lca.js +302 -131
- package/dist/src/lib/dataset-import-lca.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-apply.js +213 -46
- package/dist/src/lib/dataset-maintenance-apply.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-clear-account.js +10 -4
- package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-contract.js +1 -6
- package/dist/src/lib/dataset-maintenance-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-derivatives.js +0 -1
- package/dist/src/lib/dataset-maintenance-derivatives.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-flow-identity-capture.js +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-capture.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-pagination.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-before.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-contract.js +0 -1
- package/dist/src/lib/dataset-maintenance-protected-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-freeze.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-preparation.js +0 -2
- package/dist/src/lib/dataset-maintenance-protected-preparation.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-seal.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-verify.js +0 -3
- package/dist/src/lib/dataset-maintenance-protected-verify.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-remote.js +36 -14
- package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-verify.js +1 -2
- package/dist/src/lib/dataset-maintenance-verify.js.map +1 -1
- package/dist/src/lib/dataset-remote-refresh.js.map +1 -1
- package/dist/src/lib/dataset-remote-verify.js +2 -0
- package/dist/src/lib/dataset-remote-verify.js.map +1 -1
- package/dist/src/lib/dataset-save-draft-run.js +2 -0
- package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
- package/dist/src/lib/flow-build-alias-map.js.map +1 -1
- package/dist/src/lib/flow-fetch-rows.js.map +1 -1
- package/dist/src/lib/flow-get.js.map +1 -1
- package/dist/src/lib/flow-governance.js.map +1 -1
- package/dist/src/lib/flow-list.js +1 -0
- package/dist/src/lib/flow-list.js.map +1 -1
- package/dist/src/lib/flow-payload-validation.js.map +1 -1
- package/dist/src/lib/flow-publish-version.js +1 -0
- package/dist/src/lib/flow-publish-version.js.map +1 -1
- package/dist/src/lib/flow-read.js +1 -0
- package/dist/src/lib/flow-read.js.map +1 -1
- package/dist/src/lib/flow-regen-product.js.map +1 -1
- package/dist/src/lib/flow-remediate.js.map +1 -1
- package/dist/src/lib/http.js.map +1 -1
- package/dist/src/lib/identity-preflight.js +4 -10
- package/dist/src/lib/identity-preflight.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-bundle-save.js +1 -0
- package/dist/src/lib/lifecyclemodel-bundle-save.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-orchestrate.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-publish-resulting-process.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
- package/dist/src/lib/package-version.js.map +1 -1
- package/dist/src/lib/process-auto-build.js.map +1 -1
- package/dist/src/lib/process-dedup-review.js +14 -7
- package/dist/src/lib/process-dedup-review.js.map +1 -1
- package/dist/src/lib/process-flow-build-plan.js +111 -30
- package/dist/src/lib/process-flow-build-plan.js.map +1 -1
- package/dist/src/lib/process-get.js +1 -0
- package/dist/src/lib/process-get.js.map +1 -1
- package/dist/src/lib/process-list.js +1 -0
- package/dist/src/lib/process-list.js.map +1 -1
- package/dist/src/lib/process-payload-validation.js.map +1 -1
- package/dist/src/lib/process-qa.js.map +1 -1
- package/dist/src/lib/process-refresh-references.js +15 -10
- package/dist/src/lib/process-refresh-references.js.map +1 -1
- package/dist/src/lib/process-save-draft.js +9 -3
- package/dist/src/lib/process-save-draft.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +11 -4
- package/dist/src/lib/process-scope-statistics.js.map +1 -1
- package/dist/src/lib/process-verify-rows.js.map +1 -1
- package/dist/src/lib/publish.js.map +1 -1
- package/dist/src/lib/run.js.map +1 -1
- package/dist/src/lib/supabase-client.js +13 -1
- package/dist/src/lib/supabase-client.js.map +1 -1
- package/dist/src/lib/supabase-data-api-contract.js +328 -0
- package/dist/src/lib/supabase-data-api-contract.js.map +1 -0
- package/dist/src/lib/supabase-data-api-replay.js +69 -0
- package/dist/src/lib/supabase-data-api-replay.js.map +1 -0
- package/dist/src/lib/supabase-json-ordered-write.js +2 -0
- package/dist/src/lib/supabase-json-ordered-write.js.map +1 -1
- package/dist/src/lib/supabase-rest.js +1 -0
- package/dist/src/lib/supabase-rest.js.map +1 -1
- package/dist/src/lib/tidas-sdk-package-validator.js +5 -5
- package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
- package/dist/src/lib/validation.js.map +1 -1
- package/dist/src/main.js.map +1 -1
- package/package.json +43 -40
- package/dist/scripts/assert-full-coverage.js +0 -77
- package/dist/scripts/assert-full-coverage.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) TianGong LCA contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -14,18 +14,34 @@ whenToUpdate:
|
|
|
14
14
|
checkPaths:
|
|
15
15
|
- README.md
|
|
16
16
|
- package.json
|
|
17
|
+
- pnpm-workspace.yaml
|
|
18
|
+
- pnpm-lock.yaml
|
|
17
19
|
- bin/**
|
|
18
20
|
- src/cli.ts
|
|
19
21
|
- src/main.ts
|
|
22
|
+
- src/lib/auth-identity-receipt.ts
|
|
20
23
|
- src/lib/lca-release.ts
|
|
24
|
+
- scripts/run-auth-identity-production-case.ts
|
|
25
|
+
- test/auth-identity*.test.ts
|
|
21
26
|
- test/lca-release*.test.ts
|
|
22
|
-
lastReviewedAt: 2026-
|
|
23
|
-
lastReviewedCommit:
|
|
27
|
+
lastReviewedAt: 2026-08-25
|
|
28
|
+
lastReviewedCommit: 47b44c65cf4bf27070fa1057e672c6ef2b2e54f3
|
|
29
|
+
lastReviewedNote: 'Reviewed for Issue #230: identifies 0.1.1 as the public auth-receipt release on exact Node 24.19.0 with cryptographic Sigstore and isolated pnpm verification.'
|
|
24
30
|
---
|
|
25
31
|
|
|
26
32
|
# TianGong LCA CLI
|
|
27
33
|
|
|
28
|
-
Package: `@tiangong-lca/cli` Executable: `tiangong-lca` Node: `24.
|
|
34
|
+
Package: `@tiangong-lca/cli` Executable: `tiangong-lca` Current package version: `0.1.1` Node: `24.19.0`
|
|
35
|
+
|
|
36
|
+
Repository development is single-track on pnpm `11.23.0` and TypeScript `7.0.2`. The published package remains a clean, package-manager-neutral consumer artifact: it contains runtime files only, not pnpm, TypeScript, Oxlint, tests, source-only tooling, or repository lockfiles.
|
|
37
|
+
|
|
38
|
+
Review note, 2026-08-25: Issue #224 migrates repository development and release automation to the sole root `pnpm-workspace.yaml` / `pnpm-lock.yaml`, TypeScript 7.0.2, and type-aware Oxlint on Node 24. The feature change deliberately keeps version 0.0.33. A separate release-only PR should prepare 0.1.0 after the toolchain change merges and its full package/coverage/release gates pass.
|
|
39
|
+
|
|
40
|
+
Review note, 2026-08-25: Issue #226 publishes that 0.1.0 compatibility boundary after merged PR #225. Version metadata and public release evidence advance to 0.1.0; the runtime JavaScript/assets surface, command behavior, Node 24 runtime, pnpm/TypeScript 7 development baseline, native pnpm Trusted Publishing/provenance, and exact released-commit workspace handoff remain unchanged from the reviewed feature delivery.
|
|
41
|
+
|
|
42
|
+
Review note, 2026-08-25: Issue #228 implements `auth identity-receipt` as a bounded read-only current-user proof. It checks expected project intent before session work, verifies the live user through `/auth/v1/user`, allows one auth-refresh replay after 401/403, and emits an exact-key canonical receipt without API keys, tokens, full email addresses, session paths, or credential-derived fingerprints. Production callers must pass both expected assertions and accept only `assertions.mode="intent-bound"`.
|
|
43
|
+
|
|
44
|
+
Review note, 2026-08-25: Issue #230 publishes the merged identity receipt as `@tiangong-lca/cli@0.1.1`. Runtime logic and published dependencies remain unchanged; the sole pnpm lock changes only for exact dev-only `sigstore@5.0.0`. Local metadata, engines, and every workflow converge on Node 24.19.0. Release automation asserts actual platform/architecture across the reusable four-platform pre-tag matrix and provides `pnpm release:verify-published` for cryptographic Fulcio/CT/Rekor provenance, registry signatures, actual tarball integrity, isolated user/global package-manager configuration, exact pnpm 11.23.0, and credential-free bin/ESM/CJS consumer proof.
|
|
29
45
|
|
|
30
46
|
Review note, 2026-07-12: `dataset maintenance plan/apply/verify` provides current-user RLS-scoped exact-row maintenance with immutable plans, explicit approval, per-action logs, platform audit correlation, and independent readback. `merge-support-aliases` now runs only in `target_mode=owner_draft`: source/target support and all changed rows stay private `state_code=0`; publication is a separate future workflow.
|
|
31
47
|
|
|
@@ -47,20 +63,24 @@ Review note, 2026-07-24: CLI 0.0.32 adds bounded execution-contract concurrency
|
|
|
47
63
|
|
|
48
64
|
Review note, 2026-07-24: CLI 0.0.33 adds an explicit `dataset maintenance apply --max-parallel 1..8` profile for large owner-draft flow convergence. It accepts only unique flow delete-only plans with zero frozen and fresh visible-process inbound references, persists `PREPARED` and `DISPATCHED` before each protected RPC, requires exact absent readback for `COMMITTED`, never automatically replays success or UNKNOWN, and continues independent rows.
|
|
49
65
|
|
|
66
|
+
Review note, 2026-07-25: The complete RLS-visible process fence now paginates in the strict `(id, version)` primary-key order. It still has no `user_id` filter and retains exact-count completeness, while avoiding a redundant owner/state sort before any deletion can dispatch.
|
|
67
|
+
|
|
68
|
+
Review note, 2026-07-25: Bounded flow deletion can instead accept an explicitly SHA-approved, at-most-30-minute-old SELECT-only proof covering all process rows. The proof binds the exact project, actor, plan, ordered delete targets, and contiguous target chunks and must report zero inbound edges and zero P0/P1 findings. The CLI validates it before approval or dispatch and never executes the proof SQL itself; omitting the flags preserves the live RLS-visible scan.
|
|
69
|
+
|
|
50
70
|
## Run
|
|
51
71
|
|
|
52
72
|
One-off published run:
|
|
53
73
|
|
|
54
74
|
```bash
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
75
|
+
pnpm dlx @tiangong-lca/cli@latest --help
|
|
76
|
+
pnpm dlx @tiangong-lca/cli@latest doctor
|
|
77
|
+
pnpm dlx @tiangong-lca/cli@latest flow --help
|
|
58
78
|
```
|
|
59
79
|
|
|
60
80
|
Install the published CLI:
|
|
61
81
|
|
|
62
82
|
```bash
|
|
63
|
-
|
|
83
|
+
pnpm add --global @tiangong-lca/cli
|
|
64
84
|
tiangong-lca --help
|
|
65
85
|
tiangong-lca doctor
|
|
66
86
|
tiangong-lca flow --help
|
|
@@ -69,8 +89,8 @@ tiangong-lca flow --help
|
|
|
69
89
|
Run from this repository:
|
|
70
90
|
|
|
71
91
|
```bash
|
|
72
|
-
|
|
73
|
-
|
|
92
|
+
pnpm install --frozen-lockfile
|
|
93
|
+
pnpm build
|
|
74
94
|
node ./bin/tiangong-lca.js --help
|
|
75
95
|
```
|
|
76
96
|
|
|
@@ -99,6 +119,31 @@ TIANGONG_LCA_DISABLE_SESSION_CACHE=false
|
|
|
99
119
|
TIANGONG_LCA_FORCE_REAUTH=false
|
|
100
120
|
```
|
|
101
121
|
|
|
122
|
+
## Auth Identity Receipt
|
|
123
|
+
|
|
124
|
+
Use the identity receipt before a production-backed case or any later owner-draft write gate:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
tiangong-lca auth identity-receipt --expected-project-ref <project-ref> --expected-user-id <user-id> --json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The command performs no dataset write. It exchanges the normal user API key for a session, checks the canonical Supabase project, and makes a bounded live `GET /auth/v1/user`. A cached token that receives `401` or `403` may be refreshed and retried exactly once; all other transport or response failures are terminal. A valid production guard requires:
|
|
131
|
+
|
|
132
|
+
- `schema` exactly `tiangong-lca.auth-identity-receipt.v1`;
|
|
133
|
+
- `status: "passed"`, `operation: "current-user-read"`, and `remote_write_mode: "read-only"`;
|
|
134
|
+
- exact expected project/user values with `assertions.mode: "intent-bound"` and `requested_count: 2`;
|
|
135
|
+
- a fresh capture time and a valid recomputed `receipt_scope_sha256`.
|
|
136
|
+
|
|
137
|
+
Calling without expectations is allowed for discovery but produces `assertions.mode: "observed"`; it is not an authorization guard. The safe display email is masked and must not be used as the account key. The receipt deliberately excludes credentials, full email, session-file details, raw response metadata, and all credential/token/path-derived fingerprints.
|
|
138
|
+
|
|
139
|
+
For the explicitly authorized local production read case from a validated repository checkout, invoke the narrow TypeScript runner with a new private output directory:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
pnpm case:auth-identity:production -- --env-file <data-foundry-ignored-.env> --expected-project-ref <project-ref> --expected-user-id <user-id> --out-dir <new-private-case-directory>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The runner reads only `TIANGONG_LCA_API_BASE_URL`, `TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY`, and `TIANGONG_LCA_TEST_API_KEY`; the last is mapped to the child process's standard API-key variable. It does not accept an alternate CLI path. The pnpm command first performs a clean TS7 build without the production env. Its plain-Node runner then single-reads source/config/lock and the freshly generated `dist/src/**/*.js`, hashes the source tree, runner, runtime, exact entrypoint, and pnpm lock, and copies those exact built buffers into a private snapshot before exposing the key. It forces reauthentication with session cache disabled, runs only the built snapshot from an exclusively created clean directory with an argv array and `shell:false`, cleans the snapshot before publishing success artifacts, and persists only the parsed receipt and case manifest. POSIX creates the case directory as `0700` and files as `0600`; Windows inherits ACLs from the caller-selected parent, so use a user-restricted parent because mode bits are not an ACL guarantee. The runner never stores raw child stdout/stderr and is intentionally not wired to CI secrets. This receipt is locally hash-verifiable, not server-signed attestation.
|
|
146
|
+
|
|
102
147
|
## LCI/LCIA Data Release
|
|
103
148
|
|
|
104
149
|
The `release` command family is the authenticated transport used by the standalone release control plane. It does not introduce a TIDAS schema variant: result packages reuse the existing Process exchange structure for LCI and the existing Process LCIA result fields, with a LifecycleModel referencing the resulting Process.
|
|
@@ -255,7 +300,7 @@ Key outputs under `--out-dir`:
|
|
|
255
300
|
|
|
256
301
|
`--candidate-input` is repeatable and accepts JSON, JSONL, or a directory scanned recursively for JSON/JSONL candidate rows. Embedded `candidates` from the request and local-scan candidates are evaluated together. Add `--remote-candidates` when the preflight should also call `process_hybrid_search` or `flow_hybrid_search`; `--remote-query` overrides the target-derived search text and `--remote-limit` caps returned candidate rows. Remote candidate search uses the normal Supabase session env: `TIANGONG_LCA_API_BASE_URL`, `TIANGONG_LCA_API_KEY`, `TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY`, and optional `TIANGONG_LCA_REGION`.
|
|
257
302
|
|
|
258
|
-
When remote search is enabled, the CLI sends a compact fielded `query` string plus supported edge-search options to `process_hybrid_search` or `flow_hybrid_search`: `filter`, `match_count`, `page_size`, `data_source`, `match_threshold`, `
|
|
303
|
+
When remote search is enabled, the CLI sends a compact fielded `query` string plus supported edge-search options to `process_hybrid_search` or `flow_hybrid_search`: `filter`, `match_count`, `page_size`, `data_source`, `match_threshold`, `lexical_weight`, `semantic_weight`, and `rrf_k`. `lexical_weight` controls the single database-owned `extracted_md` lexical branch. Request-level `remote_candidate_search.profile_hints` are not sent to the Edge Function. They are applied locally before scoring candidates so Foundry can provide source-derived facts such as flow type, flow property, reference unit, elementary categories, geography, reference-flow names, technology route, and system boundary without polluting the full-text/semantic query.
|
|
259
304
|
|
|
260
305
|
Exact process exchange fingerprints with matching identity context block duplicate creation, while weaker inventory-only matches still route to manual review. Flow preflight also blocks alias-equivalent flows when type, reference property, unit, and category/CAS evidence match.
|
|
261
306
|
|
|
@@ -270,7 +315,7 @@ tiangong-lca flow build-plan validate --input ./flow-build-plan.json --out-dir .
|
|
|
270
315
|
tiangong-lca flow build-plan materialize --input ./flow-build-plan.json --out-dir ./flow-build-plan --json
|
|
271
316
|
```
|
|
272
317
|
|
|
273
|
-
The minimum plan contract requires an automatic identity decision, EvidenceManifest sources and field bindings, name plan, and the relevant process reference-flow or flow-property fields. Process materialization carries name, quantitative reference, exchange, source evidence, modelling, administrative, and annual supply/production fields from the plan into `processDataSet`; when annual volume source evidence is not explicit, Foundry-facing required-field completion uses the deterministic `9999 missing-data-sentinel/year` value so the schema-required field stays searchable for later database-side curation. Flow materialization carries name, flow type, reference property, source evidence, administrative, and classification fields into `flowDataSet`. `--report-only` keeps exit code `0` while still reporting blockers.
|
|
318
|
+
The minimum plan contract requires an automatic identity decision, EvidenceManifest sources and field bindings, name plan, and the relevant process reference-flow or flow-property fields. Plan-only materialization additionally requires an explicit canonical `classification_path`: continuous level `0..n` objects with exact locked `@classId`/`#text` for process and product/waste flow taxonomies, or `@catId`/`#text` for elementary flows. Label-only, missing, malformed, or taxonomy-spoofed classifications fail before artifact publication. Process materialization carries name, quantitative reference, exchange, source evidence, modelling, administrative, and annual supply/production fields from the plan into `processDataSet`; when annual volume source evidence is not explicit, Foundry-facing required-field completion uses the deterministic `9999 missing-data-sentinel/year` value so the schema-required field stays searchable for later database-side curation. Flow materialization carries name, flow type, reference property, source evidence, administrative, and classification fields into `flowDataSet`. `--report-only` keeps exit code `0` while still reporting blockers.
|
|
274
319
|
|
|
275
320
|
Key outputs under `--out-dir`:
|
|
276
321
|
|
|
@@ -369,6 +414,7 @@ tiangong-lca dataset classification apply --type location --input ./rows/process
|
|
|
369
414
|
tiangong-lca dataset curation-queue build --processes ./rows/processes.jsonl --flows ./rows/flows.jsonl --support ./rows/sources.jsonl --out-dir /abs/path/to/curation-queue --json
|
|
370
415
|
tiangong-lca dataset curation-queue next --queue-dir /abs/path/to/curation-queue --type support --json
|
|
371
416
|
tiangong-lca dataset curation-queue verify --queue-dir /abs/path/to/curation-queue --type process --json
|
|
417
|
+
tiangong-lca dataset import-lca convert --input ./external/simapro.csv --output-dir /abs/path/to/imported --from-format simapro-csv --target both --write-mapping --json
|
|
372
418
|
tiangong-lca dataset save-draft --input ./rows.jsonl --type auto --execution-contract ./execution-contract.json --max-parallel 8 --out-dir /abs/path/to/dataset-save-draft --commit --json
|
|
373
419
|
tiangong-lca dataset evidence-search plan --query "中国2026年电力结构数据" --out-dir /abs/path/to/evidence-search --json
|
|
374
420
|
tiangong-lca dataset evidence-search run --input ./evidence-search.request.json --results ./search-results.json --out-dir /abs/path/to/evidence-search --json
|
|
@@ -401,13 +447,13 @@ For `qa process`, `--rows-file` accepts either raw process rows as JSON/JSONL or
|
|
|
401
447
|
|
|
402
448
|
For `process identity-preflight` and `flow identity-preflight`, canonical TIDAS wrappers are schema-checked when present. Loose target objects are accepted for early planning and produce `schema_validation.status: "not_applicable"` until materialization. Candidate rows can be embedded in the request, loaded from repeatable `--candidate-input` local files/directories, or fetched through explicit `--remote-candidates` hybrid search; `identity-candidate-sources.json` records scanned files, remote endpoints, queries, filters, edge-search options, and row counts. The remote Edge Function receives only search-safe query/options fields; local-only `profile_hints` stay in the preflight target profile and candidate scoring evidence.
|
|
403
449
|
|
|
404
|
-
For `process build-plan` and `flow build-plan`, canonical payloads embedded in the plan are schema-checked during `materialize`. Plan-only materialization
|
|
450
|
+
For `process build-plan` and `flow build-plan`, canonical payloads embedded in the plan are schema-checked during `materialize`. Plan-only materialization creates deterministic canonical `processDataSet` / `flowDataSet` wrappers, requires an explicit canonical locked-taxonomy `classification_path`, and validates the result with the TIDAS SDK before reporting `passed`; it never invents taxonomy ids from free-form labels.
|
|
405
451
|
|
|
406
452
|
For `process save-draft`, canonical process payloads are validated locally with `ProcessSchema` before any `--commit` write. Schema-invalid rows remain in `outputs/save-draft-rpc/failures.jsonl` instead of being persisted. Batch import callers should pass `--target-user-id`; the CLI then verifies the current auth session and any visible draft owner before writing, while downstream readback verification still proves the final owner and payload.
|
|
407
453
|
|
|
408
454
|
For `dataset save-draft --execution-contract`, the JSON contract uses schema `dataset-save-draft-execution-contract.v1` and supplies `execution_id`, `project_ref`, an exact owner (`user_id`, lowercase `email`, `state_code: 0`), and ordered actions. Each action binds `action_id`, `desired_sha256`, `expected_operation` (`insert` or `save_draft`), table/id/version, `before_sha256`, and earlier `dependency_action_ids`. Contract mode requires `--commit`; account-local Unit Group or Flow Property support rows additionally require `--allow-account-local-support`. `--max-parallel` defaults to 1 and is capped at 8. When it is greater than 1, every action through the highest referenced dependency remains serial; only the later table/id/version-unique suffix may overlap. The exact owner token is renewed and checked before each DML dispatch. Attempts and outcomes are stored under the platform user-state directory (`$XDG_STATE_HOME/tiangong-lca-cli` when configured), not beside the contract or report. Any prior terminal or unresolved attempt is read back or retained without re-dispatch; exit status is nonzero unless every action has exact terminal success.
|
|
409
455
|
|
|
410
|
-
For `dataset maintenance apply`, explicitly passing `--max-parallel 1..8` opts into the destructive flow-convergence profile. It accepts only a non-empty, unique-target, flow delete-only plan whose current and projected reference impacts are both zero. Before dispatch it
|
|
456
|
+
For `dataset maintenance apply`, explicitly passing `--max-parallel 1..8` opts into the destructive flow-convergence profile. It accepts only a non-empty, unique-target, flow delete-only plan whose current and projected reference impacts are both zero. Before dispatch it completes a fresh SELECT-only scan of every process visible to the owner session and rejects any inbound edge. For a separately governed all-process check, pair `--global-inbound-proof /absolute/proof.json` with `--approve-global-inbound-proof <sha256>`; the proof must be fresh, SELECT-only, complete, zero-inbound, and bound to the exact project, actor, plan, and ordered target set, and it is validated before the live scan is skipped. The CLI never runs raw SQL. Each action writes append-only `PREPARED` and `DISPATCHED` evidence before its protected owner-session RPC, then records `COMMITTED` only after exact absent readback. An ambiguous action is read back, marked `UNKNOWN`, and never replayed automatically; independent actions continue. Omit `--max-parallel` to retain ordinary maintenance apply behavior.
|
|
411
457
|
|
|
412
458
|
For `flow publish-version`, canonical flow payloads are validated locally with `FlowSchema` before remote visibility planning or writes. The command always writes `flow-publish-version-gate-report.json`; blocked rows are written to the remote-failure JSONL without calling the remote service.
|
|
413
459
|
|
|
@@ -423,6 +469,8 @@ For `dataset validate`, `--type auto` supports mixed support scopes containing c
|
|
|
423
469
|
|
|
424
470
|
For `dataset curation-queue build/next/verify`, the CLI owns entity-level Foundry import queue state. `build` writes `outputs/curation-queue-manifest.json`, `outputs/curation-queue-tasks.jsonl`, `outputs/curation-queue-locks.json`, `outputs/curation-queue-blockers.jsonl`, and per-entity `input.jsonl`, `closure.json`, and `entity-run-plan.json`. `next` returns one runnable support/flow/process task based on checkpoint state. `verify` passes only when scoped checkpoints are complete and build blockers are absent. AI authoring must return structured patches or build plans, and remote writes remain gated by deterministic apply, schema/QA, prewrite verify, and readback.
|
|
425
471
|
|
|
472
|
+
For `dataset import-lca convert`, the CLI delegates all format detection, conversion, validation, bounded spooling, cancellation, and atomic publication to unified Rust `tidas import`; it does not reproduce import logic in TypeScript. Binary selection is `--tidas-bin`, then `TIDAS_BIN`, then `tidas` on PATH. Optional `--tidas-config` maps to native `--config`. Every run first requires a successful `tidas version --format json --progress never` handshake with `tidas.operation-report.v1` and a stable `0.2.x` binary version, then validates the native `tidas.import-execution-report.v1` summary and exact exit-class/code mapping. Native controls include explicit or automatic source format, target, mapping output, process-bundle disablement, warning failure, maximum entry size, memory budget, and queue capacity. The supported release matrix is Linux x86_64/ARM64, macOS Intel/Apple Silicon, and Windows x86_64; Windows ARM64 is unsupported. The npm package includes `assets/import-smoke/simapro.csv` for clean-machine proof but does not bundle a platform binary or require Python.
|
|
473
|
+
|
|
426
474
|
For `dataset references rewrite`, `--commit` executes the state-aware save-draft path for patched process and lifecyclemodel rows; without `--commit`, the command only writes local rewrite artifacts.
|
|
427
475
|
|
|
428
476
|
## Dataset Maintenance
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{SimaPro 8.0}
|
|
2
|
+
{processes}
|
|
3
|
+
{CSV separator: Semicolon}
|
|
4
|
+
{Decimal separator: ,}
|
|
5
|
+
|
|
6
|
+
Process
|
|
7
|
+
|
|
8
|
+
Process name
|
|
9
|
+
Test process
|
|
10
|
+
|
|
11
|
+
Products
|
|
12
|
+
my product;kg;0,5;100;not defined;Agricultural;
|
|
13
|
+
|
|
14
|
+
Materials/fuels
|
|
15
|
+
Soy oil, refined, at plant/kg/RNA;kg;0,2;Undefined;0;0;0;
|
|
16
|
+
|
|
17
|
+
Emissions to air
|
|
18
|
+
carbon dioxide;low. pop.;kg;1,5;Undefined;0;0;0;
|
|
19
|
+
|
|
20
|
+
End
|
package/bin/tiangong-lca.js
CHANGED
|
@@ -24,7 +24,7 @@ export function resolveInvokedUrl(argv1 = process.argv[1]) {
|
|
|
24
24
|
export async function runFromBin(argv = process.argv.slice(2), env = process.env) {
|
|
25
25
|
if (!existsSync(entryPath)) {
|
|
26
26
|
throw new Error(
|
|
27
|
-
"Missing built CLI artifacts at 'dist/src/main.js'. Run '
|
|
27
|
+
"Missing built CLI artifacts at 'dist/src/main.js'. Run 'pnpm build' or reinstall dependencies to regenerate dist.",
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
30
|
|
package/dist/src/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import { buildDoctorReport, readRuntimeEnv } from './lib/env.js';
|
|
|
3
3
|
import { CliError, toErrorPayload } from './lib/errors.js';
|
|
4
4
|
import { stringifyJson } from './lib/io.js';
|
|
5
5
|
import { loadCliPackageVersion } from './lib/package-version.js';
|
|
6
|
+
import { AUTH_IDENTITY_MAX_TIMEOUT_MS, AUTH_IDENTITY_RECEIPT_SCHEMA, runAuthIdentityReceipt, } from './lib/auth-identity-receipt.js';
|
|
6
7
|
import { runLifecyclemodelAutoBuild, } from './lib/lifecyclemodel-auto-build.js';
|
|
7
8
|
import { runLifecyclemodelBuildResultingProcess, } from './lib/lifecyclemodel-resulting-process.js';
|
|
8
9
|
import { runLifecyclemodelPublishResultingProcess, } from './lib/lifecyclemodel-publish-resulting-process.js';
|
|
@@ -86,6 +87,7 @@ Usage:
|
|
|
86
87
|
Commands:
|
|
87
88
|
Implemented Commands:
|
|
88
89
|
doctor show environment diagnostics
|
|
90
|
+
auth identity-receipt
|
|
89
91
|
search flow | process | lifecyclemodel
|
|
90
92
|
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
|
|
91
93
|
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
|
|
@@ -105,6 +107,7 @@ Planned commands currently print an explicit "not implemented yet" message and e
|
|
|
105
107
|
|
|
106
108
|
Examples:
|
|
107
109
|
tiangong-lca doctor
|
|
110
|
+
tiangong-lca auth identity-receipt --expected-project-ref <project-ref> --expected-user-id <user-id> --json
|
|
108
111
|
tiangong-lca search flow --input ./request.json
|
|
109
112
|
tiangong-lca search process --input ./request.json --dry-run
|
|
110
113
|
tiangong-lca process get --id <process-id>
|
|
@@ -180,6 +183,50 @@ Environment:
|
|
|
180
183
|
.env loaded: ${dotEnvStatus.loaded ? `yes (${dotEnvStatus.path}, ${dotEnvStatus.count} keys)` : 'no'}
|
|
181
184
|
`.trim();
|
|
182
185
|
}
|
|
186
|
+
function renderAuthHelp() {
|
|
187
|
+
return `Usage:
|
|
188
|
+
tiangong-lca auth identity-receipt [options]
|
|
189
|
+
|
|
190
|
+
Implemented Subcommands:
|
|
191
|
+
identity-receipt Live, read-only proof of the authenticated account and Supabase project
|
|
192
|
+
|
|
193
|
+
Planned Subcommands:
|
|
194
|
+
whoami | doctor-auth
|
|
195
|
+
|
|
196
|
+
Use "tiangong-lca auth identity-receipt --help" for the machine-receipt contract.
|
|
197
|
+
`.trim();
|
|
198
|
+
}
|
|
199
|
+
function renderAuthIdentityReceiptHelp() {
|
|
200
|
+
return `Usage:
|
|
201
|
+
tiangong-lca auth identity-receipt [options]
|
|
202
|
+
|
|
203
|
+
Options:
|
|
204
|
+
--expected-project-ref <ref> Assert the exact Supabase project before session/network access
|
|
205
|
+
--expected-user-id <id> Assert the exact server-verified authenticated user
|
|
206
|
+
--timeout-ms <n> Request timeout 1..${AUTH_IDENTITY_MAX_TIMEOUT_MS} ms (default: 10000)
|
|
207
|
+
--json Print compact JSON; default output is pretty JSON
|
|
208
|
+
-h, --help
|
|
209
|
+
|
|
210
|
+
Receipt schema:
|
|
211
|
+
${AUTH_IDENTITY_RECEIPT_SCHEMA}
|
|
212
|
+
|
|
213
|
+
Safety:
|
|
214
|
+
This is a read-only command that performs one live read of /auth/v1/user, with at most one
|
|
215
|
+
force-refresh retry after a 401 or 403. It never emits API keys, bearer/session
|
|
216
|
+
tokens, full email addresses, session paths, or credential-derived fingerprints. Production guards
|
|
217
|
+
must pass both expected assertions and require assertions.mode="intent-bound".
|
|
218
|
+
|
|
219
|
+
Required env:
|
|
220
|
+
TIANGONG_LCA_API_BASE_URL
|
|
221
|
+
TIANGONG_LCA_API_KEY
|
|
222
|
+
TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY
|
|
223
|
+
|
|
224
|
+
Optional session env:
|
|
225
|
+
TIANGONG_LCA_SESSION_FILE
|
|
226
|
+
TIANGONG_LCA_DISABLE_SESSION_CACHE
|
|
227
|
+
TIANGONG_LCA_FORCE_REAUTH
|
|
228
|
+
`.trim();
|
|
229
|
+
}
|
|
183
230
|
function renderDoctorHelp() {
|
|
184
231
|
return `Usage:
|
|
185
232
|
tiangong-lca doctor [--json]
|
|
@@ -335,7 +382,7 @@ Implemented Subcommands:
|
|
|
335
382
|
curation-queue build Build entity-level AI curation queue artifacts for Foundry imports
|
|
336
383
|
curation-queue next Return the next runnable support/flow/process queue task
|
|
337
384
|
curation-queue verify Verify queue task checkpoints for a scope
|
|
338
|
-
import-lca convert
|
|
385
|
+
import-lca convert Import supported external LCA packages through the unified Rust tidas binary
|
|
339
386
|
author Extract source evidence and prepare TIDAS context packs for AI authoring
|
|
340
387
|
patch apply Apply AI-authored structured dataset patches deterministically
|
|
341
388
|
save-draft Save contact/source/support or other canonical dataset rows through the platform dataset command path
|
|
@@ -537,6 +584,8 @@ Options:
|
|
|
537
584
|
--confirm <email> Current authenticated account email
|
|
538
585
|
--timeout-ms <n> Request timeout in milliseconds
|
|
539
586
|
--max-parallel <1-8> Opt into bounded flow delete-only execution with durable dispatch ledger
|
|
587
|
+
--global-inbound-proof <file> Absolute path to a fresh all-process SELECT-only zero-inbound proof
|
|
588
|
+
--approve-global-inbound-proof <sha256> Exact SHA-256 of --global-inbound-proof; requires --max-parallel
|
|
540
589
|
--json Print compact JSON
|
|
541
590
|
-h, --help
|
|
542
591
|
|
|
@@ -833,30 +882,33 @@ function renderDatasetImportLcaHelp() {
|
|
|
833
882
|
|
|
834
883
|
Options:
|
|
835
884
|
--input <path> Source file, directory, or package to import
|
|
836
|
-
--output-dir <dir> Output directory
|
|
885
|
+
--output-dir <dir> Output directory atomically published by tidas
|
|
837
886
|
--from-format <format> auto, ecospold1, ecospold2, openlca-jsonld, openlca-process-xlsx, simapro-csv, ilcd
|
|
838
887
|
--target <target> tidas | ilcd | both (default: tidas)
|
|
839
|
-
--report <file>
|
|
840
|
-
--mapping
|
|
841
|
-
--language <lang> Default language for generated text (default: en)
|
|
842
|
-
--validation-jobs <n> Parallel validation jobs passed to tidas-tools (default: 1)
|
|
843
|
-
--process-bundles Write per-process dependency bundles (default: enabled by tidas-tools)
|
|
844
|
-
--process-bundles-dir <dir>
|
|
845
|
-
Custom per-process bundle directory (default: <output-dir>/process-bundles)
|
|
888
|
+
--report <file> Persist the native operation report atomically instead of using tidas stdout
|
|
889
|
+
--write-mapping Write deterministic mapping.csv.gz
|
|
846
890
|
--no-process-bundles Disable per-process dependency bundle generation
|
|
847
|
-
--detect-only Only detect the input format and write the report
|
|
848
891
|
--fail-on-warning Return non-zero when converter warnings are present
|
|
849
|
-
--
|
|
850
|
-
--
|
|
892
|
+
--max-entry-mib <n> Maximum source-entry size in MiB (tidas default: 128)
|
|
893
|
+
--memory-budget-mib <n> Maximum accounted in-flight memory in MiB (tidas default: 512)
|
|
894
|
+
--queue-capacity <n> Maximum items in each bounded queue (tidas default: 256)
|
|
895
|
+
--tidas-bin <path> Rust tidas executable (default: TIDAS_BIN, then tidas on PATH)
|
|
896
|
+
--tidas-config <path> Explicit tidas config file (otherwise TIDAS_CONFIG is honored)
|
|
851
897
|
--json Print compact JSON
|
|
852
898
|
-h, --help
|
|
853
899
|
|
|
854
900
|
Outputs written under --output-dir:
|
|
855
|
-
-
|
|
856
|
-
- tidas/ when target includes TIDAS
|
|
857
|
-
- ilcd/ when target includes ILCD
|
|
858
|
-
- process-bundles/
|
|
859
|
-
-
|
|
901
|
+
- import-report.json and issues.jsonl
|
|
902
|
+
- tidas/ when target includes TIDAS
|
|
903
|
+
- ilcd/ when target includes ILCD
|
|
904
|
+
- process-bundles/ by default
|
|
905
|
+
- mapping.csv.gz when --write-mapping is used
|
|
906
|
+
|
|
907
|
+
Runtime contract:
|
|
908
|
+
- Linux x86_64/ARM64, macOS Intel/Apple Silicon, and Windows x86_64 are supported.
|
|
909
|
+
- Windows ARM64 is unsupported.
|
|
910
|
+
- The binary must report tidas.operation-report.v1 and a stable 0.2.x version.
|
|
911
|
+
- Import publication, cancellation cleanup, and domain validation remain owned by Rust tidas.
|
|
860
912
|
`.trim();
|
|
861
913
|
}
|
|
862
914
|
function renderDatasetAuthorHelp() {
|
|
@@ -2264,6 +2316,59 @@ function parseDoctorFlags(args) {
|
|
|
2264
2316
|
json: Boolean(values.json),
|
|
2265
2317
|
};
|
|
2266
2318
|
}
|
|
2319
|
+
function parseAuthIdentityReceiptFlags(args) {
|
|
2320
|
+
let parsed;
|
|
2321
|
+
try {
|
|
2322
|
+
parsed = parseArgs({
|
|
2323
|
+
args,
|
|
2324
|
+
allowPositionals: false,
|
|
2325
|
+
strict: true,
|
|
2326
|
+
tokens: true,
|
|
2327
|
+
options: {
|
|
2328
|
+
help: { type: 'boolean', short: 'h' },
|
|
2329
|
+
json: { type: 'boolean' },
|
|
2330
|
+
'expected-project-ref': { type: 'string' },
|
|
2331
|
+
'expected-user-id': { type: 'string' },
|
|
2332
|
+
'timeout-ms': { type: 'string' },
|
|
2333
|
+
},
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
catch (error) {
|
|
2337
|
+
throw new CliError(String(error), {
|
|
2338
|
+
code: 'INVALID_ARGS',
|
|
2339
|
+
exitCode: 2,
|
|
2340
|
+
});
|
|
2341
|
+
}
|
|
2342
|
+
const tokens = parsed.tokens;
|
|
2343
|
+
for (const optionName of ['expected-project-ref', 'expected-user-id', 'timeout-ms']) {
|
|
2344
|
+
const occurrences = tokens.filter((entry) => entry.kind === 'option' && entry.name === optionName).length;
|
|
2345
|
+
if (occurrences > 1) {
|
|
2346
|
+
throw new CliError(`Option --${optionName} may be provided only once.`, {
|
|
2347
|
+
code: 'INVALID_ARGS',
|
|
2348
|
+
exitCode: 2,
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
const timeoutText = typeof parsed.values['timeout-ms'] === 'string' ? parsed.values['timeout-ms'] : undefined;
|
|
2353
|
+
const timeoutMs = timeoutText === undefined ? 10_000 : Number(timeoutText);
|
|
2354
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > AUTH_IDENTITY_MAX_TIMEOUT_MS) {
|
|
2355
|
+
throw new CliError(`Expected --timeout-ms to be an integer between 1 and ${AUTH_IDENTITY_MAX_TIMEOUT_MS}.`, {
|
|
2356
|
+
code: 'INVALID_TIMEOUT',
|
|
2357
|
+
exitCode: 2,
|
|
2358
|
+
});
|
|
2359
|
+
}
|
|
2360
|
+
return {
|
|
2361
|
+
help: Boolean(parsed.values.help),
|
|
2362
|
+
json: Boolean(parsed.values.json),
|
|
2363
|
+
expectedProjectRef: typeof parsed.values['expected-project-ref'] === 'string'
|
|
2364
|
+
? parsed.values['expected-project-ref']
|
|
2365
|
+
: null,
|
|
2366
|
+
expectedUserId: typeof parsed.values['expected-user-id'] === 'string'
|
|
2367
|
+
? parsed.values['expected-user-id']
|
|
2368
|
+
: null,
|
|
2369
|
+
timeoutMs,
|
|
2370
|
+
};
|
|
2371
|
+
}
|
|
2267
2372
|
function parseRemoteFlags(args) {
|
|
2268
2373
|
let values;
|
|
2269
2374
|
try {
|
|
@@ -2854,16 +2959,14 @@ function parseDatasetImportLcaConvertFlags(args) {
|
|
|
2854
2959
|
'from-format': { type: 'string' },
|
|
2855
2960
|
target: { type: 'string' },
|
|
2856
2961
|
report: { type: 'string' },
|
|
2857
|
-
'mapping
|
|
2858
|
-
language: { type: 'string' },
|
|
2859
|
-
'validation-jobs': { type: 'string' },
|
|
2860
|
-
'process-bundles': { type: 'boolean' },
|
|
2861
|
-
'process-bundles-dir': { type: 'string' },
|
|
2962
|
+
'write-mapping': { type: 'boolean' },
|
|
2862
2963
|
'no-process-bundles': { type: 'boolean' },
|
|
2863
|
-
'detect-only': { type: 'boolean' },
|
|
2864
2964
|
'fail-on-warning': { type: 'boolean' },
|
|
2865
|
-
|
|
2866
|
-
'
|
|
2965
|
+
'max-entry-mib': { type: 'string' },
|
|
2966
|
+
'memory-budget-mib': { type: 'string' },
|
|
2967
|
+
'queue-capacity': { type: 'string' },
|
|
2968
|
+
'tidas-bin': { type: 'string' },
|
|
2969
|
+
'tidas-config': { type: 'string' },
|
|
2867
2970
|
},
|
|
2868
2971
|
}));
|
|
2869
2972
|
}
|
|
@@ -2873,25 +2976,9 @@ function parseDatasetImportLcaConvertFlags(args) {
|
|
|
2873
2976
|
exitCode: 2,
|
|
2874
2977
|
});
|
|
2875
2978
|
}
|
|
2876
|
-
const
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
code: 'DATASET_IMPORT_LCA_VALIDATION_JOBS_INVALID',
|
|
2880
|
-
exitCode: 2,
|
|
2881
|
-
});
|
|
2882
|
-
}
|
|
2883
|
-
if (values['process-bundles'] && values['no-process-bundles']) {
|
|
2884
|
-
throw new CliError('--process-bundles and --no-process-bundles cannot both be set.', {
|
|
2885
|
-
code: 'DATASET_IMPORT_LCA_PROCESS_BUNDLES_INVALID',
|
|
2886
|
-
exitCode: 2,
|
|
2887
|
-
});
|
|
2888
|
-
}
|
|
2889
|
-
if (values['no-process-bundles'] && typeof values['process-bundles-dir'] === 'string') {
|
|
2890
|
-
throw new CliError('--process-bundles-dir cannot be used with --no-process-bundles.', {
|
|
2891
|
-
code: 'DATASET_IMPORT_LCA_PROCESS_BUNDLES_INVALID',
|
|
2892
|
-
exitCode: 2,
|
|
2893
|
-
});
|
|
2894
|
-
}
|
|
2979
|
+
const maxEntryMib = parsePositiveIntegerFlag(values['max-entry-mib'], '--max-entry-mib');
|
|
2980
|
+
const memoryBudgetMib = parsePositiveIntegerFlag(values['memory-budget-mib'], '--memory-budget-mib');
|
|
2981
|
+
const queueCapacity = parsePositiveIntegerFlag(values['queue-capacity'], '--queue-capacity');
|
|
2895
2982
|
return {
|
|
2896
2983
|
help: Boolean(values.help),
|
|
2897
2984
|
json: Boolean(values.json),
|
|
@@ -2900,21 +2987,29 @@ function parseDatasetImportLcaConvertFlags(args) {
|
|
|
2900
2987
|
fromFormat: typeof values['from-format'] === 'string' ? values['from-format'] : undefined,
|
|
2901
2988
|
target: typeof values.target === 'string' ? values.target : undefined,
|
|
2902
2989
|
reportPath: typeof values.report === 'string' ? values.report : undefined,
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
validationJobs,
|
|
2906
|
-
processBundles: values['no-process-bundles']
|
|
2907
|
-
? false
|
|
2908
|
-
: values['process-bundles']
|
|
2909
|
-
? true
|
|
2910
|
-
: undefined,
|
|
2911
|
-
processBundlesDir: typeof values['process-bundles-dir'] === 'string' ? values['process-bundles-dir'] : undefined,
|
|
2912
|
-
detectOnly: Boolean(values['detect-only']),
|
|
2990
|
+
writeMapping: Boolean(values['write-mapping']),
|
|
2991
|
+
processBundles: values['no-process-bundles'] ? false : undefined,
|
|
2913
2992
|
failOnWarning: Boolean(values['fail-on-warning']),
|
|
2914
|
-
|
|
2915
|
-
|
|
2993
|
+
maxEntryMib,
|
|
2994
|
+
memoryBudgetMib,
|
|
2995
|
+
queueCapacity,
|
|
2996
|
+
tidasBin: typeof values['tidas-bin'] === 'string' ? values['tidas-bin'] : undefined,
|
|
2997
|
+
tidasConfig: typeof values['tidas-config'] === 'string' ? values['tidas-config'] : undefined,
|
|
2916
2998
|
};
|
|
2917
2999
|
}
|
|
3000
|
+
function parsePositiveIntegerFlag(value, flag) {
|
|
3001
|
+
if (typeof value !== 'string') {
|
|
3002
|
+
return undefined;
|
|
3003
|
+
}
|
|
3004
|
+
const parsed = Number(value);
|
|
3005
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
3006
|
+
throw new CliError(`${flag} must be a positive integer.`, {
|
|
3007
|
+
code: 'DATASET_IMPORT_LCA_RUNTIME_BOUND_INVALID',
|
|
3008
|
+
exitCode: 2,
|
|
3009
|
+
});
|
|
3010
|
+
}
|
|
3011
|
+
return parsed;
|
|
3012
|
+
}
|
|
2918
3013
|
function parseDatasetAuthorFlags(args) {
|
|
2919
3014
|
let values;
|
|
2920
3015
|
try {
|
|
@@ -3461,6 +3556,8 @@ function parseDatasetMaintenanceApplyFlags(args) {
|
|
|
3461
3556
|
'timeout-ms': { type: 'string' },
|
|
3462
3557
|
'dry-run': { type: 'boolean' },
|
|
3463
3558
|
'max-parallel': { type: 'string' },
|
|
3559
|
+
'global-inbound-proof': { type: 'string' },
|
|
3560
|
+
'approve-global-inbound-proof': { type: 'string' },
|
|
3464
3561
|
},
|
|
3465
3562
|
}));
|
|
3466
3563
|
}
|
|
@@ -3483,6 +3580,25 @@ function parseDatasetMaintenanceApplyFlags(args) {
|
|
|
3483
3580
|
exitCode: 2,
|
|
3484
3581
|
});
|
|
3485
3582
|
}
|
|
3583
|
+
const globalInboundProofPath = typeof values['global-inbound-proof'] === 'string' ? values['global-inbound-proof'] : '';
|
|
3584
|
+
const approveGlobalInboundProof = typeof values['approve-global-inbound-proof'] === 'string'
|
|
3585
|
+
? values['approve-global-inbound-proof']
|
|
3586
|
+
: '';
|
|
3587
|
+
if (Boolean(globalInboundProofPath) !== Boolean(approveGlobalInboundProof)) {
|
|
3588
|
+
throw new CliError('--global-inbound-proof and --approve-global-inbound-proof must be provided together.', { code: 'INVALID_ARGS', exitCode: 2 });
|
|
3589
|
+
}
|
|
3590
|
+
if (globalInboundProofPath && maxParallel === undefined) {
|
|
3591
|
+
throw new CliError('Global inbound proof flags require --max-parallel.', {
|
|
3592
|
+
code: 'INVALID_ARGS',
|
|
3593
|
+
exitCode: 2,
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
if (approveGlobalInboundProof && !/^[0-9a-f]{64}$/u.test(approveGlobalInboundProof)) {
|
|
3597
|
+
throw new CliError('--approve-global-inbound-proof must be a lowercase SHA-256.', {
|
|
3598
|
+
code: 'INVALID_ARGS',
|
|
3599
|
+
exitCode: 2,
|
|
3600
|
+
});
|
|
3601
|
+
}
|
|
3486
3602
|
return {
|
|
3487
3603
|
help: Boolean(values.help),
|
|
3488
3604
|
json: Boolean(values.json),
|
|
@@ -3493,6 +3609,8 @@ function parseDatasetMaintenanceApplyFlags(args) {
|
|
|
3493
3609
|
timeoutMs: parseDatasetMaintenancePositiveInteger(values['timeout-ms'], '--timeout-ms'),
|
|
3494
3610
|
dryRun: Boolean(values['dry-run']),
|
|
3495
3611
|
maxParallel,
|
|
3612
|
+
globalInboundProofPath,
|
|
3613
|
+
approveGlobalInboundProof,
|
|
3496
3614
|
};
|
|
3497
3615
|
}
|
|
3498
3616
|
function parseDatasetMaintenanceFreezeProtectedFlags(args) {
|
|
@@ -5424,6 +5542,7 @@ function applyRemoteOverrides(env, overrides) {
|
|
|
5424
5542
|
export async function executeCli(argv, deps) {
|
|
5425
5543
|
try {
|
|
5426
5544
|
const { flags, command, subcommand, commandArgs } = parseCommandLine(argv);
|
|
5545
|
+
const authIdentityReceiptImpl = deps.runAuthIdentityReceiptImpl ?? runAuthIdentityReceipt;
|
|
5427
5546
|
const publishImpl = deps.runPublishImpl ?? runPublish;
|
|
5428
5547
|
const validationImpl = deps.runValidationImpl ?? runValidation;
|
|
5429
5548
|
const lcaReleaseImpl = deps.runLcaReleaseImpl ?? runLcaRelease;
|
|
@@ -5523,6 +5642,35 @@ export async function executeCli(argv, deps) {
|
|
|
5523
5642
|
stderr: '',
|
|
5524
5643
|
};
|
|
5525
5644
|
}
|
|
5645
|
+
if (command === 'auth' && !subcommand) {
|
|
5646
|
+
if (commandArgs.length === 0 ||
|
|
5647
|
+
(commandArgs.length === 1 && ['--help', '-h'].includes(commandArgs[0]))) {
|
|
5648
|
+
return { exitCode: 0, stdout: `${renderAuthHelp()}\n`, stderr: '' };
|
|
5649
|
+
}
|
|
5650
|
+
throw new CliError('The auth namespace accepts only -h or --help.', {
|
|
5651
|
+
code: 'INVALID_ARGS',
|
|
5652
|
+
exitCode: 2,
|
|
5653
|
+
});
|
|
5654
|
+
}
|
|
5655
|
+
if (command === 'auth' && subcommand === 'identity-receipt') {
|
|
5656
|
+
const authFlags = parseAuthIdentityReceiptFlags(commandArgs);
|
|
5657
|
+
if (authFlags.help) {
|
|
5658
|
+
return { exitCode: 0, stdout: `${renderAuthIdentityReceiptHelp()}\n`, stderr: '' };
|
|
5659
|
+
}
|
|
5660
|
+
const receipt = await authIdentityReceiptImpl({
|
|
5661
|
+
env: deps.env,
|
|
5662
|
+
fetchImpl: deps.fetchImpl,
|
|
5663
|
+
cliVersion: loadCliPackageVersion(import.meta.url),
|
|
5664
|
+
expectedProjectRef: authFlags.expectedProjectRef,
|
|
5665
|
+
expectedUserId: authFlags.expectedUserId,
|
|
5666
|
+
timeoutMs: authFlags.timeoutMs,
|
|
5667
|
+
});
|
|
5668
|
+
return {
|
|
5669
|
+
exitCode: 0,
|
|
5670
|
+
stdout: stringifyJson(receipt, authFlags.json),
|
|
5671
|
+
stderr: '',
|
|
5672
|
+
};
|
|
5673
|
+
}
|
|
5526
5674
|
if (command === 'search' && !subcommand && commandArgs.includes('--help')) {
|
|
5527
5675
|
return { exitCode: 0, stdout: `${renderSearchHelp()}\n`, stderr: '' };
|
|
5528
5676
|
}
|
|
@@ -5757,19 +5905,18 @@ export async function executeCli(argv, deps) {
|
|
|
5757
5905
|
fromFormat: datasetFlags.fromFormat,
|
|
5758
5906
|
target: datasetFlags.target,
|
|
5759
5907
|
reportPath: datasetFlags.reportPath,
|
|
5760
|
-
|
|
5761
|
-
language: datasetFlags.language,
|
|
5762
|
-
validationJobs: datasetFlags.validationJobs,
|
|
5908
|
+
writeMapping: datasetFlags.writeMapping,
|
|
5763
5909
|
processBundles: datasetFlags.processBundles,
|
|
5764
|
-
processBundlesDir: datasetFlags.processBundlesDir,
|
|
5765
|
-
detectOnly: datasetFlags.detectOnly,
|
|
5766
5910
|
failOnWarning: datasetFlags.failOnWarning,
|
|
5767
|
-
|
|
5768
|
-
|
|
5911
|
+
maxEntryMib: datasetFlags.maxEntryMib,
|
|
5912
|
+
memoryBudgetMib: datasetFlags.memoryBudgetMib,
|
|
5913
|
+
queueCapacity: datasetFlags.queueCapacity,
|
|
5914
|
+
tidasBin: datasetFlags.tidasBin,
|
|
5915
|
+
tidasConfig: datasetFlags.tidasConfig,
|
|
5769
5916
|
env: deps.env,
|
|
5770
5917
|
});
|
|
5771
5918
|
return {
|
|
5772
|
-
exitCode: report.
|
|
5919
|
+
exitCode: report.exit_code,
|
|
5773
5920
|
stdout: stringifyJson(report, datasetFlags.json),
|
|
5774
5921
|
stderr: '',
|
|
5775
5922
|
};
|
|
@@ -6418,6 +6565,8 @@ export async function executeCli(argv, deps) {
|
|
|
6418
6565
|
confirm: datasetFlags.confirm,
|
|
6419
6566
|
timeoutMs: datasetFlags.timeoutMs,
|
|
6420
6567
|
maxParallel: datasetFlags.maxParallel,
|
|
6568
|
+
globalInboundProofPath: datasetFlags.globalInboundProofPath || undefined,
|
|
6569
|
+
approveGlobalInboundProof: datasetFlags.approveGlobalInboundProof || undefined,
|
|
6421
6570
|
env: deps.env,
|
|
6422
6571
|
fetchImpl: deps.fetchImpl,
|
|
6423
6572
|
});
|