@skrr-ai/cli 0.1.46 → 0.1.48
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 +1 -1
- package/dist/base-command.d.ts +18 -0
- package/dist/base-command.js +61 -1
- package/dist/commands/agents/chat.d.ts +21 -0
- package/dist/commands/agents/chat.js +26 -9
- package/dist/commands/balance/usage/breakdown.d.ts +14 -0
- package/dist/commands/balance/usage/breakdown.js +68 -0
- package/dist/commands/balance/usage.js +24 -0
- package/dist/commands/code/handover.d.ts +2 -2
- package/dist/commands/code/handover.js +12 -13
- package/dist/commands/code/install.js +31 -0
- package/dist/commands/code/update.d.ts +46 -0
- package/dist/commands/code/update.js +242 -0
- package/dist/commands/commerce/entitlements/explain.d.ts +22 -0
- package/dist/commands/commerce/entitlements/explain.js +40 -0
- package/dist/commands/commerce/incidents/audit.d.ts +20 -0
- package/dist/commands/commerce/incidents/audit.js +37 -0
- package/dist/commands/commerce/incidents/list.d.ts +22 -0
- package/dist/commands/commerce/incidents/list.js +49 -0
- package/dist/commands/commerce/incidents/resolve.d.ts +23 -0
- package/dist/commands/commerce/incidents/resolve.js +45 -0
- package/dist/commands/commerce/incidents/retry.d.ts +22 -0
- package/dist/commands/commerce/incidents/retry.js +45 -0
- package/dist/commands/commerce/incidents/show.d.ts +13 -0
- package/dist/commands/commerce/incidents/show.js +30 -0
- package/dist/commands/commerce/offers/approve.d.ts +17 -0
- package/dist/commands/commerce/offers/approve.js +33 -0
- package/dist/commands/commerce/offers/create.d.ts +18 -0
- package/dist/commands/commerce/offers/create.js +34 -0
- package/dist/commands/commerce/offers/publish.d.ts +13 -0
- package/dist/commands/commerce/offers/publish.js +28 -0
- package/dist/commands/commerce/offers/retire.d.ts +17 -0
- package/dist/commands/commerce/offers/retire.js +32 -0
- package/dist/commands/commerce/offers/validate.d.ts +18 -0
- package/dist/commands/commerce/offers/validate.js +33 -0
- package/dist/commands/commerce/products/create.d.ts +10 -0
- package/dist/commands/commerce/products/create.js +25 -0
- package/dist/commands/commerce/promotions/redeem.d.ts +13 -0
- package/dist/commands/commerce/promotions/redeem.js +32 -0
- package/dist/commands/commerce/terms/accept.d.ts +18 -0
- package/dist/commands/commerce/terms/accept.js +39 -0
- package/dist/commands/commerce/terms/show.d.ts +10 -0
- package/dist/commands/commerce/terms/show.js +34 -0
- package/dist/commands/commerce/trials/conversion-preview.d.ts +18 -0
- package/dist/commands/commerce/trials/conversion-preview.js +39 -0
- package/dist/commands/commerce/trials/start.d.ts +23 -0
- package/dist/commands/commerce/trials/start.js +58 -0
- package/dist/commands/commitments/accounting.d.ts +39 -0
- package/dist/commands/commitments/accounting.js +116 -0
- package/dist/commands/commitments/action-history.d.ts +1 -0
- package/dist/commands/commitments/action-history.js +8 -1
- package/dist/commands/commitments/case.d.ts +1 -0
- package/dist/commands/commitments/case.js +19 -3
- package/dist/commands/commitments/cases.d.ts +1 -0
- package/dist/commands/commitments/cases.js +11 -1
- package/dist/commands/commitments/checks.d.ts +1 -0
- package/dist/commands/commitments/checks.js +5 -1
- package/dist/commands/commitments/cost.d.ts +62 -0
- package/dist/commands/commitments/cost.js +130 -0
- package/dist/commands/commitments/create.js +1 -1
- package/dist/commands/commitments/delete.d.ts +1 -0
- package/dist/commands/commitments/delete.js +56 -6
- package/dist/commands/commitments/feedback.js +9 -1
- package/dist/commands/commitments/handover.js +16 -0
- package/dist/commands/commitments/hypotheses.d.ts +1 -0
- package/dist/commands/commitments/hypotheses.js +17 -2
- package/dist/commands/commitments/links/list.js +4 -1
- package/dist/commands/commitments/liveness.d.ts +18 -0
- package/dist/commands/commitments/liveness.js +80 -0
- package/dist/commands/commitments/metrics.d.ts +1 -0
- package/dist/commands/commitments/metrics.js +8 -1
- package/dist/commands/commitments/next-tick.d.ts +39 -0
- package/dist/commands/commitments/next-tick.js +122 -0
- package/dist/commands/commitments/observations.d.ts +1 -0
- package/dist/commands/commitments/observations.js +19 -2
- package/dist/commands/commitments/pause.js +12 -0
- package/dist/commands/commitments/receipt.d.ts +2 -0
- package/dist/commands/commitments/receipt.js +16 -2
- package/dist/commands/commitments/remediation-proposal.js +6 -2
- package/dist/commands/commitments/remediation-proposals.js +5 -1
- package/dist/commands/commitments/restore.d.ts +25 -0
- package/dist/commands/commitments/restore.js +46 -0
- package/dist/commands/commitments/show.js +32 -0
- package/dist/commands/commitments/trigger-status.js +33 -0
- package/dist/commands/commitments/update.d.ts +1 -0
- package/dist/commands/commitments/update.js +31 -5
- package/dist/commands/commitments/wake-capabilities.d.ts +0 -1
- package/dist/commands/commitments/wake-capabilities.js +8 -4
- package/dist/commands/convos/handover.d.ts +1 -0
- package/dist/commands/convos/handover.js +4 -0
- package/dist/commands/daemon/index.js +2 -0
- package/dist/commands/daemon/update.d.ts +19 -0
- package/dist/commands/daemon/update.js +48 -0
- package/dist/commands/enterprise/budgets/create.d.ts +11 -0
- package/dist/commands/enterprise/budgets/create.js +27 -0
- package/dist/commands/enterprise/budgets/evaluate.d.ts +17 -0
- package/dist/commands/enterprise/budgets/evaluate.js +32 -0
- package/dist/commands/enterprise/budgets/publish.d.ts +14 -0
- package/dist/commands/enterprise/budgets/publish.js +30 -0
- package/dist/commands/enterprise/contracts/activate.d.ts +14 -0
- package/dist/commands/enterprise/contracts/activate.js +30 -0
- package/dist/commands/enterprise/contracts/create.d.ts +14 -0
- package/dist/commands/enterprise/contracts/create.js +32 -0
- package/dist/commands/enterprise/contracts/issue.d.ts +18 -0
- package/dist/commands/enterprise/contracts/issue.js +34 -0
- package/dist/commands/enterprise/domains/begin.d.ts +20 -0
- package/dist/commands/enterprise/domains/begin.js +39 -0
- package/dist/commands/enterprise/domains/verify.d.ts +14 -0
- package/dist/commands/enterprise/domains/verify.js +32 -0
- package/dist/commands/enterprise/external-config/activate.d.ts +22 -0
- package/dist/commands/enterprise/external-config/activate.js +49 -0
- package/dist/commands/enterprise/external-config/set.d.ts +25 -0
- package/dist/commands/enterprise/external-config/set.js +123 -0
- package/dist/commands/enterprise/external-config/show.d.ts +12 -0
- package/dist/commands/enterprise/external-config/show.js +39 -0
- package/dist/commands/enterprise/external-config/suspend.d.ts +13 -0
- package/dist/commands/enterprise/external-config/suspend.js +41 -0
- package/dist/commands/enterprise/finance/close-snapshot.d.ts +11 -0
- package/dist/commands/enterprise/finance/close-snapshot.js +28 -0
- package/dist/commands/enterprise/finance/record-document.d.ts +18 -0
- package/dist/commands/enterprise/finance/record-document.js +35 -0
- package/dist/commands/enterprise/profile.d.ts +20 -0
- package/dist/commands/enterprise/profile.js +38 -0
- package/dist/commands/login.d.ts +13 -0
- package/dist/commands/login.js +77 -0
- package/dist/commands/machines/dedicated/index.js +3 -0
- package/dist/commands/machines/dedicated/service/apply.d.ts +23 -0
- package/dist/commands/machines/dedicated/service/apply.js +99 -0
- package/dist/commands/machines/dedicated/service/approve.d.ts +23 -0
- package/dist/commands/machines/dedicated/service/approve.js +52 -0
- package/dist/commands/machines/dedicated/service/create.d.ts +55 -0
- package/dist/commands/machines/dedicated/service/create.js +222 -0
- package/dist/commands/machines/dedicated/service/edit.d.ts +30 -0
- package/dist/commands/machines/dedicated/service/edit.js +146 -0
- package/dist/commands/machines/dedicated/service/exec.d.ts +26 -0
- package/dist/commands/machines/dedicated/service/exec.js +92 -0
- package/dist/commands/machines/dedicated/service/export.d.ts +29 -0
- package/dist/commands/machines/dedicated/service/export.js +106 -0
- package/dist/commands/machines/dedicated/service/index.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/index.js +49 -0
- package/dist/commands/machines/dedicated/service/logs.d.ts +33 -0
- package/dist/commands/machines/dedicated/service/logs.js +148 -0
- package/dist/commands/machines/dedicated/service/ls.d.ts +20 -0
- package/dist/commands/machines/dedicated/service/ls.js +80 -0
- package/dist/commands/machines/dedicated/service/restart.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/restart.js +29 -0
- package/dist/commands/machines/dedicated/service/rm.d.ts +20 -0
- package/dist/commands/machines/dedicated/service/rm.js +33 -0
- package/dist/commands/machines/dedicated/service/secret/index.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/secret/index.js +25 -0
- package/dist/commands/machines/dedicated/service/secret/rm.d.ts +22 -0
- package/dist/commands/machines/dedicated/service/secret/rm.js +54 -0
- package/dist/commands/machines/dedicated/service/secret/set.d.ts +22 -0
- package/dist/commands/machines/dedicated/service/secret/set.js +93 -0
- package/dist/commands/machines/dedicated/service/start.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/start.js +29 -0
- package/dist/commands/machines/dedicated/service/status.d.ts +21 -0
- package/dist/commands/machines/dedicated/service/status.js +85 -0
- package/dist/commands/machines/dedicated/service/stop.d.ts +20 -0
- package/dist/commands/machines/dedicated/service/stop.js +35 -0
- package/dist/commands/machines/dedicated/service/top.d.ts +22 -0
- package/dist/commands/machines/dedicated/service/top.js +120 -0
- package/dist/commands/machines/dedicated/sign-in-status.d.ts +22 -0
- package/dist/commands/machines/dedicated/sign-in-status.js +79 -0
- package/dist/commands/machines/dedicated/ssh-config.d.ts +28 -0
- package/dist/commands/machines/dedicated/ssh-config.js +66 -0
- package/dist/commands/machines/dedicated/ssh-proxy.d.ts +22 -0
- package/dist/commands/machines/dedicated/ssh-proxy.js +62 -0
- package/dist/commands/machines/dedicated/ssh.d.ts +29 -0
- package/dist/commands/machines/dedicated/ssh.js +121 -0
- package/dist/commands/native/allow-all.d.ts +14 -0
- package/dist/commands/native/allow-all.js +25 -0
- package/dist/commands/native/allow.d.ts +24 -0
- package/dist/commands/native/allow.js +45 -0
- package/dist/commands/native/deny.d.ts +24 -0
- package/dist/commands/native/deny.js +43 -0
- package/dist/commands/native/disable.d.ts +17 -0
- package/dist/commands/native/disable.js +28 -0
- package/dist/commands/native/enable.d.ts +12 -0
- package/dist/commands/native/enable.js +29 -0
- package/dist/commands/native/list-apps.d.ts +19 -0
- package/dist/commands/native/list-apps.js +30 -0
- package/dist/commands/native/restrict-to.d.ts +22 -0
- package/dist/commands/native/restrict-to.js +41 -0
- package/dist/commands/native/status.d.ts +19 -0
- package/dist/commands/native/status.js +33 -0
- package/dist/commands/native.d.ts +39 -0
- package/dist/commands/native.js +76 -0
- package/dist/commands/service/index.d.ts +14 -0
- package/dist/commands/service/index.js +31 -0
- package/dist/commands/service/logs.d.ts +18 -0
- package/dist/commands/service/logs.js +53 -0
- package/dist/commands/service/ls.d.ts +13 -0
- package/dist/commands/service/ls.js +48 -0
- package/dist/commands/service/propose.d.ts +34 -0
- package/dist/commands/service/propose.js +113 -0
- package/dist/commands/service/status.d.ts +17 -0
- package/dist/commands/service/status.js +56 -0
- package/dist/commands/spaces/auto-executor/runs.d.ts +13 -0
- package/dist/commands/spaces/auto-executor/runs.js +56 -0
- package/dist/commands/spaces/briefs/get.js +8 -0
- package/dist/commands/spaces/briefs/list.js +2 -0
- package/dist/commands/spaces/briefs/set.d.ts +3 -0
- package/dist/commands/spaces/briefs/set.js +78 -13
- package/dist/commands/spaces/expertise-suggestions.d.ts +12 -0
- package/dist/commands/spaces/expertise-suggestions.js +71 -0
- package/dist/commands/spaces/members/add.d.ts +1 -0
- package/dist/commands/spaces/members/add.js +11 -3
- package/dist/commands/spaces/members/list.js +11 -0
- package/dist/commands/store/governance/artifacts.d.ts +25 -0
- package/dist/commands/store/governance/artifacts.js +55 -0
- package/dist/commands/store/governance/assign.d.ts +16 -0
- package/dist/commands/store/governance/assign.js +54 -0
- package/dist/commands/store/governance/create-license.d.ts +18 -0
- package/dist/commands/store/governance/create-license.js +35 -0
- package/dist/commands/store/governance/install-plan.d.ts +25 -0
- package/dist/commands/store/governance/install-plan.js +56 -0
- package/dist/commands/store/governance/license-policy.d.ts +30 -0
- package/dist/commands/store/governance/license-policy.js +69 -0
- package/dist/commands/store/governance/policy.d.ts +25 -0
- package/dist/commands/store/governance/policy.js +65 -0
- package/dist/commands/store/governance/publish-release.d.ts +17 -0
- package/dist/commands/store/governance/publish-release.js +34 -0
- package/dist/commands/tasks/assign.d.ts +9 -0
- package/dist/commands/tasks/assign.js +108 -1
- package/dist/commands/tasks/deliverable/add.d.ts +15 -0
- package/dist/commands/tasks/deliverable/add.js +174 -0
- package/dist/commands/tasks/deliverable/archive.d.ts +35 -0
- package/dist/commands/tasks/deliverable/archive.js +205 -0
- package/dist/commands/tasks/labels/detach.js +3 -0
- package/dist/commands/tasks/labels/suggest.d.ts +24 -0
- package/dist/commands/tasks/labels/suggest.js +69 -0
- package/dist/commands/tasks/list.d.ts +16 -2
- package/dist/commands/tasks/list.js +100 -24
- package/dist/commands/tasks/show.d.ts +23 -0
- package/dist/commands/tasks/show.js +51 -1
- package/dist/commands/wiki/rm.d.ts +22 -1
- package/dist/commands/wiki/rm.js +52 -3
- package/dist/lib/agentic-stream.js +10 -2
- package/dist/lib/assignee-resolver.d.ts +22 -0
- package/dist/lib/assignee-resolver.js +26 -0
- package/dist/lib/balance.d.ts +6 -1
- package/dist/lib/balance.js +15 -0
- package/dist/lib/code-handover.d.ts +0 -10
- package/dist/lib/code-handover.js +20 -5
- package/dist/lib/commerce-command.d.ts +48 -0
- package/dist/lib/commerce-command.js +70 -0
- package/dist/lib/commerce.d.ts +93 -0
- package/dist/lib/commerce.js +129 -0
- package/dist/lib/commitment-product.js +1 -1
- package/dist/lib/commitments.d.ts +202 -29
- package/dist/lib/commitments.js +300 -33
- package/dist/lib/dedicated-lease-command.js +10 -0
- package/dist/lib/dedicated-machines.d.ts +37 -0
- package/dist/lib/dedicated-machines.js +47 -0
- package/dist/lib/dedicated-service-command.d.ts +60 -0
- package/dist/lib/dedicated-service-command.js +182 -0
- package/dist/lib/dedicated-service.d.ts +342 -0
- package/dist/lib/dedicated-service.js +741 -0
- package/dist/lib/dedicated-ssh.d.ts +136 -0
- package/dist/lib/dedicated-ssh.js +387 -0
- package/dist/lib/delegated-cli.js +51 -13
- package/dist/lib/enterprise-commerce.d.ts +67 -0
- package/dist/lib/enterprise-commerce.js +112 -0
- package/dist/lib/enterprise-external-configuration.d.ts +60 -0
- package/dist/lib/enterprise-external-configuration.js +58 -0
- package/dist/lib/first-party-harness.js +17 -3
- package/dist/lib/governed-store.d.ts +110 -0
- package/dist/lib/governed-store.js +79 -0
- package/dist/lib/guest-service-command.d.ts +16 -0
- package/dist/lib/guest-service-command.js +32 -0
- package/dist/lib/guest-service.d.ts +67 -0
- package/dist/lib/guest-service.js +112 -0
- package/dist/lib/prompt.d.ts +1 -0
- package/dist/lib/prompt.js +1 -0
- package/dist/lib/task-asset-upload.d.ts +20 -0
- package/dist/lib/task-asset-upload.js +30 -8
- package/dist/lib/task-extras.d.ts +23 -0
- package/dist/lib/task-extras.js +6 -0
- package/dist/lib/update-check.d.ts +80 -7
- package/dist/lib/update-check.js +365 -33
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.d.ts +9 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.js +10 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +9 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +8 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +6 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.d.ts +16 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.js +21 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +24 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.d.ts +9 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.js +10 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +9 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +8 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.d.ts +16 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.js +20 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +24 -2
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +5067 -4821
- package/oclif.manifest.json +34877 -28659
- package/package.json +43 -1
package/dist/lib/commitments.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.COMMITMENT_CLI_EVALUATORS = exports.COMMITMENT_CREATE_KEYS = exports.COMMITMENT_REMEDIATION_ACTIONS = exports.COMMITMENT_FEEDBACK_KINDS = exports.commitmentApi = exports.commitmentPackApi = exports.MAX_COMMITMENT_INTERVAL_MS = exports.MIN_COMMITMENT_INTERVAL_MS = exports.COMMITMENT_EXECUTION_ISOLATION_MODES = exports.COMMITMENT_AUTHORABLE_AUTONOMY_MODES = exports.COMMITMENT_AUTONOMY_MODES = exports.
|
|
3
|
+
exports.COMMITMENT_CLI_EVALUATORS = exports.COMMITMENT_CREATE_KEYS = exports.COMMITMENT_REMEDIATION_ACTIONS = exports.COMMITMENT_FEEDBACK_KINDS = exports.commitmentApi = exports.commitmentPackApi = exports.MAX_COMMITMENT_INTERVAL_MS = exports.MIN_COMMITMENT_INTERVAL_MS = exports.COMMITMENT_EXECUTION_ISOLATION_MODES = exports.COMMITMENT_AUTHORABLE_AUTONOMY_MODES = exports.COMMITMENT_AUTONOMY_MODES = exports.COMMITMENT_AUTHORABLE_CADENCE_MODES = exports.COMMITMENT_KIND_VALUES = exports.COMMITMENT_STATUSES = exports.COMMITMENT_CADENCE_MAX_TIMES = exports.COMMITMENT_CADENCE_TIME_PATTERN = exports.COMMITMENT_CADENCE_MODES = exports.COMMITMENT_TEMPLATE_IDS = exports.COMMITMENT_WATCHED_SOURCES = void 0;
|
|
4
4
|
exports.storedAutonomyModeForAuthoring = storedAutonomyModeForAuthoring;
|
|
5
5
|
exports.authoringAutonomyModeForStored = authoringAutonomyModeForStored;
|
|
6
6
|
exports.commitmentAutonomyLabel = commitmentAutonomyLabel;
|
|
@@ -12,6 +12,7 @@ exports.describeCommitmentConcurrency = describeCommitmentConcurrency;
|
|
|
12
12
|
exports.parseIntervalToMs = parseIntervalToMs;
|
|
13
13
|
exports.buildWatchedSources = buildWatchedSources;
|
|
14
14
|
exports.describeEvidenceHealth = describeEvidenceHealth;
|
|
15
|
+
exports.describeStalledHealth = describeStalledHealth;
|
|
15
16
|
exports.describeIntervalMs = describeIntervalMs;
|
|
16
17
|
exports.buildSuccessCriteria = buildSuccessCriteria;
|
|
17
18
|
exports.cadenceLabel = cadenceLabel;
|
|
@@ -25,10 +26,15 @@ exports.describeWakeDecision = describeWakeDecision;
|
|
|
25
26
|
exports.renderCheckList = renderCheckList;
|
|
26
27
|
exports.renderCommitmentLedger = renderCommitmentLedger;
|
|
27
28
|
exports.renderCommitmentTrace = renderCommitmentTrace;
|
|
29
|
+
exports.renderListPageHint = renderListPageHint;
|
|
28
30
|
exports.renderCommitmentObservations = renderCommitmentObservations;
|
|
29
31
|
exports.renderCommitmentHypotheses = renderCommitmentHypotheses;
|
|
30
32
|
exports.renderCommitmentLineage = renderCommitmentLineage;
|
|
31
33
|
exports.renderCommitmentMetrics = renderCommitmentMetrics;
|
|
34
|
+
exports.renderCommitmentCases = renderCommitmentCases;
|
|
35
|
+
exports.renderCommitmentCaseDetail = renderCommitmentCaseDetail;
|
|
36
|
+
exports.renderCommitmentRemediationProposals = renderCommitmentRemediationProposals;
|
|
37
|
+
exports.renderCommitmentRemediationProposal = renderCommitmentRemediationProposal;
|
|
32
38
|
/**
|
|
33
39
|
* commitments.ts — request-based client for the Commitments subsystem
|
|
34
40
|
* (`/api/commitments/*`).
|
|
@@ -55,6 +61,8 @@ Object.defineProperty(exports, "COMMITMENT_CADENCE_TIME_PATTERN", { enumerable:
|
|
|
55
61
|
Object.defineProperty(exports, "COMMITMENT_CADENCE_MAX_TIMES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_CADENCE_MAX_TIMES; } });
|
|
56
62
|
Object.defineProperty(exports, "COMMITMENT_AUTONOMY_MODES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_AUTONOMY_MODES; } });
|
|
57
63
|
Object.defineProperty(exports, "COMMITMENT_EXECUTION_ISOLATION_MODES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_EXECUTION_ISOLATION_MODES; } });
|
|
64
|
+
Object.defineProperty(exports, "COMMITMENT_STATUSES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_STATUSES; } });
|
|
65
|
+
Object.defineProperty(exports, "COMMITMENT_KIND_VALUES", { enumerable: true, get: function () { return data_provider_1.COMMITMENT_KIND_VALUES; } });
|
|
58
66
|
const commitment_product_1 = require("./commitment-product");
|
|
59
67
|
const instruction_input_1 = require("./instruction-input");
|
|
60
68
|
const format_1 = require("./format");
|
|
@@ -62,22 +70,6 @@ const triggers_1 = require("./triggers");
|
|
|
62
70
|
/** Derived from the installed compatibility vocabulary so the CLI remains
|
|
63
71
|
* safe even while data-provider and CLI packages roll out separately. */
|
|
64
72
|
exports.COMMITMENT_AUTHORABLE_CADENCE_MODES = data_provider_1.COMMITMENT_CADENCE_MODES.filter((mode) => mode !== 'sampled');
|
|
65
|
-
/**
|
|
66
|
-
* oclif's `options:` needs runtime arrays, but data-provider models these two as
|
|
67
|
-
* union TYPES only. The values live here — and both directions of drift are a
|
|
68
|
-
* COMPILE error: `satisfies` rejects an invalid or extra value, and the
|
|
69
|
-
* `_Exhaustive*` guards fail to resolve if a canonical value is missing.
|
|
70
|
-
*/
|
|
71
|
-
exports.COMMITMENT_STATUSES = [
|
|
72
|
-
'draft',
|
|
73
|
-
'active',
|
|
74
|
-
'paused',
|
|
75
|
-
'completed',
|
|
76
|
-
'cancelled',
|
|
77
|
-
'archived',
|
|
78
|
-
];
|
|
79
|
-
const _statusDriftGuard = true;
|
|
80
|
-
void _statusDriftGuard;
|
|
81
73
|
exports.COMMITMENT_AUTHORABLE_AUTONOMY_MODES = ['monitor', 'prepare', 'execute'];
|
|
82
74
|
function storedAutonomyModeForAuthoring(mode) {
|
|
83
75
|
if (mode === 'monitor')
|
|
@@ -139,6 +131,11 @@ exports.commitmentApi = {
|
|
|
139
131
|
* anything failing.
|
|
140
132
|
*/
|
|
141
133
|
list: (query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)('/api/commitments', query)),
|
|
134
|
+
/**
|
|
135
|
+
* Fleet-level liveness sweep health (OSK-10958): when the reconciler last
|
|
136
|
+
* swept, how stale that is, and the tally it last persisted. Aggregate only.
|
|
137
|
+
*/
|
|
138
|
+
livenessSweep: () => data_provider_1.request.get('/api/commitments/liveness/sweep'),
|
|
142
139
|
manifest: (id) => data_provider_1.request.get(`${base(id)}/manifest`),
|
|
143
140
|
import: (body) => data_provider_1.request.post('/api/commitments/import', body),
|
|
144
141
|
fork: (id, body) => data_provider_1.request.post(`${base(id)}/fork`, body),
|
|
@@ -154,8 +151,8 @@ exports.commitmentApi = {
|
|
|
154
151
|
detachWorkLink: (id, linkId) => data_provider_1.request.delete(`${base(id)}/links/${encodeURIComponent(linkId)}`),
|
|
155
152
|
plan: (body) => data_provider_1.request.post('/api/commitments/plan', body),
|
|
156
153
|
checkNow: (id) => data_provider_1.request.post(`${base(id)}/check-now`, {}),
|
|
157
|
-
checks: (id,
|
|
158
|
-
actionHistory: (id,
|
|
154
|
+
checks: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/checks`, query)),
|
|
155
|
+
actionHistory: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/action-history`, query)),
|
|
159
156
|
actionProposals: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/action-proposals`, query)),
|
|
160
157
|
/**
|
|
161
158
|
* Propose a prepared action for a check.
|
|
@@ -192,7 +189,7 @@ exports.commitmentApi = {
|
|
|
192
189
|
autonomy: (id, body) => data_provider_1.request.post(`${base(id)}/autonomy`, body),
|
|
193
190
|
mode: (id, body) => data_provider_1.request.post(`${base(id)}/mode`, body),
|
|
194
191
|
delivery: (id, body) => data_provider_1.request.post(`${base(id)}/delivery`, body),
|
|
195
|
-
receipts: (id,
|
|
192
|
+
receipts: (id, query = 1) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/receipts`, typeof query === 'number' ? { limit: query } : query)),
|
|
196
193
|
receiptQuarterlyMetrics: (id, year, quarter) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/receipt-metrics/quarterly`, { year, quarter })),
|
|
197
194
|
deliveryPatch: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/patch`),
|
|
198
195
|
deliveryBundle: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/bundle`),
|
|
@@ -228,12 +225,53 @@ exports.commitmentApi = {
|
|
|
228
225
|
* reference it stay resolvable. Refused for an active or system-managed
|
|
229
226
|
* commitment — see CommitmentControl.deleteCommitment.
|
|
230
227
|
*/
|
|
231
|
-
remove: (id, reason) => data_provider_1.request.delete((0, triggers_1.withQuery)(base(id),
|
|
228
|
+
remove: (id, reason, opts = {}) => data_provider_1.request.delete((0, triggers_1.withQuery)(base(id), {
|
|
229
|
+
...(reason ? { reason } : {}),
|
|
230
|
+
// Only sent when the caller actually decided. Omitting it is what makes
|
|
231
|
+
// the server ask rather than guess when there is open work.
|
|
232
|
+
...(opts.stopOpenWork === undefined ? {} : { stopOpenWork: String(opts.stopOpenWork) }),
|
|
233
|
+
})),
|
|
234
|
+
/** What a delete would leave behind. Read-only. */
|
|
235
|
+
deletionPreview: (id) => data_provider_1.request.get(`${base(id)}/deletion-preview`),
|
|
236
|
+
/** Un-delete. Returns the Commitment PAUSED, never active. */
|
|
237
|
+
restore: (id) => data_provider_1.request.post(`${base(id)}/restore`, {}),
|
|
232
238
|
trace: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/trace`, query)),
|
|
233
239
|
ledger: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/ledger`, query)),
|
|
234
240
|
wakeCapabilities: (id) => data_provider_1.request.get(`${base(id)}/wake-capabilities`),
|
|
235
|
-
dailyMetrics: (id,
|
|
241
|
+
dailyMetrics: (id, query = {}) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/daily-metrics`, query)),
|
|
236
242
|
cadenceDecisions: (id, limit) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/cadence-decisions`, { limit })),
|
|
243
|
+
/**
|
|
244
|
+
* What the NEXT check would decide, computed without taking it.
|
|
245
|
+
*
|
|
246
|
+
* Every other read on this object is retrospective. This one stops at the
|
|
247
|
+
* DecisionEnvelope → Arbiter boundary — no Check row, no budget debit, no
|
|
248
|
+
* delivery gate, no contract write — so it is the only way to answer "what is
|
|
249
|
+
* this commitment about to do" before it does it. Worth its own command for
|
|
250
|
+
* the same reason `trigger-status` is: when a commitment is about to nudge
|
|
251
|
+
* somebody and nobody can say why, the posture and its policy trail are the
|
|
252
|
+
* answer, and re-running a real check to find out changes the thing you are
|
|
253
|
+
* trying to observe.
|
|
254
|
+
*/
|
|
255
|
+
nextTick: (id) => data_provider_1.request.get(`${base(id)}/next-tick`),
|
|
256
|
+
/**
|
|
257
|
+
* The accounting SHADOW readout behind allowance accounting.
|
|
258
|
+
*
|
|
259
|
+
* WORKSPACE-scoped despite hanging off one commitment's id: it aggregates
|
|
260
|
+
* every closed daily metric in the workspace, because the question it answers
|
|
261
|
+
* is "does this workspace have enough closed evidence to activate" rather than
|
|
262
|
+
* "what has this commitment spent". `cost` is the per-commitment question.
|
|
263
|
+
*/
|
|
264
|
+
accountingReadout: (id) => data_provider_1.request.get(`${base(id)}/accounting-readout`),
|
|
265
|
+
/**
|
|
266
|
+
* Closed-period spend for ONE commitment over a UTC day window.
|
|
267
|
+
*
|
|
268
|
+
* `costStatus` is the load-bearing field, not the dollar figure: `partial` and
|
|
269
|
+
* `unavailable` mean some runs carried no cost attribution at all, so the
|
|
270
|
+
* number understates the spend and a caller that printed it bare would be
|
|
271
|
+
* quietly wrong. The server refuses a window that is not on UTC day
|
|
272
|
+
* boundaries, so the caller builds one rather than passing a wall-clock time.
|
|
273
|
+
*/
|
|
274
|
+
cost: (id, window) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/cost`, window)),
|
|
237
275
|
/**
|
|
238
276
|
* What this commitment's RUNS claim to have seen (agent-as-sensor).
|
|
239
277
|
*
|
|
@@ -565,6 +603,45 @@ function describeEvidenceHealth(health, criteriaCount) {
|
|
|
565
603
|
}
|
|
566
604
|
return `${state}${detail}`;
|
|
567
605
|
}
|
|
606
|
+
/**
|
|
607
|
+
* Why a commitment is `stalled`, in the reconciler's own words.
|
|
608
|
+
*
|
|
609
|
+
* These clauses are the CLI voicing of the `details` table in
|
|
610
|
+
* `CommitmentLivenessReconciler.alertCopy` — an operator who gets the alert
|
|
611
|
+
* ("<name> is stalled — its expected checks are no longer arriving") and then
|
|
612
|
+
* runs `commitments show` must read the same sentence, or the two surfaces look
|
|
613
|
+
* like two different problems.
|
|
614
|
+
*
|
|
615
|
+
* `contract_version_mismatch` has no entry there because it is not a diagnosis;
|
|
616
|
+
* the reconciler synthesises it when the running contract is fenced behind the
|
|
617
|
+
* authored one. It still reaches `state.liveness.diagnosisKind`, so it needs a
|
|
618
|
+
* clause here or the one case with an obvious fix prints bare.
|
|
619
|
+
*/
|
|
620
|
+
const STALLED_DIAGNOSES = {
|
|
621
|
+
scheduler_stalled: 'its expected checks are no longer arriving',
|
|
622
|
+
work_failing: 'every recent run reached the agent and failed while doing the work',
|
|
623
|
+
observation_unreadable: 'the latest check could not read every configured source',
|
|
624
|
+
execution_budget_exhausted: 'recent planned work was skipped — the execution budget is exhausted',
|
|
625
|
+
no_advancement: 'no server-recorded advancement exists inside the declared window',
|
|
626
|
+
contract_version_mismatch: 'the running contract is older than the authored one; its triggers have not resynced',
|
|
627
|
+
};
|
|
628
|
+
/**
|
|
629
|
+
* `stalled` is a verdict, not a reason. Printed bare it reads like `unknown`
|
|
630
|
+
* with a harsher word, and the operator's next move is to go and read run
|
|
631
|
+
* history to find what the reconciler had already decided. Returns undefined
|
|
632
|
+
* for every other health value, including `unknown` — "nobody has judged" has
|
|
633
|
+
* no diagnosis to name.
|
|
634
|
+
*/
|
|
635
|
+
function describeStalledHealth(commitment) {
|
|
636
|
+
if (commitment.state?.health !== 'stalled')
|
|
637
|
+
return undefined;
|
|
638
|
+
const liveness = (commitment.state?.liveness || {});
|
|
639
|
+
const kind = typeof liveness.diagnosisKind === 'string' ? liveness.diagnosisKind : undefined;
|
|
640
|
+
const clause = (kind && STALLED_DIAGNOSES[kind]) ||
|
|
641
|
+
'this loop has stopped producing; the reconciler did not record which check failed';
|
|
642
|
+
const since = typeof liveness.unhealthySinceAt === 'string' ? ` (since ${liveness.unhealthySinceAt})` : '';
|
|
643
|
+
return `${clause}${since}`;
|
|
644
|
+
}
|
|
568
645
|
/** Render an interval back as a compact human string. */
|
|
569
646
|
function describeIntervalMs(ms) {
|
|
570
647
|
if (!ms || !Number.isFinite(ms))
|
|
@@ -801,8 +878,6 @@ latestCheck) {
|
|
|
801
878
|
if (commitment.target?.deadlineAt)
|
|
802
879
|
log(`Deadline: ${commitment.target.deadlineAt}`);
|
|
803
880
|
log(`Cadence: ${cadenceLabel(commitment)}`);
|
|
804
|
-
if (commitment.cadence?.nextCheckAt)
|
|
805
|
-
log(`Next check:${` ${commitment.cadence.nextCheckAt}`}`);
|
|
806
881
|
log(`Mode: ${describeAutonomyLine(commitment, latestCheck)}`);
|
|
807
882
|
log(`Delivery: ${(0, commitment_product_1.deliveryLabel)(commitment.delivery?.mode)}${commitment.delivery?.repo ? ` · ${commitment.delivery.repo}` : ''}${commitment.delivery?.baseBranch ? ` → ${commitment.delivery.baseBranch}` : ''}`);
|
|
808
883
|
log(`Concurrency: ${describeCommitmentConcurrency(commitment)}`);
|
|
@@ -810,9 +885,13 @@ latestCheck) {
|
|
|
810
885
|
const evidenceHealth = latestCheck?.inputs?.evidenceHealth;
|
|
811
886
|
const evidenceLine = describeEvidenceHealth(evidenceHealth, criteria.length);
|
|
812
887
|
const health = commitment.state?.health ?? 'unknown';
|
|
813
|
-
const
|
|
888
|
+
const unevidenceableExplanation = health === 'unknown' && evidenceHealth?.state === 'unevidenceable_criteria'
|
|
814
889
|
? ' — evidence cannot establish a positive health verdict as configured'
|
|
815
890
|
: '';
|
|
891
|
+
// The two explanations are mutually exclusive by construction: one only fires
|
|
892
|
+
// on `unknown`, the other only on `stalled`.
|
|
893
|
+
const stalledExplanation = describeStalledHealth(commitment);
|
|
894
|
+
const healthExplanation = unevidenceableExplanation || (stalledExplanation ? ` — ${stalledExplanation}` : '');
|
|
816
895
|
log(`Health: ${health}${healthExplanation}`);
|
|
817
896
|
if (commitment.state?.lastCheckedAt)
|
|
818
897
|
log(`Checked: ${commitment.state.lastCheckedAt}`);
|
|
@@ -850,6 +929,15 @@ latestCheck) {
|
|
|
850
929
|
.map((s) => s.source);
|
|
851
930
|
if (sources.length)
|
|
852
931
|
log(`Watching: ${sources.join(', ')}`);
|
|
932
|
+
// The executor-rebind audit trail was recorded but never rendered — after a
|
|
933
|
+
// handover, `show` still read as if the original agent had always run it
|
|
934
|
+
// (OSK-10963).
|
|
935
|
+
const handovers = commitment.executorHandovers || [];
|
|
936
|
+
if (handovers.length) {
|
|
937
|
+
const latest = handovers[handovers.length - 1];
|
|
938
|
+
const from = latest.fromAgentId ? `${latest.fromAgentId} → ` : '';
|
|
939
|
+
log(`Handovers: ${handovers.length} (last: ${from}${latest.toAgentId} at ${latest.at instanceof Date ? latest.at.toISOString() : text(latest.at)})`);
|
|
940
|
+
}
|
|
853
941
|
// Whether the criteria below can be EVIDENCED at all.
|
|
854
942
|
//
|
|
855
943
|
// Without this an author reads `Health: at_risk` beside five criteria and has
|
|
@@ -1015,7 +1103,9 @@ function renderCommitmentLedger(ledger, log) {
|
|
|
1015
1103
|
renderRows(checks.map((item) => {
|
|
1016
1104
|
const decision = record(item.decision);
|
|
1017
1105
|
return {
|
|
1018
|
-
|
|
1106
|
+
// `startedAt` is the reservation instant — it can precede queuedAt.
|
|
1107
|
+
// `claimedAt` is when a worker actually began the check (OSK-11441).
|
|
1108
|
+
started: text(firstValue(item, ['claimedAt', 'startedAt', 'createdAt'])),
|
|
1019
1109
|
status: text(item.status),
|
|
1020
1110
|
posture: text(decision?.posture),
|
|
1021
1111
|
loops: count(item.openLoops),
|
|
@@ -1051,6 +1141,23 @@ function renderCommitmentLedger(ledger, log) {
|
|
|
1051
1141
|
if (wakeState) {
|
|
1052
1142
|
log(`Wake state: ${wakeState.dirty === true ? 'pending' : 'clean'} (${text(wakeState.processedRev, '0')}/${text(wakeState.wakeRev, '0')} revisions processed)`);
|
|
1053
1143
|
}
|
|
1144
|
+
const auditTrail = records(ledger.auditTrail);
|
|
1145
|
+
if (auditTrail.length) {
|
|
1146
|
+
log('Audit trail:');
|
|
1147
|
+
renderRows(auditTrail.map((item) => ({
|
|
1148
|
+
at: text(item.occurredAt),
|
|
1149
|
+
change: text(item.changeType),
|
|
1150
|
+
actor: text(firstValue(item, ['actorAgentId', 'actorUserId'])),
|
|
1151
|
+
status: `${text(item.previousStatus, '-')}→${text(item.nextStatus, '-')}`,
|
|
1152
|
+
reason: text(item.reason, ''),
|
|
1153
|
+
})), [
|
|
1154
|
+
{ key: 'at', header: 'AT', maxWidth: 24 },
|
|
1155
|
+
{ key: 'change', header: 'CHANGE', maxWidth: 28 },
|
|
1156
|
+
{ key: 'actor', header: 'ACTOR', maxWidth: 24 },
|
|
1157
|
+
{ key: 'status', header: 'STATUS' },
|
|
1158
|
+
{ key: 'reason', header: 'REASON', maxWidth: 40 },
|
|
1159
|
+
], 'No audit events recorded.', log);
|
|
1160
|
+
}
|
|
1054
1161
|
}
|
|
1055
1162
|
/** Human view for the ordered commitment trace. */
|
|
1056
1163
|
function renderCommitmentTrace(trace, log) {
|
|
@@ -1070,6 +1177,15 @@ function renderCommitmentTrace(trace, log) {
|
|
|
1070
1177
|
log(`More events are available; continue with --cursor ${text(trace.next_cursor)}.`);
|
|
1071
1178
|
}
|
|
1072
1179
|
}
|
|
1180
|
+
/**
|
|
1181
|
+
* Print the continuation hint for a paged `object:'list'` response — the line
|
|
1182
|
+
* that makes history beyond the newest page reachable instead of invisible.
|
|
1183
|
+
*/
|
|
1184
|
+
function renderListPageHint(page, log) {
|
|
1185
|
+
if (page?.has_more === true && page.next_cursor) {
|
|
1186
|
+
log(`More rows are available; continue with --cursor ${text(page.next_cursor)}.`);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1073
1189
|
/** Human view for run-reported observations. */
|
|
1074
1190
|
/**
|
|
1075
1191
|
* Yes/no for a server-owned boolean verdict.
|
|
@@ -1085,7 +1201,7 @@ function yesNo(value) {
|
|
|
1085
1201
|
return 'no';
|
|
1086
1202
|
return '-';
|
|
1087
1203
|
}
|
|
1088
|
-
function renderCommitmentObservations(response, log) {
|
|
1204
|
+
function renderCommitmentObservations(response, log, options = {}) {
|
|
1089
1205
|
const data = records(response.data);
|
|
1090
1206
|
renderRows(data.map((item) => ({
|
|
1091
1207
|
at: text(firstValue(item, ['observedAt', 'createdAt', 'updatedAt'])),
|
|
@@ -1108,10 +1224,10 @@ function renderCommitmentObservations(response, log) {
|
|
|
1108
1224
|
{ key: 'declared', header: 'DECLARED', maxWidth: 9 },
|
|
1109
1225
|
{ key: 'access', header: 'ACCESS', maxWidth: 13 },
|
|
1110
1226
|
{ key: 'confidence', header: 'CONF', maxWidth: 6 },
|
|
1111
|
-
], 'No observations recorded.', log);
|
|
1227
|
+
], options.emptyMessage || 'No observations recorded.', log);
|
|
1112
1228
|
}
|
|
1113
1229
|
/** Human view for causal hypotheses. */
|
|
1114
|
-
function renderCommitmentHypotheses(response, log) {
|
|
1230
|
+
function renderCommitmentHypotheses(response, log, options = {}) {
|
|
1115
1231
|
const data = records(response.data);
|
|
1116
1232
|
renderRows(data.map((item) => ({
|
|
1117
1233
|
// `proposedAt` is the domain's own "when was this recorded". Rendering
|
|
@@ -1124,19 +1240,38 @@ function renderCommitmentHypotheses(response, log) {
|
|
|
1124
1240
|
// `observation_key` means the SERVER can settle this from a declared
|
|
1125
1241
|
// observation cursor with no model call; `agent_check` means only a run
|
|
1126
1242
|
// can. That is the whole point of the falsifiability constraint, so it
|
|
1127
|
-
// belongs on the list
|
|
1243
|
+
// belongs on the list — and for a key-bound falsifier the column names
|
|
1244
|
+
// WHICH key settles it, because `observation_key` alone hides the
|
|
1245
|
+
// difference between a real check and a degraded self-certification
|
|
1246
|
+
// (OSK-10954). (A hypothesis carries no `confidence` — that is an
|
|
1128
1247
|
// observation concept — so the column that read it was always empty.)
|
|
1129
|
-
falsifier:
|
|
1248
|
+
falsifier: describeFalsifier(item.falsifier),
|
|
1130
1249
|
authority: text(item.authority),
|
|
1131
1250
|
episode: (0, format_1.formatCell)(item.episode),
|
|
1132
1251
|
})), [
|
|
1133
1252
|
{ key: 'at', header: 'RECORDED', maxWidth: 24 },
|
|
1134
1253
|
{ key: 'status', header: 'STATUS', maxWidth: 12 },
|
|
1135
1254
|
{ key: 'claim', header: 'CLAIM', maxWidth: 62 },
|
|
1136
|
-
{ key: 'falsifier', header: 'FALSIFIER', maxWidth:
|
|
1255
|
+
{ key: 'falsifier', header: 'FALSIFIER', maxWidth: 26 },
|
|
1137
1256
|
{ key: 'authority', header: 'AUTHORITY', maxWidth: 18 },
|
|
1138
1257
|
{ key: 'episode', header: 'EP', maxWidth: 4 },
|
|
1139
|
-
], 'No hypotheses recorded.', log);
|
|
1258
|
+
], options.emptyMessage || 'No hypotheses recorded.', log);
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* One falsifier rendered as what settles the claim, not just its kind.
|
|
1262
|
+
*
|
|
1263
|
+
* `observation_key` names the declared key the server settles from;
|
|
1264
|
+
* `agent_check` stays the literal kind — the claim can only be settled by the
|
|
1265
|
+
* same agent that proposed it, and the column should keep saying so.
|
|
1266
|
+
*/
|
|
1267
|
+
function describeFalsifier(falsifier) {
|
|
1268
|
+
const f = record(falsifier);
|
|
1269
|
+
if (!f)
|
|
1270
|
+
return '-';
|
|
1271
|
+
if (f.kind === 'observation_key' && typeof f.observationKey === 'string') {
|
|
1272
|
+
return `key:${f.observationKey}`;
|
|
1273
|
+
}
|
|
1274
|
+
return text(f.kind);
|
|
1140
1275
|
}
|
|
1141
1276
|
function renderLineageRows(label, value, log) {
|
|
1142
1277
|
const rows = records(value);
|
|
@@ -1146,10 +1281,14 @@ function renderLineageRows(label, value, log) {
|
|
|
1146
1281
|
renderRows(rows.map((item) => ({
|
|
1147
1282
|
id: text(item.id),
|
|
1148
1283
|
status: text(item.status),
|
|
1284
|
+
// Goal rows carry `linkedVia` — which link store(s) own the edge — so
|
|
1285
|
+
// `links list` and this view can be reconciled by eye (OSK-10960).
|
|
1286
|
+
via: Array.isArray(item.linkedVia) ? item.linkedVia.join('+') : '',
|
|
1149
1287
|
summary: text(firstValue(item, ['title', 'summary', 'kind', 'reason']), ''),
|
|
1150
1288
|
})), [
|
|
1151
1289
|
{ key: 'id', header: 'ID', verbatim: true },
|
|
1152
1290
|
{ key: 'status', header: 'STATUS', maxWidth: 16 },
|
|
1291
|
+
{ key: 'via', header: 'VIA', maxWidth: 24 },
|
|
1153
1292
|
{ key: 'summary', header: 'SUMMARY', maxWidth: 72 },
|
|
1154
1293
|
], `No ${label.toLowerCase()} recorded.`, log);
|
|
1155
1294
|
}
|
|
@@ -1194,3 +1333,131 @@ function renderCommitmentMetrics(response, log) {
|
|
|
1194
1333
|
{ key: 'sources', header: 'SOURCES', maxWidth: 48 },
|
|
1195
1334
|
], 'No daily metrics recorded.', log);
|
|
1196
1335
|
}
|
|
1336
|
+
/** Human view for the case list — one row per durable problem case. */
|
|
1337
|
+
function renderCommitmentCases(response, log) {
|
|
1338
|
+
const data = records(response.data);
|
|
1339
|
+
renderRows(data.map((item) => ({
|
|
1340
|
+
id: text(item.id),
|
|
1341
|
+
status: text(item.status),
|
|
1342
|
+
severity: text(item.severity),
|
|
1343
|
+
subject: text(firstValue(item, ['subjectKey', 'kind']), ''),
|
|
1344
|
+
facts: text(item.factCount, '0'),
|
|
1345
|
+
hypotheses: text(item.hypothesisCount, '0'),
|
|
1346
|
+
receipts: text(item.receiptCount, '0'),
|
|
1347
|
+
last: text(firstValue(item, ['lastObservedAt', 'updatedAt'])),
|
|
1348
|
+
})), [
|
|
1349
|
+
{ key: 'id', header: 'ID', verbatim: true },
|
|
1350
|
+
{ key: 'status', header: 'STATUS', maxWidth: 12 },
|
|
1351
|
+
{ key: 'severity', header: 'SEV', maxWidth: 8 },
|
|
1352
|
+
{ key: 'subject', header: 'SUBJECT', maxWidth: 44 },
|
|
1353
|
+
{ key: 'facts', header: 'FACTS', maxWidth: 6 },
|
|
1354
|
+
{ key: 'hypotheses', header: 'HYPO', maxWidth: 6 },
|
|
1355
|
+
{ key: 'receipts', header: 'RCPTS', maxWidth: 6 },
|
|
1356
|
+
{ key: 'last', header: 'LAST OBSERVED', maxWidth: 24 },
|
|
1357
|
+
], 'No cases recorded.', log);
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Human view for one case — a bounded digest, never the raw document.
|
|
1361
|
+
*
|
|
1362
|
+
* A case accumulates factRefs, hypothesisRefs, actionRefs, and receipts with
|
|
1363
|
+
* no per-case bound, and the route projects the whole thing again as `trace`.
|
|
1364
|
+
* Printing the payload verbatim produced a 93k-line dump for a single case
|
|
1365
|
+
* (OSK-10952); the summary counts and the most recent entries answer "what is
|
|
1366
|
+
* this case and what happened last" in one screen, and `--json` stays the
|
|
1367
|
+
* opt-in for the full document.
|
|
1368
|
+
*/
|
|
1369
|
+
function renderCommitmentCaseDetail(response, log, options = {}) {
|
|
1370
|
+
const data = record(response.data);
|
|
1371
|
+
if (!data) {
|
|
1372
|
+
log('Case not found.');
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
const maxEntries = options.maxEntries ?? 10;
|
|
1376
|
+
log(`Case: ${text(data.id)} (${text(data.status)})`);
|
|
1377
|
+
log(`Subject: ${text(data.subjectKey, '-')} · kind ${text(data.kind, '-')}`);
|
|
1378
|
+
log(`Severity: ${text(data.severity, '-')} · revision ${text(data.caseRevision, '-')} · epoch ${text(data.activeEpoch, '-')}`);
|
|
1379
|
+
log(`Detected: ${text(data.firstDetectedAt, '-')} · last observed ${text(data.lastObservedAt, '-')}`);
|
|
1380
|
+
log(`Contents: ${text(data.factCount, '0')} facts · ${text(data.hypothesisCount, '0')} hypotheses · ${text(data.actionCount, '0')} actions · ${text(data.receiptCount, '0')} receipts`);
|
|
1381
|
+
const verification = record(data.verification);
|
|
1382
|
+
if (verification) {
|
|
1383
|
+
log(`Verification: ${text(verification.verdict, '-')}${verification.reason ? ` — ${text(verification.reason)}` : ''}`);
|
|
1384
|
+
}
|
|
1385
|
+
const resolution = record(data.resolution);
|
|
1386
|
+
if (resolution)
|
|
1387
|
+
log(`Resolution: ${text(resolution.kind, '-')} at ${text(resolution.at, '-')}`);
|
|
1388
|
+
const facts = records(data.factRefs);
|
|
1389
|
+
if (facts.length) {
|
|
1390
|
+
const shown = facts.slice(-maxEntries);
|
|
1391
|
+
log('');
|
|
1392
|
+
log(`Latest facts (${shown.length} of ${facts.length}):`);
|
|
1393
|
+
for (const fact of shown) {
|
|
1394
|
+
const label = text(firstValue(fact, ['kind', 'adapter']), 'fact');
|
|
1395
|
+
log(` - ${text(firstValue(fact, ['occurredAt', 'observedAt']))} ${label} ${text(fact.subjectKey, '')} ${text(fact.trust, '')}`.trimEnd());
|
|
1396
|
+
}
|
|
1397
|
+
if (facts.length > shown.length)
|
|
1398
|
+
log(` … ${facts.length - shown.length} earlier facts — use --json for the full document`);
|
|
1399
|
+
}
|
|
1400
|
+
const receipts = records(data.receipts);
|
|
1401
|
+
if (receipts.length) {
|
|
1402
|
+
const shown = receipts.slice(-maxEntries);
|
|
1403
|
+
log('');
|
|
1404
|
+
log(`Latest receipts (${shown.length} of ${receipts.length}):`);
|
|
1405
|
+
for (const receipt of shown) {
|
|
1406
|
+
const transition = receipt.from || receipt.to
|
|
1407
|
+
? ` ${text(receipt.from, 'new')} → ${text(receipt.to, '-')}`
|
|
1408
|
+
: '';
|
|
1409
|
+
log(` - ${text(receipt.at)} ${text(receipt.kind, 'receipt')}${transition}`);
|
|
1410
|
+
}
|
|
1411
|
+
if (receipts.length > shown.length)
|
|
1412
|
+
log(` … ${receipts.length - shown.length} earlier receipts — use --json for the full document`);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
/** Human view for the remediation-proposal list. */
|
|
1416
|
+
function renderCommitmentRemediationProposals(response, log) {
|
|
1417
|
+
const advisory = record(response.executionAdvisory);
|
|
1418
|
+
if (advisory)
|
|
1419
|
+
log(`Advisory: ${text(advisory.code, '-')} — ${text(advisory.message, '')}`);
|
|
1420
|
+
const data = records(response.data);
|
|
1421
|
+
renderRows(data.map((item) => ({
|
|
1422
|
+
id: text(item.id),
|
|
1423
|
+
status: text(item.status),
|
|
1424
|
+
case: text(item.caseId),
|
|
1425
|
+
rev: text(item.caseRevision),
|
|
1426
|
+
action: text(item.actionKind),
|
|
1427
|
+
risk: text(item.riskLevel),
|
|
1428
|
+
expires: text(item.expiresAt),
|
|
1429
|
+
})), [
|
|
1430
|
+
{ key: 'id', header: 'ID', verbatim: true },
|
|
1431
|
+
{ key: 'status', header: 'STATUS', maxWidth: 12 },
|
|
1432
|
+
{ key: 'case', header: 'CASE', maxWidth: 30 },
|
|
1433
|
+
{ key: 'rev', header: 'REV', maxWidth: 4 },
|
|
1434
|
+
{ key: 'action', header: 'ACTION', maxWidth: 22 },
|
|
1435
|
+
{ key: 'risk', header: 'RISK', maxWidth: 8 },
|
|
1436
|
+
{ key: 'expires', header: 'EXPIRES', maxWidth: 24 },
|
|
1437
|
+
], 'No remediation proposals recorded.', log);
|
|
1438
|
+
}
|
|
1439
|
+
/** Human view for one frozen remediation proposal. */
|
|
1440
|
+
function renderCommitmentRemediationProposal(response, log) {
|
|
1441
|
+
const proposal = record(response.proposal) || record(response.data) || response;
|
|
1442
|
+
log(`Proposal: ${text(proposal.id)} (${text(proposal.status)})`);
|
|
1443
|
+
log(`Case: ${text(proposal.caseId, '-')} · revision ${text(proposal.caseRevision, '-')}`);
|
|
1444
|
+
log(`Action: ${text(proposal.actionKind, '-')} · risk ${text(proposal.riskLevel, '-')}`);
|
|
1445
|
+
const action = record(proposal.actionSnapshot) || record(proposal.action);
|
|
1446
|
+
if (action?.title)
|
|
1447
|
+
log(`Title: ${text(action.title)}`);
|
|
1448
|
+
if (proposal.expiresAt)
|
|
1449
|
+
log(`Expires: ${text(proposal.expiresAt)}`);
|
|
1450
|
+
const advisory = record(response.executionAdvisory);
|
|
1451
|
+
if (advisory)
|
|
1452
|
+
log(`Advisory: ${text(advisory.code, '-')} — ${text(advisory.message, '')}`);
|
|
1453
|
+
const lifecycle = records(proposal.lifecycle);
|
|
1454
|
+
if (lifecycle.length) {
|
|
1455
|
+
log('Lifecycle:');
|
|
1456
|
+
for (const entry of lifecycle.slice(-10)) {
|
|
1457
|
+
const what = text(entry.status ?? entry.event ?? entry.kind, '-');
|
|
1458
|
+
const reason = entry.reason ? ` — ${text(entry.reason)}` : '';
|
|
1459
|
+
log(` - ${text(entry.at)} ${what}${reason} ${text(entry.actorUserId ?? entry.by, '')}`.trimEnd());
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
log('Full detail: re-run with --json');
|
|
1463
|
+
}
|
|
@@ -210,6 +210,16 @@ class DedicatedLeaseCommand extends base_command_1.BaseCommand {
|
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
212
|
this.log(`Dedicated Runtime ${id || 'unknown'} ${(0, dedicated_machines_1.dedicatedLeaseState)(lease)}.`);
|
|
213
|
+
// Whether the machine paused its work and saved the workspace before this
|
|
214
|
+
// ran. Printed for every settled outcome, in the same register as the line
|
|
215
|
+
// above: a clean checkpoint and one the operation gave up waiting for are
|
|
216
|
+
// both policy-conforming, and printing only the second would make the
|
|
217
|
+
// line's presence the alarm — and teach a reader that silence means a
|
|
218
|
+
// checkpoint was taken. `requested` is the operation still asking, which is
|
|
219
|
+
// what a call without --wait sees, and it has nothing to report yet.
|
|
220
|
+
const checkpoint = (0, dedicated_machines_1.describeDedicatedCheckpoint)(lease);
|
|
221
|
+
if (checkpoint && !checkpoint.pending)
|
|
222
|
+
this.log(checkpoint.sentence);
|
|
213
223
|
if (!flags.wait && goal && id) {
|
|
214
224
|
this.log(`The operation continues in the background. Watch it with \`${this.config.bin} machines dedicated show ${id}\`, or pass --wait.`);
|
|
215
225
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type MachineCheckpointDescription } from '@skrr-ai/data-provider';
|
|
2
|
+
import type { DedicatedRuntimeSignInStatus } from '@skrr-ai/data-provider';
|
|
1
3
|
import type { Harness, HarnessLease } from './harnesses';
|
|
2
4
|
export type DedicatedLeaseAction = 'start' | 'stop' | 'restart' | 'update-image' | 'snapshot' | 'health-check';
|
|
3
5
|
export declare const DEDICATED_LEASE_ACTIONS: DedicatedLeaseAction[];
|
|
@@ -84,7 +86,23 @@ export interface DedicatedLeaseOperation {
|
|
|
84
86
|
status?: 'in_progress' | 'succeeded' | 'failed' | 'cancelled';
|
|
85
87
|
startedAt?: string | null;
|
|
86
88
|
completedAt?: string | null;
|
|
89
|
+
/**
|
|
90
|
+
* Whether the machine paused its work and saved the workspace for THIS
|
|
91
|
+
* operation. Null for an action that never asks (`start`, `grow`, a create)
|
|
92
|
+
* and from a server that predates the field — which is why the renderer says
|
|
93
|
+
* nothing rather than guessing a clean checkpoint. The vocabulary is
|
|
94
|
+
* `@skrr-ai/data-provider`'s (`MachineCheckpointOutcome`); it is typed as a
|
|
95
|
+
* plain string here so a value a newer server ships still reaches the
|
|
96
|
+
* fallback copy instead of failing to parse.
|
|
97
|
+
*/
|
|
98
|
+
checkpoint?: string | null;
|
|
87
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* What an operation's guest checkpoint says, or null when the lease records
|
|
102
|
+
* none. One line, because the copy — and the judgement that this is a plain
|
|
103
|
+
* fact and not a warning — lives once in `@skrr-ai/data-provider`.
|
|
104
|
+
*/
|
|
105
|
+
export declare function describeDedicatedCheckpoint(lease: DedicatedLease | undefined | null): MachineCheckpointDescription | null;
|
|
88
106
|
/**
|
|
89
107
|
* A Dedicated Runtime's root image, as the server judges it (D11). The platform
|
|
90
108
|
* owns the image: a machine on an older one moves onto the current image at its
|
|
@@ -339,6 +357,25 @@ export declare const DEDICATED_EXEC_DEFAULT_TIMEOUT_MS: number;
|
|
|
339
357
|
* command twice is two intents even when the text is identical.
|
|
340
358
|
*/
|
|
341
359
|
export declare function execDedicatedRuntime(leaseId: string, input: DedicatedRuntimeExecInput, scope?: DedicatedRuntimeScope): Promise<DedicatedRuntimeExecResult>;
|
|
360
|
+
export interface DedicatedRuntimeSignInStatusResponse {
|
|
361
|
+
statuses: DedicatedRuntimeSignInStatus[];
|
|
362
|
+
/** When the machine was asked, not when this row was cached. */
|
|
363
|
+
checkedAt: string;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* `GET /api/machines/dedicated/:leaseId/sign-in-status` — is this machine
|
|
367
|
+
* signed in to gh, Claude Code and Codex?
|
|
368
|
+
*
|
|
369
|
+
* Its own endpoint rather than a caller of `exec`, for the reason recorded
|
|
370
|
+
* beside the route: before it, the only way to find out was to START a sign-in
|
|
371
|
+
* against a credential that was already fine (OSK-10795). Read-only on the
|
|
372
|
+
* guest — three `… status` subcommands, no writes, no tokens read back.
|
|
373
|
+
*
|
|
374
|
+
* The vocabulary (`DedicatedRuntimeSignInStatus`, its states, the probe and its
|
|
375
|
+
* parser) is OWNED by `@skrr-ai/data-provider` and re-exported here. A second
|
|
376
|
+
* declaration is how a surface drifts from the server that answers it.
|
|
377
|
+
*/
|
|
378
|
+
export declare function getDedicatedRuntimeSignInStatus(leaseId: string, scope?: DedicatedRuntimeScope): Promise<DedicatedRuntimeSignInStatusResponse>;
|
|
342
379
|
export type DedicatedRuntimeExecutionState = 'running' | 'completed' | 'failed' | 'unknown';
|
|
343
380
|
/** A started command, as `GET .../executions/:id` reports it. */
|
|
344
381
|
export interface DedicatedRuntimeExecution {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DEDICATED_FILE_MAX_BYTES = exports.DEDICATED_FILE_CHUNK_BYTES = exports.DEDICATED_EXEC_DEFAULT_TIMEOUT_MS = exports.DEDICATED_EXEC_MAX_TIMEOUT_MS = exports.DEDICATED_MACHINE_PRODUCT = exports.DEDICATED_LEASE_ACTIONS = void 0;
|
|
4
|
+
exports.describeDedicatedCheckpoint = describeDedicatedCheckpoint;
|
|
4
5
|
exports.describeDedicatedImageStanding = describeDedicatedImageStanding;
|
|
5
6
|
exports.dedicatedRuntimeCreateInput = dedicatedRuntimeCreateInput;
|
|
6
7
|
exports.isDedicatedRepositoryRef = isDedicatedRepositoryRef;
|
|
@@ -16,6 +17,7 @@ exports.setDedicatedRuntimeSpendingLimit = setDedicatedRuntimeSpendingLimit;
|
|
|
16
17
|
exports.closeDedicatedRuntimeIncidentHold = closeDedicatedRuntimeIncidentHold;
|
|
17
18
|
exports.destroyDedicatedRuntime = destroyDedicatedRuntime;
|
|
18
19
|
exports.execDedicatedRuntime = execDedicatedRuntime;
|
|
20
|
+
exports.getDedicatedRuntimeSignInStatus = getDedicatedRuntimeSignInStatus;
|
|
19
21
|
exports.startDedicatedRuntimeExecution = startDedicatedRuntimeExecution;
|
|
20
22
|
exports.observeDedicatedRuntimeExecution = observeDedicatedRuntimeExecution;
|
|
21
23
|
exports.readDedicatedRuntimeFileChunk = readDedicatedRuntimeFileChunk;
|
|
@@ -46,6 +48,7 @@ exports.dedicatedRuntimeApiErrorCode = dedicatedRuntimeApiErrorCode;
|
|
|
46
48
|
exports.dedicatedRuntimeApiErrorDetails = dedicatedRuntimeApiErrorDetails;
|
|
47
49
|
exports.formatDedicatedRuntimeApiError = formatDedicatedRuntimeApiError;
|
|
48
50
|
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
51
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
49
52
|
const api_fetch_1 = require("./api-fetch");
|
|
50
53
|
const edge_error_page_1 = require("./edge-error-page");
|
|
51
54
|
const harnesses_1 = require("./harnesses");
|
|
@@ -58,6 +61,17 @@ exports.DEDICATED_LEASE_ACTIONS = [
|
|
|
58
61
|
'health-check',
|
|
59
62
|
];
|
|
60
63
|
exports.DEDICATED_MACHINE_PRODUCT = 'dedicated-machine';
|
|
64
|
+
/**
|
|
65
|
+
* What an operation's guest checkpoint says, or null when the lease records
|
|
66
|
+
* none. One line, because the copy — and the judgement that this is a plain
|
|
67
|
+
* fact and not a warning — lives once in `@skrr-ai/data-provider`.
|
|
68
|
+
*/
|
|
69
|
+
function describeDedicatedCheckpoint(lease) {
|
|
70
|
+
const operation = lease?.operation;
|
|
71
|
+
if (!operation)
|
|
72
|
+
return null;
|
|
73
|
+
return (0, data_provider_1.describeMachineCheckpointOutcome)(operation.checkpoint, { action: operation.action });
|
|
74
|
+
}
|
|
61
75
|
/** One line saying where a machine's image stands and what the owner can do. */
|
|
62
76
|
function describeDedicatedImageStanding(image, leaseId) {
|
|
63
77
|
const last = image.lastUpdate;
|
|
@@ -304,6 +318,22 @@ async function execDedicatedRuntime(leaseId, input, scope = {}) {
|
|
|
304
318
|
},
|
|
305
319
|
});
|
|
306
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* `GET /api/machines/dedicated/:leaseId/sign-in-status` — is this machine
|
|
323
|
+
* signed in to gh, Claude Code and Codex?
|
|
324
|
+
*
|
|
325
|
+
* Its own endpoint rather than a caller of `exec`, for the reason recorded
|
|
326
|
+
* beside the route: before it, the only way to find out was to START a sign-in
|
|
327
|
+
* against a credential that was already fine (OSK-10795). Read-only on the
|
|
328
|
+
* guest — three `… status` subcommands, no writes, no tokens read back.
|
|
329
|
+
*
|
|
330
|
+
* The vocabulary (`DedicatedRuntimeSignInStatus`, its states, the probe and its
|
|
331
|
+
* parser) is OWNED by `@skrr-ai/data-provider` and re-exported here. A second
|
|
332
|
+
* declaration is how a surface drifts from the server that answers it.
|
|
333
|
+
*/
|
|
334
|
+
async function getDedicatedRuntimeSignInStatus(leaseId, scope = {}) {
|
|
335
|
+
return (0, api_fetch_1.apiFetch)(withDedicatedScope(`/api/machines/dedicated/${encodeURIComponent(leaseId)}/sign-in-status`, scope));
|
|
336
|
+
}
|
|
307
337
|
/**
|
|
308
338
|
* Start one command. `requestId` is the idempotency key: the same id, for the
|
|
309
339
|
* same command on the same lease, returns the execution it already started —
|
|
@@ -586,6 +616,23 @@ function describeDedicatedLease(lease, harnesses = []) {
|
|
|
586
616
|
if (hold?.status === 'open') {
|
|
587
617
|
row('incident', `hold open since ${hold.heldAt || '?'} — the failed source volume is billed until \`incident-close\``);
|
|
588
618
|
}
|
|
619
|
+
// The lease's last (or current) operation, and — the reason this row exists —
|
|
620
|
+
// whether the machine saved its workspace for it. A stop that paused the work
|
|
621
|
+
// first and a stop that gave up waiting are different facts about whether the
|
|
622
|
+
// owner's last writes landed, and until OSK-11023 the server recorded the
|
|
623
|
+
// difference and no surface printed it. Dated, because on a machine that has
|
|
624
|
+
// since started again the sentence is about a past operation.
|
|
625
|
+
const operation = lease.operation;
|
|
626
|
+
if (operation?.action || operation?.status) {
|
|
627
|
+
const settledAt = operation.completedAt || operation.startedAt;
|
|
628
|
+
// The payload's own spelling, minus the underscore: this row is read by a
|
|
629
|
+
// person, and `in_progress` beside a plain English sentence reads as a code.
|
|
630
|
+
const status = operation.status === 'in_progress' ? 'in progress' : operation.status;
|
|
631
|
+
row('operation', [operation.action, status, settledAt].filter(Boolean).join(' '));
|
|
632
|
+
const checkpoint = describeDedicatedCheckpoint(lease);
|
|
633
|
+
if (checkpoint)
|
|
634
|
+
lines.push(` ${''.padEnd(13)}${checkpoint.sentence}`);
|
|
635
|
+
}
|
|
589
636
|
const engines = dedicatedLeaseHarnesses(lease, harnesses);
|
|
590
637
|
if (engines.length > 0) {
|
|
591
638
|
row('engines', engines.map((harness) => `${harness.provider} (${harness.status || 'unknown'})`).join(', '));
|