@skrr-ai/cli 0.1.91 → 0.1.93
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/dist/base-command.d.ts +44 -0
- package/dist/base-command.js +96 -0
- package/dist/commands/agents/badge.d.ts +41 -0
- package/dist/commands/agents/badge.js +158 -0
- package/dist/commands/agents/create.d.ts +24 -0
- package/dist/commands/agents/create.js +212 -0
- package/dist/commands/agents/embed.d.ts +20 -0
- package/dist/commands/agents/embed.js +61 -0
- package/dist/commands/agents/share.d.ts +27 -0
- package/dist/commands/agents/share.js +100 -0
- package/dist/commands/agents/vanity.d.ts +21 -0
- package/dist/commands/agents/vanity.js +77 -0
- package/dist/commands/agents/visibility.d.ts +21 -1
- package/dist/commands/agents/visibility.js +112 -0
- package/dist/commands/commands.d.ts +1 -0
- package/dist/commands/commands.js +22 -9
- package/dist/commands/earnings/attributions.d.ts +17 -0
- package/dist/commands/earnings/attributions.js +82 -0
- package/dist/commands/earnings/index.js +2 -1
- package/dist/commands/generate-recovery-code.js +4 -3
- package/dist/commands/github/allow-tools.d.ts +1 -0
- package/dist/commands/github/app/install.d.ts +1 -0
- package/dist/commands/github/app/status.d.ts +1 -0
- package/dist/commands/github/connect.d.ts +1 -0
- package/dist/commands/github/connections.d.ts +1 -0
- package/dist/commands/github/disconnect.d.ts +1 -0
- package/dist/commands/github/finalize.d.ts +1 -0
- package/dist/commands/github/reconnect.d.ts +1 -0
- package/dist/commands/github/run.d.ts +1 -0
- package/dist/commands/github/tools.d.ts +1 -0
- package/dist/commands/integrations/connections/connect.d.ts +1 -0
- package/dist/commands/integrations/connections/disconnect.d.ts +1 -0
- package/dist/commands/integrations/connections/finalize.d.ts +1 -0
- package/dist/commands/integrations/connections/list.d.ts +1 -0
- package/dist/commands/integrations/connections/reconnect.d.ts +1 -0
- package/dist/commands/integrations/execute.d.ts +1 -0
- package/dist/commands/integrations/search.d.ts +1 -0
- package/dist/commands/integrations/toolkits.d.ts +1 -0
- package/dist/commands/integrations/tools/allow.d.ts +1 -0
- package/dist/commands/integrations/tools/list.d.ts +1 -0
- package/dist/commands/login.js +12 -0
- package/dist/commands/machines/dedicated/logs.d.ts +19 -0
- package/dist/commands/machines/dedicated/logs.js +103 -0
- package/dist/commands/machines/dedicated/power/index.js +3 -2
- package/dist/commands/machines/dedicated/power/set.js +1 -1
- package/dist/commands/machines/dedicated/power/waiting.d.ts +13 -0
- package/dist/commands/machines/dedicated/power/waiting.js +36 -0
- package/dist/commands/open.d.ts +24 -0
- package/dist/commands/open.js +74 -0
- package/dist/commands/projects/archive.d.ts +1 -0
- package/dist/commands/projects/archive.js +23 -0
- package/dist/commands/projects/delete.d.ts +1 -0
- package/dist/commands/projects/delete.js +23 -0
- package/dist/commands/projects/list.d.ts +3 -0
- package/dist/commands/projects/list.js +12 -2
- package/dist/commands/spaces/actions/add.js +4 -3
- package/dist/commands/spaces/actions/available.js +3 -2
- package/dist/commands/spaces/actions/list.js +5 -4
- package/dist/commands/spaces/actions/replace.js +6 -5
- package/dist/commands/spaces/archive.js +3 -2
- package/dist/commands/spaces/auto-executor/preview.js +4 -3
- package/dist/commands/spaces/auto-executor/run.js +4 -3
- package/dist/commands/spaces/auto-executor/runs.js +3 -2
- package/dist/commands/spaces/auto-executor/update.js +4 -3
- package/dist/commands/spaces/bootstrap.js +3 -2
- package/dist/commands/spaces/briefs/delete.js +3 -2
- package/dist/commands/spaces/briefs/get.js +3 -2
- package/dist/commands/spaces/briefs/list.js +3 -2
- package/dist/commands/spaces/briefs/set.js +5 -4
- package/dist/commands/spaces/capacity.js +5 -4
- package/dist/commands/spaces/conversations.js +3 -2
- package/dist/commands/spaces/cycles/create.js +3 -2
- package/dist/commands/spaces/cycles/graph.js +2 -1
- package/dist/commands/spaces/cycles/list.js +3 -2
- package/dist/commands/spaces/cycles/settings.js +4 -3
- package/dist/commands/spaces/cycles/show.js +3 -2
- package/dist/commands/spaces/cycles/update.js +3 -2
- package/dist/commands/spaces/delete.js +4 -3
- package/dist/commands/spaces/expertise-suggestions.js +4 -3
- package/dist/commands/spaces/files/delete.js +3 -2
- package/dist/commands/spaces/files/folders/create.js +3 -2
- package/dist/commands/spaces/files/folders/delete.js +3 -2
- package/dist/commands/spaces/files/folders/list.js +3 -2
- package/dist/commands/spaces/files/folders/update.js +3 -2
- package/dist/commands/spaces/files/list.js +3 -2
- package/dist/commands/spaces/files/move.js +3 -2
- package/dist/commands/spaces/files/rename.js +3 -2
- package/dist/commands/spaces/files/upload.js +6 -5
- package/dist/commands/spaces/github-automations/set.js +3 -2
- package/dist/commands/spaces/github-automations/show.js +3 -2
- package/dist/commands/spaces/goals.js +2 -1
- package/dist/commands/spaces/heartbeats/create.js +4 -3
- package/dist/commands/spaces/heartbeats/delete.js +4 -3
- package/dist/commands/spaces/heartbeats/list.js +4 -3
- package/dist/commands/spaces/heartbeats/status.js +3 -2
- package/dist/commands/spaces/heartbeats/update.js +4 -3
- package/dist/commands/spaces/insights.js +5 -4
- package/dist/commands/spaces/labels/add.js +4 -3
- package/dist/commands/spaces/labels/list.js +2 -1
- package/dist/commands/spaces/labels/remove.js +4 -3
- package/dist/commands/spaces/list.d.ts +3 -0
- package/dist/commands/spaces/list.js +11 -2
- package/dist/commands/spaces/live/cards/create.js +3 -2
- package/dist/commands/spaces/live/cards/list.js +3 -2
- package/dist/commands/spaces/live/cards/reorder.js +7 -2
- package/dist/commands/spaces/live/scene.js +4 -3
- package/dist/commands/spaces/members/add.js +7 -6
- package/dist/commands/spaces/members/list.js +4 -3
- package/dist/commands/spaces/members/remove.js +7 -6
- package/dist/commands/spaces/move.js +3 -2
- package/dist/commands/spaces/pin.js +5 -4
- package/dist/commands/spaces/preferences/show.js +4 -3
- package/dist/commands/spaces/preferences/tabs.js +4 -3
- package/dist/commands/spaces/revisions.js +3 -2
- package/dist/commands/spaces/room/ensure.js +5 -4
- package/dist/commands/spaces/room/messages.js +3 -2
- package/dist/commands/spaces/room/show.js +5 -4
- package/dist/commands/spaces/skills/add.js +4 -3
- package/dist/commands/spaces/skills/list.js +3 -2
- package/dist/commands/spaces/skills/pin.js +4 -3
- package/dist/commands/spaces/skills/remove.js +4 -3
- package/dist/commands/spaces/snapshot.js +3 -2
- package/dist/commands/spaces/states/archive.js +3 -2
- package/dist/commands/spaces/states/create.js +3 -2
- package/dist/commands/spaces/states/list.js +3 -2
- package/dist/commands/spaces/states/reorder.js +2 -1
- package/dist/commands/spaces/states/update.js +3 -2
- package/dist/commands/spaces/summary.js +4 -3
- package/dist/commands/spaces/tasks.d.ts +3 -0
- package/dist/commands/spaces/tasks.js +14 -3
- package/dist/commands/spaces/triggers/delete.js +5 -4
- package/dist/commands/spaces/triggers/set.js +4 -3
- package/dist/commands/spaces/triggers/show.js +4 -3
- package/dist/commands/spaces/unarchive.js +3 -2
- package/dist/commands/spaces/update.js +5 -4
- package/dist/commands/spaces/views/create.js +3 -2
- package/dist/commands/spaces/views/list.js +3 -2
- package/dist/commands/spaces/views/reorder.js +6 -3
- package/dist/commands/spaces/views/subscribe.js +2 -1
- package/dist/commands/spaces/views/subscriptions.js +1 -0
- package/dist/commands/spaces/views/unsubscribe.js +2 -1
- package/dist/commands/spaces/widgets/add.js +4 -3
- package/dist/commands/spaces/widgets/list.js +3 -2
- package/dist/commands/spaces/widgets/remove.js +5 -4
- package/dist/commands/spaces/work-graph.js +2 -1
- package/dist/commands/store/install.d.ts +1 -1
- package/dist/commands/store/install.js +24 -8
- package/dist/commands/store/show.d.ts +25 -0
- package/dist/commands/store/show.js +203 -0
- package/dist/commands/store/stats.d.ts +33 -0
- package/dist/commands/store/stats.js +258 -0
- package/dist/commands/tasks/actions/attach.js +1 -1
- package/dist/commands/tasks/actions/detach.js +4 -3
- package/dist/commands/tasks/activity.js +3 -2
- package/dist/commands/tasks/ancestors.js +2 -1
- package/dist/commands/tasks/approvals/create.js +2 -1
- package/dist/commands/tasks/approvals/delete.js +3 -2
- package/dist/commands/tasks/approvals/list.js +5 -4
- package/dist/commands/tasks/approvals/resolve.js +2 -1
- package/dist/commands/tasks/archive.js +3 -2
- package/dist/commands/tasks/assign.js +4 -3
- package/dist/commands/tasks/attachments/delete.js +3 -2
- package/dist/commands/tasks/attachments/download.d.ts +1 -0
- package/dist/commands/tasks/attachments/download.js +20 -1
- package/dist/commands/tasks/attachments/list.js +2 -1
- package/dist/commands/tasks/attachments/set-role.js +2 -1
- package/dist/commands/tasks/attachments/upload.js +2 -1
- package/dist/commands/tasks/bulk-update.d.ts +1 -0
- package/dist/commands/tasks/bulk-update.js +106 -15
- package/dist/commands/tasks/cancel-cascade.d.ts +1 -0
- package/dist/commands/tasks/cancel-cascade.js +13 -3
- package/dist/commands/tasks/cascade-status.js +2 -1
- package/dist/commands/tasks/chat/send.d.ts +44 -0
- package/dist/commands/tasks/chat/send.js +112 -0
- package/dist/commands/tasks/checkout.js +3 -2
- package/dist/commands/tasks/children.js +2 -1
- package/dist/commands/tasks/comments/add.js +7 -6
- package/dist/commands/tasks/comments/anchor.js +8 -7
- package/dist/commands/tasks/comments/delete.js +3 -2
- package/dist/commands/tasks/comments/list.js +2 -1
- package/dist/commands/tasks/comments/reopen.js +3 -2
- package/dist/commands/tasks/comments/resolve.js +3 -2
- package/dist/commands/tasks/create-tree.d.ts +63 -0
- package/dist/commands/tasks/create-tree.js +197 -4
- package/dist/commands/tasks/delete.js +5 -4
- package/dist/commands/tasks/descendants.js +2 -1
- package/dist/commands/tasks/dri-plan.js +3 -2
- package/dist/commands/tasks/dri-run.js +3 -2
- package/dist/commands/tasks/dri-status.js +2 -1
- package/dist/commands/tasks/duplicate-pipeline.js +2 -1
- package/dist/commands/tasks/execution-summary.js +2 -1
- package/dist/commands/tasks/execution-timeline.js +2 -1
- package/dist/commands/tasks/fork.js +1 -0
- package/dist/commands/tasks/forward.js +4 -3
- package/dist/commands/tasks/handover.js +1 -0
- package/dist/commands/tasks/interrupt.js +3 -2
- package/dist/commands/tasks/labels/attach.js +4 -3
- package/dist/commands/tasks/labels/detach.js +4 -3
- package/dist/commands/tasks/labels/suggest.js +5 -4
- package/dist/commands/tasks/list.d.ts +27 -1
- package/dist/commands/tasks/list.js +101 -3
- package/dist/commands/tasks/move.js +4 -3
- package/dist/commands/tasks/output.js +6 -5
- package/dist/commands/tasks/pause-schedule.js +3 -2
- package/dist/commands/tasks/promote.js +1 -0
- package/dist/commands/tasks/prompt-log.js +2 -1
- package/dist/commands/tasks/release.js +5 -4
- package/dist/commands/tasks/remind.js +2 -1
- package/dist/commands/tasks/replay.js +3 -2
- package/dist/commands/tasks/report.js +1 -0
- package/dist/commands/tasks/resume-schedule.js +3 -2
- package/dist/commands/tasks/retry-schedule.js +3 -2
- package/dist/commands/tasks/retry.js +10 -9
- package/dist/commands/tasks/revisions.js +2 -1
- package/dist/commands/tasks/runs.js +6 -5
- package/dist/commands/tasks/schedule.js +3 -2
- package/dist/commands/tasks/self-schedule.js +6 -5
- package/dist/commands/tasks/skills/pin.js +3 -2
- package/dist/commands/tasks/skills/unpin.js +3 -2
- package/dist/commands/tasks/snooze.js +6 -5
- package/dist/commands/tasks/start-all.js +5 -4
- package/dist/commands/tasks/subscribe.js +1 -0
- package/dist/commands/tasks/tags/add.js +4 -3
- package/dist/commands/tasks/tags/remove.js +4 -3
- package/dist/commands/tasks/timeline.js +3 -2
- package/dist/commands/tasks/today.d.ts +4 -1
- package/dist/commands/tasks/today.js +12 -2
- package/dist/commands/tasks/transcript.js +6 -5
- package/dist/commands/tasks/unschedule.js +3 -2
- package/dist/commands/tasks/unsnooze.js +3 -2
- package/dist/commands/tasks/unsubscribe.js +2 -1
- package/dist/commands/tasks/update.js +5 -4
- package/dist/commands/tasks/wait.js +5 -4
- package/dist/lib/agent-distribution.d.ts +37 -0
- package/dist/lib/agent-distribution.js +63 -0
- package/dist/lib/agent-ref.d.ts +69 -0
- package/dist/lib/agent-ref.js +168 -0
- package/dist/lib/api-fetch.d.ts +2 -0
- package/dist/lib/api-fetch.js +14 -3
- package/dist/lib/command-hygiene.d.ts +13 -0
- package/dist/lib/command-hygiene.js +62 -2
- package/dist/lib/dedicated-power.d.ts +16 -1
- package/dist/lib/dedicated-power.js +153 -2
- package/dist/lib/dry-run-plans.d.ts +50 -0
- package/dist/lib/dry-run-plans.js +85 -0
- package/dist/lib/json-output.d.ts +31 -0
- package/dist/lib/json-output.js +78 -0
- package/dist/lib/list-output.d.ts +75 -0
- package/dist/lib/list-output.js +266 -0
- package/dist/lib/machine-daemon-log.d.ts +36 -0
- package/dist/lib/machine-daemon-log.js +78 -0
- package/dist/lib/node-adapter.js +10 -1
- package/dist/lib/open-target.d.ts +12 -0
- package/dist/lib/open-target.js +108 -0
- package/dist/lib/rate-limit-retry.d.ts +45 -0
- package/dist/lib/rate-limit-retry.js +88 -0
- package/dist/lib/store-listing.d.ts +45 -0
- package/dist/lib/store-listing.js +186 -0
- package/dist/lib/task-batch.d.ts +67 -0
- package/dist/lib/task-batch.js +227 -0
- package/dist/lib/terminal-qr.d.ts +55 -0
- package/dist/lib/terminal-qr.js +119 -0
- package/dist/lib/web-url.d.ts +11 -0
- package/dist/lib/web-url.js +24 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +46 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +6615 -6112
- package/oclif.manifest.json +41499 -32585
- package/package.json +2 -1
|
@@ -4,9 +4,15 @@ exports.setDedicatedPowerPolicy = setDedicatedPowerPolicy;
|
|
|
4
4
|
exports.describePolicyWords = describePolicyWords;
|
|
5
5
|
exports.describePowerPolicy = describePowerPolicy;
|
|
6
6
|
exports.getDedicatedPowerSummary = getDedicatedPowerSummary;
|
|
7
|
+
exports.getDedicatedWaitingWork = getDedicatedWaitingWork;
|
|
8
|
+
exports.describeWaitingWork = describeWaitingWork;
|
|
9
|
+
exports.describeLastWakeTiming = describeLastWakeTiming;
|
|
10
|
+
exports.describeOnDemandAvailability = describeOnDemandAvailability;
|
|
11
|
+
exports.describePrewarm = describePrewarm;
|
|
7
12
|
exports.describePowerDecisionLines = describePowerDecisionLines;
|
|
8
13
|
exports.describeLastAutoStopLines = describeLastAutoStopLines;
|
|
9
14
|
exports.describeLastWakeDecisionLines = describeLastWakeDecisionLines;
|
|
15
|
+
exports.describePendingStopLines = describePendingStopLines;
|
|
10
16
|
exports.describePowerSummary = describePowerSummary;
|
|
11
17
|
exports.describePowerExplanation = describePowerExplanation;
|
|
12
18
|
exports.describeBudget = describeBudget;
|
|
@@ -45,7 +51,7 @@ async function setDedicatedPowerPolicy(leaseId, request, scope = {}) {
|
|
|
45
51
|
return {
|
|
46
52
|
ok: false,
|
|
47
53
|
refusal: {
|
|
48
|
-
error: String(body.error ?? '
|
|
54
|
+
error: String(body.error ?? 'On demand is not available for this machine yet.'),
|
|
49
55
|
code: 'ON_DEMAND_INELIGIBLE',
|
|
50
56
|
reason: reason,
|
|
51
57
|
detail: String(body.detail ?? copy?.detail ?? ''),
|
|
@@ -83,11 +89,126 @@ function describePowerPolicy(power, autoStopMode) {
|
|
|
83
89
|
function getDedicatedPowerSummary(leaseId, scope = {}) {
|
|
84
90
|
return (0, api_fetch_1.apiFetch)((0, dedicated_machines_1.withDedicatedScope)(`/api/machines/dedicated/${encodeURIComponent(leaseId)}/power`, scope));
|
|
85
91
|
}
|
|
92
|
+
/** `GET /api/machines/dedicated/:leaseId/power/waiting` — work waiting for this machine. */
|
|
93
|
+
function getDedicatedWaitingWork(leaseId, scope = {}) {
|
|
94
|
+
return (0, api_fetch_1.apiFetch)((0, dedicated_machines_1.withDedicatedScope)(`/api/machines/dedicated/${encodeURIComponent(leaseId)}/power/waiting`, scope));
|
|
95
|
+
}
|
|
96
|
+
const WAITING_SOURCE_LABELS = {
|
|
97
|
+
dispatch_intent: 'just dispatched',
|
|
98
|
+
parked_fire: 'parked trigger fire',
|
|
99
|
+
parked_run: 'parked run',
|
|
100
|
+
queued_run: 'queued run',
|
|
101
|
+
agent_queued_run: 'queued run (agent)',
|
|
102
|
+
expected_firing: 'expected firing',
|
|
103
|
+
};
|
|
104
|
+
/** The lines of `power waiting`. An unreadable source is said, never folded into "nothing waiting". */
|
|
105
|
+
function describeWaitingWork(waiting, when = {}) {
|
|
106
|
+
const lines = [`Dedicated Runtime ${waiting.leaseId} (${waiting.state})`];
|
|
107
|
+
if (waiting.items.length === 0 && waiting.unreadable.length === 0) {
|
|
108
|
+
lines.push('Waiting work: none');
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
lines.push(waiting.items.length === 0
|
|
112
|
+
? 'Waiting work: none seen'
|
|
113
|
+
: `Waiting work: ${waiting.items.length} item${waiting.items.length === 1 ? '' : 's'}`);
|
|
114
|
+
for (const item of waiting.items) {
|
|
115
|
+
const label = WAITING_SOURCE_LABELS[item.source] ?? item.source;
|
|
116
|
+
lines.push(` - ${label} ${item.ref}${item.since ? ` · since ${(0, format_1.formatWhen)(item.since, when)}` : ''}`);
|
|
117
|
+
if (item.detail)
|
|
118
|
+
lines.push(` ${item.detail}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (waiting.truncated.length > 0) {
|
|
122
|
+
lines.push(`More exists than is listed (${waiting.truncated.join(', ')}).`);
|
|
123
|
+
}
|
|
124
|
+
for (const u of waiting.unreadable) {
|
|
125
|
+
lines.push(`Cannot see ${u.source} (${u.reason}) — treat the list as incomplete.`);
|
|
126
|
+
}
|
|
127
|
+
const up = waiting.upcoming;
|
|
128
|
+
if (up) {
|
|
129
|
+
if (up.items.length > 0) {
|
|
130
|
+
lines.push(`Scheduled to fire: ${up.items.length}${up.truncated ? '+' : ''}`);
|
|
131
|
+
for (const f of up.items) {
|
|
132
|
+
lines.push(` - ${f.source} ${f.title ?? f.ref}${f.at ? ` · ${(0, format_1.formatWhen)(f.at, when)}` : ''}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else if (up.unreadable.length === 0) {
|
|
136
|
+
lines.push('Scheduled to fire: none');
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
lines.push('Scheduled to fire: none seen');
|
|
140
|
+
}
|
|
141
|
+
if (up.overdue > 0) {
|
|
142
|
+
lines.push(`${up.overdue} overdue firing${up.overdue === 1 ? '' : 's'} not yet fired.`);
|
|
143
|
+
}
|
|
144
|
+
for (const u of up.unreadable) {
|
|
145
|
+
lines.push(`Cannot see ${u.source} (${u.reason}) — scheduled firings may be missing.`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (waiting.state === 'stopped' && waiting.items.length > 0) {
|
|
149
|
+
lines.push('The machine is stopped. `skrr machines dedicated start <lease> --wait` starts it; work on an on_demand machine wakes it by itself.');
|
|
150
|
+
}
|
|
151
|
+
return lines;
|
|
152
|
+
}
|
|
153
|
+
const PHASE_ORDER = [
|
|
154
|
+
'start_requested',
|
|
155
|
+
'provider_start_accepted',
|
|
156
|
+
'instance_running',
|
|
157
|
+
'daemon_connected',
|
|
158
|
+
'first_heartbeat',
|
|
159
|
+
'assignable',
|
|
160
|
+
];
|
|
161
|
+
function formatMs(ms) {
|
|
162
|
+
return ms >= 1000 ? `${Math.round(ms / 100) / 10}s` : `${Math.round(ms)}ms`;
|
|
163
|
+
}
|
|
164
|
+
/** Last wake timing. A wake that never became assignable shows the phases it reached and no latency. */
|
|
165
|
+
function describeLastWakeTiming(wake) {
|
|
166
|
+
if (!wake)
|
|
167
|
+
return [];
|
|
168
|
+
const known = Object.keys(wake.phases ?? {});
|
|
169
|
+
const names = [
|
|
170
|
+
...PHASE_ORDER.filter((p) => known.includes(p)),
|
|
171
|
+
...known.filter((p) => !PHASE_ORDER.includes(p)),
|
|
172
|
+
].filter((p) => p !== 'start_requested');
|
|
173
|
+
const phases = names.map((p) => `${p} +${formatMs(wake.phases[p])}`).join(', ');
|
|
174
|
+
const total = wake.latencyMs === null || wake.latencyMs === undefined
|
|
175
|
+
? 'not ready yet (no latency recorded)'
|
|
176
|
+
: `ready after ${formatMs(wake.latencyMs)}`;
|
|
177
|
+
return [`Wake timing: ${total}${phases ? ` — ${phases}` : ''}`];
|
|
178
|
+
}
|
|
179
|
+
/** on_demand availability, so a plan does not need a failed `power set` to find out. */
|
|
180
|
+
function describeOnDemandAvailability(onDemand) {
|
|
181
|
+
if (!onDemand)
|
|
182
|
+
return [];
|
|
183
|
+
if (onDemand.eligible)
|
|
184
|
+
return ['on_demand: available'];
|
|
185
|
+
return [
|
|
186
|
+
`on_demand: not available (${onDemand.reason})`,
|
|
187
|
+
` ${onDemand.detail}`,
|
|
188
|
+
` Fix: ${onDemand.fix}`,
|
|
189
|
+
];
|
|
190
|
+
}
|
|
191
|
+
/** Pre-warm lines: only a PAUSED pre-warm is in the summary, so silence here is not "pre-warm is on". */
|
|
192
|
+
function describePrewarm(prewarm, when = {}) {
|
|
193
|
+
if (!prewarm?.paused)
|
|
194
|
+
return [];
|
|
195
|
+
const lines = [
|
|
196
|
+
`Pre-warm: paused${prewarm.since ? ` since ${(0, format_1.formatWhen)(prewarm.since, when)}` : ''} (${prewarm.idleStreak} early start${prewarm.idleStreak === 1 ? '' : 's'} in a row went unused)`,
|
|
197
|
+
];
|
|
198
|
+
if (prewarm.decision?.detail)
|
|
199
|
+
lines.push(` ${prewarm.decision.detail}`);
|
|
200
|
+
if (prewarm.decision?.fix)
|
|
201
|
+
lines.push(` ${prewarm.decision.fix}`);
|
|
202
|
+
return lines;
|
|
203
|
+
}
|
|
86
204
|
/** The stay/stop/wake decision in words: the shared reason copy backs the server's detail. */
|
|
87
205
|
function describePowerDecisionLines(decision) {
|
|
88
206
|
const copy = (0, data_provider_1.describePowerReason)(decision.reason);
|
|
89
207
|
const VERBS = { stay: 'Staying on', stop: 'Stopped', wake: 'Wake' };
|
|
90
|
-
|
|
208
|
+
// `stop_scheduled` answers the stop question for a machine that is still running.
|
|
209
|
+
const verb = decision.reason === 'stop_scheduled'
|
|
210
|
+
? 'Scheduled to stop'
|
|
211
|
+
: (VERBS[decision.question] ?? decision.question);
|
|
91
212
|
return {
|
|
92
213
|
// The headline is the human label only; the reason token lives in `--json` and `power explain`.
|
|
93
214
|
// With no shared copy and no server detail there is no sentence, so the token is the last resort.
|
|
@@ -158,6 +279,28 @@ function describeLastWakeDecisionLines(wake, when = {}) {
|
|
|
158
279
|
lines.push(` ${wake.fix}`);
|
|
159
280
|
return lines;
|
|
160
281
|
}
|
|
282
|
+
/** What the Keep awake offered by the stop notice means in the CLI: two hours. */
|
|
283
|
+
const PENDING_STOP_KEEP_AWAKE_HOURS = 2;
|
|
284
|
+
/**
|
|
285
|
+
* The announced-but-not-yet-done stop, in the shared words (`describePendingStop`). Empty when the
|
|
286
|
+
* summary carries none, which is also what an older server sends: absent is not "no stop coming".
|
|
287
|
+
*/
|
|
288
|
+
function describePendingStopLines(summary, when = {}) {
|
|
289
|
+
const pending = summary.pendingStop;
|
|
290
|
+
if (!pending)
|
|
291
|
+
return [];
|
|
292
|
+
const words = (0, data_provider_1.describePendingStop)(pending, {
|
|
293
|
+
nowMs: (when.now ?? new Date()).getTime(),
|
|
294
|
+
when: (0, format_1.formatWhen)(pending.stopsAt, when),
|
|
295
|
+
capWhen: pending.unreachableStopsAt ? (0, format_1.formatWhen)(pending.unreachableStopsAt, when) : null,
|
|
296
|
+
keepAwakeHours: PENDING_STOP_KEEP_AWAKE_HOURS,
|
|
297
|
+
});
|
|
298
|
+
const lines = [`Stop: ${words.headline}`];
|
|
299
|
+
if (words.detail)
|
|
300
|
+
lines.push(` ${words.detail}`);
|
|
301
|
+
lines.push(` ${words.fix} skrr machines dedicated power keep-awake ${summary.leaseId} --for ${PENDING_STOP_KEEP_AWAKE_HOURS}h`);
|
|
302
|
+
return lines;
|
|
303
|
+
}
|
|
161
304
|
/** The lines of `power show`. */
|
|
162
305
|
function describePowerSummary(summary, when = {}) {
|
|
163
306
|
const { power } = summary;
|
|
@@ -186,6 +329,7 @@ function describePowerSummary(summary, when = {}) {
|
|
|
186
329
|
lines.push('Decision: nothing to explain for this state');
|
|
187
330
|
}
|
|
188
331
|
}
|
|
332
|
+
lines.push(...describePendingStopLines(summary, when));
|
|
189
333
|
lines.push(...describeLastAutoStopLines(summary.lastAutoStop, summary.decision?.detail, when).lines);
|
|
190
334
|
lines.push(...describeLastWakeDecisionLines(summary.lastWakeDecision, when));
|
|
191
335
|
if (summary.holders === null) {
|
|
@@ -205,6 +349,10 @@ function describePowerSummary(summary, when = {}) {
|
|
|
205
349
|
lines.push(`Last wake: ${summary.lastWake
|
|
206
350
|
? `${summary.lastWake.at ? (0, format_1.formatWhen)(summary.lastWake.at, when) : 'unknown time'}${summary.lastWake.source ? ` (${summary.lastWake.source})` : ''}`
|
|
207
351
|
: 'none'}`);
|
|
352
|
+
lines.push(...describeLastWakeTiming(summary.lastWake));
|
|
353
|
+
lines.push(...describePrewarm(summary.prewarm, when));
|
|
354
|
+
if (power.policy !== 'on_demand')
|
|
355
|
+
lines.push(...describeOnDemandAvailability(summary.onDemand));
|
|
208
356
|
return lines;
|
|
209
357
|
}
|
|
210
358
|
/** The lines of `power explain`; the fix is always last. */
|
|
@@ -226,9 +374,12 @@ function describePowerExplanation(summary, when = {}) {
|
|
|
226
374
|
lines.push(`At: ${(0, format_1.formatWhen)(d.at, when)}`);
|
|
227
375
|
if (text.detail)
|
|
228
376
|
lines.push(`Detail: ${text.detail}`);
|
|
377
|
+
lines.push(...describePendingStopLines(summary, when));
|
|
229
378
|
const stop = describeLastAutoStopLines(summary.lastAutoStop, d.detail, when);
|
|
230
379
|
lines.push(...stop.lines);
|
|
231
380
|
lines.push(...wakeLines);
|
|
381
|
+
lines.push(...describeLastWakeTiming(summary.lastWake));
|
|
382
|
+
lines.push(...describePrewarm(summary.prewarm, when));
|
|
232
383
|
// A false stop's fix replaces nothing: the decision's own fix is still last-but-one.
|
|
233
384
|
if (text.fix && text.fix !== stop.fix)
|
|
234
385
|
lines.push(`Fix: ${text.fix}`);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
type Row = Record<string, unknown>;
|
|
2
|
+
export type ProjectAction = 'archive' | 'unarchive' | 'delete';
|
|
3
|
+
export declare function planProjectChange(action: ProjectAction, project: Row, projectRef: string): {
|
|
4
|
+
object: string;
|
|
5
|
+
source: string;
|
|
6
|
+
ok: boolean;
|
|
7
|
+
action: ProjectAction;
|
|
8
|
+
project: {
|
|
9
|
+
id: unknown;
|
|
10
|
+
ref: {};
|
|
11
|
+
title: unknown;
|
|
12
|
+
archived: boolean;
|
|
13
|
+
};
|
|
14
|
+
changes: {
|
|
15
|
+
deletesProject: boolean;
|
|
16
|
+
detachedTasksEstimate: number | null;
|
|
17
|
+
reversible: boolean;
|
|
18
|
+
archived?: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
archived: boolean;
|
|
21
|
+
reversible: boolean;
|
|
22
|
+
deletesProject?: undefined;
|
|
23
|
+
detachedTasksEstimate?: undefined;
|
|
24
|
+
};
|
|
25
|
+
errors: string[];
|
|
26
|
+
notes: string[];
|
|
27
|
+
};
|
|
28
|
+
export type BulkUpdateInput = {
|
|
29
|
+
id: string;
|
|
30
|
+
patch: Row;
|
|
31
|
+
};
|
|
32
|
+
export declare function planBulkUpdate(updates: BulkUpdateInput[], currentById: Record<string, Row | null | undefined>, failedReads?: Record<string, string>): {
|
|
33
|
+
object: string;
|
|
34
|
+
source: string;
|
|
35
|
+
ok: boolean;
|
|
36
|
+
requested: number;
|
|
37
|
+
wouldChange: number;
|
|
38
|
+
invalid: number;
|
|
39
|
+
results: {
|
|
40
|
+
id: string;
|
|
41
|
+
ok: boolean;
|
|
42
|
+
changes: Record<string, {
|
|
43
|
+
from: unknown;
|
|
44
|
+
to: unknown;
|
|
45
|
+
}>;
|
|
46
|
+
noop: boolean;
|
|
47
|
+
errors: string[];
|
|
48
|
+
}[];
|
|
49
|
+
};
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.planProjectChange = planProjectChange;
|
|
4
|
+
exports.planBulkUpdate = planBulkUpdate;
|
|
5
|
+
/**
|
|
6
|
+
* Client-side validated previews for `--dry-run` (audit P5).
|
|
7
|
+
*
|
|
8
|
+
* Each plan is built from READS only (a GET of the current row) and answers three
|
|
9
|
+
* things a caller needs before a destructive call: would it be accepted, what
|
|
10
|
+
* would change, and what is the blast radius. It is a preview, not a promise:
|
|
11
|
+
* the real call re-validates server-side, and a concurrent writer can still
|
|
12
|
+
* change the outcome. Where the server has no validate-only path the plan says
|
|
13
|
+
* `source: 'client_preview'` so nobody mistakes it for one.
|
|
14
|
+
*/
|
|
15
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
16
|
+
function planProjectChange(action, project, projectRef) {
|
|
17
|
+
const archived = Boolean(project.archivedAt);
|
|
18
|
+
const taskCounts = (project.taskCounts ?? {});
|
|
19
|
+
const errors = [];
|
|
20
|
+
const notes = [];
|
|
21
|
+
if (action === 'archive' && archived)
|
|
22
|
+
notes.push('Already archived; archiving again is a no-op.');
|
|
23
|
+
if (action === 'unarchive' && !archived)
|
|
24
|
+
notes.push('Not archived; unarchiving is a no-op.');
|
|
25
|
+
return {
|
|
26
|
+
object: 'project_change_dry_run',
|
|
27
|
+
source: 'client_preview',
|
|
28
|
+
ok: errors.length === 0,
|
|
29
|
+
action,
|
|
30
|
+
project: {
|
|
31
|
+
id: project.id,
|
|
32
|
+
ref: project.identifier ?? projectRef,
|
|
33
|
+
title: project.title,
|
|
34
|
+
archived,
|
|
35
|
+
},
|
|
36
|
+
changes: action === 'delete'
|
|
37
|
+
? {
|
|
38
|
+
deletesProject: true,
|
|
39
|
+
// Member tasks are detached, never deleted (invariant P3).
|
|
40
|
+
detachedTasksEstimate: taskCounts.total ?? null,
|
|
41
|
+
reversible: false,
|
|
42
|
+
}
|
|
43
|
+
: { archived: action === 'archive', reversible: true },
|
|
44
|
+
errors,
|
|
45
|
+
notes,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function planBulkUpdate(updates, currentById, failedReads = {}) {
|
|
49
|
+
const rows = updates.map(({ id, patch }) => {
|
|
50
|
+
const errors = [];
|
|
51
|
+
const current = currentById[id];
|
|
52
|
+
if (failedReads[id])
|
|
53
|
+
errors.push(`could not read task: ${failedReads[id]}`);
|
|
54
|
+
else if (!current)
|
|
55
|
+
errors.push('task not found');
|
|
56
|
+
const status = patch.status;
|
|
57
|
+
if (status !== undefined && !data_provider_1.TASK_STATUSES.includes(status)) {
|
|
58
|
+
errors.push(`status must be one of: ${data_provider_1.TASK_STATUSES.join(', ')}`);
|
|
59
|
+
}
|
|
60
|
+
const changes = {};
|
|
61
|
+
for (const [field, to] of Object.entries(patch)) {
|
|
62
|
+
if (to === undefined)
|
|
63
|
+
continue;
|
|
64
|
+
const from = current?.[field];
|
|
65
|
+
if (JSON.stringify(from) !== JSON.stringify(to))
|
|
66
|
+
changes[field] = { from, to };
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
id,
|
|
70
|
+
ok: errors.length === 0,
|
|
71
|
+
changes,
|
|
72
|
+
noop: errors.length === 0 && Object.keys(changes).length === 0,
|
|
73
|
+
errors,
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
object: 'task_bulk_update_dry_run',
|
|
78
|
+
source: 'client_preview',
|
|
79
|
+
ok: rows.every((r) => r.ok),
|
|
80
|
+
requested: rows.length,
|
|
81
|
+
wouldChange: rows.filter((r) => r.ok && !r.noop).length,
|
|
82
|
+
invalid: rows.filter((r) => !r.ok).length,
|
|
83
|
+
results: rows,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage-field stripping for `--json` output (audit P9).
|
|
3
|
+
*
|
|
4
|
+
* The API returns Mongo documents, so every row carries `_id` and `__v` beside
|
|
5
|
+
* the real `id`: 47 keys per task row, two of which are storage detail an agent
|
|
6
|
+
* pays tokens for and can mistake for the identifier (OSK-12205 was exactly
|
|
7
|
+
* that: a 24-hex `_id` passed where a task id was wanted).
|
|
8
|
+
*
|
|
9
|
+
* This runs at the CLI SERIALIZER only (`BaseCommand.log`), never in the API or
|
|
10
|
+
* the data layer, so no other consumer's payload changes. `--raw` (or
|
|
11
|
+
* `OVERSKY_CLI_RAW=1`) turns it off for the caller that does want them.
|
|
12
|
+
*
|
|
13
|
+
* Two rules, both conservative:
|
|
14
|
+
* - `__v` is the Mongoose version key and is always dropped.
|
|
15
|
+
* - `_id` is dropped only when the same object has a usable `id`. A row that
|
|
16
|
+
* has ONLY `_id` (some legacy collections) keeps it: removing the sole
|
|
17
|
+
* identifier would turn a cosmetic cleanup into data loss.
|
|
18
|
+
*/
|
|
19
|
+
type Json = unknown;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the SAME reference when nothing needed stripping, so a caller can tell
|
|
22
|
+
* "unchanged" apart from "rebuilt" and leave the original text alone.
|
|
23
|
+
*/
|
|
24
|
+
export declare function stripStorageFields(value: Json): Json;
|
|
25
|
+
/**
|
|
26
|
+
* Apply {@link stripStorageFields} to one line of CLI output. Anything that is
|
|
27
|
+
* not a JSON object/array (prose, a bare string, malformed text) is returned
|
|
28
|
+
* untouched, as is JSON with nothing to strip, so existing formatting survives.
|
|
29
|
+
*/
|
|
30
|
+
export declare function stripStorageFieldsFromText(text: string): string;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Storage-field stripping for `--json` output (audit P9).
|
|
4
|
+
*
|
|
5
|
+
* The API returns Mongo documents, so every row carries `_id` and `__v` beside
|
|
6
|
+
* the real `id`: 47 keys per task row, two of which are storage detail an agent
|
|
7
|
+
* pays tokens for and can mistake for the identifier (OSK-12205 was exactly
|
|
8
|
+
* that: a 24-hex `_id` passed where a task id was wanted).
|
|
9
|
+
*
|
|
10
|
+
* This runs at the CLI SERIALIZER only (`BaseCommand.log`), never in the API or
|
|
11
|
+
* the data layer, so no other consumer's payload changes. `--raw` (or
|
|
12
|
+
* `OVERSKY_CLI_RAW=1`) turns it off for the caller that does want them.
|
|
13
|
+
*
|
|
14
|
+
* Two rules, both conservative:
|
|
15
|
+
* - `__v` is the Mongoose version key and is always dropped.
|
|
16
|
+
* - `_id` is dropped only when the same object has a usable `id`. A row that
|
|
17
|
+
* has ONLY `_id` (some legacy collections) keeps it: removing the sole
|
|
18
|
+
* identifier would turn a cosmetic cleanup into data loss.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.stripStorageFields = stripStorageFields;
|
|
22
|
+
exports.stripStorageFieldsFromText = stripStorageFieldsFromText;
|
|
23
|
+
function usableId(value) {
|
|
24
|
+
return (typeof value === 'string' && value.length > 0) || typeof value === 'number';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Returns the SAME reference when nothing needed stripping, so a caller can tell
|
|
28
|
+
* "unchanged" apart from "rebuilt" and leave the original text alone.
|
|
29
|
+
*/
|
|
30
|
+
function stripStorageFields(value) {
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
let changed = false;
|
|
33
|
+
const next = value.map((item) => {
|
|
34
|
+
const stripped = stripStorageFields(item);
|
|
35
|
+
if (stripped !== item)
|
|
36
|
+
changed = true;
|
|
37
|
+
return stripped;
|
|
38
|
+
});
|
|
39
|
+
return changed ? next : value;
|
|
40
|
+
}
|
|
41
|
+
if (value === null || typeof value !== 'object')
|
|
42
|
+
return value;
|
|
43
|
+
const source = value;
|
|
44
|
+
const dropId = '_id' in source && usableId(source.id);
|
|
45
|
+
const dropVersion = '__v' in source;
|
|
46
|
+
let changed = dropId || dropVersion;
|
|
47
|
+
const next = {};
|
|
48
|
+
for (const [key, child] of Object.entries(source)) {
|
|
49
|
+
if ((key === '_id' && dropId) || (key === '__v' && dropVersion))
|
|
50
|
+
continue;
|
|
51
|
+
const stripped = stripStorageFields(child);
|
|
52
|
+
if (stripped !== child)
|
|
53
|
+
changed = true;
|
|
54
|
+
next[key] = stripped;
|
|
55
|
+
}
|
|
56
|
+
return changed ? next : value;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Apply {@link stripStorageFields} to one line of CLI output. Anything that is
|
|
60
|
+
* not a JSON object/array (prose, a bare string, malformed text) is returned
|
|
61
|
+
* untouched, as is JSON with nothing to strip, so existing formatting survives.
|
|
62
|
+
*/
|
|
63
|
+
function stripStorageFieldsFromText(text) {
|
|
64
|
+
const head = text.trimStart()[0];
|
|
65
|
+
if (head !== '{' && head !== '[')
|
|
66
|
+
return text;
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
parsed = JSON.parse(text);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return text;
|
|
73
|
+
}
|
|
74
|
+
const stripped = stripStorageFields(parsed);
|
|
75
|
+
if (stripped === parsed)
|
|
76
|
+
return text;
|
|
77
|
+
return JSON.stringify(stripped, null, text.includes('\n') ? 2 : undefined);
|
|
78
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type ListWarning = {
|
|
2
|
+
code: string;
|
|
3
|
+
value?: unknown;
|
|
4
|
+
hint: string;
|
|
5
|
+
};
|
|
6
|
+
export type ListEnvelope = {
|
|
7
|
+
object: 'list';
|
|
8
|
+
data: Array<Record<string, unknown>>;
|
|
9
|
+
has_more: boolean;
|
|
10
|
+
next_cursor: string | null;
|
|
11
|
+
limit_applied?: number;
|
|
12
|
+
warnings?: ListWarning[];
|
|
13
|
+
} & Record<string, unknown>;
|
|
14
|
+
/**
|
|
15
|
+
* The navigation projection per resource: enough to identify a row, decide
|
|
16
|
+
* whether it matters and fetch it with `show`. Allowlists, not drop-lists, so a
|
|
17
|
+
* field the server adds tomorrow does not silently re-inflate every compact row.
|
|
18
|
+
* Documented in docs/cli/SKRR_TASKS.md (List output for agents).
|
|
19
|
+
*/
|
|
20
|
+
export declare const COMPACT_FIELDS: {
|
|
21
|
+
readonly task: readonly ["id", "identifier", "ref", "title", "status", "statusType", "priority", "estimate", "assigneeAgentIds", "assigneeUserIds", "parentId", "spaceId", "projectId", "goalId", "dueDate", "scheduledFor", "labelIds", "tags", "externalKey", "version", "executionMode", "nextAction", "createdAt", "updatedAt", "url"];
|
|
22
|
+
readonly space: readonly ["id", "identifier", "title", "status", "parentSpaceId", "leadAgentId", "labelIds", "archivedAt", "createdAt", "updatedAt", "url"];
|
|
23
|
+
readonly project: readonly ["id", "identifier", "title", "spaceId", "externalKey", "taskCounts", "archivedAt", "createdAt", "updatedAt", "url"];
|
|
24
|
+
};
|
|
25
|
+
export type ListResource = keyof typeof COMPACT_FIELDS;
|
|
26
|
+
/** The three flags every projecting list command declares. */
|
|
27
|
+
export declare const listOutputFlags: {
|
|
28
|
+
fields: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
29
|
+
compact: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
30
|
+
ndjson: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
31
|
+
};
|
|
32
|
+
export type ListOutputFlags = {
|
|
33
|
+
fields?: string;
|
|
34
|
+
compact?: boolean;
|
|
35
|
+
ndjson?: boolean;
|
|
36
|
+
};
|
|
37
|
+
/** `--fields a, b ,c` -> ['a','b','c']; empty/blank -> undefined. */
|
|
38
|
+
export declare function parseFields(raw: string | undefined): string[] | undefined;
|
|
39
|
+
export declare function projectRow(row: Record<string, unknown>, fields: readonly string[]): Record<string, unknown>;
|
|
40
|
+
/**
|
|
41
|
+
* Normalize any list response to the shared envelope. `data` is where rows live
|
|
42
|
+
* for every list command; `projects` (an older serialization) is folded into it.
|
|
43
|
+
* A response that is not list-shaped is returned untouched (never invent rows).
|
|
44
|
+
*/
|
|
45
|
+
export declare function toListEnvelope(response: unknown): ListEnvelope | undefined;
|
|
46
|
+
export type ShapeListOptions = ListOutputFlags & {
|
|
47
|
+
resource: ListResource;
|
|
48
|
+
/** What the caller asked for with --limit (undefined when the command has none). */
|
|
49
|
+
requestedLimit?: number;
|
|
50
|
+
warnings?: ListWarning[];
|
|
51
|
+
/** A filter the CLI applied that the caller did not ask for (E12). Echoed as `filter_applied`. */
|
|
52
|
+
filterApplied?: Record<string, unknown>;
|
|
53
|
+
};
|
|
54
|
+
/** Pure: envelope + projection + notes. Returns the response untouched if not a list. */
|
|
55
|
+
export declare function shapeListResponse(response: unknown, options: ShapeListOptions): unknown;
|
|
56
|
+
/**
|
|
57
|
+
* E11: the server silently clamps `--limit` (cap) and coerces `0` to its default.
|
|
58
|
+
* Echo what was applied. `applied` is only reported when we can prove it: a full
|
|
59
|
+
* page that still has more rows means the cap is exactly the row count.
|
|
60
|
+
*/
|
|
61
|
+
export declare function limitNote(requested: number | undefined, rowCount: number, hasMore: boolean): {
|
|
62
|
+
applied?: number;
|
|
63
|
+
warning?: ListWarning;
|
|
64
|
+
};
|
|
65
|
+
/** The text-mode twin of a warning: one `Note:` line a person can act on. */
|
|
66
|
+
export declare function warningLines(warnings: readonly ListWarning[] | undefined): string[];
|
|
67
|
+
export type ListOutput = {
|
|
68
|
+
stdout: string[];
|
|
69
|
+
stderr: string[];
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Render a shaped list for `--json` (pretty envelope) or `--ndjson` (rows one per
|
|
73
|
+
* line, `_meta` on stderr). Pure; the caller writes the lines.
|
|
74
|
+
*/
|
|
75
|
+
export declare function renderListOutput(shaped: unknown, ndjson: boolean): ListOutput;
|