chainlesschain 0.165.3 → 0.165.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -29
- package/package.json +2 -2
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-BiHNUlbU.js → AIOps-CEeYTeDB.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-D-UFjDRQ.js → ActionButton-BeRUQ3V2.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DazVsDgW.js → Analytics-DrV718XF.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DXh9UfNJ.js → AppLayout-Cd2Frt7Q.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CZ6tsceY.js → Artifacts-CUJMlORU.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-RyxnBr_h.js → Audit-CXJcfT6p.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BWS51Q6X.js → BackgroundAgents-DOv6Z7H9.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BRtPcUul.js → Backup-BwdDyBI0.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CGd4vZYY.js → BaseInput-BmLn4kYH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-h8ijVwCg.js → Chat-COg8pAW2.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-4gGkdGgA.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-NyF6dPl8.js → Checkbox-BCP4uoU8.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Ci4OOxr5.js → Codegen-pRt6Y9JI.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CwTkc9BM.js → Col-DLaprKhS.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DW_tM82m.js → Community-DyATsz5f.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DEvHRV4S.js → Compact-BXAaupZK.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BbjBEEfD.js → Compliance-DpcJBELr.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-10IXBaBa.js → Cowork-DG4EFWyd.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BZkbpd5I.js → Cron-F6Oy5n2P.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CFQ8L_6v.js → Crosschain-BOdgtalX.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BDF6AkXe.js → DID-DT1dSkjH.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CoOdWMi4.js → Dashboard-NBUIqWzC.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DEsGmu8Y.js → Dropdown-CSpHeMYB.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BS89SWlK.js → EmailListRenderer-CEG0xISr.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-C1FpCHiI.js → FamilyGuardDashboard-BTZ0BZna.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BzvpVmLA.js → Federation-BuuCTn2V.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BeC259PQ.js → FormItemContext-KAVceevk.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-azgG3bmV.js → GenericCardRenderer-DnHpcQvW.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BmSSowc5.js → Git-C_B_0HwB.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CTBCSyQZ.js → Governance-DPSZuzuu.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DA5xyk4a.js → Inference-BV-06V7q.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-D1gPHNig.js → KnowledgeGraph-wpDuupn6.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BPmLf1AR.js → Logs-Bseca1_I.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-SVLOg49H.js → MarkdownRenderer-B4RLp2zs.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-DtUFcR0E.js → Marketplace-d3kM4DDL.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DS_kqBv-.js → McpTools-DQ_xZ23i.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-Fvh7XL7V.js → Memory-CRIeYO4L.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-C7itAP45.js → MobileBridge-BsllIa9l.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BUuQy30X.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B57MiNLK.js → Mtc-BOFDIzrC.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-BXfCUcM7.js → MtcAudit-BQg-vyvG.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-yaJ-ZcF6.js → Multisig-Bo1jrPdN.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CoaUCKrO.js → NLProgramming-Bmod8alw.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BKLM_65R.js → Notes-CGGFL8w-.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DoDtK9uZ.js → NotificationSettings-BsZvCJxC.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BJ28TGr-.js → OrderTableRenderer-C1-Quo_h.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-MuGsdoIb.js → Organization-BjOeDYOi.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BLUN9J4R.js → Overflow-DwVV3l5A.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DWuoBUPd.js → P2P-Cu3DQT9W.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CUi37YPj.js → PdhVaultBrowser-Cg0gR7dH.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BYQg2pcr.js → Permissions-CsAXxRN5.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CAxoV2xu.js → PersonalDataHub-C-nNmnYp.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-B33wGvIO.js → Pipeline-BOnW7nNc.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-A8yXTORP.js → Privacy-ClLSyGKt.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-D49I2I1O.js → ProjectInit-DuLvjjq7.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Ci73jJDw.js → ProjectSettings-DQYYbDD9.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-CF-yD6Cn.js → Projects-Drw8MBGK.js} +1 -1
- package/src/assets/web-panel/assets/Providers-ckqHQe6K.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-Brza0ykJ.js → QrScannerModal-DW5BXk-G.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DFydhjxL.js → QuickAsk-DDLnhNTp.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DLF8_NhA.js → Recommend-PJQ2C91U.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-dyuStW3x.js → RemoteSession-s6wmda34.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-5F3tA6yw.js → Reputation-DC2sb-I3.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Ca2A57S5.js → Row-hPGk1eGj.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B0bxBkq_.js → RssFeed-RIvfZql0.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CFNvHalZ.js → Search-DFg1G1eR.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DSoH3Hav.js → Security-D6H5p8Dp.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BHpfEmBQ.js → Services-nxYiFV_w.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Dsh-QNmn.js → Skeleton-BmgFNAdB.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BhT1NkSU.js → Skills-CsaaD2av.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DY9snPeJ.js → Sla-yM5y9yvK.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CWaX0_Cx.js → SpeechSettings-DPy1XMYh.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B690y_TC.js → SyncSettings-CFVhEyyr.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-2N-w3zWd.js → Tasks-DdO02Inn.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BjwQOQYC.js → Templates-Eo2d8Llu.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CUqHErxY.js → Tenant-ChESOXgy.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-C13rXvNy.js → Terminal-BJ7oDxTI.js} +2 -2
- package/src/assets/web-panel/assets/TimelineRenderer-hWX0fUvz.js +1 -0
- package/src/assets/web-panel/assets/{Tokens-BXHLGXYC.js → Tokens-DVBZQnd-.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-1e5i65o3.js → Trigger-D89cQfVq.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-FLGqNHs5.js → Trust-BIVSb4-V.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BbaR_LJB.js → UkeySign-B58gWopl.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-NOp4RIov.js → VideoEditing-DhHI7bmG.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-B7DW7bG4.js → Wallet-C4FheWS_.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-BptSUWix.js → WebAuthn-DnPRq-Bx.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CAJnDOXS.js → WorkflowEditor-BerRPjpJ.js} +1 -1
- package/src/assets/web-panel/assets/{chat-I8LgG1-Z.js → chat-BzZ52iKr.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CWe7SOVD.js → colors-BI_E4BAn.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cx3u3CA3.js → compact-item-d50mr3yk.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CgD5ArwY.js → createContext-C6FsQ1IH.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CagEcIex.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BfQWiXN8.js → hasIn-DLZEMgLP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuEQSorC.js → index-9H_M2jju.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiI-xPRH.js → index-A5CDWP7y.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAVy98u7.js → index-AHr7ryWf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BUAR7RY-.js → index-B81mo1Et.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlIyt1qF.js → index-BAE3hwev.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dcdm_Z2c.js → index-BB9SqVSt.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWZ3REg6.js → index-BRGx3w6T.js} +3 -3
- package/src/assets/web-panel/assets/{index-B6yChzt1.js → index-BTpIOTfR.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeizoQVZ.js → index-BZjjdQ62.js} +1 -1
- package/src/assets/web-panel/assets/{index-e8BM1yY1.js → index-BcSUl9fA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNYFQxAW.js → index-BeM4hfht.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGMYTN5W.js → index-Bmr_vxXD.js} +1 -1
- package/src/assets/web-panel/assets/{index-BREnPKGo.js → index-BoNZlzhQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1cX4Rxu.js → index-C3k8kevG.js} +1 -1
- package/src/assets/web-panel/assets/{index-3iKP9OTJ.js → index-CLoTQr0W.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1UjHdgZ.js → index-CO8DAF7U.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cy_cCJlr.js → index-CRN5TRTQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0nDKhWv.js → index-CUaEHfQ0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DslTuqro.js → index-CVzuawCX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAUnl4Jv.js → index-CdKt9fOd.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMu16vPC.js → index-CgkoH3_g.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-rIKccl.js → index-CjuKZBqJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bx7BNIRH.js → index-Co7s9LsB.js} +1 -1
- package/src/assets/web-panel/assets/{index-Doc0Ftpd.js → index-D-aBumtY.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cd79NQAx.js → index-DE0V6cp-.js} +1 -1
- package/src/assets/web-panel/assets/{index-V-kIHzAV.js → index-DY4j5zkF.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bi24S7Dw.js → index-Dec0Kf_Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-DCJEY2T0.js → index-DoFtCVZ7.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0ztiqtB.js → index-DqkbHHg8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcX4FSPf.js → index-DsscwxPE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdRkCwm4.js → index-GXE0D8Nx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmgtY58H.js → index-IPkwSAW_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQDKYbnv.js → index-KNGgO4Wm.js} +1 -1
- package/src/assets/web-panel/assets/{index-87gMxqhN.js → index-Pvf30m8Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmrdUwzU.js → index-Q5Tn735s.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFb-XIKy.js → index-TWG-_D1M.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsQcURkA.js → index-Y2-q7QLm.js} +1 -1
- package/src/assets/web-panel/assets/index-pzT9PpOU.js +1 -0
- package/src/assets/web-panel/assets/index-z1kFadaX.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-DiBszVdG.js → initDefaultProps-D-4Hzgej.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BGIFFozv.js → motion-D4Wl4xU7.js} +1 -1
- package/src/assets/web-panel/assets/{move-D5W7mp7B.js → move-Cd5eQvL0.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-JFIlxJ7F.js → mtc-parser-B4ilslCW.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CQ3o6LIU.js → omit-Ckarx-tf.js} +1 -1
- package/src/assets/web-panel/assets/parsers-YNLm7sQ0.js +4 -0
- package/src/assets/web-panel/assets/{pickAttrs-R8MIlXo3.js → pickAttrs-QJ0bpCmc.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-sW7ylSky.js → placementArrow-CKHm-tq8.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Cnl39Vbz.js → responsiveObserve-CV6a_w_Y.js} +1 -1
- package/src/assets/web-panel/assets/{slide-sn8tFd14.js → slide-mHpeQFgk.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-IKKY_QxZ.js → statusUtils-DIaQNQWA.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BNpV4Nqs.js → styleChecker-PJpzavV8.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BWyT_eoU.js → useFlexGapSupport-BH7zTw8S.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-D09p6_U9.js → useFs-BDNG3JDd.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CzW3TkJZ.js → usePersonalDataHub-CY2VWdUg.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-3s3WoAKB.js → vnode-D0kw9jhz.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Cjy_673s.js → zoom-B5g7TN7r.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +105 -35
- package/src/commands/artifacts.js +598 -33
- package/src/commands/cowork.js +200 -5
- package/src/commands/session-budget.js +155 -0
- package/src/commands/session-location.js +968 -1
- package/src/commands/session.js +23 -2
- package/src/data/changelog.json +28 -2
- package/src/gateways/ws/artifact-protocol.js +77 -13
- package/src/gateways/ws/message-dispatcher.js +57 -0
- package/src/gateways/ws/session-protocol.js +391 -24
- package/src/gateways/ws/ws-agent-handler.js +191 -14
- package/src/gateways/ws/ws-server.js +14 -3
- package/src/gateways/ws/ws-session-gateway.js +101 -5
- package/src/harness/jsonl-session-store.js +1210 -0
- package/src/lib/agent-team/team-runner.js +43 -13
- package/src/lib/artifact-access-ledger.js +462 -0
- package/src/lib/artifact-cleanup-ledger.js +861 -0
- package/src/lib/artifact-deletion-ledger.js +678 -0
- package/src/lib/artifact-recovery.js +970 -0
- package/src/lib/artifact-store.js +256 -51
- package/src/lib/artifact-workbench-projection.js +171 -0
- package/src/lib/command-lifecycle-report.js +8 -4
- package/src/lib/cowork-adapter.js +9 -5
- package/src/lib/cowork-task-runner.js +20 -0
- package/src/lib/cowork-workflow.js +178 -20
- package/src/lib/direct-model-usage.js +62 -22
- package/src/lib/dynamic-workflow-runtime.js +3592 -112
- package/src/lib/execution-location-result-apply.js +339 -0
- package/src/lib/execution-location-result-artifact.js +271 -0
- package/src/lib/execution-location-result-review.js +253 -0
- package/src/lib/execution-location-result-store.js +331 -0
- package/src/lib/execution-location-result.js +617 -0
- package/src/lib/execution-location-target.js +240 -3
- package/src/lib/managed-tool-checkpoint.js +47 -4
- package/src/lib/mcp-stdio-executable-identity.js +16 -0
- package/src/lib/mcp-stdio-native-code-policy.js +74 -0
- package/src/lib/mcp-stdio-package-materialization.js +12 -3
- package/src/lib/process-execution-broker/index.js +112 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +57 -3
- package/src/lib/process-execution-broker/workspace-transaction.js +29 -0
- package/src/lib/session-budget-production-root.js +376 -0
- package/src/lib/session-budget-runtime.js +109 -18
- package/src/lib/session-budget-usage.js +63 -0
- package/src/lib/session-host-snapshot.js +19 -2
- package/src/lib/session-projection.js +126 -10
- package/src/lib/session-resource-budget.js +766 -105
- package/src/lib/sub-agent-context.js +69 -22
- package/src/lib/web-ui-server.js +12 -1
- package/src/repl/agent-repl.js +237 -16
- package/src/runtime/agent-core.js +135 -0
- package/src/runtime/headless-runner.js +135 -46
- package/src/runtime/headless-stream.js +133 -25
- package/src/runtime/policies/agent-policy.js +10 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-D7tcdDS9.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-DGbP36-3.js +0 -1
- package/src/assets/web-panel/assets/Providers-D-etEhg5.js +0 -1
- package/src/assets/web-panel/assets/TimelineRenderer-CpbWcya_.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DLv_872g.js +0 -1
- package/src/assets/web-panel/assets/index-CdiGCibe.js +0 -1
- package/src/assets/web-panel/assets/index-D_0z-gyz.js +0 -1
- package/src/assets/web-panel/assets/parsers-UEvh_ShA.js +0 -4
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* `~/.chainlesschain/artifacts/`; this command is the user-facing surface:
|
|
6
6
|
*
|
|
7
7
|
* cc artifacts list [--session <id>] [--kind <k>] [--json]
|
|
8
|
-
* cc artifacts show <id> [--json] metadata +
|
|
9
|
-
* cc artifacts open <id> print
|
|
10
|
-
* cc artifacts remove <id>
|
|
11
|
-
* cc artifacts clean [--
|
|
8
|
+
* cc artifacts show <id> [--json] public metadata + integrity
|
|
9
|
+
* cc artifacts open <id> audit access, then print local path
|
|
10
|
+
* cc artifacts remove <id> settle managed-copy removal
|
|
11
|
+
* cc artifacts clean [--cleanup-id <id>] settle expired-artifact batch
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import chalk from "chalk";
|
|
@@ -18,6 +18,28 @@ import {
|
|
|
18
18
|
ArtifactStore,
|
|
19
19
|
publicArtifactMetadata,
|
|
20
20
|
} from "../lib/artifact-store.js";
|
|
21
|
+
import {
|
|
22
|
+
ARTIFACT_ACCESS_ACTIONS,
|
|
23
|
+
ARTIFACT_ACCESS_CLIENTS,
|
|
24
|
+
authorizeArtifactContentAccess,
|
|
25
|
+
readArtifactAccessLedger,
|
|
26
|
+
} from "../lib/artifact-access-ledger.js";
|
|
27
|
+
import {
|
|
28
|
+
ARTIFACT_DELETION_CLIENTS,
|
|
29
|
+
readArtifactDeletionLedger,
|
|
30
|
+
settleArtifactDeletion,
|
|
31
|
+
} from "../lib/artifact-deletion-ledger.js";
|
|
32
|
+
import {
|
|
33
|
+
readArtifactCleanupLedger,
|
|
34
|
+
settleArtifactCleanup,
|
|
35
|
+
} from "../lib/artifact-cleanup-ledger.js";
|
|
36
|
+
import {
|
|
37
|
+
ARTIFACT_RECOVERY_DECISIONS,
|
|
38
|
+
adjudicateArtifactRecovery,
|
|
39
|
+
buildArtifactRecoveryPlan,
|
|
40
|
+
readArtifactOrphanGcLedger,
|
|
41
|
+
} from "../lib/artifact-recovery.js";
|
|
42
|
+
import { buildArtifactWorkbenchProjection } from "../lib/artifact-workbench-projection.js";
|
|
21
43
|
import {
|
|
22
44
|
assessDeliveryEvidence,
|
|
23
45
|
createDeliveryEvidenceRecord,
|
|
@@ -58,7 +80,7 @@ export function registerArtifactsCommand(program) {
|
|
|
58
80
|
|
|
59
81
|
cmd
|
|
60
82
|
.command("show <id>")
|
|
61
|
-
.description("Show one artifact's metadata
|
|
83
|
+
.description("Show one artifact's public metadata and integrity")
|
|
62
84
|
.option("--json", "Machine-readable JSON output")
|
|
63
85
|
.action((id, options) => {
|
|
64
86
|
process.exitCode = runArtifactsShow(id, options);
|
|
@@ -66,28 +88,142 @@ export function registerArtifactsCommand(program) {
|
|
|
66
88
|
|
|
67
89
|
cmd
|
|
68
90
|
.command("open <id>")
|
|
69
|
-
.description("
|
|
91
|
+
.description("Authorize local content access and print the stored path")
|
|
70
92
|
.action((id) => {
|
|
71
93
|
process.exitCode = runArtifactsOpen(id);
|
|
72
94
|
});
|
|
73
95
|
|
|
96
|
+
cmd
|
|
97
|
+
.command("access <id>")
|
|
98
|
+
.description(
|
|
99
|
+
"Authorize one official client action and record content-free access lineage",
|
|
100
|
+
)
|
|
101
|
+
.requiredOption(
|
|
102
|
+
"--client <client>",
|
|
103
|
+
`Declared client (${ARTIFACT_ACCESS_CLIENTS.join("|")})`,
|
|
104
|
+
)
|
|
105
|
+
.requiredOption(
|
|
106
|
+
"--action <action>",
|
|
107
|
+
`Requested action (${ARTIFACT_ACCESS_ACTIONS.join("|")})`,
|
|
108
|
+
)
|
|
109
|
+
.option("--access-id <id>", "Stable id for response-loss retry")
|
|
110
|
+
.option("--json", "Machine-readable authorization and local path")
|
|
111
|
+
.action((id, options) => {
|
|
112
|
+
process.exitCode = runArtifactsAccess(id, options);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
cmd
|
|
116
|
+
.command("access-log")
|
|
117
|
+
.description("Verify and display the content-free artifact access ledger")
|
|
118
|
+
.option("--artifact <id>", "Only events for one artifact id")
|
|
119
|
+
.option("--json", "Machine-readable verified ledger projection")
|
|
120
|
+
.action((options) => {
|
|
121
|
+
process.exitCode = runArtifactsAccessLog(options);
|
|
122
|
+
});
|
|
123
|
+
|
|
74
124
|
cmd
|
|
75
125
|
.command("remove <id>")
|
|
76
126
|
.alias("rm")
|
|
77
|
-
.description("
|
|
127
|
+
.description("Settle and audit removal of one managed artifact copy")
|
|
128
|
+
.option(
|
|
129
|
+
"--client <client>",
|
|
130
|
+
`Declared client (${ARTIFACT_DELETION_CLIENTS.join("|")})`,
|
|
131
|
+
"cli",
|
|
132
|
+
)
|
|
133
|
+
.option("--deletion-id <id>", "Stable id for response-loss recovery")
|
|
78
134
|
.option("--json", "Machine-readable JSON output")
|
|
79
135
|
.action((id, options) => {
|
|
80
136
|
process.exitCode = runArtifactsRemove(id, options);
|
|
81
137
|
});
|
|
82
138
|
|
|
139
|
+
cmd
|
|
140
|
+
.command("deletion-log")
|
|
141
|
+
.description(
|
|
142
|
+
"Verify and display the content-free deletion settlement ledger",
|
|
143
|
+
)
|
|
144
|
+
.option("--artifact <id>", "Only events for one artifact id")
|
|
145
|
+
.option("--deletion <id>", "Only events for one deletion id")
|
|
146
|
+
.option("--json", "Machine-readable verified ledger projection")
|
|
147
|
+
.action((options) => {
|
|
148
|
+
process.exitCode = runArtifactsDeletionLog(options);
|
|
149
|
+
});
|
|
150
|
+
|
|
83
151
|
cmd
|
|
84
152
|
.command("clean")
|
|
85
|
-
.description("
|
|
153
|
+
.description("Settle and audit one frozen batch of expired artifacts")
|
|
154
|
+
.option(
|
|
155
|
+
"--client <client>",
|
|
156
|
+
`Declared client (${ARTIFACT_DELETION_CLIENTS.join("|")})`,
|
|
157
|
+
"cli",
|
|
158
|
+
)
|
|
159
|
+
.option("--cleanup-id <id>", "Stable batch id for response-loss recovery")
|
|
86
160
|
.option("--json", "Machine-readable JSON output")
|
|
87
161
|
.action((options) => {
|
|
88
162
|
process.exitCode = runArtifactsClean(options);
|
|
89
163
|
});
|
|
90
164
|
|
|
165
|
+
cmd
|
|
166
|
+
.command("cleanup-log")
|
|
167
|
+
.description(
|
|
168
|
+
"Verify and display the content-free cleanup settlement ledger",
|
|
169
|
+
)
|
|
170
|
+
.option("--cleanup <id>", "Only events for one cleanup id")
|
|
171
|
+
.option("--artifact <id>", "Only batches containing one artifact id")
|
|
172
|
+
.option("--json", "Machine-readable verified ledger projection")
|
|
173
|
+
.action((options) => {
|
|
174
|
+
process.exitCode = runArtifactsCleanupLog(options);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
cmd
|
|
178
|
+
.command("recovery-plan")
|
|
179
|
+
.description(
|
|
180
|
+
"Inventory pending settlements and orphaned managed copies without mutating them",
|
|
181
|
+
)
|
|
182
|
+
.option(
|
|
183
|
+
"--timeout-ms <ms>",
|
|
184
|
+
"Age after which a pending settlement is reported as timed out",
|
|
185
|
+
)
|
|
186
|
+
.option("--json", "Machine-readable content-free recovery plan")
|
|
187
|
+
.action((options) => {
|
|
188
|
+
process.exitCode = runArtifactsRecoveryPlan(options);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
cmd
|
|
192
|
+
.command("workbench")
|
|
193
|
+
.description(
|
|
194
|
+
"Project artifacts, returned-result lineage, history, and recovery risk for product clients",
|
|
195
|
+
)
|
|
196
|
+
.option("--json", "Machine-readable canonical workbench projection")
|
|
197
|
+
.action((options) => {
|
|
198
|
+
process.exitCode = runArtifactsWorkbench(options);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
cmd
|
|
202
|
+
.command("recovery-adjudicate <item>")
|
|
203
|
+
.description(
|
|
204
|
+
"Apply one explicit, plan-bound administrator recovery decision",
|
|
205
|
+
)
|
|
206
|
+
.requiredOption("--plan-digest <digest>", "Exact recovery plan digest")
|
|
207
|
+
.requiredOption(
|
|
208
|
+
"--decision <decision>",
|
|
209
|
+
`Decision (${ARTIFACT_RECOVERY_DECISIONS.join("|")})`,
|
|
210
|
+
)
|
|
211
|
+
.option("--adjudication-id <id>", "Stable id for response-loss recovery")
|
|
212
|
+
.option("--approve", "Confirm the reviewed recovery mutation")
|
|
213
|
+
.option("--json", "Machine-readable adjudication receipt")
|
|
214
|
+
.action((item, options) => {
|
|
215
|
+
process.exitCode = runArtifactsRecoveryAdjudicate(item, options);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
cmd
|
|
219
|
+
.command("orphan-gc-log")
|
|
220
|
+
.description("Verify and display the content-free orphan GC ledger")
|
|
221
|
+
.option("--adjudication <id>", "Only events for one adjudication id")
|
|
222
|
+
.option("--json", "Machine-readable verified ledger projection")
|
|
223
|
+
.action((options) => {
|
|
224
|
+
process.exitCode = runArtifactsOrphanGcLog(options);
|
|
225
|
+
});
|
|
226
|
+
|
|
91
227
|
cmd
|
|
92
228
|
.command("select-gates <input>")
|
|
93
229
|
.description(
|
|
@@ -193,7 +329,13 @@ export function runArtifactsList(options = {}, deps = {}) {
|
|
|
193
329
|
entries = entries.filter((e) => e.kind === String(options.kind));
|
|
194
330
|
}
|
|
195
331
|
if (options.json) {
|
|
196
|
-
console.log(
|
|
332
|
+
console.log(
|
|
333
|
+
JSON.stringify(
|
|
334
|
+
{ artifacts: entries.map(publicArtifactMetadata) },
|
|
335
|
+
null,
|
|
336
|
+
2,
|
|
337
|
+
),
|
|
338
|
+
);
|
|
197
339
|
return 0;
|
|
198
340
|
}
|
|
199
341
|
if (entries.length === 0) {
|
|
@@ -227,8 +369,7 @@ export function runArtifactsShow(id, options = {}, deps = {}) {
|
|
|
227
369
|
return 1;
|
|
228
370
|
}
|
|
229
371
|
const payload = {
|
|
230
|
-
...entry,
|
|
231
|
-
storedPath: store.storedPath(entry),
|
|
372
|
+
...publicArtifactMetadata(entry),
|
|
232
373
|
integrity: store.verifyIntegrity(entry),
|
|
233
374
|
};
|
|
234
375
|
if (options.json) {
|
|
@@ -242,44 +383,468 @@ export function runArtifactsShow(id, options = {}, deps = {}) {
|
|
|
242
383
|
}
|
|
243
384
|
|
|
244
385
|
export function runArtifactsOpen(id, deps = {}) {
|
|
386
|
+
return runArtifactsAccess(id, { client: "cli", action: "open" }, deps);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export function runArtifactsAccess(id, options = {}, deps = {}) {
|
|
245
390
|
const store = deps.store || new ArtifactStore();
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
391
|
+
try {
|
|
392
|
+
const authorization = (
|
|
393
|
+
deps.authorizeArtifactContentAccess || authorizeArtifactContentAccess
|
|
394
|
+
)(
|
|
395
|
+
store,
|
|
396
|
+
{
|
|
397
|
+
artifactId: id,
|
|
398
|
+
client: options.client,
|
|
399
|
+
action: options.action,
|
|
400
|
+
accessId: options.accessId,
|
|
401
|
+
},
|
|
402
|
+
deps.accessOptions || {},
|
|
403
|
+
);
|
|
404
|
+
const payload = {
|
|
405
|
+
schema: "cc-artifact-content-access-authorization/v1",
|
|
406
|
+
access: authorization.access,
|
|
407
|
+
recorded: authorization.recorded,
|
|
408
|
+
storedPath: authorization.storedPath,
|
|
409
|
+
integrity: authorization.integrity,
|
|
410
|
+
};
|
|
411
|
+
if (options.json) {
|
|
412
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
413
|
+
} else {
|
|
414
|
+
console.log(authorization.storedPath);
|
|
415
|
+
}
|
|
416
|
+
return 0;
|
|
417
|
+
} catch (error) {
|
|
418
|
+
if (options.json) {
|
|
419
|
+
console.error(
|
|
420
|
+
JSON.stringify({
|
|
421
|
+
schema: "cc-artifact-content-access-authorization-error/v1",
|
|
422
|
+
authorized: false,
|
|
423
|
+
error: error.message,
|
|
424
|
+
}),
|
|
425
|
+
);
|
|
426
|
+
} else {
|
|
427
|
+
console.error(chalk.red(`Artifact access failed: ${error.message}`));
|
|
428
|
+
}
|
|
429
|
+
return 1;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export function runArtifactsAccessLog(options = {}, deps = {}) {
|
|
434
|
+
const store = deps.store || new ArtifactStore();
|
|
435
|
+
try {
|
|
436
|
+
const ledger = (deps.readArtifactAccessLedger || readArtifactAccessLedger)(
|
|
437
|
+
store,
|
|
438
|
+
deps.accessOptions || {},
|
|
439
|
+
);
|
|
440
|
+
const events = options.artifact
|
|
441
|
+
? ledger.events.filter(
|
|
442
|
+
(event) => event.artifactId === String(options.artifact),
|
|
443
|
+
)
|
|
444
|
+
: ledger.events;
|
|
445
|
+
const projection = {
|
|
446
|
+
...ledger,
|
|
447
|
+
filtered: Boolean(options.artifact),
|
|
448
|
+
matchedEventCount: events.length,
|
|
449
|
+
events,
|
|
450
|
+
};
|
|
451
|
+
if (options.json) {
|
|
452
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
453
|
+
} else if (events.length === 0) {
|
|
454
|
+
console.log(chalk.dim("No artifact content access events."));
|
|
455
|
+
} else {
|
|
456
|
+
for (const event of events) {
|
|
457
|
+
console.log(
|
|
458
|
+
`${chalk.cyan(event.sequence)} ${event.artifactId} ${event.client}/${event.action} ${event.authorizedAt} ${event.eventDigest}`,
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return 0;
|
|
463
|
+
} catch (error) {
|
|
464
|
+
if (options.json) {
|
|
465
|
+
console.error(
|
|
466
|
+
JSON.stringify({
|
|
467
|
+
schema: "cc-artifact-content-access-ledger-error/v1",
|
|
468
|
+
verified: false,
|
|
469
|
+
error: error.message,
|
|
470
|
+
}),
|
|
471
|
+
);
|
|
472
|
+
} else {
|
|
473
|
+
console.error(chalk.red(`Artifact access log failed: ${error.message}`));
|
|
474
|
+
}
|
|
249
475
|
return 1;
|
|
250
476
|
}
|
|
251
|
-
console.log(store.storedPath(entry));
|
|
252
|
-
return 0;
|
|
253
477
|
}
|
|
254
478
|
|
|
255
479
|
export function runArtifactsRemove(id, options = {}, deps = {}) {
|
|
256
480
|
const store = deps.store || new ArtifactStore();
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
481
|
+
const deletionId = String(
|
|
482
|
+
options.deletionId || `delete_${randomUUID().replaceAll("-", "")}`,
|
|
483
|
+
);
|
|
484
|
+
try {
|
|
485
|
+
const result = (deps.settleArtifactDeletion || settleArtifactDeletion)(
|
|
486
|
+
store,
|
|
487
|
+
{
|
|
488
|
+
deletionId,
|
|
489
|
+
artifactId: id,
|
|
490
|
+
reason: "explicit",
|
|
491
|
+
client: options.client || "cli",
|
|
492
|
+
},
|
|
493
|
+
deps.deletionOptions || {},
|
|
494
|
+
);
|
|
495
|
+
if (options.json) {
|
|
496
|
+
console.log(JSON.stringify(result, null, 2));
|
|
497
|
+
return result.found ? 0 : 1;
|
|
498
|
+
}
|
|
499
|
+
if (!result.found) {
|
|
500
|
+
console.error(chalk.red(`No artifact with id "${id}".`));
|
|
501
|
+
return 1;
|
|
502
|
+
}
|
|
503
|
+
console.log(
|
|
504
|
+
chalk.green(`Removed managed copy ${id} (deletion ${deletionId}).`),
|
|
505
|
+
);
|
|
506
|
+
return 0;
|
|
507
|
+
} catch (error) {
|
|
508
|
+
if (options.json) {
|
|
509
|
+
console.error(
|
|
510
|
+
JSON.stringify({
|
|
511
|
+
schema: "cc-artifact-deletion-error/v1",
|
|
512
|
+
deletionId: error.deletionId || deletionId,
|
|
513
|
+
artifactId: String(id),
|
|
514
|
+
settled: false,
|
|
515
|
+
error: error.message,
|
|
516
|
+
}),
|
|
517
|
+
);
|
|
518
|
+
} else {
|
|
519
|
+
console.error(
|
|
520
|
+
chalk.red(
|
|
521
|
+
`Artifact removal ${error.deletionId || deletionId} is not settled: ${error.message}`,
|
|
522
|
+
),
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
return 1;
|
|
261
526
|
}
|
|
262
|
-
|
|
263
|
-
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
export function runArtifactsDeletionLog(options = {}, deps = {}) {
|
|
530
|
+
const store = deps.store || new ArtifactStore();
|
|
531
|
+
try {
|
|
532
|
+
const ledger = (
|
|
533
|
+
deps.readArtifactDeletionLedger || readArtifactDeletionLedger
|
|
534
|
+
)(store, deps.deletionOptions || {});
|
|
535
|
+
const events = ledger.events.filter(
|
|
536
|
+
(event) =>
|
|
537
|
+
(!options.artifact || event.artifactId === String(options.artifact)) &&
|
|
538
|
+
(!options.deletion || event.deletionId === String(options.deletion)),
|
|
539
|
+
);
|
|
540
|
+
const projection = {
|
|
541
|
+
...ledger,
|
|
542
|
+
filtered: Boolean(options.artifact || options.deletion),
|
|
543
|
+
matchedEventCount: events.length,
|
|
544
|
+
events,
|
|
545
|
+
};
|
|
546
|
+
if (options.json) {
|
|
547
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
548
|
+
} else if (events.length === 0) {
|
|
549
|
+
console.log(chalk.dim("No artifact deletion settlement events."));
|
|
550
|
+
} else {
|
|
551
|
+
for (const event of events) {
|
|
552
|
+
console.log(
|
|
553
|
+
`${event.sequence}\t${event.phase}\t${event.artifactId}\t${event.deletionId}\t${event.eventDigest}`,
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return 0;
|
|
558
|
+
} catch (error) {
|
|
559
|
+
if (options.json) {
|
|
560
|
+
console.error(
|
|
561
|
+
JSON.stringify({
|
|
562
|
+
schema: "cc-artifact-deletion-ledger-error/v1",
|
|
563
|
+
verified: false,
|
|
564
|
+
error: error.message,
|
|
565
|
+
}),
|
|
566
|
+
);
|
|
567
|
+
} else {
|
|
568
|
+
console.error(
|
|
569
|
+
chalk.red(`Artifact deletion log failed: ${error.message}`),
|
|
570
|
+
);
|
|
571
|
+
}
|
|
264
572
|
return 1;
|
|
265
573
|
}
|
|
266
|
-
console.log(chalk.green(`Removed ${id}.`));
|
|
267
|
-
return 0;
|
|
268
574
|
}
|
|
269
575
|
|
|
270
576
|
export function runArtifactsClean(options = {}, deps = {}) {
|
|
271
577
|
const store = deps.store || new ArtifactStore();
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
578
|
+
const cleanupId = String(
|
|
579
|
+
options.cleanupId || `cleanup_${randomUUID().replaceAll("-", "")}`,
|
|
580
|
+
);
|
|
581
|
+
try {
|
|
582
|
+
const result = (deps.settleArtifactCleanup || settleArtifactCleanup)(
|
|
583
|
+
store,
|
|
584
|
+
{
|
|
585
|
+
cleanupId,
|
|
586
|
+
client: options.client || "cli",
|
|
587
|
+
},
|
|
588
|
+
deps.cleanupOptions || {},
|
|
589
|
+
);
|
|
590
|
+
if (options.json) {
|
|
591
|
+
console.log(JSON.stringify(result, null, 2));
|
|
592
|
+
return 0;
|
|
593
|
+
}
|
|
594
|
+
console.log(
|
|
595
|
+
result.removed > 0
|
|
596
|
+
? chalk.green(
|
|
597
|
+
`Settled cleanup ${cleanupId}: removed ${result.removed} expired artifact(s).`,
|
|
598
|
+
)
|
|
599
|
+
: chalk.dim(`Settled cleanup ${cleanupId}: nothing expired.`),
|
|
600
|
+
);
|
|
275
601
|
return 0;
|
|
602
|
+
} catch (error) {
|
|
603
|
+
if (options.json) {
|
|
604
|
+
console.error(
|
|
605
|
+
JSON.stringify({
|
|
606
|
+
schema: "cc-artifact-cleanup-error/v1",
|
|
607
|
+
cleanupId: error.cleanupId || cleanupId,
|
|
608
|
+
settled: false,
|
|
609
|
+
...(error.cleanup ? { cleanup: error.cleanup } : {}),
|
|
610
|
+
error: error.message,
|
|
611
|
+
}),
|
|
612
|
+
);
|
|
613
|
+
} else {
|
|
614
|
+
console.error(
|
|
615
|
+
chalk.red(
|
|
616
|
+
`Artifact cleanup ${error.cleanupId || cleanupId} is not settled: ${error.message}`,
|
|
617
|
+
),
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
return 1;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export function runArtifactsCleanupLog(options = {}, deps = {}) {
|
|
625
|
+
const store = deps.store || new ArtifactStore();
|
|
626
|
+
try {
|
|
627
|
+
const ledger = (
|
|
628
|
+
deps.readArtifactCleanupLedger || readArtifactCleanupLedger
|
|
629
|
+
)(store, deps.cleanupOptions || {});
|
|
630
|
+
const events = ledger.events.filter(
|
|
631
|
+
(event) =>
|
|
632
|
+
(!options.cleanup || event.cleanupId === String(options.cleanup)) &&
|
|
633
|
+
(!options.artifact ||
|
|
634
|
+
event.items.some(
|
|
635
|
+
(item) => item.artifactId === String(options.artifact),
|
|
636
|
+
)),
|
|
637
|
+
);
|
|
638
|
+
const projection = {
|
|
639
|
+
...ledger,
|
|
640
|
+
filtered: Boolean(options.cleanup || options.artifact),
|
|
641
|
+
matchedEventCount: events.length,
|
|
642
|
+
events,
|
|
643
|
+
};
|
|
644
|
+
if (options.json) {
|
|
645
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
646
|
+
} else if (events.length === 0) {
|
|
647
|
+
console.log(chalk.dim("No artifact cleanup settlement events."));
|
|
648
|
+
} else {
|
|
649
|
+
for (const event of events) {
|
|
650
|
+
console.log(
|
|
651
|
+
`${event.sequence}\t${event.phase}\t${event.itemCount}\t${event.cleanupId}\t${event.eventDigest}`,
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return 0;
|
|
656
|
+
} catch (error) {
|
|
657
|
+
if (options.json) {
|
|
658
|
+
console.error(
|
|
659
|
+
JSON.stringify({
|
|
660
|
+
schema: "cc-artifact-cleanup-ledger-error/v1",
|
|
661
|
+
verified: false,
|
|
662
|
+
error: error.message,
|
|
663
|
+
}),
|
|
664
|
+
);
|
|
665
|
+
} else {
|
|
666
|
+
console.error(chalk.red(`Artifact cleanup log failed: ${error.message}`));
|
|
667
|
+
}
|
|
668
|
+
return 1;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
export function runArtifactsRecoveryPlan(options = {}, deps = {}) {
|
|
673
|
+
const store = deps.store || new ArtifactStore();
|
|
674
|
+
try {
|
|
675
|
+
const parsedTimeout =
|
|
676
|
+
options.timeoutMs == null ? undefined : Number(options.timeoutMs);
|
|
677
|
+
const plan = (deps.buildArtifactRecoveryPlan || buildArtifactRecoveryPlan)(
|
|
678
|
+
store,
|
|
679
|
+
{
|
|
680
|
+
...(parsedTimeout == null ? {} : { timeoutMs: parsedTimeout }),
|
|
681
|
+
...(deps.recoveryOptions || {}),
|
|
682
|
+
},
|
|
683
|
+
);
|
|
684
|
+
if (options.json) {
|
|
685
|
+
console.log(JSON.stringify(plan, null, 2));
|
|
686
|
+
} else if (plan.items.length === 0) {
|
|
687
|
+
console.log(
|
|
688
|
+
chalk.dim(`Artifact recovery is clear (${plan.planDigest}).`),
|
|
689
|
+
);
|
|
690
|
+
} else {
|
|
691
|
+
console.log(
|
|
692
|
+
chalk.yellow(
|
|
693
|
+
`Artifact recovery requires review: ${plan.summary.itemCount} item(s), ${plan.summary.criticalCount} critical (${plan.planDigest}).`,
|
|
694
|
+
),
|
|
695
|
+
);
|
|
696
|
+
for (const item of plan.items) {
|
|
697
|
+
console.log(
|
|
698
|
+
`${item.severity}\t${item.kind}\t${item.recommendedDecision}\t${item.itemId}`,
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return plan.summary.itemCount > 0 ? 2 : 0;
|
|
703
|
+
} catch (error) {
|
|
704
|
+
if (options.json) {
|
|
705
|
+
console.error(
|
|
706
|
+
JSON.stringify({
|
|
707
|
+
schema: "cc-artifact-recovery-plan-error/v1",
|
|
708
|
+
verified: false,
|
|
709
|
+
error: error.message,
|
|
710
|
+
}),
|
|
711
|
+
);
|
|
712
|
+
} else {
|
|
713
|
+
console.error(
|
|
714
|
+
chalk.red(`Artifact recovery inventory failed: ${error.message}`),
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
return 1;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
export function runArtifactsWorkbench(options = {}, deps = {}) {
|
|
722
|
+
const store = deps.store || new ArtifactStore();
|
|
723
|
+
try {
|
|
724
|
+
const projection = (
|
|
725
|
+
deps.buildArtifactWorkbenchProjection || buildArtifactWorkbenchProjection
|
|
726
|
+
)(store, deps.workbenchOptions || {});
|
|
727
|
+
if (options.json) {
|
|
728
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
729
|
+
} else {
|
|
730
|
+
console.log(
|
|
731
|
+
`${projection.artifacts.length} artifact(s); ${projection.recovery.summary.itemCount} recovery item(s); ${projection.history.totalEventCount} history event(s).`,
|
|
732
|
+
);
|
|
733
|
+
console.log(chalk.dim(projection.recovery.planDigest));
|
|
734
|
+
}
|
|
735
|
+
return 0;
|
|
736
|
+
} catch (error) {
|
|
737
|
+
if (options.json) {
|
|
738
|
+
console.error(
|
|
739
|
+
JSON.stringify({
|
|
740
|
+
schema: "cc-artifact-workbench-error/v1",
|
|
741
|
+
verified: false,
|
|
742
|
+
error: error.message,
|
|
743
|
+
}),
|
|
744
|
+
);
|
|
745
|
+
} else {
|
|
746
|
+
console.error(
|
|
747
|
+
chalk.red(`Artifact workbench projection failed: ${error.message}`),
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
return 1;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
export function runArtifactsRecoveryAdjudicate(item, options = {}, deps = {}) {
|
|
755
|
+
const store = deps.store || new ArtifactStore();
|
|
756
|
+
try {
|
|
757
|
+
if (options.decision !== "defer" && options.approve !== true) {
|
|
758
|
+
throw new Error("recovery mutation requires explicit --approve");
|
|
759
|
+
}
|
|
760
|
+
const result = (
|
|
761
|
+
deps.adjudicateArtifactRecovery || adjudicateArtifactRecovery
|
|
762
|
+
)(
|
|
763
|
+
store,
|
|
764
|
+
{
|
|
765
|
+
itemId: item,
|
|
766
|
+
planDigest: options.planDigest,
|
|
767
|
+
decision: options.decision,
|
|
768
|
+
adjudicationId: options.adjudicationId,
|
|
769
|
+
},
|
|
770
|
+
deps.recoveryOptions || {},
|
|
771
|
+
);
|
|
772
|
+
if (options.json) {
|
|
773
|
+
console.log(JSON.stringify(result, null, 2));
|
|
774
|
+
} else {
|
|
775
|
+
console.log(
|
|
776
|
+
result.settled
|
|
777
|
+
? chalk.green(
|
|
778
|
+
`Artifact recovery adjudication ${result.adjudicationId || options.adjudicationId || ""} settled.`,
|
|
779
|
+
)
|
|
780
|
+
: chalk.dim("Artifact recovery item was deferred without mutation."),
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
return result.settled || options.decision === "defer" ? 0 : 1;
|
|
784
|
+
} catch (error) {
|
|
785
|
+
if (options.json) {
|
|
786
|
+
console.error(
|
|
787
|
+
JSON.stringify({
|
|
788
|
+
schema: "cc-artifact-recovery-adjudication-error/v1",
|
|
789
|
+
itemId: String(item),
|
|
790
|
+
settled: false,
|
|
791
|
+
error: error.message,
|
|
792
|
+
}),
|
|
793
|
+
);
|
|
794
|
+
} else {
|
|
795
|
+
console.error(
|
|
796
|
+
chalk.red(`Artifact recovery adjudication failed: ${error.message}`),
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
return 1;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
export function runArtifactsOrphanGcLog(options = {}, deps = {}) {
|
|
804
|
+
const store = deps.store || new ArtifactStore();
|
|
805
|
+
try {
|
|
806
|
+
const ledger = (
|
|
807
|
+
deps.readArtifactOrphanGcLedger || readArtifactOrphanGcLedger
|
|
808
|
+
)(store, deps.recoveryOptions || {});
|
|
809
|
+
const events = ledger.events.filter(
|
|
810
|
+
(event) =>
|
|
811
|
+
!options.adjudication ||
|
|
812
|
+
event.adjudicationId === String(options.adjudication),
|
|
813
|
+
);
|
|
814
|
+
const projection = {
|
|
815
|
+
...ledger,
|
|
816
|
+
filtered: Boolean(options.adjudication),
|
|
817
|
+
matchedEventCount: events.length,
|
|
818
|
+
events,
|
|
819
|
+
};
|
|
820
|
+
if (options.json) {
|
|
821
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
822
|
+
} else if (events.length === 0) {
|
|
823
|
+
console.log(chalk.dim("No artifact orphan GC settlement events."));
|
|
824
|
+
} else {
|
|
825
|
+
for (const event of events) {
|
|
826
|
+
console.log(
|
|
827
|
+
`${event.sequence}\t${event.phase}\t${event.outcome}\t${event.adjudicationId}\t${event.eventDigest}`,
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
return 0;
|
|
832
|
+
} catch (error) {
|
|
833
|
+
if (options.json) {
|
|
834
|
+
console.error(
|
|
835
|
+
JSON.stringify({
|
|
836
|
+
schema: "cc-artifact-orphan-gc-ledger-error/v1",
|
|
837
|
+
verified: false,
|
|
838
|
+
error: error.message,
|
|
839
|
+
}),
|
|
840
|
+
);
|
|
841
|
+
} else {
|
|
842
|
+
console.error(
|
|
843
|
+
chalk.red(`Artifact orphan GC log failed: ${error.message}`),
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
return 1;
|
|
276
847
|
}
|
|
277
|
-
console.log(
|
|
278
|
-
removed > 0
|
|
279
|
-
? chalk.green(`Removed ${removed} expired artifact(s).`)
|
|
280
|
-
: chalk.dim("Nothing expired."),
|
|
281
|
-
);
|
|
282
|
-
return 0;
|
|
283
848
|
}
|
|
284
849
|
|
|
285
850
|
function readJsonFile(inputPath, deps = {}) {
|