@skrr-ai/cli 0.1.21 → 0.1.23
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 +43 -0
- package/dist/base-command.d.ts +15 -0
- package/dist/base-command.js +71 -10
- 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/create.d.ts +1 -0
- package/dist/commands/commitments/create.js +19 -5
- 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 +48 -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/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/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 +15 -5
- package/dist/commands/tasks/complete.d.ts +18 -150
- package/dist/commands/tasks/complete.js +161 -600
- package/dist/commands/tasks/create.d.ts +5 -0
- package/dist/commands/tasks/create.js +107 -4
- package/dist/commands/tasks/deliverable/add.d.ts +8 -0
- package/dist/commands/tasks/deliverable/add.js +41 -8
- 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 +37 -0
- package/dist/commands/tasks/events/append.d.ts +2 -0
- package/dist/commands/tasks/events/append.js +11 -4
- 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 +77 -0
- package/dist/commands/tasks/expectations.js +14 -18
- package/dist/commands/tasks/judge.d.ts +1 -0
- package/dist/commands/tasks/judge.js +2 -1
- package/dist/commands/tasks/output.d.ts +2 -11
- package/dist/commands/tasks/output.js +64 -145
- package/dist/commands/tasks/report.d.ts +3 -3
- package/dist/commands/tasks/report.js +64 -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 +46 -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 +59 -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/timeline.d.ts +2 -2
- package/dist/commands/tasks/timeline.js +10 -23
- package/dist/commands/tasks/updates/add.d.ts +22 -0
- package/dist/commands/tasks/updates/add.js +101 -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 +4 -1
- package/dist/lib/commitments.js +32 -1
- package/dist/lib/conversation-search.d.ts +3 -0
- package/dist/lib/conversation-search.js +75 -0
- package/dist/lib/execution-target.d.ts +21 -0
- package/dist/lib/execution-target.js +22 -6
- package/dist/lib/harnesses.d.ts +82 -6
- package/dist/lib/harnesses.js +30 -2
- 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-transcript.d.ts +5 -7
- package/dist/lib/task-transcript.js +8 -16
- package/dist/lib/tasks.d.ts +7 -21
- package/dist/lib/tasks.js +17 -20
- 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/node_modules/@skrr-ai/data-provider/index.js +3733 -3618
- package/oclif.manifest.json +25726 -19886
- 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>>;
|
|
@@ -449,6 +450,8 @@ export declare function parseIntervalToMs(input: string): number;
|
|
|
449
450
|
export type WatchFlagInputs = {
|
|
450
451
|
watch?: string[];
|
|
451
452
|
metricKey?: string[];
|
|
453
|
+
githubEvents?: string[];
|
|
454
|
+
githubRepository?: string;
|
|
452
455
|
/** Already resolved to canonical space ids by the caller. */
|
|
453
456
|
spaceIds?: string[];
|
|
454
457
|
monitorIds?: string[];
|
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`),
|
|
@@ -438,11 +439,17 @@ function buildWatchedSources(inputs) {
|
|
|
438
439
|
const metricKeys = (inputs.metricKey ?? []).filter(Boolean);
|
|
439
440
|
const spaceIds = (inputs.spaceIds ?? []).filter(Boolean);
|
|
440
441
|
const monitorIds = (inputs.monitorIds ?? []).filter(Boolean);
|
|
442
|
+
const githubEvents = (inputs.githubEvents ?? []).filter(Boolean);
|
|
443
|
+
const githubRepository = String(inputs.githubRepository || '')
|
|
444
|
+
.trim()
|
|
445
|
+
.toLowerCase();
|
|
441
446
|
const effective = new Set(watched);
|
|
442
447
|
if (spaceIds.length)
|
|
443
448
|
effective.add('space');
|
|
444
449
|
if (monitorIds.length)
|
|
445
450
|
effective.add('monitor');
|
|
451
|
+
if (githubEvents.length)
|
|
452
|
+
effective.add('github');
|
|
446
453
|
if (effective.has('space') && spaceIds.length === 0) {
|
|
447
454
|
throw new Error('--watch space needs at least one --watch-space <space-id-or-ref>. ' +
|
|
448
455
|
'The `space` source requires a scope id, which the enum on its own cannot carry.');
|
|
@@ -466,7 +473,7 @@ function buildWatchedSources(inputs) {
|
|
|
466
473
|
seen.add(s);
|
|
467
474
|
}
|
|
468
475
|
}
|
|
469
|
-
for (const implied of ['space', 'monitor']) {
|
|
476
|
+
for (const implied of ['space', 'monitor', 'github']) {
|
|
470
477
|
if (effective.has(implied) && !seen.has(implied)) {
|
|
471
478
|
orderedSources.push(implied);
|
|
472
479
|
seen.add(implied);
|
|
@@ -487,6 +494,30 @@ function buildWatchedSources(inputs) {
|
|
|
487
494
|
else if (source === 'metrics' && metricKeys.length) {
|
|
488
495
|
rows.push({ source, enabled: true, config: { metricKeys } });
|
|
489
496
|
}
|
|
497
|
+
else if (source === 'github' && (githubEvents.length || githubRepository)) {
|
|
498
|
+
rows.push({
|
|
499
|
+
source,
|
|
500
|
+
enabled: true,
|
|
501
|
+
config: {
|
|
502
|
+
...(githubRepository ? { repository: githubRepository } : {}),
|
|
503
|
+
...(githubEvents.length
|
|
504
|
+
? {
|
|
505
|
+
events: githubEvents.map((eventType) => ({
|
|
506
|
+
entityType: 'github',
|
|
507
|
+
eventType,
|
|
508
|
+
...(githubRepository
|
|
509
|
+
? {
|
|
510
|
+
filterField: 'repoFullName',
|
|
511
|
+
filterMode: 'equals',
|
|
512
|
+
filterValue: githubRepository,
|
|
513
|
+
}
|
|
514
|
+
: {}),
|
|
515
|
+
})),
|
|
516
|
+
}
|
|
517
|
+
: {}),
|
|
518
|
+
},
|
|
519
|
+
});
|
|
520
|
+
}
|
|
490
521
|
else {
|
|
491
522
|
rows.push({ source, enabled: true });
|
|
492
523
|
}
|
|
@@ -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
|
+
}
|
|
@@ -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,54 @@ 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>;
|
|
61
100
|
createdAt?: string;
|
|
62
|
-
|
|
101
|
+
updatedAt?: string;
|
|
63
102
|
}
|
|
64
103
|
/** `pause | resume | destroy | terminate | health-check` (MachineLeaseService). */
|
|
65
104
|
export declare const HARNESS_LEASE_ACTIONS: string[];
|
|
@@ -80,6 +119,32 @@ export declare function getHarnessUsage(id: string): Promise<unknown>;
|
|
|
80
119
|
/** The rollup across every harness. The web calls this key `fleetUsage`. */
|
|
81
120
|
export declare function getAllHarnessUsage(): Promise<unknown>;
|
|
82
121
|
export type { QuotaAccountSummary, QuotaHistory };
|
|
122
|
+
/** One hosted product's monthly runtime spend cap and where this month stands. */
|
|
123
|
+
export type RuntimeMonthlySpend = {
|
|
124
|
+
machineProduct: string;
|
|
125
|
+
hasLimit: boolean;
|
|
126
|
+
exceeded?: boolean;
|
|
127
|
+
limitCents?: number;
|
|
128
|
+
currentSpendCents?: number;
|
|
129
|
+
openUsageEstimateCents?: number;
|
|
130
|
+
projectedCents?: number;
|
|
131
|
+
monthStartedAt?: string;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* The monthly runtime spend cap, read before it refuses anything.
|
|
135
|
+
*
|
|
136
|
+
* Distinct from the balance's own spend cap, which is a per-period RATE LIMIT
|
|
137
|
+
* on credits. A user can have headroom on that one and still be refused by
|
|
138
|
+
* this one, which is exactly what happened: every number on `balance show`
|
|
139
|
+
* said there was room while a monthly hosted-runtime cap turned every turn
|
|
140
|
+
* away (OSK-7920).
|
|
141
|
+
*/
|
|
142
|
+
export declare function getRuntimeMonthlySpend(): Promise<{
|
|
143
|
+
scope: {
|
|
144
|
+
teamId: string | null;
|
|
145
|
+
};
|
|
146
|
+
spend: RuntimeMonthlySpend[];
|
|
147
|
+
}>;
|
|
83
148
|
/** The CLI subscription accounts this user's daemons have reported readings for. */
|
|
84
149
|
export declare function listQuotaAccounts(): Promise<{
|
|
85
150
|
accounts: QuotaAccountSummary[];
|
|
@@ -123,7 +188,18 @@ export declare function readHarnessPing(id: string, pingId: string): Promise<{
|
|
|
123
188
|
latencyMs?: number;
|
|
124
189
|
error?: string;
|
|
125
190
|
}>;
|
|
126
|
-
|
|
191
|
+
/**
|
|
192
|
+
* List leases. The server answers newest-first and caps at 50 unless asked
|
|
193
|
+
* otherwise (`Math.min(Math.max(Number(limit) || 50, 1), 100)`), so an account
|
|
194
|
+
* with more than fifty leases could not see past the newest fifty from here —
|
|
195
|
+
* including `lost` ones, which are terminal, invisible, and still billed for
|
|
196
|
+
* the whole window the platform had lost track of them.
|
|
197
|
+
*/
|
|
198
|
+
export declare function listHarnessLeases(options?: {
|
|
199
|
+
limit?: number;
|
|
200
|
+
state?: string;
|
|
201
|
+
machineProduct?: string;
|
|
202
|
+
}): Promise<{
|
|
127
203
|
leases?: HarnessLease[];
|
|
128
204
|
}>;
|
|
129
205
|
export declare function getHarnessLease(leaseId: string): Promise<{
|
package/dist/lib/harnesses.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.getHarnessModels = getHarnessModels;
|
|
|
7
7
|
exports.listHarnessProducts = listHarnessProducts;
|
|
8
8
|
exports.getHarnessUsage = getHarnessUsage;
|
|
9
9
|
exports.getAllHarnessUsage = getAllHarnessUsage;
|
|
10
|
+
exports.getRuntimeMonthlySpend = getRuntimeMonthlySpend;
|
|
10
11
|
exports.listQuotaAccounts = listQuotaAccounts;
|
|
11
12
|
exports.getQuotaHistory = getQuotaHistory;
|
|
12
13
|
exports.updateHarness = updateHarness;
|
|
@@ -71,6 +72,18 @@ async function getAllHarnessUsage() {
|
|
|
71
72
|
const ownerWide = '?scope=all';
|
|
72
73
|
return (0, api_fetch_1.apiFetch)('/api/harnesses/usage/aggregate' + ownerWide);
|
|
73
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* The monthly runtime spend cap, read before it refuses anything.
|
|
77
|
+
*
|
|
78
|
+
* Distinct from the balance's own spend cap, which is a per-period RATE LIMIT
|
|
79
|
+
* on credits. A user can have headroom on that one and still be refused by
|
|
80
|
+
* this one, which is exactly what happened: every number on `balance show`
|
|
81
|
+
* said there was room while a monthly hosted-runtime cap turned every turn
|
|
82
|
+
* away (OSK-7920).
|
|
83
|
+
*/
|
|
84
|
+
async function getRuntimeMonthlySpend() {
|
|
85
|
+
return (0, api_fetch_1.apiFetch)('/api/harnesses/spend');
|
|
86
|
+
}
|
|
74
87
|
/** The CLI subscription accounts this user's daemons have reported readings for. */
|
|
75
88
|
async function listQuotaAccounts() {
|
|
76
89
|
return (0, api_fetch_1.apiFetch)('/api/harnesses/quota/accounts');
|
|
@@ -149,8 +162,23 @@ async function readHarnessPing(id, pingId) {
|
|
|
149
162
|
return (0, api_fetch_1.apiFetch)(`/api/harnesses/${encodeURIComponent(id)}/ping/${encodeURIComponent(pingId)}`);
|
|
150
163
|
}
|
|
151
164
|
// ── Leases (hosted billing plane) ──────────────────────────────────────────
|
|
152
|
-
|
|
153
|
-
|
|
165
|
+
/**
|
|
166
|
+
* List leases. The server answers newest-first and caps at 50 unless asked
|
|
167
|
+
* otherwise (`Math.min(Math.max(Number(limit) || 50, 1), 100)`), so an account
|
|
168
|
+
* with more than fifty leases could not see past the newest fifty from here —
|
|
169
|
+
* including `lost` ones, which are terminal, invisible, and still billed for
|
|
170
|
+
* the whole window the platform had lost track of them.
|
|
171
|
+
*/
|
|
172
|
+
async function listHarnessLeases(options = {}) {
|
|
173
|
+
const query = new URLSearchParams();
|
|
174
|
+
if (options.limit)
|
|
175
|
+
query.set('limit', String(options.limit));
|
|
176
|
+
if (options.state)
|
|
177
|
+
query.set('state', options.state);
|
|
178
|
+
if (options.machineProduct)
|
|
179
|
+
query.set('machineProduct', options.machineProduct);
|
|
180
|
+
const suffix = query.toString() ? `?${query.toString()}` : '';
|
|
181
|
+
return (0, api_fetch_1.apiFetch)(`/api/machines/leases${suffix}`);
|
|
154
182
|
}
|
|
155
183
|
async function getHarnessLease(leaseId) {
|
|
156
184
|
return (0, api_fetch_1.apiFetch)(`/api/machines/leases/${encodeURIComponent(leaseId)}`);
|
|
@@ -237,6 +237,15 @@ async function waitForHostedMachineReady(id, options) {
|
|
|
237
237
|
const detail = hostedMachineErrorSummary(session);
|
|
238
238
|
throw new Error(`Hosted Machine ${id} reached ${status}${detail ? `: ${detail}` : ''}`);
|
|
239
239
|
}
|
|
240
|
+
// Async resume deliberately rolls a recoverable failure back to `paused`
|
|
241
|
+
// so the retained workspace remains resumable. That is terminal for THIS
|
|
242
|
+
// wait operation even though it is not terminal for the machine. The
|
|
243
|
+
// resuming transition clears old error state, so an error-bearing paused
|
|
244
|
+
// row here belongs to the attempt we just started.
|
|
245
|
+
if (status === 'paused') {
|
|
246
|
+
const detail = hostedMachineErrorSummary(session);
|
|
247
|
+
throw new Error(`Hosted Machine ${id} returned to paused before it became ready${detail ? `: ${detail}` : ''}`);
|
|
248
|
+
}
|
|
240
249
|
if (options.timeoutMs && Date.now() - startedAt >= options.timeoutMs) {
|
|
241
250
|
throw new HostedMachineReadyTimeoutError(id, hostedMachineProgressSummary(session));
|
|
242
251
|
}
|
package/dist/lib/inbox.d.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Gap analysis §3.3 (b): *"50 个命令组中没有 `skrr inbox` / `listen` / `tail` /
|
|
5
5
|
* `notify`,CLI 全是 pull"*. The audit's third use case wants an agent that
|
|
6
6
|
* *"像真人一样时不时发两三条消息"* — and the reply half of that loop already
|
|
7
|
-
* works (`skrr agents chat --conversation <id
|
|
7
|
+
* works (`skrr agents chat <agent-id> --conversation <id> --prompt "…"` stamps
|
|
8
|
+
* `Message.intentId` and
|
|
8
9
|
* wakes the originating run). What was missing is the other direction: nothing
|
|
9
10
|
* in the CLI ever told you the agent had said something.
|
|
10
11
|
*
|
package/dist/lib/machines.d.ts
CHANGED
|
@@ -87,6 +87,23 @@ export interface Machine {
|
|
|
87
87
|
canTerminate: boolean;
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* What a machine's state actually is, when `offline` is doing two jobs.
|
|
92
|
+
*
|
|
93
|
+
* A TERMINATED ephemeral sandbox — destroyed, unrecoverable, `canResume:
|
|
94
|
+
* false`, no lease — rendered `offline`, identically to a machine that is
|
|
95
|
+
* merely not connected right now. Those are opposite situations: one can come
|
|
96
|
+
* back and one never will, and the board's original target turned out to be the
|
|
97
|
+
* second while every surface said the first. The only way to learn the
|
|
98
|
+
* difference was to run `skrr machines hosted list` separately and match
|
|
99
|
+
* sandbox ids by hand (OSK-7639).
|
|
100
|
+
*
|
|
101
|
+
* `canResume` is the discriminator the payload already carries: a machine that
|
|
102
|
+
* could come back says so, and a destroyed one cannot.
|
|
103
|
+
*/
|
|
104
|
+
export declare function machineStateLabel(machine: Machine): string;
|
|
105
|
+
/** Is this a machine a user could still use, or bring back? */
|
|
106
|
+
export declare function isReachableMachine(machine: Machine): boolean;
|
|
90
107
|
/** The user-editable slice. Identities, capabilities and lifecycle are not. */
|
|
91
108
|
export interface MachinePreferencesPatch {
|
|
92
109
|
name?: string;
|
package/dist/lib/machines.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.machineStateLabel = machineStateLabel;
|
|
4
|
+
exports.isReachableMachine = isReachableMachine;
|
|
3
5
|
exports.liveHarnessCount = liveHarnessCount;
|
|
4
6
|
exports.listMachines = listMachines;
|
|
5
7
|
exports.getMachine = getMachine;
|
|
@@ -7,6 +9,33 @@ exports.updateMachine = updateMachine;
|
|
|
7
9
|
exports.disconnectMachine = disconnectMachine;
|
|
8
10
|
exports.resolveMachineRef = resolveMachineRef;
|
|
9
11
|
const api_fetch_1 = require("./api-fetch");
|
|
12
|
+
/**
|
|
13
|
+
* What a machine's state actually is, when `offline` is doing two jobs.
|
|
14
|
+
*
|
|
15
|
+
* A TERMINATED ephemeral sandbox — destroyed, unrecoverable, `canResume:
|
|
16
|
+
* false`, no lease — rendered `offline`, identically to a machine that is
|
|
17
|
+
* merely not connected right now. Those are opposite situations: one can come
|
|
18
|
+
* back and one never will, and the board's original target turned out to be the
|
|
19
|
+
* second while every surface said the first. The only way to learn the
|
|
20
|
+
* difference was to run `skrr machines hosted list` separately and match
|
|
21
|
+
* sandbox ids by hand (OSK-7639).
|
|
22
|
+
*
|
|
23
|
+
* `canResume` is the discriminator the payload already carries: a machine that
|
|
24
|
+
* could come back says so, and a destroyed one cannot.
|
|
25
|
+
*/
|
|
26
|
+
function machineStateLabel(machine) {
|
|
27
|
+
if (machine.status !== 'offline')
|
|
28
|
+
return machine.status;
|
|
29
|
+
const controls = machine.controls;
|
|
30
|
+
if (controls && controls.canResume === false && controls.canTerminate === false) {
|
|
31
|
+
return 'terminated';
|
|
32
|
+
}
|
|
33
|
+
return 'offline';
|
|
34
|
+
}
|
|
35
|
+
/** Is this a machine a user could still use, or bring back? */
|
|
36
|
+
function isReachableMachine(machine) {
|
|
37
|
+
return machineStateLabel(machine) !== 'terminated' && machine.status !== 'offline';
|
|
38
|
+
}
|
|
10
39
|
/**
|
|
11
40
|
* How many of a machine's harnesses still represent a capability it has.
|
|
12
41
|
*
|