@skrr-ai/cli 0.1.95 → 0.1.96
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 +22 -0
- package/dist/commands/agent/message/send.d.ts +2 -0
- package/dist/commands/agent/message/send.js +75 -5
- package/dist/commands/agents/chat.js +1 -1
- package/dist/commands/agents/create.d.ts +0 -3
- package/dist/commands/agents/create.js +0 -26
- package/dist/commands/agents/egress.d.ts +17 -0
- package/dist/commands/agents/egress.js +84 -0
- package/dist/commands/agents/mailbox/messages.d.ts +14 -0
- package/dist/commands/agents/mailbox/messages.js +52 -0
- package/dist/commands/agents/mailbox/show.d.ts +13 -0
- package/dist/commands/agents/mailbox/show.js +52 -0
- package/dist/commands/agents/operating-plan.js +8 -0
- package/dist/commands/agents/roles/capture.d.ts +16 -0
- package/dist/commands/agents/roles/capture.js +53 -0
- package/dist/commands/agents/roles/install.d.ts +1 -0
- package/dist/commands/agents/roles/install.js +8 -1
- package/dist/commands/agents/roles/preview.d.ts +2 -0
- package/dist/commands/agents/roles/preview.js +27 -3
- package/dist/commands/agents/update.d.ts +0 -3
- package/dist/commands/agents/update.js +1 -31
- package/dist/commands/agents/usage-cap.d.ts +4 -1
- package/dist/commands/agents/usage-cap.js +49 -10
- package/dist/commands/code/jobs/show.js +12 -0
- package/dist/commands/commitments/action-proposals/decide.d.ts +2 -0
- package/dist/commands/commitments/action-proposals/decide.js +12 -0
- package/dist/commands/commitments/action-proposals.js +7 -0
- package/dist/commands/commitments/create.d.ts +1 -0
- package/dist/commands/commitments/create.js +17 -1
- package/dist/commands/commitments/delivery.d.ts +1 -0
- package/dist/commands/commitments/delivery.js +11 -1
- package/dist/commands/commitments/doctor.js +4 -0
- package/dist/commands/commitments/effective-policy.js +26 -0
- package/dist/commands/commitments/endpoints/create.js +5 -2
- package/dist/commands/commitments/observations.d.ts +10 -0
- package/dist/commands/commitments/observations.js +88 -0
- package/dist/commands/commitments/pause.d.ts +1 -1
- package/dist/commands/commitments/pause.js +4 -3
- package/dist/commands/commitments/preflight.js +2 -1
- package/dist/commands/commitments/reports.d.ts +2 -0
- package/dist/commands/commitments/reports.js +22 -4
- package/dist/commands/commitments/update.d.ts +1 -0
- package/dist/commands/commitments/update.js +35 -5
- package/dist/commands/grants/create.d.ts +1 -0
- package/dist/commands/grants/create.js +8 -0
- package/dist/commands/grants/rotate.d.ts +5 -0
- package/dist/commands/grants/rotate.js +13 -1
- package/dist/commands/grants/update.d.ts +12 -0
- package/dist/commands/grants/update.js +27 -0
- package/dist/commands/machines/hosted/start.js +7 -1
- package/dist/commands/machines/list.js +4 -4
- package/dist/commands/measures/confirm.d.ts +1 -7
- package/dist/commands/measures/confirm.js +15 -14
- package/dist/commands/measures/list.d.ts +1 -7
- package/dist/commands/measures/list.js +1 -7
- package/dist/commands/measures/record.js +4 -4
- package/dist/commands/measures/show.d.ts +11 -0
- package/dist/commands/measures/show.js +26 -0
- package/dist/commands/northstars/governance/configure.d.ts +1 -0
- package/dist/commands/northstars/governance/configure.js +8 -1
- package/dist/commands/proposals/discard.d.ts +5 -0
- package/dist/commands/proposals/discard.js +8 -0
- package/dist/commands/proposals/keep.d.ts +5 -0
- package/dist/commands/proposals/keep.js +8 -0
- package/dist/commands/proposals/list.d.ts +15 -0
- package/dist/commands/proposals/list.js +74 -0
- package/dist/commands/proposals/show.d.ts +12 -0
- package/dist/commands/proposals/show.js +27 -0
- package/dist/commands/proposals/snooze.d.ts +5 -0
- package/dist/commands/proposals/snooze.js +8 -0
- package/dist/commands/signals/monitors/create.d.ts +9 -0
- package/dist/commands/signals/monitors/create.js +29 -0
- package/dist/commands/signals/monitors/list.d.ts +8 -0
- package/dist/commands/signals/monitors/list.js +16 -0
- package/dist/commands/signals/monitors/pause.d.ts +11 -0
- package/dist/commands/signals/monitors/pause.js +17 -0
- package/dist/commands/signals/monitors/resume.d.ts +11 -0
- package/dist/commands/signals/monitors/resume.js +17 -0
- package/dist/commands/signals/monitors/revise.d.ts +12 -0
- package/dist/commands/signals/monitors/revise.js +25 -0
- package/dist/commands/signals/monitors/show.d.ts +11 -0
- package/dist/commands/signals/monitors/show.js +17 -0
- package/dist/commands/signals/monitors/test.d.ts +12 -0
- package/dist/commands/signals/monitors/test.js +25 -0
- package/dist/commands/signals/monitors/transitions.d.ts +11 -0
- package/dist/commands/signals/monitors/transitions.js +17 -0
- package/dist/commands/signals/monitors/validate.d.ts +9 -0
- package/dist/commands/signals/monitors/validate.js +24 -0
- package/dist/commands/signals/schemas/list.d.ts +8 -0
- package/dist/commands/signals/schemas/list.js +16 -0
- package/dist/commands/signals/schemas/show.d.ts +11 -0
- package/dist/commands/signals/schemas/show.js +17 -0
- package/dist/commands/signals/sources/list.d.ts +8 -0
- package/dist/commands/signals/sources/list.js +16 -0
- package/dist/commands/signals/sources/receipts.d.ts +11 -0
- package/dist/commands/signals/sources/receipts.js +17 -0
- package/dist/commands/signals/sources/show.d.ts +11 -0
- package/dist/commands/signals/sources/show.js +17 -0
- package/dist/commands/spaces/usage.d.ts +12 -0
- package/dist/commands/spaces/usage.js +28 -0
- package/dist/commands/spaces/workflows/run.js +3 -0
- package/dist/commands/spaces/workflows/runs.js +2 -1
- package/dist/commands/spaces/workflows/update.d.ts +6 -1
- package/dist/commands/spaces/workflows/update.js +34 -2
- package/dist/commands/tasks/cascade-status.d.ts +2 -0
- package/dist/commands/tasks/cascade-status.js +27 -1
- package/dist/commands/tasks/create.d.ts +4 -0
- package/dist/commands/tasks/create.js +16 -0
- package/dist/commands/tasks/deliverable/add.js +12 -3
- package/dist/commands/tasks/economics-compare.d.ts +15 -0
- package/dist/commands/tasks/economics-compare.js +60 -0
- package/dist/commands/tasks/expectations/evaluate.d.ts +13 -0
- package/dist/commands/tasks/expectations/evaluate.js +43 -0
- package/dist/commands/tasks/list.d.ts +1 -0
- package/dist/commands/tasks/list.js +44 -1
- package/dist/commands/tasks/show.d.ts +5 -0
- package/dist/commands/tasks/show.js +17 -0
- package/dist/commands/tasks/update.d.ts +4 -0
- package/dist/commands/tasks/update.js +9 -0
- package/dist/commands/tasks/workflow-findings.js +2 -2
- package/dist/commands/triggers/create.d.ts +2 -0
- package/dist/commands/triggers/create.js +15 -0
- package/dist/commands/workspaces/grants.d.ts +12 -0
- package/dist/commands/workspaces/grants.js +31 -0
- package/dist/commands/workspaces/stewardship.d.ts +13 -0
- package/dist/commands/workspaces/stewardship.js +34 -0
- package/dist/lib/agent-config.d.ts +0 -12
- package/dist/lib/agent-config.js +1 -27
- package/dist/lib/agent-mailbox.d.ts +35 -0
- package/dist/lib/agent-mailbox.js +55 -0
- package/dist/lib/commitment-endpoints.d.ts +2 -1
- package/dist/lib/commitment-endpoints.js +2 -5
- package/dist/lib/commitment-product.d.ts +3 -1
- package/dist/lib/commitment-product.js +10 -0
- package/dist/lib/commitment-terms.js +1 -1
- package/dist/lib/commitments.d.ts +17 -7
- package/dist/lib/commitments.js +173 -85
- package/dist/lib/compasses.d.ts +14 -0
- package/dist/lib/compasses.js +25 -11
- package/dist/lib/grants.d.ts +5 -1
- package/dist/lib/grants.js +9 -1
- package/dist/lib/hosted-machines.d.ts +7 -0
- package/dist/lib/mailbox-human-command.d.ts +11 -0
- package/dist/lib/mailbox-human-command.js +41 -0
- package/dist/lib/measures.d.ts +28 -2
- package/dist/lib/measures.js +38 -14
- package/dist/lib/message-intent.d.ts +6 -2
- package/dist/lib/message-intent.js +1 -0
- package/dist/lib/northstars.js +2 -1
- package/dist/lib/proposal-decision-command.d.ts +19 -0
- package/dist/lib/proposal-decision-command.js +64 -0
- package/dist/lib/proposals.d.ts +8 -0
- package/dist/lib/proposals.js +22 -0
- package/dist/lib/roles.d.ts +141 -6
- package/dist/lib/roles.js +8 -2
- package/dist/lib/signals.d.ts +20 -0
- package/dist/lib/signals.js +24 -0
- package/dist/lib/space-usage.d.ts +3 -0
- package/dist/lib/space-usage.js +17 -0
- package/dist/lib/stewardship-output.d.ts +4 -0
- package/dist/lib/stewardship-output.js +82 -0
- package/dist/lib/task-asset-upload.d.ts +3 -1
- package/dist/lib/task-asset-upload.js +1 -0
- package/dist/lib/task-economics.d.ts +16 -0
- package/dist/lib/task-economics.js +22 -0
- package/dist/lib/triggers.d.ts +11 -3
- package/dist/lib/triggers.js +58 -1
- package/dist/lib/usage-discovery.d.ts +10 -0
- package/dist/lib/usage-discovery.js +24 -3
- package/dist/lib/workflow-run-budget.d.ts +12 -0
- package/dist/lib/workflow-run-budget.js +37 -0
- package/dist/lib/workspaces.d.ts +48 -0
- package/dist/lib/workspaces.js +8 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.d.ts +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.js +14 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/githubPushRefusal.d.ts +9 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/githubPushRefusal.js +49 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.d.ts +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.js +12 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/githubPushRefusal.d.ts +9 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/githubPushRefusal.js +44 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +10 -0
- package/dist/node_modules/@skrr-ai/data-provider/index.js +8017 -7086
- package/oclif.manifest.json +3872 -1167
- package/package.json +22 -1
|
@@ -1,8 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseObservationWindow = parseObservationWindow;
|
|
4
|
+
exports.renderObservationWindow = renderObservationWindow;
|
|
3
5
|
const core_1 = require("@oclif/core");
|
|
6
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
4
7
|
const base_command_1 = require("../../base-command");
|
|
5
8
|
const commitments_1 = require("../../lib/commitments");
|
|
9
|
+
/** Explicit ISO FROM/TO intervals avoid local-time or rolling-window ambiguity. */
|
|
10
|
+
function parseObservationWindow(value) {
|
|
11
|
+
const parts = value.split('/');
|
|
12
|
+
const timestamp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
13
|
+
const [from, to] = parts.map((entry) => new Date(entry).getTime());
|
|
14
|
+
const realCalendarDay = (part) => {
|
|
15
|
+
const day = part.slice(0, 10);
|
|
16
|
+
const parsed = new Date(`${day}T00:00:00Z`);
|
|
17
|
+
return Number.isFinite(parsed.getTime()) && parsed.toISOString().slice(0, 10) === day;
|
|
18
|
+
};
|
|
19
|
+
if (parts.length !== 2 ||
|
|
20
|
+
!parts.every((part) => timestamp.test(part) && realCalendarDay(part)) ||
|
|
21
|
+
!Number.isFinite(from) ||
|
|
22
|
+
!Number.isFinite(to) ||
|
|
23
|
+
to <= from ||
|
|
24
|
+
to - from > data_provider_1.OBSERVATION_WINDOW_MAX_MS)
|
|
25
|
+
throw new Error('Window requires ISO FROM/TO with an explicit timezone and a positive span of at most 90 days');
|
|
26
|
+
return { from: new Date(from).toISOString(), to: new Date(to).toISOString() };
|
|
27
|
+
}
|
|
28
|
+
function renderObservationWindow(response, log) {
|
|
29
|
+
// Always announce partial data before showing figures, including baseline truncation.
|
|
30
|
+
if (response.truncated)
|
|
31
|
+
log('TRUNCATED: bounded sample only; figures are incomplete.');
|
|
32
|
+
log('Agent-reported samples; as-of interval coverage is not independent verification.');
|
|
33
|
+
const display = (label, value) => {
|
|
34
|
+
const window = value;
|
|
35
|
+
log(`${label}: [${window.from}, ${window.to})`);
|
|
36
|
+
log(`Samples: ${window.count}; numeric: ${window.numericCount}; unreadable: ${window.gapCount}; uncovered ms: ${window.gapMs}`);
|
|
37
|
+
log(`Mean: ${window.mean ?? 'unknown'}; sum: ${window.sum ?? 'unknown'}; first: ${window.first ?? 'unknown'}; last: ${window.last ?? 'unknown'}`);
|
|
38
|
+
};
|
|
39
|
+
if (response.baseline) {
|
|
40
|
+
display('Baseline', response.baseline);
|
|
41
|
+
display('After', response.after);
|
|
42
|
+
log(`Comparison: ${response.sufficient ? `delta=${response.delta}; ratio=${response.ratio}` : `unavailable (${response.reason})`}`);
|
|
43
|
+
}
|
|
44
|
+
else
|
|
45
|
+
display('Window', response.summary);
|
|
46
|
+
}
|
|
6
47
|
/**
|
|
7
48
|
* `skrr commitments observations <id>` — what this commitment's runs saw.
|
|
8
49
|
*
|
|
@@ -30,6 +71,18 @@ class CommitmentsObservations extends base_command_1.BaseCommand {
|
|
|
30
71
|
};
|
|
31
72
|
static flags = {
|
|
32
73
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
74
|
+
latest: core_1.Flags.boolean({
|
|
75
|
+
description: 'Latest recorded attempt per current declared key (not history)',
|
|
76
|
+
}),
|
|
77
|
+
key: core_1.Flags.string({ description: 'Observation key for --window' }),
|
|
78
|
+
window: core_1.Flags.string({
|
|
79
|
+
description: 'Half-open ISO FROM/TO interval, at most 90 days',
|
|
80
|
+
dependsOn: ['key'],
|
|
81
|
+
}),
|
|
82
|
+
'compare-to': core_1.Flags.string({
|
|
83
|
+
description: 'Baseline ISO FROM/TO interval',
|
|
84
|
+
dependsOn: ['window'],
|
|
85
|
+
}),
|
|
33
86
|
limit: core_1.Flags.integer({ description: 'Rows to include', min: 1, max: 200 }),
|
|
34
87
|
'declared-only': core_1.Flags.boolean({
|
|
35
88
|
description: 'Only keys the operator declared — the rows that can move the loop',
|
|
@@ -45,10 +98,42 @@ class CommitmentsObservations extends base_command_1.BaseCommand {
|
|
|
45
98
|
async run() {
|
|
46
99
|
this.requireAuth();
|
|
47
100
|
const { args, flags } = await this.parse(CommitmentsObservations);
|
|
101
|
+
if (flags.latest && (flags.window || flags.cursor || flags['changed-only'] || flags.since))
|
|
102
|
+
this.error('--latest cannot be combined with --window, --cursor, --changed-only, or --since');
|
|
48
103
|
let response;
|
|
104
|
+
if (flags.window) {
|
|
105
|
+
try {
|
|
106
|
+
if (flags['declared-only'] || flags['changed-only'] || flags.since || flags.cursor)
|
|
107
|
+
this.error('--window cannot be combined with list filters');
|
|
108
|
+
const query = {
|
|
109
|
+
key: flags.key,
|
|
110
|
+
...parseObservationWindow(flags.window),
|
|
111
|
+
limit: flags.limit,
|
|
112
|
+
};
|
|
113
|
+
const baseline = flags['compare-to'] ? parseObservationWindow(flags['compare-to']) : null;
|
|
114
|
+
response = baseline
|
|
115
|
+
? await commitments_1.commitmentApi.observationCompare(args.commitmentId, {
|
|
116
|
+
...query,
|
|
117
|
+
baselineFrom: baseline.from,
|
|
118
|
+
baselineTo: baseline.to,
|
|
119
|
+
})
|
|
120
|
+
: await commitments_1.commitmentApi.observationSeries(args.commitmentId, query);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
this.handleApiError(err);
|
|
124
|
+
}
|
|
125
|
+
if (flags.json)
|
|
126
|
+
this.log(JSON.stringify(response, null, 2));
|
|
127
|
+
else
|
|
128
|
+
renderObservationWindow(response, (line) => this.log(line));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (flags.key)
|
|
132
|
+
this.error('--key requires --window');
|
|
49
133
|
try {
|
|
50
134
|
response = await commitments_1.commitmentApi.observations(args.commitmentId, {
|
|
51
135
|
limit: flags.limit,
|
|
136
|
+
latest: flags.latest || undefined,
|
|
52
137
|
declaredOnly: flags['declared-only'] || undefined,
|
|
53
138
|
changedOnly: flags['changed-only'] || undefined,
|
|
54
139
|
since: flags.since,
|
|
@@ -66,6 +151,7 @@ class CommitmentsObservations extends base_command_1.BaseCommand {
|
|
|
66
151
|
// facts; a filter that empties the list must not claim the first
|
|
67
152
|
// (OSK-10953).
|
|
68
153
|
const filters = [
|
|
154
|
+
flags.latest ? '--latest' : null,
|
|
69
155
|
flags['declared-only'] ? '--declared-only' : null,
|
|
70
156
|
flags['changed-only'] ? '--changed-only' : null,
|
|
71
157
|
flags.since ? `--since ${flags.since}` : null,
|
|
@@ -73,6 +159,8 @@ class CommitmentsObservations extends base_command_1.BaseCommand {
|
|
|
73
159
|
const emptyMessage = filters.length
|
|
74
160
|
? `No observations match ${filters.join(' ')}.`
|
|
75
161
|
: 'No observations recorded.';
|
|
162
|
+
if (response?.truncated)
|
|
163
|
+
this.log(`TRUNCATED: ${response.omitted} current keys omitted; increase --limit (max 200).`);
|
|
76
164
|
(0, commitments_1.renderCommitmentObservations)(response, (line) => this.log(line), { emptyMessage });
|
|
77
165
|
}
|
|
78
166
|
(0, commitments_1.renderListPageHint)(response, (line) => this.log(line));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseCommand } from '../../base-command';
|
|
2
2
|
/**
|
|
3
3
|
* `skrr commitments pause <id>` — stop the control loop without losing the
|
|
4
|
-
* contract or its history.
|
|
4
|
+
* contract or its history. An already executing turn may continue.
|
|
5
5
|
*/
|
|
6
6
|
export default class CommitmentsPause extends BaseCommand {
|
|
7
7
|
static description: string;
|
|
@@ -6,10 +6,10 @@ const web_url_1 = require("../../lib/web-url");
|
|
|
6
6
|
const commitments_1 = require("../../lib/commitments");
|
|
7
7
|
/**
|
|
8
8
|
* `skrr commitments pause <id>` — stop the control loop without losing the
|
|
9
|
-
* contract or its history.
|
|
9
|
+
* contract or its history. An already executing turn may continue.
|
|
10
10
|
*/
|
|
11
11
|
class CommitmentsPause extends base_command_1.BaseCommand {
|
|
12
|
-
static description = 'Pause a commitment —
|
|
12
|
+
static description = 'Pause a commitment — stops new work; a turn already running may continue until it finishes or reaches its deadline';
|
|
13
13
|
static examples = ['<%= config.bin %> commitments pause <commitment-id>'];
|
|
14
14
|
static args = {
|
|
15
15
|
id: core_1.Args.string({ description: 'Commitment ID', required: true, ignoreStdin: true }),
|
|
@@ -30,6 +30,7 @@ class CommitmentsPause extends base_command_1.BaseCommand {
|
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
this.log(`Paused commitment ${args.id}.`);
|
|
33
|
+
this.log('Stops new work. A turn already running may continue until it finishes or reaches its deadline.');
|
|
33
34
|
// The status write is the fence and it has landed. The teardown of the
|
|
34
35
|
// wake tree behind it is best-effort, and used to be silent — so a pause
|
|
35
36
|
// that left triggers live looked exactly like one that did not. Say which
|
|
@@ -39,7 +40,7 @@ class CommitmentsPause extends base_command_1.BaseCommand {
|
|
|
39
40
|
.teardown;
|
|
40
41
|
if (teardown?.status === 'degraded') {
|
|
41
42
|
this.warn('The control loop is stopped, but some scheduled wakes may not have been retired yet. ' +
|
|
42
|
-
'They cannot
|
|
43
|
+
'They cannot start new work — every wake is refused while this Commitment is paused — ' +
|
|
43
44
|
`and the reconciler retries automatically. Check with: skrr commitments trigger-status ${args.id}`);
|
|
44
45
|
}
|
|
45
46
|
(0, commitments_1.renderCommitmentSummary)(commitment, (line) => this.log(line));
|
|
@@ -153,7 +153,8 @@ class CommitmentsPreflight extends base_command_1.BaseCommand {
|
|
|
153
153
|
for (const endpoint of report.endpoints || []) {
|
|
154
154
|
this.log(` ${endpoint.available ? 'ok ' : 'BLOCK'} ${endpoint.label || endpoint.destination}` +
|
|
155
155
|
` — ${(endpoint.capabilities || []).join(', ') || 'no capabilities'}` +
|
|
156
|
-
(endpoint.reason ? ` (${endpoint.reason})` : '')
|
|
156
|
+
(endpoint.reason ? ` (${endpoint.reason})` : '') +
|
|
157
|
+
(!endpoint.available && endpoint.detail ? ` — ${endpoint.detail}` : ''));
|
|
157
158
|
}
|
|
158
159
|
this.log(`\nAttention: ${report.attention?.allowed ? 'delivery allowed now' : `suppressed by ${report.attention?.suppressedBy || 'policy'}`}`);
|
|
159
160
|
if (report.verdict === 'blocked')
|
|
@@ -19,7 +19,9 @@ export default class CommitmentsReports extends BaseCommand {
|
|
|
19
19
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
20
20
|
add: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
21
|
target: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
review: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
23
|
on: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
+
format: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
25
|
remove: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
26
|
};
|
|
25
27
|
run(): Promise<void>;
|
|
@@ -6,16 +6,18 @@ const base_command_1 = require("../../base-command");
|
|
|
6
6
|
const commitments_1 = require("../../lib/commitments");
|
|
7
7
|
const commitment_terms_1 = require("../../lib/commitment-terms");
|
|
8
8
|
/** Destinations that address one specific place and therefore need a target. */
|
|
9
|
-
const DESTINATIONS_NEEDING_TARGET = new Set(
|
|
9
|
+
const DESTINATIONS_NEEDING_TARGET = new Set(Object.values(data_provider_1.COMMITMENT_DESTINATION_REGISTRY)
|
|
10
|
+
.filter((destination) => destination.requiresTarget)
|
|
11
|
+
.map((destination) => destination.key));
|
|
10
12
|
/**
|
|
11
13
|
* Keep the CLI safe across a rolling data-provider build. Older installed
|
|
12
14
|
* packages expose the compatibility destination list but not the narrowed
|
|
13
15
|
* authoring list; derive the same restriction instead of crashing command
|
|
14
|
-
* discovery
|
|
16
|
+
* discovery.
|
|
15
17
|
*/
|
|
16
18
|
const AUTHORABLE_REPORT_DESTINATIONS = Array.isArray(data_provider_1.COMMITMENT_AUTHORABLE_REPORT_DESTINATIONS)
|
|
17
19
|
? data_provider_1.COMMITMENT_AUTHORABLE_REPORT_DESTINATIONS
|
|
18
|
-
: data_provider_1.COMMITMENT_REPORT_DESTINATIONS
|
|
20
|
+
: data_provider_1.COMMITMENT_REPORT_DESTINATIONS;
|
|
19
21
|
/**
|
|
20
22
|
* Identity of a report target = destination + its target id. The same channel
|
|
21
23
|
* may legitimately appear twice with different `on` conditions (a digest on
|
|
@@ -41,6 +43,7 @@ class CommitmentsReports extends base_command_1.BaseCommand {
|
|
|
41
43
|
'<%= config.bin %> commitments reports <commitment-id>',
|
|
42
44
|
'<%= config.bin %> commitments reports <commitment-id> --add slack_channel --target C0123456 --on material_change',
|
|
43
45
|
'<%= config.bin %> commitments reports <commitment-id> --add main --on completion',
|
|
46
|
+
'<%= config.bin %> commitments reports <commitment-id> --add user_notify --target <user-id> --review owner',
|
|
44
47
|
'<%= config.bin %> commitments reports <commitment-id> --remove slack_channel:C0123456',
|
|
45
48
|
];
|
|
46
49
|
static args = {
|
|
@@ -53,12 +56,20 @@ class CommitmentsReports extends base_command_1.BaseCommand {
|
|
|
53
56
|
options: [...AUTHORABLE_REPORT_DESTINATIONS],
|
|
54
57
|
}),
|
|
55
58
|
target: core_1.Flags.string({
|
|
56
|
-
description: 'Channel id for slack_channel. App
|
|
59
|
+
description: 'Channel id for slack_channel, or the user id for user_notify. App, owner-DM and email destinations need no target (email goes to your verified account address).',
|
|
60
|
+
}),
|
|
61
|
+
review: core_1.Flags.string({
|
|
62
|
+
description: 'Hold the exact text for approver approval before it is sent to this target (owner)',
|
|
63
|
+
options: [...data_provider_1.COMMITMENT_REPORT_REVIEW_MODES],
|
|
57
64
|
}),
|
|
58
65
|
on: core_1.Flags.string({
|
|
59
66
|
description: 'When to report (default: material_change)',
|
|
60
67
|
options: [...data_provider_1.COMMITMENT_REPORT_TRIGGERS],
|
|
61
68
|
}),
|
|
69
|
+
format: core_1.Flags.string({
|
|
70
|
+
description: 'Optional report format (absent: text)',
|
|
71
|
+
options: ['text', 'report_v1'],
|
|
72
|
+
}),
|
|
62
73
|
remove: core_1.Flags.string({
|
|
63
74
|
description: 'Report target to remove: "<destination>" or "<destination>:<target>"',
|
|
64
75
|
}),
|
|
@@ -66,6 +77,8 @@ class CommitmentsReports extends base_command_1.BaseCommand {
|
|
|
66
77
|
async run() {
|
|
67
78
|
this.requireAuth();
|
|
68
79
|
const { args, flags } = await this.parse(CommitmentsReports);
|
|
80
|
+
if (flags.format && !flags.add)
|
|
81
|
+
this.error('--format requires --add.', { exit: 1 });
|
|
69
82
|
if (flags.add && flags.remove) {
|
|
70
83
|
this.error('Pass --add or --remove, not both.', { exit: 1 });
|
|
71
84
|
}
|
|
@@ -89,6 +102,9 @@ class CommitmentsReports extends base_command_1.BaseCommand {
|
|
|
89
102
|
try {
|
|
90
103
|
const current = await (0, commitment_terms_1.loadCommitment)(args.id);
|
|
91
104
|
const reports = current.reports ?? [];
|
|
105
|
+
if (flags.review && !flags.add) {
|
|
106
|
+
throw new Error('--review applies to a report being added (--add).');
|
|
107
|
+
}
|
|
92
108
|
if (flags.add) {
|
|
93
109
|
const destination = flags.add;
|
|
94
110
|
if (DESTINATIONS_NEEDING_TARGET.has(destination) && !flags.target) {
|
|
@@ -102,8 +118,10 @@ class CommitmentsReports extends base_command_1.BaseCommand {
|
|
|
102
118
|
const next = {
|
|
103
119
|
destination,
|
|
104
120
|
...(flags.target ? { destinationTarget: flags.target } : {}),
|
|
121
|
+
...(flags.review ? { review: flags.review } : {}),
|
|
105
122
|
on: flags.on ?? 'material_change',
|
|
106
123
|
enabled: true,
|
|
124
|
+
...(flags.format ? { format: flags.format } : {}),
|
|
107
125
|
};
|
|
108
126
|
payload = { reports: (0, commitment_terms_1.appendUnique)(reports, next, reportKey, 'Report target') };
|
|
109
127
|
}
|
|
@@ -30,6 +30,7 @@ export default class CommitmentsUpdate extends BaseCommand {
|
|
|
30
30
|
yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
31
31
|
'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
32
32
|
'if-version': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
33
|
+
'task-review-policy': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
33
34
|
title: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
34
35
|
description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
35
36
|
'agent-directive': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@oclif/core");
|
|
4
3
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const commitment_product_1 = require("../../lib/commitment-product");
|
|
6
|
+
const data_provider_2 = require("@skrr-ai/data-provider");
|
|
5
7
|
const base_command_1 = require("../../base-command");
|
|
6
8
|
const prompt_1 = require("../../lib/prompt");
|
|
7
9
|
const web_url_1 = require("../../lib/web-url");
|
|
@@ -52,6 +54,10 @@ class CommitmentsUpdate extends base_command_1.BaseCommand {
|
|
|
52
54
|
'if-version': core_1.Flags.integer({
|
|
53
55
|
description: 'Only update this observed contract version; returns a conflict if it changed',
|
|
54
56
|
}),
|
|
57
|
+
'task-review-policy': core_1.Flags.string({
|
|
58
|
+
options: [...data_provider_1.TASK_REVIEW_POLICIES],
|
|
59
|
+
description: 'Owner choice for generated Tasks; required records a blocker but does not stop the owner close.',
|
|
60
|
+
}),
|
|
55
61
|
title: core_1.Flags.string({ description: 'New title' }),
|
|
56
62
|
description: core_1.Flags.string({ description: 'New description' }),
|
|
57
63
|
'agent-directive': core_1.Flags.string({
|
|
@@ -133,9 +139,22 @@ class CommitmentsUpdate extends base_command_1.BaseCommand {
|
|
|
133
139
|
const wantsCadence = flags.cadence !== undefined ||
|
|
134
140
|
flags['cadence-mode'] !== undefined ||
|
|
135
141
|
flags.timezone !== undefined;
|
|
142
|
+
let payload;
|
|
143
|
+
try {
|
|
144
|
+
payload = await (0, prompt_2.readJsonBody)(flags['from-json']);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
this.error(err.message, { exit: 1 });
|
|
148
|
+
}
|
|
149
|
+
const authoredDelivery = payload.delivery && typeof payload.delivery === 'object' && !Array.isArray(payload.delivery)
|
|
150
|
+
? payload.delivery
|
|
151
|
+
: undefined;
|
|
136
152
|
// Read-modify-write: only pay the extra round-trip when we must merge.
|
|
137
153
|
let current;
|
|
138
|
-
if (wantsTarget ||
|
|
154
|
+
if (wantsTarget ||
|
|
155
|
+
wantsCadence ||
|
|
156
|
+
authoredDelivery ||
|
|
157
|
+
flags['task-review-policy'] !== undefined) {
|
|
139
158
|
try {
|
|
140
159
|
const res = await commitments_1.commitmentApi.get(args.id);
|
|
141
160
|
current = res?.commitment;
|
|
@@ -147,11 +166,22 @@ class CommitmentsUpdate extends base_command_1.BaseCommand {
|
|
|
147
166
|
this.error(`Commitment ${args.id} not found.`, { exit: 4 });
|
|
148
167
|
}
|
|
149
168
|
}
|
|
150
|
-
let payload;
|
|
151
169
|
try {
|
|
152
|
-
payload = await (0, prompt_2.readJsonBody)(flags['from-json']);
|
|
153
170
|
if (flags['if-version'] !== undefined)
|
|
154
171
|
payload.expectedVersion = flags['if-version'];
|
|
172
|
+
if (authoredDelivery || flags['task-review-policy'] !== undefined) {
|
|
173
|
+
payload.delivery = {
|
|
174
|
+
...(current?.delivery || { version: 1, mode: 'report_only' }),
|
|
175
|
+
...authoredDelivery,
|
|
176
|
+
...(flags['task-review-policy'] !== undefined
|
|
177
|
+
? { reviewPolicy: (0, commitment_product_1.normalizeTaskReviewPolicy)(flags['task-review-policy']) }
|
|
178
|
+
: {}),
|
|
179
|
+
};
|
|
180
|
+
payload.expectedVersion ??= current?.version;
|
|
181
|
+
}
|
|
182
|
+
const declaredDelivery = payload.delivery;
|
|
183
|
+
if (declaredDelivery?.reviewPolicy !== undefined)
|
|
184
|
+
(0, commitment_product_1.normalizeTaskReviewPolicy)(declaredDelivery.reviewPolicy);
|
|
155
185
|
if (flags.title)
|
|
156
186
|
payload.title = flags.title;
|
|
157
187
|
if (flags.description !== undefined)
|
|
@@ -168,7 +198,7 @@ class CommitmentsUpdate extends base_command_1.BaseCommand {
|
|
|
168
198
|
// generic PATCH with no ceremony at all, while `commitments delete` —
|
|
169
199
|
// whose data is all still on disk, and which is now restorable —
|
|
170
200
|
// prompts. Ceremony should track how hard something is to undo.
|
|
171
|
-
if ((0,
|
|
201
|
+
if ((0, data_provider_2.isTerminalCommitmentStatus)(flags.status)) {
|
|
172
202
|
let confirmed;
|
|
173
203
|
try {
|
|
174
204
|
confirmed = await (0, prompt_1.confirmDestructive)(`Set ${args.id} to ${flags.status}? This ends the Commitment — making it active again means archiving it first, then resuming.`, flags.yes);
|
|
@@ -20,6 +20,7 @@ export default class GrantsCreate extends BaseCommand {
|
|
|
20
20
|
commitment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
21
|
provider: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
22
|
label: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
access: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
24
|
description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
25
|
env: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
25
26
|
daemon: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const base_command_1 = require("../../base-command");
|
|
5
5
|
const grants_1 = require("../../lib/grants");
|
|
6
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
7
|
/**
|
|
7
8
|
* `skrr grants create` — give an agent a credential.
|
|
8
9
|
*
|
|
@@ -29,6 +30,10 @@ class GrantsCreate extends base_command_1.BaseCommand {
|
|
|
29
30
|
}),
|
|
30
31
|
provider: core_1.Flags.string({ description: 'Provider slug (e.g. aws, stripe)', required: true }),
|
|
31
32
|
label: core_1.Flags.string({ description: 'Human label', required: true }),
|
|
33
|
+
access: core_1.Flags.string({
|
|
34
|
+
description: 'Advisory provider access class (declared, not verified)',
|
|
35
|
+
options: [...data_provider_1.GRANT_ACCESS_CLASSES],
|
|
36
|
+
}),
|
|
32
37
|
description: core_1.Flags.string({ description: 'Optional description' }),
|
|
33
38
|
env: core_1.Flags.string({
|
|
34
39
|
description: 'Credential as NAME=VALUE (repeatable)',
|
|
@@ -67,6 +72,7 @@ class GrantsCreate extends base_command_1.BaseCommand {
|
|
|
67
72
|
: { kind: 'commitment', commitmentId: flags.commitment },
|
|
68
73
|
provider: flags.provider,
|
|
69
74
|
label: flags.label,
|
|
75
|
+
...(flags.access ? { access: flags.access } : {}),
|
|
70
76
|
description: flags.description,
|
|
71
77
|
credential: { kind: 'env', env },
|
|
72
78
|
runtime: { sandbox: !flags['no-sandbox'], daemon: flags.daemon },
|
|
@@ -77,6 +83,8 @@ class GrantsCreate extends base_command_1.BaseCommand {
|
|
|
77
83
|
return;
|
|
78
84
|
}
|
|
79
85
|
this.log(`Stored grant ${grant.id} (${grant.label}).`);
|
|
86
|
+
if (grant.access)
|
|
87
|
+
this.log(` access: ${(0, data_provider_1.describeGrantAccess)(grant.access, grant.accessSource).label}`);
|
|
80
88
|
this.log(` variables: ${grant.credential?.envKeys.join(', ') || '—'}`);
|
|
81
89
|
this.log(' Values are encrypted and cannot be read back.');
|
|
82
90
|
}
|
|
@@ -4,6 +4,10 @@ import { BaseCommand } from '../../base-command';
|
|
|
4
4
|
*
|
|
5
5
|
* Replacement, never a merge: a partial update could leave half of a previous
|
|
6
6
|
* key pair alive alongside the new one.
|
|
7
|
+
*
|
|
8
|
+
* A declared access class describes the OLD credential, so rotating clears it
|
|
9
|
+
* unless `--access` re-declares it for the new one (creator only). Installation-
|
|
10
|
+
* backed grants keep their attested access; it refreshes through the platform.
|
|
7
11
|
*/
|
|
8
12
|
export default class GrantsRotate extends BaseCommand {
|
|
9
13
|
static description: string;
|
|
@@ -14,6 +18,7 @@ export default class GrantsRotate extends BaseCommand {
|
|
|
14
18
|
static flags: {
|
|
15
19
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
20
|
env: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
access: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
22
|
};
|
|
18
23
|
run(): Promise<void>;
|
|
19
24
|
}
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const base_command_1 = require("../../base-command");
|
|
5
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
6
|
const grants_1 = require("../../lib/grants");
|
|
6
7
|
/**
|
|
7
8
|
* `skrr grants rotate` — replace a credential wholesale.
|
|
8
9
|
*
|
|
9
10
|
* Replacement, never a merge: a partial update could leave half of a previous
|
|
10
11
|
* key pair alive alongside the new one.
|
|
12
|
+
*
|
|
13
|
+
* A declared access class describes the OLD credential, so rotating clears it
|
|
14
|
+
* unless `--access` re-declares it for the new one (creator only). Installation-
|
|
15
|
+
* backed grants keep their attested access; it refreshes through the platform.
|
|
11
16
|
*/
|
|
12
17
|
class GrantsRotate extends base_command_1.BaseCommand {
|
|
13
18
|
static description = 'Rotate the credential on an existing grant';
|
|
@@ -24,6 +29,10 @@ class GrantsRotate extends base_command_1.BaseCommand {
|
|
|
24
29
|
multiple: true,
|
|
25
30
|
required: true,
|
|
26
31
|
}),
|
|
32
|
+
access: core_1.Flags.string({
|
|
33
|
+
options: [...data_provider_1.GRANT_ACCESS_CLASSES],
|
|
34
|
+
description: 'Re-declare the access class of the NEW credential (creator only). Without it, rotation clears the declared class.',
|
|
35
|
+
}),
|
|
27
36
|
};
|
|
28
37
|
async run() {
|
|
29
38
|
this.requireAuth();
|
|
@@ -35,13 +44,16 @@ class GrantsRotate extends base_command_1.BaseCommand {
|
|
|
35
44
|
catch (err) {
|
|
36
45
|
this.error(err.message);
|
|
37
46
|
}
|
|
38
|
-
const grant = await grants_1.grantApi.rotate(args.grantId, { kind: 'env', env });
|
|
47
|
+
const grant = await grants_1.grantApi.rotate(args.grantId, { kind: 'env', env }, flags.access);
|
|
39
48
|
if (flags.json) {
|
|
40
49
|
this.log(JSON.stringify(grant, null, 2));
|
|
41
50
|
return;
|
|
42
51
|
}
|
|
43
52
|
this.log(`Rotated grant ${grant.id}.`);
|
|
44
53
|
this.log(` variables: ${grant.credential?.envKeys.join(', ') || '—'}`);
|
|
54
|
+
if (!grant.access) {
|
|
55
|
+
this.log(' access: not declared (rotation clears the declared class; use --access to re-declare)');
|
|
56
|
+
}
|
|
45
57
|
}
|
|
46
58
|
}
|
|
47
59
|
exports.default = GrantsRotate;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class GrantsUpdate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static flags: {
|
|
8
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
access: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
const grants_1 = require("../../lib/grants");
|
|
7
|
+
class GrantsUpdate extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Update a Grant advisory access class (creator only)';
|
|
9
|
+
static args = { id: core_1.Args.string({ ignoreStdin: true, required: true }) };
|
|
10
|
+
static flags = {
|
|
11
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
12
|
+
access: core_1.Flags.string({
|
|
13
|
+
required: true,
|
|
14
|
+
options: [...data_provider_1.GRANT_ACCESS_CLASSES],
|
|
15
|
+
description: 'Declared provider access; does not verify or alter the credential',
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
async run() {
|
|
19
|
+
this.requireAuth();
|
|
20
|
+
const { args, flags } = await this.parse(GrantsUpdate);
|
|
21
|
+
const grant = await grants_1.grantApi.updateAccess(args.id, flags.access);
|
|
22
|
+
this.log(flags.json
|
|
23
|
+
? JSON.stringify(grant, null, 2)
|
|
24
|
+
: `${grant.id}: ${(0, data_provider_1.describeGrantAccess)(grant.access, grant.accessSource).label}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = GrantsUpdate;
|
|
@@ -13,7 +13,7 @@ class HostedMachinesStart extends base_command_1.BaseCommand {
|
|
|
13
13
|
];
|
|
14
14
|
static flags = {
|
|
15
15
|
agent: core_1.Flags.string({
|
|
16
|
-
description:
|
|
16
|
+
description: "Agent id (an agent you can view): applies that agent's declared network access. Use `agents attach-harness` to make it the agent default.",
|
|
17
17
|
}),
|
|
18
18
|
conversation: core_1.Flags.string({ description: 'Bind the machine to a conversation id' }),
|
|
19
19
|
environment: core_1.Flags.string({ description: 'Hosted environment id' }),
|
|
@@ -154,6 +154,12 @@ class HostedMachinesStart extends base_command_1.BaseCommand {
|
|
|
154
154
|
}
|
|
155
155
|
const id = (0, hosted_machines_1.hostedMachineId)(session);
|
|
156
156
|
this.log(`Hosted Machine ${id || '(unknown)'} ${(0, hosted_machines_1.hostedMachineStatus)(session)}.`);
|
|
157
|
+
if (session?.egressPolicy) {
|
|
158
|
+
this.log(`Network: ${session.egressPolicy} (${session.egressSource || 'source unknown'}; ${session.egressAllowHosts?.length || 0} hosts)`);
|
|
159
|
+
}
|
|
160
|
+
if (session?.egressDroppedHosts?.length) {
|
|
161
|
+
this.log(`Workspace policy dropped: ${session.egressDroppedHosts.join(', ')}`);
|
|
162
|
+
}
|
|
157
163
|
if (session?.previewUrl)
|
|
158
164
|
this.log(`Preview: ${session.previewUrl}`);
|
|
159
165
|
if (!(0, hosted_machines_1.isHostedMachineReady)(session)) {
|
|
@@ -37,16 +37,16 @@ class MachinesList extends base_command_1.BaseCommand {
|
|
|
37
37
|
catch (err) {
|
|
38
38
|
this.handleApiError(err);
|
|
39
39
|
}
|
|
40
|
+
const all = machines ?? [];
|
|
41
|
+
const shown = flags.all ? all : all.filter((m) => (0, machines_1.isReachableMachine)(m));
|
|
40
42
|
if (flags.json) {
|
|
41
|
-
this.log(JSON.stringify(
|
|
43
|
+
this.log(JSON.stringify(shown, null, 2));
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
44
|
-
if (
|
|
46
|
+
if (all.length === 0) {
|
|
45
47
|
this.log('No machines. Install a daemon with `skrr harnesses install-token`.');
|
|
46
48
|
return;
|
|
47
49
|
}
|
|
48
|
-
const all = machines;
|
|
49
|
-
const shown = flags.all ? all : all.filter((m) => (0, machines_1.isReachableMachine)(m));
|
|
50
50
|
if (shown.length === 0) {
|
|
51
51
|
this.log(`No machine is reachable right now (${(0, machines_1.hiddenMachinesSummary)(all)}) — see them with --all.`);
|
|
52
52
|
return;
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { BaseCommand } from '../../base-command';
|
|
2
|
-
/**
|
|
3
|
-
* `skrr measures confirm` — turn a claim into ground truth.
|
|
4
|
-
*
|
|
5
|
-
* This is the human-in-the-loop step whose `agentOutcome` equivalent shipped
|
|
6
|
-
* with zero callers, which left every value claim in the system permanently
|
|
7
|
-
* unverified.
|
|
8
|
-
*/
|
|
2
|
+
/** Confirm a reading and display the server-derived attribution. */
|
|
9
3
|
export default class MeasuresConfirm extends BaseCommand {
|
|
10
4
|
static description: string;
|
|
11
5
|
static examples: string[];
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
4
5
|
const base_command_1 = require("../../base-command");
|
|
5
6
|
const measures_1 = require("../../lib/measures");
|
|
6
|
-
/**
|
|
7
|
-
* `skrr measures confirm` — turn a claim into ground truth.
|
|
8
|
-
*
|
|
9
|
-
* This is the human-in-the-loop step whose `agentOutcome` equivalent shipped
|
|
10
|
-
* with zero callers, which left every value claim in the system permanently
|
|
11
|
-
* unverified.
|
|
12
|
-
*/
|
|
7
|
+
/** Confirm a reading and display the server-derived attribution. */
|
|
13
8
|
class MeasuresConfirm extends base_command_1.BaseCommand {
|
|
14
|
-
static description = 'Confirm an observation
|
|
9
|
+
static description = 'Confirm an observation with credential-derived evidence attribution';
|
|
15
10
|
static examples = [
|
|
16
11
|
'<%= config.bin %> measures confirm <measure-id> --at 2026-07-28T00:00:00Z',
|
|
17
12
|
'<%= config.bin %> measures confirm <measure-id> --latest',
|
|
@@ -22,7 +17,9 @@ class MeasuresConfirm extends base_command_1.BaseCommand {
|
|
|
22
17
|
static flags = {
|
|
23
18
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
24
19
|
at: core_1.Flags.string({ description: 'observedAt of the reading to confirm (ISO-8601)' }),
|
|
25
|
-
latest: core_1.Flags.boolean({
|
|
20
|
+
latest: core_1.Flags.boolean({
|
|
21
|
+
description: 'Confirm the most recent reading lacking person confirmation',
|
|
22
|
+
}),
|
|
26
23
|
};
|
|
27
24
|
async run() {
|
|
28
25
|
this.requireAuth();
|
|
@@ -33,19 +30,23 @@ class MeasuresConfirm extends base_command_1.BaseCommand {
|
|
|
33
30
|
this.error('Specify --at <iso-instant> or --latest.');
|
|
34
31
|
}
|
|
35
32
|
const measure = await measures_1.measureApi.get(args.measureId);
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
this.
|
|
33
|
+
const selection = (0, data_provider_1.latestConfirmableMeasureReading)(measure.observations);
|
|
34
|
+
if (selection.ambiguous) {
|
|
35
|
+
this.error('Multiple retained readings have the same timestamp; the existing confirmation endpoint cannot distinguish them. No confirmation was sent.');
|
|
36
|
+
}
|
|
37
|
+
const unconfirmed = selection.reading;
|
|
38
|
+
if (!unconfirmed) {
|
|
39
|
+
this.log('Nothing to confirm — no eligible reading lacking person confirmation is available.');
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
|
-
observedAt = unconfirmed
|
|
42
|
+
observedAt = unconfirmed.observedAt;
|
|
42
43
|
}
|
|
43
44
|
const measure = await measures_1.measureApi.confirm(args.measureId, observedAt);
|
|
44
45
|
if (flags.json) {
|
|
45
46
|
this.log(JSON.stringify(measure, null, 2));
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
48
|
-
this.log(
|
|
49
|
+
this.log((0, measures_1.recordConfirmationForObservation)(measure.observations.find((o) => Date.parse(o.observedAt) === Date.parse(observedAt))).message);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
exports.default = MeasuresConfirm;
|