@skrr-ai/cli 0.1.22 → 0.1.24
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 +83 -73
- package/bin/dev-fallback.js +221 -0
- package/bin/run.js +96 -0
- package/dist/base-command.d.ts +15 -0
- package/dist/base-command.js +145 -11
- package/dist/commands/agents/attach-harness.d.ts +37 -0
- package/dist/commands/agents/attach-harness.js +102 -3
- package/dist/commands/agents/chat.d.ts +69 -1
- package/dist/commands/agents/chat.js +202 -22
- package/dist/commands/agents/create.d.ts +38 -0
- package/dist/commands/agents/create.js +95 -2
- package/dist/commands/agents/schedule-trace.js +11 -0
- package/dist/commands/agents/show.js +29 -1
- package/dist/commands/api-keys/create.d.ts +24 -0
- package/dist/commands/api-keys/create.js +80 -0
- package/dist/commands/api-keys/list.d.ts +11 -0
- package/dist/commands/api-keys/list.js +42 -0
- package/dist/commands/api-keys/revoke.d.ts +14 -0
- package/dist/commands/api-keys/revoke.js +33 -0
- package/dist/commands/api-keys/rotate.d.ts +19 -0
- package/dist/commands/api-keys/rotate.js +42 -0
- package/dist/commands/balance/index.d.ts +18 -0
- package/dist/commands/balance/index.js +29 -0
- package/dist/commands/balance/show.d.ts +25 -0
- package/dist/commands/balance/show.js +60 -0
- package/dist/commands/balance/statement.d.ts +19 -0
- package/dist/commands/balance/statement.js +52 -0
- package/dist/commands/browser/doctor.d.ts +11 -0
- package/dist/commands/browser/doctor.js +11 -0
- package/dist/commands/code/jobs/approve.d.ts +25 -0
- package/dist/commands/code/jobs/approve.js +52 -0
- package/dist/commands/code/jobs/cancel.d.ts +12 -0
- package/dist/commands/code/jobs/cancel.js +39 -0
- package/dist/commands/code/jobs/index.d.ts +19 -0
- package/dist/commands/code/jobs/index.js +38 -0
- package/dist/commands/code/jobs/list.d.ts +12 -0
- package/dist/commands/code/jobs/list.js +87 -0
- package/dist/commands/code/jobs/run.d.ts +32 -0
- package/dist/commands/code/jobs/run.js +151 -0
- package/dist/commands/code/jobs/show.d.ts +12 -0
- package/dist/commands/code/jobs/show.js +86 -0
- package/dist/commands/commitments/preflight.js +18 -4
- package/dist/commands/commitments/receipt-metrics.d.ts +39 -0
- package/dist/commands/commitments/receipt-metrics.js +78 -0
- package/dist/commands/convos/search.js +5 -5
- package/dist/commands/harnesses/leases/list.d.ts +3 -0
- package/dist/commands/harnesses/leases/list.js +59 -12
- package/dist/commands/harnesses/leases/show.js +36 -0
- package/dist/commands/harnesses/list.d.ts +18 -0
- package/dist/commands/harnesses/list.js +30 -0
- package/dist/commands/harnesses/products.js +49 -3
- package/dist/commands/harnesses/quota.d.ts +16 -0
- package/dist/commands/harnesses/quota.js +26 -1
- package/dist/commands/harnesses/usage.js +17 -0
- package/dist/commands/inbox/index.d.ts +2 -1
- package/dist/commands/inbox/index.js +27 -4
- package/dist/commands/login.js +4 -1
- package/dist/commands/machines/dedicated/create.d.ts +18 -0
- package/dist/commands/machines/dedicated/create.js +90 -0
- package/dist/commands/machines/dedicated/destroy.d.ts +14 -0
- package/dist/commands/machines/dedicated/destroy.js +56 -0
- package/dist/commands/machines/dedicated/grow.d.ts +13 -0
- package/dist/commands/machines/dedicated/grow.js +46 -0
- package/dist/commands/machines/dedicated/health-check.d.ts +12 -0
- package/dist/commands/machines/dedicated/health-check.js +42 -0
- package/dist/commands/machines/dedicated/incident-close.d.ts +12 -0
- package/dist/commands/machines/dedicated/incident-close.js +42 -0
- package/dist/commands/machines/dedicated/index.d.ts +6 -0
- package/dist/commands/machines/dedicated/index.js +39 -0
- package/dist/commands/machines/dedicated/list.d.ts +11 -0
- package/dist/commands/machines/dedicated/list.js +58 -0
- package/dist/commands/machines/dedicated/restart.d.ts +12 -0
- package/dist/commands/machines/dedicated/restart.js +42 -0
- package/dist/commands/machines/dedicated/show.d.ts +12 -0
- package/dist/commands/machines/dedicated/show.js +58 -0
- package/dist/commands/machines/dedicated/snapshot.d.ts +12 -0
- package/dist/commands/machines/dedicated/snapshot.js +42 -0
- package/dist/commands/machines/dedicated/start.d.ts +12 -0
- package/dist/commands/machines/dedicated/start.js +42 -0
- package/dist/commands/machines/dedicated/stop.d.ts +12 -0
- package/dist/commands/machines/dedicated/stop.js +42 -0
- package/dist/commands/machines/hosted/index.js +4 -1
- package/dist/commands/machines/list.d.ts +1 -0
- package/dist/commands/machines/list.js +33 -5
- package/dist/commands/memory/approvals/issue.d.ts +18 -0
- package/dist/commands/memory/approvals/issue.js +63 -0
- package/dist/commands/memory/commit.js +5 -2
- package/dist/commands/memory/context.d.ts +3 -2
- package/dist/commands/memory/context.js +9 -11
- package/dist/commands/memory/delete.d.ts +1 -1
- package/dist/commands/memory/list.d.ts +1 -1
- package/dist/commands/memory/list.js +1 -1
- package/dist/commands/memory/mounts/resolve.d.ts +10 -0
- package/dist/commands/memory/mounts/resolve.js +27 -0
- package/dist/commands/memory/proposals/commit.d.ts +18 -0
- package/dist/commands/memory/proposals/commit.js +32 -0
- package/dist/commands/memory/proposals/create.d.ts +18 -0
- package/dist/commands/memory/proposals/create.js +56 -0
- package/dist/commands/memory/proposals/list.d.ts +13 -0
- package/dist/commands/memory/proposals/list.js +31 -0
- package/dist/commands/memory/proposals/promote.d.ts +22 -0
- package/dist/commands/memory/proposals/promote.js +33 -0
- package/dist/commands/memory/proposals/reject.d.ts +16 -0
- package/dist/commands/memory/proposals/reject.js +28 -0
- package/dist/commands/memory/rebuild-index.d.ts +20 -0
- package/dist/commands/memory/rebuild-index.js +25 -0
- package/dist/commands/memory/save.d.ts +1 -1
- package/dist/commands/memory/save.js +1 -1
- package/dist/commands/memory/search.d.ts +6 -3
- package/dist/commands/memory/search.js +27 -3
- package/dist/commands/memory/show.d.ts +1 -1
- package/dist/commands/memory/stores/archive.d.ts +14 -0
- package/dist/commands/memory/stores/archive.js +31 -0
- package/dist/commands/memory/stores/create.d.ts +12 -0
- package/dist/commands/memory/stores/create.js +30 -0
- package/dist/commands/memory/stores/delete.d.ts +15 -0
- package/dist/commands/memory/stores/delete.js +38 -0
- package/dist/commands/memory/stores/list.d.ts +10 -0
- package/dist/commands/memory/stores/list.js +29 -0
- package/dist/commands/memory/stores/show.d.ts +12 -0
- package/dist/commands/memory/stores/show.js +14 -0
- package/dist/commands/memory/stores/update.d.ts +15 -0
- package/dist/commands/memory/stores/update.js +39 -0
- package/dist/commands/memory/sync/delete.d.ts +13 -0
- package/dist/commands/memory/sync/delete.js +35 -0
- package/dist/commands/memory/sync/pull.d.ts +19 -0
- package/dist/commands/memory/sync/pull.js +52 -0
- package/dist/commands/memory/sync/push.d.ts +18 -0
- package/dist/commands/memory/sync/push.js +115 -0
- package/dist/commands/memory/sync/resolve.d.ts +23 -0
- package/dist/commands/memory/sync/resolve.js +27 -0
- package/dist/commands/memory/sync/status.d.ts +9 -0
- package/dist/commands/memory/sync/status.js +22 -0
- package/dist/commands/memory/topics/archive.d.ts +20 -0
- package/dist/commands/memory/topics/archive.js +29 -0
- package/dist/commands/memory/topics/create.d.ts +23 -0
- package/dist/commands/memory/topics/create.js +46 -0
- package/dist/commands/memory/topics/delete.d.ts +22 -0
- package/dist/commands/memory/topics/delete.js +30 -0
- package/dist/commands/memory/topics/forget.d.ts +22 -0
- package/dist/commands/memory/topics/forget.js +29 -0
- package/dist/commands/memory/topics/list.d.ts +13 -0
- package/dist/commands/memory/topics/list.js +22 -0
- package/dist/commands/memory/topics/move.d.ts +22 -0
- package/dist/commands/memory/topics/move.js +26 -0
- package/dist/commands/memory/topics/show.d.ts +17 -0
- package/dist/commands/memory/topics/show.js +21 -0
- package/dist/commands/memory/topics/update.d.ts +23 -0
- package/dist/commands/memory/topics/update.js +27 -0
- package/dist/commands/memory/tree.d.ts +5 -2
- package/dist/commands/memory/tree.js +20 -2
- package/dist/commands/memory/update.d.ts +1 -1
- package/dist/commands/memory/versions/list.d.ts +16 -0
- package/dist/commands/memory/versions/list.js +22 -0
- package/dist/commands/memory/versions/redact.d.ts +21 -0
- package/dist/commands/memory/versions/redact.js +22 -0
- package/dist/commands/memory/versions/restore.d.ts +20 -0
- package/dist/commands/memory/versions/restore.js +16 -0
- package/dist/commands/memory/versions/show.d.ts +15 -0
- package/dist/commands/memory/versions/show.js +17 -0
- package/dist/commands/messages/list.js +25 -8
- package/dist/commands/messages/show.js +10 -0
- package/dist/commands/spaces/update.js +16 -12
- package/dist/commands/spaces/work-sync/reconcile.d.ts +38 -0
- package/dist/commands/spaces/work-sync/reconcile.js +90 -0
- package/dist/commands/spaces/work-sync/telemetry.d.ts +29 -0
- package/dist/commands/spaces/work-sync/telemetry.js +96 -0
- package/dist/commands/store/install.js +5 -1
- package/dist/commands/store/releases.js +1 -1
- package/dist/commands/store/update.js +5 -1
- package/dist/commands/subscriptions/cancel.js +5 -1
- package/dist/commands/subscriptions/health.js +5 -1
- package/dist/commands/subscriptions/status.js +5 -1
- package/dist/commands/subscriptions/subscribe.js +5 -1
- package/dist/commands/tasks/activity.d.ts +2 -3
- package/dist/commands/tasks/activity.js +20 -6
- package/dist/commands/tasks/complete.d.ts +22 -150
- package/dist/commands/tasks/complete.js +174 -599
- package/dist/commands/tasks/create.d.ts +6 -0
- package/dist/commands/tasks/create.js +114 -4
- package/dist/commands/tasks/deliverable/add.d.ts +8 -0
- package/dist/commands/tasks/deliverable/add.js +62 -11
- package/dist/commands/tasks/deliverable/confirm.d.ts +5 -5
- package/dist/commands/tasks/deliverable/confirm.js +9 -18
- package/dist/commands/tasks/deliverable/list.d.ts +12 -0
- package/dist/commands/tasks/deliverable/list.js +58 -0
- package/dist/commands/tasks/events/append.d.ts +2 -0
- package/dist/commands/tasks/events/append.js +41 -6
- package/dist/commands/tasks/events/list.d.ts +1 -0
- package/dist/commands/tasks/events/list.js +1 -0
- package/dist/commands/tasks/events/tail.d.ts +1 -0
- package/dist/commands/tasks/events/tail.js +1 -0
- package/dist/commands/tasks/expectations/assess.d.ts +21 -0
- package/dist/commands/tasks/expectations/assess.js +103 -0
- package/dist/commands/tasks/expectations.js +121 -25
- package/dist/commands/tasks/judge.d.ts +1 -0
- package/dist/commands/tasks/judge.js +2 -1
- package/dist/commands/tasks/output.d.ts +1 -11
- package/dist/commands/tasks/output.js +80 -141
- package/dist/commands/tasks/report.d.ts +3 -3
- package/dist/commands/tasks/report.js +66 -41
- package/dist/commands/tasks/resource/add.d.ts +23 -0
- package/dist/commands/tasks/resource/add.js +76 -0
- package/dist/commands/tasks/resource/list.d.ts +13 -0
- package/dist/commands/tasks/resource/list.js +41 -0
- package/dist/commands/tasks/result/show.d.ts +13 -0
- package/dist/commands/tasks/result/show.js +64 -0
- package/dist/commands/tasks/result/submit.d.ts +26 -0
- package/dist/commands/tasks/result/submit.js +134 -0
- package/dist/commands/tasks/resume/save.d.ts +16 -0
- package/dist/commands/tasks/resume/save.js +69 -0
- package/dist/commands/tasks/resume/show.d.ts +13 -0
- package/dist/commands/tasks/resume/show.js +35 -0
- package/dist/commands/tasks/review.d.ts +17 -0
- package/dist/commands/tasks/review.js +54 -0
- package/dist/commands/tasks/runs.js +5 -0
- package/dist/commands/tasks/self-schedule.js +7 -4
- package/dist/commands/tasks/show.js +19 -0
- package/dist/commands/tasks/timeline.d.ts +2 -2
- package/dist/commands/tasks/timeline.js +19 -24
- package/dist/commands/tasks/updates/add.d.ts +22 -0
- package/dist/commands/tasks/updates/add.js +122 -0
- package/dist/commands/tasks/updates/list.d.ts +15 -0
- package/dist/commands/tasks/updates/list.js +57 -0
- package/dist/commands/tasks/waive.d.ts +1 -0
- package/dist/commands/tasks/waive.js +2 -1
- package/dist/lib/agentic-stream.d.ts +257 -0
- package/dist/lib/agentic-stream.js +490 -33
- package/dist/lib/balance.d.ts +8 -0
- package/dist/lib/commitment-product.d.ts +10 -1
- package/dist/lib/commitment-product.js +66 -2
- package/dist/lib/commitments.d.ts +2 -1
- package/dist/lib/commitments.js +1 -0
- package/dist/lib/conversation-search.d.ts +3 -0
- package/dist/lib/conversation-search.js +75 -0
- package/dist/lib/dedicated-machines.d.ts +66 -0
- package/dist/lib/dedicated-machines.js +161 -0
- package/dist/lib/execution-target.d.ts +21 -0
- package/dist/lib/execution-target.js +22 -6
- package/dist/lib/harnesses.d.ts +87 -6
- package/dist/lib/harnesses.js +32 -1
- package/dist/lib/hosted-machines.js +9 -0
- package/dist/lib/inbox.d.ts +2 -1
- package/dist/lib/machines.d.ts +17 -0
- package/dist/lib/machines.js +29 -0
- package/dist/lib/managed-agent-keys.d.ts +104 -0
- package/dist/lib/managed-agent-keys.js +50 -0
- package/dist/lib/memory-scope.d.ts +4 -3
- package/dist/lib/memory-scope.js +9 -9
- package/dist/lib/memory-sync.d.ts +114 -0
- package/dist/lib/memory-sync.js +730 -0
- package/dist/lib/message-provenance.d.ts +42 -0
- package/dist/lib/message-provenance.js +89 -0
- package/dist/lib/scoped-memory-command.d.ts +68 -0
- package/dist/lib/scoped-memory-command.js +183 -0
- package/dist/lib/session-task-endpoints.d.ts +1 -1
- package/dist/lib/session-task-endpoints.js +7 -0
- package/dist/lib/sky-code-broker.d.ts +47 -0
- package/dist/lib/sky-code-broker.js +50 -0
- package/dist/lib/sky-code-doctor.js +10 -1
- package/dist/lib/task-artifact-flags.d.ts +2 -0
- package/dist/lib/task-artifact-flags.js +7 -0
- package/dist/lib/task-execution.d.ts +4 -5
- package/dist/lib/task-execution.js +4 -5
- package/dist/lib/task-extras.d.ts +1 -5
- package/dist/lib/task-extras.js +1 -5
- package/dist/lib/task-legacy.d.ts +24 -0
- package/dist/lib/task-legacy.js +48 -0
- package/dist/lib/task-transcript.d.ts +5 -7
- package/dist/lib/task-transcript.js +8 -16
- package/dist/lib/tasks.d.ts +39 -21
- package/dist/lib/tasks.js +64 -21
- package/dist/lib/triggers.d.ts +39 -1
- package/dist/lib/triggers.js +70 -2
- package/dist/lib/usage-discovery.d.ts +17 -1
- package/dist/lib/usage-discovery.js +17 -1
- package/dist/lib/work-sync.d.ts +70 -0
- package/dist/lib/work-sync.js +29 -0
- package/dist/node_modules/@skrr-ai/data-provider/index.js +3760 -3621
- package/oclif.manifest.json +14653 -7813
- package/package.json +26 -5
package/dist/lib/balance.d.ts
CHANGED
|
@@ -163,6 +163,14 @@ export interface BalanceStatementEntry {
|
|
|
163
163
|
service: string | null;
|
|
164
164
|
provider: string | null;
|
|
165
165
|
model: string | null;
|
|
166
|
+
/**
|
|
167
|
+
* WHICH agent and conversation incurred it (OSK-7641).
|
|
168
|
+
*
|
|
169
|
+
* Optional because they are: the ledger carries them only where the producer
|
|
170
|
+
* knows them, and an older row has neither.
|
|
171
|
+
*/
|
|
172
|
+
agentId?: string | null;
|
|
173
|
+
conversationId?: string | null;
|
|
166
174
|
/** What incurred it, e.g. `session` / `run` — with `sourceId`, the thing
|
|
167
175
|
* `balance history` could never name. */
|
|
168
176
|
sourceType?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CommitmentDeliveryIntent, CommitmentExecutionReceipt } from '@skrr-ai/data-provider';
|
|
1
|
+
import type { CommitmentDeliveryIntent, CommitmentExecutionReceipt, CommitmentExecutionReceiptQuarterlyMetricsResponse } from '@skrr-ai/data-provider';
|
|
2
2
|
export declare const COMMITMENT_PRODUCT_MODES: readonly ["monitor", "prepare", "execute"];
|
|
3
3
|
export declare const COMMITMENT_DELIVERY_CHOICES: readonly ["report-only", "local-patch", "draft-pr", "push-branch", "direct-branch"];
|
|
4
4
|
/** Compatibility is accepted at the input boundary; everyday output uses the product contract. */
|
|
@@ -12,3 +12,12 @@ export declare function deliveryInput(mode: string, options?: {
|
|
|
12
12
|
/** Monitor is observation-only; retain report expectations, never repo coordinates. */
|
|
13
13
|
export declare function deliveryForProductMode(mode: string | undefined, delivery?: CommitmentDeliveryIntent): CommitmentDeliveryIntent | undefined;
|
|
14
14
|
export declare function renderExecutionReceipt(receipt: CommitmentExecutionReceipt, log: (line: string) => void, verbose?: boolean): void;
|
|
15
|
+
/**
|
|
16
|
+
* `skrr commitments receipt-metrics <id>` — the closed-quarter rollup.
|
|
17
|
+
*
|
|
18
|
+
* Ordered as the funnel it describes rather than as the payload's field order:
|
|
19
|
+
* a wake arrives, some wakes were eligible to act on, some of those started an
|
|
20
|
+
* execution, some declared a delivery, and some of THOSE were verified. Reading
|
|
21
|
+
* it top to bottom is how you see which step the loop is losing work at.
|
|
22
|
+
*/
|
|
23
|
+
export declare function renderExecutionReceiptQuarterlyMetrics(response: CommitmentExecutionReceiptQuarterlyMetricsResponse, log: (line: string) => void, verbose?: boolean): void;
|
|
@@ -7,6 +7,7 @@ exports.deliveryLabel = deliveryLabel;
|
|
|
7
7
|
exports.deliveryInput = deliveryInput;
|
|
8
8
|
exports.deliveryForProductMode = deliveryForProductMode;
|
|
9
9
|
exports.renderExecutionReceipt = renderExecutionReceipt;
|
|
10
|
+
exports.renderExecutionReceiptQuarterlyMetrics = renderExecutionReceiptQuarterlyMetrics;
|
|
10
11
|
exports.COMMITMENT_PRODUCT_MODES = ['monitor', 'prepare', 'execute'];
|
|
11
12
|
exports.COMMITMENT_DELIVERY_CHOICES = [
|
|
12
13
|
'report-only',
|
|
@@ -71,8 +72,9 @@ function renderExecutionReceipt(receipt, log, verbose = false) {
|
|
|
71
72
|
const mark = { done: '✓', working: '→', waiting: '…', failed: '×', skipped: '–' }[phase.status];
|
|
72
73
|
log(` ${mark} ${phase.phase[0].toUpperCase() + phase.phase.slice(1)}: ${phase.summary}${phase.at ? ` · ${phase.at}` : ''}`);
|
|
73
74
|
for (const evidence of phase.evidence) {
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
const location = evidence.url || evidence.path;
|
|
76
|
+
if (location)
|
|
77
|
+
log(` ${evidence.label}: ${location}`);
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
if (receipt.nextActor)
|
|
@@ -85,3 +87,65 @@ function renderExecutionReceipt(receipt, log, verbose = false) {
|
|
|
85
87
|
if (verbose)
|
|
86
88
|
log(`Diagnostics:\n${JSON.stringify({ id: receipt.id, revision: receipt.revision, evidence: receipt.evidence, diagnostics: receipt.diagnostics }, null, 2)}`);
|
|
87
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* A rate the server could not compute is NOT zero.
|
|
92
|
+
*
|
|
93
|
+
* Every `*Rate` on the metrics payload is `number | null`, and the null means
|
|
94
|
+
* "no denominator in this cohort" — a quarter with no eligible material wake
|
|
95
|
+
* has no verified-outcome rate to report. Printing that as `0%` would read as
|
|
96
|
+
* "we tried and delivered nothing", which is the opposite of "we were never
|
|
97
|
+
* asked". So an absent rate renders as an em dash and stays visibly absent.
|
|
98
|
+
*/
|
|
99
|
+
function rate(value) {
|
|
100
|
+
if (value === null || value === undefined)
|
|
101
|
+
return '—';
|
|
102
|
+
return `${(value * 100).toFixed(1)}%`;
|
|
103
|
+
}
|
|
104
|
+
/** Same rule for a ratio that is not a percentage. */
|
|
105
|
+
function ratio(value) {
|
|
106
|
+
if (value === null || value === undefined)
|
|
107
|
+
return '—';
|
|
108
|
+
return value.toFixed(2);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* `skrr commitments receipt-metrics <id>` — the closed-quarter rollup.
|
|
112
|
+
*
|
|
113
|
+
* Ordered as the funnel it describes rather than as the payload's field order:
|
|
114
|
+
* a wake arrives, some wakes were eligible to act on, some of those started an
|
|
115
|
+
* execution, some declared a delivery, and some of THOSE were verified. Reading
|
|
116
|
+
* it top to bottom is how you see which step the loop is losing work at.
|
|
117
|
+
*/
|
|
118
|
+
function renderExecutionReceiptQuarterlyMetrics(response, log, verbose = false) {
|
|
119
|
+
const { cohort, metrics } = response;
|
|
120
|
+
log(`Q${cohort.quarter} ${cohort.year} · ${cohort.from} → ${cohort.to}`);
|
|
121
|
+
log(`Checks in cohort: ${cohort.checkCount} · receipts: ${metrics.receiptCount}`);
|
|
122
|
+
log('');
|
|
123
|
+
log('Funnel');
|
|
124
|
+
log(` Material wakes: ${metrics.materialWakes} (${metrics.eligibleMaterialWakes} eligible)`);
|
|
125
|
+
log(` Execute starts: ${metrics.executeStarts}`);
|
|
126
|
+
log(` Declared deliveries: ${metrics.declaredDeliveries}`);
|
|
127
|
+
log(` Verified outcomes: ${metrics.verifiedOutcomes}`);
|
|
128
|
+
log(` Blocked: ${metrics.blocked}`);
|
|
129
|
+
log('');
|
|
130
|
+
log('Rates');
|
|
131
|
+
log(` Verified per eligible wake: ${ratio(metrics.verifiedOutcomesPerEligibleMaterialWake)}`);
|
|
132
|
+
log(` Verified outcome rate: ${rate(metrics.verifiedOutcomeRate)}`);
|
|
133
|
+
log(` Delivery ratio: ${rate(metrics.deliveryRatio)}`);
|
|
134
|
+
log(` Autonomous, no intervention: ${rate(metrics.autonomousDeliveryWithoutInterventionRate)}`);
|
|
135
|
+
log(` Human intervention rate: ${rate(metrics.humanInterventionRate)}`);
|
|
136
|
+
log(` Orphaned delivery rate: ${rate(metrics.orphanedDeliveryRate)}`);
|
|
137
|
+
log(` False ready / false blocked: ${rate(metrics.falseReadyRate)} / ${rate(metrics.falseBlockedRate)}`);
|
|
138
|
+
// The unknown counts decide whether the rates above are worth acting on, so
|
|
139
|
+
// they are one flag away rather than buried in --json.
|
|
140
|
+
if (verbose) {
|
|
141
|
+
const m = metrics.measurement;
|
|
142
|
+
log('');
|
|
143
|
+
log('Measurement');
|
|
144
|
+
log(` Cohort: ${m.cohort}`);
|
|
145
|
+
log(` Intervention: ${m.interventionDefinition}`);
|
|
146
|
+
log(` Eligible material wake: ${m.eligibleMaterialWakeDefinition}`);
|
|
147
|
+
log(` Unknown admission runs: ${m.unknownAdmissionRuns} · unknown startup runs: ${m.unknownStartupRuns}`);
|
|
148
|
+
log(` Tracked completed runs: ${m.trackedCompletedRuns}`);
|
|
149
|
+
log(` Time to explanation: p50 ${metrics.timeToExplanationMs.p50 ?? '—'}ms · p95 ${metrics.timeToExplanationMs.p95 ?? '—'}ms (n=${metrics.timeToExplanationMs.count})`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* "hold this state", derived from a Compass invariant — not authored here).
|
|
18
18
|
*/
|
|
19
19
|
import { COMMITMENT_WATCHED_SOURCES, COMMITMENT_TEMPLATE_IDS, COMMITMENT_CADENCE_MODES, COMMITMENT_CADENCE_TIME_PATTERN, COMMITMENT_CADENCE_MAX_TIMES, COMMITMENT_AUTONOMY_MODES, COMMITMENT_EXECUTION_ISOLATION_MODES } from '@skrr-ai/data-provider';
|
|
20
|
-
import type { CommitmentCheck, CommitmentChecksResponse, Commitment, CommitmentActionProposal, CommitmentListResponse, CommitmentPlanResponse, CommitmentStatusResponse, CommitmentWorkLink, CommitmentExecutionReceiptListResponse, CommitmentCapabilitySource, CommitmentDeliveryPatchResponse, CommitmentDeliveryBundleResponse } from '@skrr-ai/data-provider';
|
|
20
|
+
import type { CommitmentCheck, CommitmentChecksResponse, Commitment, CommitmentActionProposal, CommitmentListResponse, CommitmentPlanResponse, CommitmentStatusResponse, CommitmentWorkLink, CommitmentExecutionReceiptListResponse, CommitmentExecutionReceiptQuarterlyMetricsResponse, CommitmentCapabilitySource, CommitmentDeliveryPatchResponse, CommitmentDeliveryBundleResponse } from '@skrr-ai/data-provider';
|
|
21
21
|
import { withQuery } from './triggers';
|
|
22
22
|
export { COMMITMENT_WATCHED_SOURCES, COMMITMENT_TEMPLATE_IDS, COMMITMENT_CADENCE_MODES, COMMITMENT_CADENCE_TIME_PATTERN, COMMITMENT_CADENCE_MAX_TIMES, };
|
|
23
23
|
export type { CommitmentCheck, CommitmentChecksResponse, Commitment, CommitmentActionProposal, CommitmentListResponse, CommitmentPlanResponse, CommitmentStatusResponse, CommitmentWorkLink, };
|
|
@@ -284,6 +284,7 @@ export declare const commitmentApi: {
|
|
|
284
284
|
mode: (id: string, body: Record<string, unknown>) => Promise<Commitment>;
|
|
285
285
|
delivery: (id: string, body: Record<string, unknown>) => Promise<Commitment>;
|
|
286
286
|
receipts: (id: string, limit?: number) => Promise<CommitmentExecutionReceiptListResponse>;
|
|
287
|
+
receiptQuarterlyMetrics: (id: string, year: number, quarter: number) => Promise<CommitmentExecutionReceiptQuarterlyMetricsResponse>;
|
|
287
288
|
deliveryPatch: (id: string, taskId: string) => Promise<CommitmentDeliveryPatchResponse>;
|
|
288
289
|
deliveryBundle: (id: string, taskId: string) => Promise<CommitmentDeliveryBundleResponse>;
|
|
289
290
|
operatingReview: (agentId: string) => Promise<Record<string, unknown>>;
|
package/dist/lib/commitments.js
CHANGED
|
@@ -183,6 +183,7 @@ exports.commitmentApi = {
|
|
|
183
183
|
mode: (id, body) => data_provider_1.request.post(`${base(id)}/mode`, body),
|
|
184
184
|
delivery: (id, body) => data_provider_1.request.post(`${base(id)}/delivery`, body),
|
|
185
185
|
receipts: (id, limit = 1) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/receipts`, { limit })),
|
|
186
|
+
receiptQuarterlyMetrics: (id, year, quarter) => data_provider_1.request.get((0, triggers_1.withQuery)(`${base(id)}/receipt-metrics/quarterly`, { year, quarter })),
|
|
186
187
|
deliveryPatch: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/patch`),
|
|
187
188
|
deliveryBundle: (id, taskId) => data_provider_1.request.get(`${base(id)}/delivery/${encodeURIComponent(taskId)}/bundle`),
|
|
188
189
|
operatingReview: (agentId) => data_provider_1.request.get(`/api/commitments/agents/${encodeURIComponent(agentId)}/operating-review`),
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function normalizedSnippetLength(value: number): number;
|
|
2
|
+
/** Keep search output a navigation result, never a transcript payload. */
|
|
3
|
+
export declare function compactMessageSearchHit(message: Record<string, unknown>, requestedSnippetLength: number, query?: string): Record<string, unknown>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizedSnippetLength = normalizedSnippetLength;
|
|
4
|
+
exports.compactMessageSearchHit = compactMessageSearchHit;
|
|
5
|
+
const MAX_SEARCH_SNIPPET_CHARS = 4000;
|
|
6
|
+
function normalizedSnippetLength(value) {
|
|
7
|
+
if (!Number.isFinite(value))
|
|
8
|
+
return 160;
|
|
9
|
+
return Math.min(MAX_SEARCH_SNIPPET_CHARS, Math.max(1, Math.trunc(value)));
|
|
10
|
+
}
|
|
11
|
+
function findQueryMatch(text, query) {
|
|
12
|
+
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
13
|
+
if (!normalizedQuery)
|
|
14
|
+
return null;
|
|
15
|
+
const loweredText = text.toLocaleLowerCase();
|
|
16
|
+
const exactAt = loweredText.indexOf(normalizedQuery);
|
|
17
|
+
if (exactAt >= 0)
|
|
18
|
+
return { at: exactAt, length: normalizedQuery.length };
|
|
19
|
+
// Meilisearch tokenizes punctuation-bearing queries and can legitimately
|
|
20
|
+
// match AGENT_EMPTY_RESPONSE as separate words. If the exact phrase is not
|
|
21
|
+
// present, center on the earliest substantive query token so the bounded CLI
|
|
22
|
+
// result still explains why it matched instead of truncating just before the
|
|
23
|
+
// highlighted word returned by the server crop.
|
|
24
|
+
const tokens = Array.from(new Set(normalizedQuery.split(/[^\p{L}\p{N}]+/u).filter((token) => token.length >= 2)));
|
|
25
|
+
let best = null;
|
|
26
|
+
for (const token of tokens) {
|
|
27
|
+
const at = loweredText.indexOf(token);
|
|
28
|
+
if (at >= 0 && (!best || at < best.at))
|
|
29
|
+
best = { at, length: token.length };
|
|
30
|
+
}
|
|
31
|
+
return best;
|
|
32
|
+
}
|
|
33
|
+
/** Keep search output a navigation result, never a transcript payload. */
|
|
34
|
+
function compactMessageSearchHit(message, requestedSnippetLength, query = '') {
|
|
35
|
+
const limit = normalizedSnippetLength(requestedSnippetLength);
|
|
36
|
+
const normalizedText = String(message.text ?? '')
|
|
37
|
+
.replace(/\s+/g, ' ')
|
|
38
|
+
.trim();
|
|
39
|
+
const normalizedQuery = query.trim();
|
|
40
|
+
let text = normalizedText;
|
|
41
|
+
if (!text) {
|
|
42
|
+
text = '[matching text unavailable]';
|
|
43
|
+
}
|
|
44
|
+
else if (text.length > limit) {
|
|
45
|
+
const match = findQueryMatch(text, normalizedQuery);
|
|
46
|
+
if (!match) {
|
|
47
|
+
text = text.slice(0, limit);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const matchAt = match.at;
|
|
51
|
+
const matchLength = Math.min(match.length, limit);
|
|
52
|
+
const prefixBudget = Math.floor((limit - matchLength) / 2);
|
|
53
|
+
let start = Math.max(0, matchAt - prefixBudget);
|
|
54
|
+
let prefix = start > 0 ? '…' : '';
|
|
55
|
+
let suffix = '…';
|
|
56
|
+
let contentBudget = Math.max(1, limit - prefix.length - suffix.length);
|
|
57
|
+
start = Math.min(start, Math.max(0, text.length - contentBudget));
|
|
58
|
+
prefix = start > 0 ? '…' : '';
|
|
59
|
+
suffix = start + contentBudget < text.length ? '…' : '';
|
|
60
|
+
contentBudget = Math.max(1, limit - prefix.length - suffix.length);
|
|
61
|
+
start = Math.min(start, Math.max(0, text.length - contentBudget));
|
|
62
|
+
text = `${prefix}${text.slice(start, start + contentBudget)}${suffix}`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
text = text.slice(0, limit);
|
|
66
|
+
return {
|
|
67
|
+
messageId: message.messageId,
|
|
68
|
+
conversationId: message.conversationId,
|
|
69
|
+
title: message.title,
|
|
70
|
+
sender: message.sender,
|
|
71
|
+
isCreatedByUser: message.isCreatedByUser,
|
|
72
|
+
createdAt: message.createdAt,
|
|
73
|
+
text,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type HarnessLease } from './harnesses';
|
|
2
|
+
export type DedicatedLeaseAction = 'start' | 'stop' | 'restart' | 'snapshot' | 'health-check';
|
|
3
|
+
export declare const DEDICATED_LEASE_ACTIONS: DedicatedLeaseAction[];
|
|
4
|
+
export interface DedicatedRuntimeScope {
|
|
5
|
+
workspaceId?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CreateDedicatedRuntimeInput extends DedicatedRuntimeScope {
|
|
8
|
+
requestId: string;
|
|
9
|
+
displayName: string;
|
|
10
|
+
sizePreset: string;
|
|
11
|
+
regionClass?: string;
|
|
12
|
+
storageGb?: number;
|
|
13
|
+
retentionClass?: string;
|
|
14
|
+
backupProfile?: 'crash-consistent' | 'application-consistent';
|
|
15
|
+
monthlySpendingLimitCents: number;
|
|
16
|
+
repositoryRef?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DedicatedRuntimeResponse {
|
|
19
|
+
lease?: HarnessLease;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Flags in, request body out — and the point of it being a function is the
|
|
23
|
+
* OMISSION.
|
|
24
|
+
*
|
|
25
|
+
* A field the user did not set must be ABSENT from the body, not present as
|
|
26
|
+
* `undefined`, because the server reaches its own default through
|
|
27
|
+
* `input.x || <default>`. Restating those defaults on the client looks
|
|
28
|
+
* harmless and is not: `--storage-gb` shipped with a client default of 100
|
|
29
|
+
* against a product default of 50, so a user who never chose a disk size was
|
|
30
|
+
* billed for twice the documented one and `workspaceDefaultGb` was unreachable
|
|
31
|
+
* through the CLI. The three neighbouring flags happened to agree, which only
|
|
32
|
+
* means the same bug was invisible in them.
|
|
33
|
+
*/
|
|
34
|
+
export declare function dedicatedRuntimeCreateInput(input: {
|
|
35
|
+
requestId: string;
|
|
36
|
+
displayName: string;
|
|
37
|
+
sizePreset: string;
|
|
38
|
+
monthlySpendingLimitCents: number;
|
|
39
|
+
regionClass?: string;
|
|
40
|
+
storageGb?: number;
|
|
41
|
+
retentionClass?: string;
|
|
42
|
+
backupProfile?: string;
|
|
43
|
+
workspaceId?: string;
|
|
44
|
+
}): CreateDedicatedRuntimeInput;
|
|
45
|
+
export declare function createDedicatedRuntime(input: CreateDedicatedRuntimeInput): Promise<DedicatedRuntimeResponse>;
|
|
46
|
+
export declare function listDedicatedRuntimes(options?: {
|
|
47
|
+
limit?: number;
|
|
48
|
+
state?: string;
|
|
49
|
+
}): Promise<{
|
|
50
|
+
leases?: HarnessLease[];
|
|
51
|
+
}>;
|
|
52
|
+
export declare function getDedicatedRuntime(leaseId: string): Promise<DedicatedRuntimeResponse>;
|
|
53
|
+
export declare function performDedicatedLeaseAction(leaseId: string, action: DedicatedLeaseAction): Promise<DedicatedRuntimeResponse>;
|
|
54
|
+
export declare function growDedicatedRuntime(leaseId: string, storageGb: number, options?: {
|
|
55
|
+
requestId?: string;
|
|
56
|
+
}): Promise<DedicatedRuntimeResponse>;
|
|
57
|
+
export declare function closeDedicatedRuntimeIncidentHold(leaseId: string, options?: {
|
|
58
|
+
requestId?: string;
|
|
59
|
+
}): Promise<DedicatedRuntimeResponse>;
|
|
60
|
+
export declare function destroyDedicatedRuntime(leaseId: string, options?: {
|
|
61
|
+
retentionIntent?: 'retain' | 'purge';
|
|
62
|
+
}): Promise<DedicatedRuntimeResponse>;
|
|
63
|
+
export declare function dedicatedLeaseId(lease: HarnessLease | undefined | null): string;
|
|
64
|
+
export declare function dedicatedLeaseState(lease: HarnessLease | undefined | null): string;
|
|
65
|
+
export declare function dedicatedLeaseDisplayName(lease: HarnessLease | undefined | null): string;
|
|
66
|
+
export declare function formatDedicatedRuntimeApiError(err: unknown): string | null;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEDICATED_LEASE_ACTIONS = void 0;
|
|
4
|
+
exports.dedicatedRuntimeCreateInput = dedicatedRuntimeCreateInput;
|
|
5
|
+
exports.createDedicatedRuntime = createDedicatedRuntime;
|
|
6
|
+
exports.listDedicatedRuntimes = listDedicatedRuntimes;
|
|
7
|
+
exports.getDedicatedRuntime = getDedicatedRuntime;
|
|
8
|
+
exports.performDedicatedLeaseAction = performDedicatedLeaseAction;
|
|
9
|
+
exports.growDedicatedRuntime = growDedicatedRuntime;
|
|
10
|
+
exports.closeDedicatedRuntimeIncidentHold = closeDedicatedRuntimeIncidentHold;
|
|
11
|
+
exports.destroyDedicatedRuntime = destroyDedicatedRuntime;
|
|
12
|
+
exports.dedicatedLeaseId = dedicatedLeaseId;
|
|
13
|
+
exports.dedicatedLeaseState = dedicatedLeaseState;
|
|
14
|
+
exports.dedicatedLeaseDisplayName = dedicatedLeaseDisplayName;
|
|
15
|
+
exports.formatDedicatedRuntimeApiError = formatDedicatedRuntimeApiError;
|
|
16
|
+
const api_fetch_1 = require("./api-fetch");
|
|
17
|
+
const harnesses_1 = require("./harnesses");
|
|
18
|
+
exports.DEDICATED_LEASE_ACTIONS = [
|
|
19
|
+
'start',
|
|
20
|
+
'stop',
|
|
21
|
+
'restart',
|
|
22
|
+
'snapshot',
|
|
23
|
+
'health-check',
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* Flags in, request body out — and the point of it being a function is the
|
|
27
|
+
* OMISSION.
|
|
28
|
+
*
|
|
29
|
+
* A field the user did not set must be ABSENT from the body, not present as
|
|
30
|
+
* `undefined`, because the server reaches its own default through
|
|
31
|
+
* `input.x || <default>`. Restating those defaults on the client looks
|
|
32
|
+
* harmless and is not: `--storage-gb` shipped with a client default of 100
|
|
33
|
+
* against a product default of 50, so a user who never chose a disk size was
|
|
34
|
+
* billed for twice the documented one and `workspaceDefaultGb` was unreachable
|
|
35
|
+
* through the CLI. The three neighbouring flags happened to agree, which only
|
|
36
|
+
* means the same bug was invisible in them.
|
|
37
|
+
*/
|
|
38
|
+
function dedicatedRuntimeCreateInput(input) {
|
|
39
|
+
return {
|
|
40
|
+
requestId: input.requestId,
|
|
41
|
+
displayName: input.displayName,
|
|
42
|
+
sizePreset: input.sizePreset,
|
|
43
|
+
monthlySpendingLimitCents: input.monthlySpendingLimitCents,
|
|
44
|
+
...(input.regionClass ? { regionClass: input.regionClass } : {}),
|
|
45
|
+
...(input.storageGb !== undefined ? { storageGb: input.storageGb } : {}),
|
|
46
|
+
...(input.retentionClass ? { retentionClass: input.retentionClass } : {}),
|
|
47
|
+
...(input.backupProfile
|
|
48
|
+
? { backupProfile: input.backupProfile }
|
|
49
|
+
: {}),
|
|
50
|
+
...(input.workspaceId ? { workspaceId: input.workspaceId } : {}),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async function createDedicatedRuntime(input) {
|
|
54
|
+
const { requestId, workspaceId, ...body } = input;
|
|
55
|
+
if (workspaceId) {
|
|
56
|
+
return (0, api_fetch_1.apiFetch)(`/api/machines/dedicated?workspaceId=${encodeURIComponent(workspaceId)}`, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
body,
|
|
59
|
+
headers: { 'Idempotency-Key': requestId },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return (0, api_fetch_1.apiFetch)('/api/machines/dedicated', {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
body,
|
|
65
|
+
headers: { 'Idempotency-Key': requestId },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async function listDedicatedRuntimes(options = {}) {
|
|
69
|
+
return (0, harnesses_1.listHarnessLeases)({
|
|
70
|
+
...options,
|
|
71
|
+
machineProduct: 'dedicated-machine',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function getDedicatedRuntime(leaseId) {
|
|
75
|
+
return (0, harnesses_1.getHarnessLease)(leaseId);
|
|
76
|
+
}
|
|
77
|
+
async function performDedicatedLeaseAction(leaseId, action) {
|
|
78
|
+
return (0, harnesses_1.performHarnessLeaseAction)(leaseId, action);
|
|
79
|
+
}
|
|
80
|
+
async function growDedicatedRuntime(leaseId, storageGb, options = {}) {
|
|
81
|
+
return (0, api_fetch_1.apiFetch)(`/api/machines/dedicated/${encodeURIComponent(leaseId)}/storage`, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
body: { storageGb },
|
|
84
|
+
...(options.requestId ? { headers: { 'Idempotency-Key': options.requestId } } : {}),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async function closeDedicatedRuntimeIncidentHold(leaseId, options = {}) {
|
|
88
|
+
return (0, api_fetch_1.apiFetch)(`/api/machines/dedicated/${encodeURIComponent(leaseId)}/incident-hold/close`, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
body: {},
|
|
91
|
+
...(options.requestId ? { headers: { 'Idempotency-Key': options.requestId } } : {}),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async function destroyDedicatedRuntime(leaseId, options = {}) {
|
|
95
|
+
const query = options.retentionIntent
|
|
96
|
+
? `?retentionIntent=${encodeURIComponent(options.retentionIntent)}`
|
|
97
|
+
: '';
|
|
98
|
+
return (0, api_fetch_1.apiFetch)(`/api/machines/leases/${encodeURIComponent(leaseId)}${query}`, { method: 'DELETE' });
|
|
99
|
+
}
|
|
100
|
+
function dedicatedLeaseId(lease) {
|
|
101
|
+
return String(lease?.id ?? '');
|
|
102
|
+
}
|
|
103
|
+
function dedicatedLeaseState(lease) {
|
|
104
|
+
return String(lease?.state ?? 'unknown');
|
|
105
|
+
}
|
|
106
|
+
function dedicatedLeaseDisplayName(lease) {
|
|
107
|
+
return lease?.displayName ? String(lease.displayName) : '-';
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Dedicated Runtime commands are unusually likely to meet a server that has
|
|
111
|
+
* never heard of them.
|
|
112
|
+
*
|
|
113
|
+
* The CLI ships independently of the API (`@skrr-ai/cli` on npm), so "CLI newer
|
|
114
|
+
* than the deployed server" is the normal state for anyone who runs
|
|
115
|
+
* `npm update`, and this feature widened that window: twelve commands arrived at
|
|
116
|
+
* once, and three of them call endpoints that land in a later deploy. The server
|
|
117
|
+
* redacts an unknown-route 404 to "An unexpected error occurred.", so every one
|
|
118
|
+
* of those users got eight words that cannot be told apart from a wrong lease
|
|
119
|
+
* id or a broken server.
|
|
120
|
+
*
|
|
121
|
+
* A 404 carrying no product `code` is that case. Naming it is the difference
|
|
122
|
+
* between "wait for the deploy" and "open a bug".
|
|
123
|
+
*/
|
|
124
|
+
function describeMissingEndpoint(err) {
|
|
125
|
+
if (err.status !== 404) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(err.body || '');
|
|
130
|
+
// A product code means the server DID handle the route and refused on the
|
|
131
|
+
// merits — that message is the useful one and must not be overwritten.
|
|
132
|
+
if (parsed.code) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// Unparseable body: no product code by definition.
|
|
138
|
+
}
|
|
139
|
+
return ('This server does not have that Dedicated Runtime endpoint. Your CLI is probably ahead of ' +
|
|
140
|
+
'the deployment — `skrr context` names the server it is talking to, and `skrr machines ' +
|
|
141
|
+
'dedicated list` will still work if the feature is deployed at all.');
|
|
142
|
+
}
|
|
143
|
+
function formatDedicatedRuntimeApiError(err) {
|
|
144
|
+
if (!(err instanceof api_fetch_1.ApiFetchError) || !err.body) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
if (err.status === 401) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const missingEndpoint = describeMissingEndpoint(err);
|
|
151
|
+
if (missingEndpoint) {
|
|
152
|
+
return missingEndpoint;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const parsed = JSON.parse(err.body);
|
|
156
|
+
return parsed.message || parsed.error || parsed.code || null;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return err.body.trim() || null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -21,8 +21,29 @@ export interface BuildExecutionOrderPatchInput {
|
|
|
21
21
|
selectors: string[];
|
|
22
22
|
/** Reasons that permit each non-final target to advance. */
|
|
23
23
|
advanceOn?: string[];
|
|
24
|
+
/**
|
|
25
|
+
* No category permits an advance — a STRICT chain.
|
|
26
|
+
*
|
|
27
|
+
* `advanceOn` omitted defaults to `['offline','unavailable']` on every
|
|
28
|
+
* non-final target (see below), and the enum has no empty member, so
|
|
29
|
+
* "strictly pinned, with a declared next target" was inexpressible from any
|
|
30
|
+
* flag: the only way to build it was to bypass the flags entirely and
|
|
31
|
+
* hand-write `executionPolicy` through `--from-json` (OSK-7669).
|
|
32
|
+
*/
|
|
33
|
+
strict?: boolean;
|
|
24
34
|
}
|
|
25
35
|
export declare function normalizeExecutionTargetSelector(input: string): string;
|
|
26
36
|
export declare function normalizeAdvanceReasons(values: string[] | undefined): ExecutionTargetAdvanceReason[];
|
|
27
37
|
export declare function executionTargetForSelector(input: string): AgentExecutionTarget;
|
|
38
|
+
/**
|
|
39
|
+
* What a non-final target may advance on when the caller said nothing.
|
|
40
|
+
*
|
|
41
|
+
* Exported because it is a DEFAULT the operator is not told about anywhere:
|
|
42
|
+
* `--advance-on` reads as an explicit opt-in ("Failure category that PERMITS
|
|
43
|
+
* the current target to advance"), so omitting it looks like opting into
|
|
44
|
+
* nothing — and it grants two categories on a target the caller explicitly
|
|
45
|
+
* pinned (OSK-7669). Naming it here lets the help text and the confirmation
|
|
46
|
+
* output say the same thing the code does.
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEFAULT_ADVANCE_REASONS: readonly ExecutionTargetAdvanceReason[];
|
|
28
49
|
export declare function buildExecutionOrderPatch(input: BuildExecutionOrderPatchInput): AgentExecutionPatch;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EXECUTION_TARGET_ADVANCE_REASONS = void 0;
|
|
3
|
+
exports.DEFAULT_ADVANCE_REASONS = exports.EXECUTION_TARGET_ADVANCE_REASONS = void 0;
|
|
4
4
|
exports.normalizeExecutionTargetSelector = normalizeExecutionTargetSelector;
|
|
5
5
|
exports.normalizeAdvanceReasons = normalizeAdvanceReasons;
|
|
6
6
|
exports.executionTargetForSelector = executionTargetForSelector;
|
|
@@ -78,6 +78,20 @@ function executionTargetForSelector(input) {
|
|
|
78
78
|
managedUsageConsent: false,
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* What a non-final target may advance on when the caller said nothing.
|
|
83
|
+
*
|
|
84
|
+
* Exported because it is a DEFAULT the operator is not told about anywhere:
|
|
85
|
+
* `--advance-on` reads as an explicit opt-in ("Failure category that PERMITS
|
|
86
|
+
* the current target to advance"), so omitting it looks like opting into
|
|
87
|
+
* nothing — and it grants two categories on a target the caller explicitly
|
|
88
|
+
* pinned (OSK-7669). Naming it here lets the help text and the confirmation
|
|
89
|
+
* output say the same thing the code does.
|
|
90
|
+
*/
|
|
91
|
+
exports.DEFAULT_ADVANCE_REASONS = [
|
|
92
|
+
'offline',
|
|
93
|
+
'unavailable',
|
|
94
|
+
];
|
|
81
95
|
function buildExecutionOrderPatch(input) {
|
|
82
96
|
const values = input.selectors.map((value) => String(value || '').trim()).filter(Boolean);
|
|
83
97
|
if (values.length === 0)
|
|
@@ -91,11 +105,13 @@ function buildExecutionOrderPatch(input) {
|
|
|
91
105
|
mode: 'ordered',
|
|
92
106
|
targets: targets.map((target, index) => ({
|
|
93
107
|
...target,
|
|
94
|
-
advanceOn:
|
|
95
|
-
?
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
108
|
+
advanceOn: input.strict
|
|
109
|
+
? []
|
|
110
|
+
: index < targets.length - 1
|
|
111
|
+
? advanceOn.length > 0
|
|
112
|
+
? advanceOn
|
|
113
|
+
: [...exports.DEFAULT_ADVANCE_REASONS]
|
|
114
|
+
: [],
|
|
99
115
|
})),
|
|
100
116
|
},
|
|
101
117
|
};
|
package/dist/lib/harnesses.d.ts
CHANGED
|
@@ -51,15 +51,59 @@ export interface Harness {
|
|
|
51
51
|
claudeEngine?: 'cli' | 'sdk';
|
|
52
52
|
lastSeenAt?: string;
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* One open lease, as `/api/machines/leases` actually returns it.
|
|
56
|
+
*
|
|
57
|
+
* This shape was previously guessed — it declared `productId`, `runtimeId` and
|
|
58
|
+
* `expiresAt`, none of which the server has ever sent. Optional properties made
|
|
59
|
+
* that compile, so `leases list` rendered three permanently empty columns while
|
|
60
|
+
* `--json` showed the data plainly, and the one view built to tell a
|
|
61
|
+
* Hosted Machine lease from a Hosted Job Machine lease could not.
|
|
62
|
+
*
|
|
63
|
+
* So: only fields `toPublicMachineLeasePayload` emits belong here. There is no
|
|
64
|
+
* expiry on a lease — it lives until released — and no top-level runtime id.
|
|
65
|
+
*/
|
|
54
66
|
export interface HarnessLease {
|
|
55
67
|
id?: string;
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
machineProduct?: string;
|
|
69
|
+
machineProductLabel?: string;
|
|
70
|
+
displayName?: string;
|
|
58
71
|
state?: string;
|
|
59
|
-
|
|
60
|
-
|
|
72
|
+
stateReason?: string;
|
|
73
|
+
lifecycleSemantics?: string;
|
|
74
|
+
/**
|
|
75
|
+
* `active | paused | storage | none` — whether this lease is still costing
|
|
76
|
+
* money — plus the monthly spend status the server already computes.
|
|
77
|
+
*
|
|
78
|
+
* These six were allow-listed in `PUBLIC_RUNTIME_BILLING_KEYS` and attached
|
|
79
|
+
* by `attachMonthlySpendStatus` on every lease read, and the web renders
|
|
80
|
+
* them. Nothing in the CLI read them, so the number that actually refuses a
|
|
81
|
+
* Hosted Machine — the MONTHLY cap — was unreadable from here while
|
|
82
|
+
* `skrr balance show` reported a DAILY cap with full headroom. A user who
|
|
83
|
+
* correctly suspected billing could not confirm it (OSK-7920).
|
|
84
|
+
*/
|
|
85
|
+
billing?: {
|
|
86
|
+
billableState?: string;
|
|
87
|
+
monthlySpendLimitCents?: number | null;
|
|
88
|
+
currentMonthSpendCents?: number;
|
|
89
|
+
openUsageEstimateCents?: number;
|
|
90
|
+
projectedCurrentMonthSpendCents?: number;
|
|
91
|
+
spendingLimitExceeded?: boolean;
|
|
92
|
+
spendStatusUnavailable?: boolean;
|
|
93
|
+
monthStartedAt?: string | null;
|
|
94
|
+
} & Record<string, unknown>;
|
|
95
|
+
leaseTimestamps?: Record<string, string>;
|
|
96
|
+
health?: {
|
|
97
|
+
assignable?: boolean;
|
|
98
|
+
reasons?: string[];
|
|
99
|
+
} & Record<string, unknown>;
|
|
100
|
+
storage?: {
|
|
101
|
+
retentionClass?: string;
|
|
102
|
+
lastBackupAt?: string;
|
|
103
|
+
backupProfile?: string;
|
|
104
|
+
};
|
|
61
105
|
createdAt?: string;
|
|
62
|
-
|
|
106
|
+
updatedAt?: string;
|
|
63
107
|
}
|
|
64
108
|
/** `pause | resume | destroy | terminate | health-check` (MachineLeaseService). */
|
|
65
109
|
export declare const HARNESS_LEASE_ACTIONS: string[];
|
|
@@ -80,6 +124,32 @@ export declare function getHarnessUsage(id: string): Promise<unknown>;
|
|
|
80
124
|
/** The rollup across every harness. The web calls this key `fleetUsage`. */
|
|
81
125
|
export declare function getAllHarnessUsage(): Promise<unknown>;
|
|
82
126
|
export type { QuotaAccountSummary, QuotaHistory };
|
|
127
|
+
/** One hosted product's monthly runtime spend cap and where this month stands. */
|
|
128
|
+
export type RuntimeMonthlySpend = {
|
|
129
|
+
machineProduct: string;
|
|
130
|
+
hasLimit: boolean;
|
|
131
|
+
exceeded?: boolean;
|
|
132
|
+
limitCents?: number;
|
|
133
|
+
currentSpendCents?: number;
|
|
134
|
+
openUsageEstimateCents?: number;
|
|
135
|
+
projectedCents?: number;
|
|
136
|
+
monthStartedAt?: string;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* The monthly runtime spend cap, read before it refuses anything.
|
|
140
|
+
*
|
|
141
|
+
* Distinct from the balance's own spend cap, which is a per-period RATE LIMIT
|
|
142
|
+
* on credits. A user can have headroom on that one and still be refused by
|
|
143
|
+
* this one, which is exactly what happened: every number on `balance show`
|
|
144
|
+
* said there was room while a monthly hosted-runtime cap turned every turn
|
|
145
|
+
* away (OSK-7920).
|
|
146
|
+
*/
|
|
147
|
+
export declare function getRuntimeMonthlySpend(): Promise<{
|
|
148
|
+
scope: {
|
|
149
|
+
teamId: string | null;
|
|
150
|
+
};
|
|
151
|
+
spend: RuntimeMonthlySpend[];
|
|
152
|
+
}>;
|
|
83
153
|
/** The CLI subscription accounts this user's daemons have reported readings for. */
|
|
84
154
|
export declare function listQuotaAccounts(): Promise<{
|
|
85
155
|
accounts: QuotaAccountSummary[];
|
|
@@ -123,7 +193,18 @@ export declare function readHarnessPing(id: string, pingId: string): Promise<{
|
|
|
123
193
|
latencyMs?: number;
|
|
124
194
|
error?: string;
|
|
125
195
|
}>;
|
|
126
|
-
|
|
196
|
+
/**
|
|
197
|
+
* List leases. The server answers newest-first and caps at 50 unless asked
|
|
198
|
+
* otherwise (`Math.min(Math.max(Number(limit) || 50, 1), 100)`), so an account
|
|
199
|
+
* with more than fifty leases could not see past the newest fifty from here —
|
|
200
|
+
* including `lost` ones, which are terminal, invisible, and still billed for
|
|
201
|
+
* the whole window the platform had lost track of them.
|
|
202
|
+
*/
|
|
203
|
+
export declare function listHarnessLeases(options?: {
|
|
204
|
+
limit?: number;
|
|
205
|
+
state?: string;
|
|
206
|
+
machineProduct?: string;
|
|
207
|
+
}): Promise<{
|
|
127
208
|
leases?: HarnessLease[];
|
|
128
209
|
}>;
|
|
129
210
|
export declare function getHarnessLease(leaseId: string): Promise<{
|