@skrr-ai/cli 0.1.15 → 0.1.18
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 +10 -4
- package/dist/commands/commitments/action-proposals/decide.d.ts +13 -0
- package/dist/commands/commitments/action-proposals/decide.js +41 -0
- package/dist/commands/commitments/action-proposals/execute.d.ts +12 -0
- package/dist/commands/commitments/action-proposals/execute.js +29 -0
- package/dist/commands/commitments/action-proposals.d.ts +13 -0
- package/dist/commands/commitments/action-proposals.js +56 -0
- package/dist/commands/commitments/autonomy.d.ts +7 -11
- package/dist/commands/commitments/autonomy.js +16 -17
- package/dist/commands/commitments/bundle.d.ts +14 -0
- package/dist/commands/commitments/bundle.js +49 -0
- package/dist/commands/commitments/create.d.ts +33 -5
- package/dist/commands/commitments/create.js +234 -27
- package/dist/commands/commitments/delivery.d.ts +16 -0
- package/dist/commands/commitments/delivery.js +71 -0
- package/dist/commands/commitments/doctor.d.ts +20 -0
- package/dist/commands/commitments/doctor.js +88 -0
- package/dist/commands/commitments/effective-policy.d.ts +2 -0
- package/dist/commands/commitments/effective-policy.js +50 -5
- package/dist/commands/commitments/endpoints/connect.d.ts +3 -10
- package/dist/commands/commitments/endpoints/connect.js +6 -37
- package/dist/commands/commitments/endpoints/create.d.ts +2 -9
- package/dist/commands/commitments/endpoints/create.js +10 -23
- package/dist/commands/commitments/mode.d.ts +15 -0
- package/dist/commands/commitments/mode.js +57 -0
- package/dist/commands/commitments/pack/promote.d.ts +1 -1
- package/dist/commands/commitments/pack/promote.js +7 -3
- package/dist/commands/commitments/pack/shadow.d.ts +3 -2
- package/dist/commands/commitments/pack/shadow.js +6 -4
- package/dist/commands/commitments/patch.d.ts +14 -0
- package/dist/commands/commitments/patch.js +51 -0
- package/dist/commands/commitments/preflight.d.ts +5 -2
- package/dist/commands/commitments/preflight.js +47 -6
- package/dist/commands/commitments/receipt.d.ts +15 -0
- package/dist/commands/commitments/receipt.js +34 -0
- package/dist/commands/commitments/remediate.d.ts +0 -1
- package/dist/commands/commitments/remediate.js +5 -3
- package/dist/commands/commitments/reports.js +27 -5
- package/dist/commands/commitments/show.d.ts +1 -0
- package/dist/commands/commitments/show.js +22 -1
- package/dist/commands/commitments/update.d.ts +9 -2
- package/dist/commands/commitments/update.js +40 -4
- package/dist/commands/commitments/wake-capabilities.d.ts +5 -0
- package/dist/commands/commitments/wake-capabilities.js +23 -7
- package/dist/commands/spaces/bootstrap.js +1 -1
- package/dist/commands/tasks/complete.js +57 -0
- package/dist/commands/tasks/create.js +2 -1
- package/dist/commands/tasks/deliverable/confirm.d.ts +35 -0
- package/dist/commands/tasks/deliverable/confirm.js +77 -0
- package/dist/commands/tasks/expectations.js +20 -1
- package/dist/commands/tasks/report.js +24 -0
- package/dist/commands/tasks/trust.d.ts +35 -0
- package/dist/commands/tasks/trust.js +75 -0
- package/dist/commands/tasks/waive.js +1 -1
- package/dist/lib/commitment-endpoints.d.ts +3 -2
- package/dist/lib/commitment-endpoints.js +12 -9
- package/dist/lib/commitment-product.d.ts +14 -0
- package/dist/lib/commitment-product.js +78 -0
- package/dist/lib/commitments.d.ts +67 -20
- package/dist/lib/commitments.js +89 -39
- package/dist/lib/tasks.js +27 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +3733 -3570
- package/oclif.manifest.json +9291 -8306
- package/package.json +1 -1
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { BaseCommand } from '../../../base-command';
|
|
2
2
|
/**
|
|
3
|
-
* `skrr commitments endpoints connect <id>`
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* connected endpoint: open it, approve, then run the same command with
|
|
7
|
-
* `--finalize`. That two-step is the reason this needed a CLI — without it a
|
|
8
|
-
* headless operator could not connect a delivery target at all.
|
|
9
|
-
*
|
|
10
|
-
* `--reconnect` runs the same handshake for an endpoint that has gone stale.
|
|
3
|
+
* `skrr commitments endpoints connect <id>` probes the Agent's native App or
|
|
4
|
+
* Slack transport and records its live health. `--reconnect` reruns the same
|
|
5
|
+
* probe for a stale/revoked endpoint.
|
|
11
6
|
*/
|
|
12
7
|
export default class CommitmentsEndpointsConnect extends BaseCommand {
|
|
13
8
|
static description: string;
|
|
@@ -17,9 +12,7 @@ export default class CommitmentsEndpointsConnect extends BaseCommand {
|
|
|
17
12
|
};
|
|
18
13
|
static flags: {
|
|
19
14
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
20
|
-
finalize: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
15
|
reconnect: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
|
-
request: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
16
|
};
|
|
24
17
|
run(): Promise<void>;
|
|
25
18
|
}
|
|
@@ -4,21 +4,14 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const base_command_1 = require("../../../base-command");
|
|
5
5
|
const commitment_endpoints_1 = require("../../../lib/commitment-endpoints");
|
|
6
6
|
/**
|
|
7
|
-
* `skrr commitments endpoints connect <id>`
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* connected endpoint: open it, approve, then run the same command with
|
|
11
|
-
* `--finalize`. That two-step is the reason this needed a CLI — without it a
|
|
12
|
-
* headless operator could not connect a delivery target at all.
|
|
13
|
-
*
|
|
14
|
-
* `--reconnect` runs the same handshake for an endpoint that has gone stale.
|
|
7
|
+
* `skrr commitments endpoints connect <id>` probes the Agent's native App or
|
|
8
|
+
* Slack transport and records its live health. `--reconnect` reruns the same
|
|
9
|
+
* probe for a stale/revoked endpoint.
|
|
15
10
|
*/
|
|
16
11
|
class CommitmentsEndpointsConnect extends base_command_1.BaseCommand {
|
|
17
|
-
static description = 'Connect
|
|
12
|
+
static description = 'Connect or recheck a native commitment endpoint';
|
|
18
13
|
static examples = [
|
|
19
14
|
'<%= config.bin %> commitments endpoints connect ep_abc123',
|
|
20
|
-
'<%= config.bin %> commitments endpoints connect ep_abc123 --finalize',
|
|
21
|
-
'<%= config.bin %> commitments endpoints connect ep_abc123 --finalize --request req_xyz',
|
|
22
15
|
'<%= config.bin %> commitments endpoints connect ep_abc123 --reconnect',
|
|
23
16
|
];
|
|
24
17
|
static args = {
|
|
@@ -26,29 +19,14 @@ class CommitmentsEndpointsConnect extends base_command_1.BaseCommand {
|
|
|
26
19
|
};
|
|
27
20
|
static flags = {
|
|
28
21
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
29
|
-
|
|
30
|
-
description: 'Complete an OAuth handshake that `connect` started',
|
|
31
|
-
exclusive: ['reconnect'],
|
|
32
|
-
}),
|
|
33
|
-
reconnect: core_1.Flags.boolean({
|
|
34
|
-
description: 'Re-run the handshake for a stale endpoint',
|
|
35
|
-
exclusive: ['finalize'],
|
|
36
|
-
}),
|
|
37
|
-
request: core_1.Flags.string({
|
|
38
|
-
description: 'Connection request id (defaults to the one stored on the endpoint)',
|
|
39
|
-
}),
|
|
22
|
+
reconnect: core_1.Flags.boolean({ description: 'Re-run the native transport probe' }),
|
|
40
23
|
};
|
|
41
24
|
async run() {
|
|
42
25
|
this.requireAuth();
|
|
43
26
|
const { args, flags } = await this.parse(CommitmentsEndpointsConnect);
|
|
44
27
|
let result;
|
|
45
28
|
try {
|
|
46
|
-
if (flags.
|
|
47
|
-
result = await commitment_endpoints_1.commitmentEndpointApi.finalizeConnect(args.endpointId, {
|
|
48
|
-
...(flags.request ? { requestId: flags.request } : {}),
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
else if (flags.reconnect) {
|
|
29
|
+
if (flags.reconnect) {
|
|
52
30
|
result = await commitment_endpoints_1.commitmentEndpointApi.reconnect(args.endpointId);
|
|
53
31
|
}
|
|
54
32
|
else {
|
|
@@ -62,15 +40,6 @@ class CommitmentsEndpointsConnect extends base_command_1.BaseCommand {
|
|
|
62
40
|
this.log(JSON.stringify(result, null, 2));
|
|
63
41
|
return;
|
|
64
42
|
}
|
|
65
|
-
const oauth = result.oauth;
|
|
66
|
-
const authorizationUrl = oauth?.authorizationUrl ??
|
|
67
|
-
result.authorizationUrl;
|
|
68
|
-
if (authorizationUrl) {
|
|
69
|
-
this.log('Authorization required. Open this URL, approve, then re-run with --finalize:');
|
|
70
|
-
this.log('');
|
|
71
|
-
this.log(` ${authorizationUrl}`);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
43
|
const endpoint = (result.endpoint ?? result);
|
|
75
44
|
this.log(`${args.endpointId} → ${String(endpoint.status ?? 'updated')}`);
|
|
76
45
|
}
|
|
@@ -7,9 +7,8 @@ import { BaseCommand } from '../../../base-command';
|
|
|
7
7
|
* cannot use it. Declaring capabilities up front is what lets the Attention
|
|
8
8
|
* Contract refuse an impossible delivery instead of dropping it silently.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `endpoints health`.
|
|
10
|
+
* Slack endpoints use the Agent's native Slack installation; App DM is built
|
|
11
|
+
* in. Connector metadata is not a delivery adapter and is not authorable here.
|
|
13
12
|
*/
|
|
14
13
|
export default class CommitmentsEndpointsCreate extends BaseCommand {
|
|
15
14
|
static description: string;
|
|
@@ -18,15 +17,9 @@ export default class CommitmentsEndpointsCreate extends BaseCommand {
|
|
|
18
17
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
18
|
agent: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
19
|
label: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
-
provider: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
20
|
destination: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
21
|
target: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
22
|
capability: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
25
|
-
'integration-provider': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
26
|
-
toolkit: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
27
|
-
'authorization-url': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
28
|
-
'reconnect-url': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
29
|
-
'external-ref': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
30
23
|
};
|
|
31
24
|
run(): Promise<void>;
|
|
32
25
|
}
|
|
@@ -11,23 +11,22 @@ const commitment_endpoints_1 = require("../../../lib/commitment-endpoints");
|
|
|
11
11
|
* cannot use it. Declaring capabilities up front is what lets the Attention
|
|
12
12
|
* Contract refuse an impossible delivery instead of dropping it silently.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `endpoints health`.
|
|
14
|
+
* Slack endpoints use the Agent's native Slack installation; App DM is built
|
|
15
|
+
* in. Connector metadata is not a delivery adapter and is not authorable here.
|
|
17
16
|
*/
|
|
18
17
|
class CommitmentsEndpointsCreate extends base_command_1.BaseCommand {
|
|
19
18
|
static description = 'Create a commitment delivery endpoint';
|
|
20
19
|
static examples = [
|
|
21
|
-
'<%= config.bin %> commitments endpoints create --agent agent_abc --label "Ops channel" --
|
|
22
|
-
'<%= config.bin %> commitments endpoints create --agent agent_abc --label "My DM" --
|
|
20
|
+
'<%= config.bin %> commitments endpoints create --agent agent_abc --label "Ops channel" --destination slack_channel --target C123 --capability push --capability reply',
|
|
21
|
+
'<%= config.bin %> commitments endpoints create --agent agent_abc --label "My DM" --destination slack_owner_dm --capability push',
|
|
23
22
|
];
|
|
24
23
|
static flags = {
|
|
25
24
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
26
25
|
agent: core_1.Flags.string({ description: 'Agent ID', required: true }),
|
|
27
26
|
label: core_1.Flags.string({ description: 'Human-readable label', required: true }),
|
|
28
|
-
provider: core_1.Flags.string({ description: 'Provider, e.g. slack / email', required: true }),
|
|
29
27
|
destination: core_1.Flags.string({
|
|
30
|
-
description: '
|
|
28
|
+
description: 'Implemented destination: slack_channel, slack_owner_dm, or app_owner_dm',
|
|
29
|
+
options: [...commitment_endpoints_1.COMMITMENT_ENDPOINT_DESTINATIONS],
|
|
31
30
|
required: true,
|
|
32
31
|
}),
|
|
33
32
|
target: core_1.Flags.string({ description: 'Channel/address id for destinations that address one' }),
|
|
@@ -37,13 +36,6 @@ class CommitmentsEndpointsCreate extends base_command_1.BaseCommand {
|
|
|
37
36
|
multiple: true,
|
|
38
37
|
required: true,
|
|
39
38
|
}),
|
|
40
|
-
'integration-provider': core_1.Flags.string({
|
|
41
|
-
description: 'Installed IntegrationProvider to run the OAuth lifecycle through',
|
|
42
|
-
}),
|
|
43
|
-
toolkit: core_1.Flags.string({ description: 'Toolkit for the integration provider' }),
|
|
44
|
-
'authorization-url': core_1.Flags.string({ description: 'Pre-known authorization URL' }),
|
|
45
|
-
'reconnect-url': core_1.Flags.string({ description: 'Pre-known reconnect URL' }),
|
|
46
|
-
'external-ref': core_1.Flags.string({ description: 'Provider-side reference id' }),
|
|
47
39
|
};
|
|
48
40
|
async run() {
|
|
49
41
|
this.requireAuth();
|
|
@@ -53,17 +45,10 @@ class CommitmentsEndpointsCreate extends base_command_1.BaseCommand {
|
|
|
53
45
|
endpoint = await commitment_endpoints_1.commitmentEndpointApi.create({
|
|
54
46
|
agentId: flags.agent,
|
|
55
47
|
label: flags.label,
|
|
56
|
-
provider: flags.
|
|
48
|
+
provider: flags.destination.startsWith('slack_') ? 'slack' : 'app',
|
|
57
49
|
destination: flags.destination,
|
|
58
50
|
capabilities: flags.capability,
|
|
59
51
|
...(flags.target ? { target: flags.target } : {}),
|
|
60
|
-
...(flags['integration-provider']
|
|
61
|
-
? { integrationProvider: flags['integration-provider'] }
|
|
62
|
-
: {}),
|
|
63
|
-
...(flags.toolkit ? { toolkit: flags.toolkit } : {}),
|
|
64
|
-
...(flags['authorization-url'] ? { authorizationUrl: flags['authorization-url'] } : {}),
|
|
65
|
-
...(flags['reconnect-url'] ? { reconnectUrl: flags['reconnect-url'] } : {}),
|
|
66
|
-
...(flags['external-ref'] ? { externalRef: flags['external-ref'] } : {}),
|
|
67
52
|
});
|
|
68
53
|
}
|
|
69
54
|
catch (err) {
|
|
@@ -74,7 +59,9 @@ class CommitmentsEndpointsCreate extends base_command_1.BaseCommand {
|
|
|
74
59
|
return;
|
|
75
60
|
}
|
|
76
61
|
this.log(`Created ${endpoint.id} (${endpoint.status ?? 'pending'}).`);
|
|
77
|
-
this.log(
|
|
62
|
+
this.log(endpoint.status === 'connected'
|
|
63
|
+
? 'The built-in App endpoint is ready.'
|
|
64
|
+
: `Next: skrr commitments endpoints connect ${endpoint.id}`);
|
|
78
65
|
}
|
|
79
66
|
}
|
|
80
67
|
exports.default = CommitmentsEndpointsCreate;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class CommitmentsMode extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
mode: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
reason: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const commitments_1 = require("../../lib/commitments");
|
|
6
|
+
const commitment_product_1 = require("../../lib/commitment-product");
|
|
7
|
+
const web_url_1 = require("../../lib/web-url");
|
|
8
|
+
class CommitmentsMode extends base_command_1.BaseCommand {
|
|
9
|
+
static description = 'Choose how a commitment progresses: Monitor, Prepare, or Execute';
|
|
10
|
+
static examples = ['<%= config.bin %> commitments mode <id> execute'];
|
|
11
|
+
static args = {
|
|
12
|
+
id: core_1.Args.string({ required: true, ignoreStdin: true }),
|
|
13
|
+
mode: core_1.Args.string({
|
|
14
|
+
required: true,
|
|
15
|
+
options: [...commitment_product_1.COMMITMENT_PRODUCT_MODES],
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
json: core_1.Flags.boolean({ description: 'Output the complete contract as JSON' }),
|
|
20
|
+
verbose: core_1.Flags.boolean({ description: 'Include compatibility values' }),
|
|
21
|
+
reason: core_1.Flags.string({ description: 'Reason recorded with this contract change' }),
|
|
22
|
+
};
|
|
23
|
+
async run() {
|
|
24
|
+
this.requireAuth();
|
|
25
|
+
const { args, flags } = await this.parse(CommitmentsMode);
|
|
26
|
+
try {
|
|
27
|
+
if (args.mode === 'off') {
|
|
28
|
+
this.error('Use commitments pause <id> to stop wakes; lifecycle is separate from mode.');
|
|
29
|
+
}
|
|
30
|
+
const result = await commitments_1.commitmentApi.mode(args.id, {
|
|
31
|
+
mode: (0, commitment_product_1.productMode)(args.mode),
|
|
32
|
+
...(flags.reason ? { reason: flags.reason } : {}),
|
|
33
|
+
});
|
|
34
|
+
const linked = (0, web_url_1.withCommitmentUrl)(this.cliConfig.baseURL, result);
|
|
35
|
+
if (flags.json)
|
|
36
|
+
return this.log(JSON.stringify(linked, null, 2));
|
|
37
|
+
const stagingForPromotion = result.pack?.phase === 'shadow';
|
|
38
|
+
this.log(stagingForPromotion
|
|
39
|
+
? `Promotion mode staged as ${(0, commitment_product_1.productModeLabel)(args.mode)}.`
|
|
40
|
+
: `Mode set to ${(0, commitment_product_1.productModeLabel)(args.mode)}.`);
|
|
41
|
+
if (stagingForPromotion) {
|
|
42
|
+
this.log('Live Pack Shadow remains Monitor until explicit promotion.');
|
|
43
|
+
}
|
|
44
|
+
if ((0, commitment_product_1.productMode)(args.mode) === 'monitor') {
|
|
45
|
+
this.log(`${stagingForPromotion ? 'Promotion delivery' : 'Delivery'} set to Report only. Monitor cannot create patches, branches, or pull requests.`);
|
|
46
|
+
}
|
|
47
|
+
(0, commitments_1.renderCommitmentSummary)(result, (line) => this.log(line));
|
|
48
|
+
if (flags.verbose)
|
|
49
|
+
this.log(`Compatibility value: ${result.policy?.autonomyMode}`);
|
|
50
|
+
this.log(`URL: ${linked.url}`);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
this.handleApiError(error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.default = CommitmentsMode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseCommand } from '../../../base-command';
|
|
2
2
|
/**
|
|
3
|
-
* Graduate a Pack out of shadow and restore the saved
|
|
3
|
+
* Graduate a Pack out of shadow and restore the saved Mode and delivery.
|
|
4
4
|
*
|
|
5
5
|
* Explicit by design — promotion is never inferred from a passing preflight.
|
|
6
6
|
* The saved policy tracks explicit policy writes made DURING shadow, so an
|
|
@@ -3,15 +3,16 @@ 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 commitments_1 = require("../../../lib/commitments");
|
|
6
|
+
const commitment_product_1 = require("../../../lib/commitment-product");
|
|
6
7
|
/**
|
|
7
|
-
* Graduate a Pack out of shadow and restore the saved
|
|
8
|
+
* Graduate a Pack out of shadow and restore the saved Mode and delivery.
|
|
8
9
|
*
|
|
9
10
|
* Explicit by design — promotion is never inferred from a passing preflight.
|
|
10
11
|
* The saved policy tracks explicit policy writes made DURING shadow, so an
|
|
11
12
|
* autonomy change made while observing is not discarded here.
|
|
12
13
|
*/
|
|
13
14
|
class CommitmentsPackPromote extends base_command_1.BaseCommand {
|
|
14
|
-
static description = 'Graduate a Pack out of shadow, restoring
|
|
15
|
+
static description = 'Graduate a Pack out of shadow, restoring its staged Mode and delivery';
|
|
15
16
|
static examples = ['<%= config.bin %> commitments pack promote <commitment-id>'];
|
|
16
17
|
static args = {
|
|
17
18
|
id: core_1.Args.string({ description: 'Commitment ID', required: true, ignoreStdin: true }),
|
|
@@ -36,7 +37,10 @@ class CommitmentsPackPromote extends base_command_1.BaseCommand {
|
|
|
36
37
|
this.log(`Phase: ${result.phase}`);
|
|
37
38
|
const mode = result.commitment?.policy?.autonomyMode;
|
|
38
39
|
if (mode)
|
|
39
|
-
this.log(`
|
|
40
|
+
this.log(`Mode: ${(0, commitment_product_1.productModeLabel)(mode)}`);
|
|
41
|
+
if (result.commitment?.delivery?.mode) {
|
|
42
|
+
this.log(`Delivery: ${(0, commitment_product_1.deliveryLabel)(result.commitment.delivery.mode)}`);
|
|
43
|
+
}
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
46
|
exports.default = CommitmentsPackPromote;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export declare const SHADOW_ACTIVE_COPY = "Shadow is active in Monitor: checks continue, but delivery cannot run and live delivery stays\nReport only. The prior Mode and delivery are saved as the promotion target;\n`skrr commitments pack promote` applies them.";
|
|
2
3
|
/**
|
|
3
|
-
* Activate shadow: the Commitment goes active and starts checking
|
|
4
|
-
*
|
|
4
|
+
* Activate shadow: the Commitment goes active in Monitor and starts checking.
|
|
5
|
+
* Its prior Mode and delivery are saved as the target for `promote`.
|
|
5
6
|
*
|
|
6
7
|
* Requires a STORED preflight verdict of `ready`, which is why
|
|
7
8
|
* `pack preflight` exists as its own command.
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SHADOW_ACTIVE_COPY = void 0;
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const base_command_1 = require("../../../base-command");
|
|
5
6
|
const commitments_1 = require("../../../lib/commitments");
|
|
7
|
+
exports.SHADOW_ACTIVE_COPY = 'Shadow is active in Monitor: checks continue, but delivery cannot run and live delivery stays\nReport only. The prior Mode and delivery are saved as the promotion target;\n`skrr commitments pack promote` applies them.';
|
|
6
8
|
/**
|
|
7
|
-
* Activate shadow: the Commitment goes active and starts checking
|
|
8
|
-
*
|
|
9
|
+
* Activate shadow: the Commitment goes active in Monitor and starts checking.
|
|
10
|
+
* Its prior Mode and delivery are saved as the target for `promote`.
|
|
9
11
|
*
|
|
10
12
|
* Requires a STORED preflight verdict of `ready`, which is why
|
|
11
13
|
* `pack preflight` exists as its own command.
|
|
12
14
|
*/
|
|
13
15
|
class CommitmentsPackShadow extends base_command_1.BaseCommand {
|
|
14
|
-
static description = 'Activate shadow
|
|
16
|
+
static description = 'Activate shadow: run the Pack in Monitor while saving its Mode and delivery promotion target';
|
|
15
17
|
static examples = ['<%= config.bin %> commitments pack shadow <commitment-id>'];
|
|
16
18
|
static args = {
|
|
17
19
|
id: core_1.Args.string({ description: 'Commitment ID', required: true, ignoreStdin: true }),
|
|
@@ -34,7 +36,7 @@ class CommitmentsPackShadow extends base_command_1.BaseCommand {
|
|
|
34
36
|
}
|
|
35
37
|
this.log(`Pack: ${result.pack?.id}@${result.pack?.version}`);
|
|
36
38
|
this.log(`Phase: ${result.phase}`);
|
|
37
|
-
this.log(
|
|
39
|
+
this.log(`\n${exports.SHADOW_ACTIVE_COPY}`);
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
exports.default = CommitmentsPackShadow;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class CommitmentsPatch extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
task: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
output: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const base_command_1 = require("../../base-command");
|
|
8
|
+
const commitments_1 = require("../../lib/commitments");
|
|
9
|
+
class CommitmentsPatch extends base_command_1.BaseCommand {
|
|
10
|
+
static description = 'Download the durable patch retained by a Commitment delivery Task';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> commitments patch <id> --task <task-id> --output remediation.patch',
|
|
13
|
+
];
|
|
14
|
+
static args = { id: core_1.Args.string({ required: true, ignoreStdin: true }) };
|
|
15
|
+
static flags = {
|
|
16
|
+
task: core_1.Flags.string({
|
|
17
|
+
required: true,
|
|
18
|
+
description: 'Delivery Task ID from the execution receipt',
|
|
19
|
+
}),
|
|
20
|
+
output: core_1.Flags.string({
|
|
21
|
+
description: 'Save a new patch file (existing files are not overwritten)',
|
|
22
|
+
}),
|
|
23
|
+
json: core_1.Flags.boolean({ description: 'Output patch content and integrity metadata as JSON' }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
this.requireAuth();
|
|
27
|
+
const { args, flags } = await this.parse(CommitmentsPatch);
|
|
28
|
+
try {
|
|
29
|
+
const result = await commitments_1.commitmentApi.deliveryPatch(args.id, flags.task);
|
|
30
|
+
const content = result.patch.content;
|
|
31
|
+
if ((0, node_crypto_1.createHash)('sha256').update(content).digest('hex') !== result.patch.sha256 ||
|
|
32
|
+
Buffer.byteLength(content, 'utf8') !== result.patch.bytes) {
|
|
33
|
+
this.error('Patch integrity check failed. The downloaded content was not saved.');
|
|
34
|
+
}
|
|
35
|
+
if (flags.output) {
|
|
36
|
+
const output = (0, node_path_1.resolve)(flags.output);
|
|
37
|
+
(0, node_fs_1.writeFileSync)(output, content, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
|
|
38
|
+
if (!flags.json)
|
|
39
|
+
this.log(`Patch saved: ${output}\nSHA-256: ${result.patch.sha256}`);
|
|
40
|
+
}
|
|
41
|
+
if (flags.json)
|
|
42
|
+
this.log(JSON.stringify(result, null, 2));
|
|
43
|
+
else if (!flags.output)
|
|
44
|
+
this.log(content);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
this.handleApiError(error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.default = CommitmentsPatch;
|
|
@@ -23,16 +23,19 @@ type PreflightGate = CommitmentPreflightReport['gates'][number];
|
|
|
23
23
|
* The note gets its own indented line. It is prose, and hanging it off the same
|
|
24
24
|
* dash as a short code puts two different kinds of thing in one slot.
|
|
25
25
|
*/
|
|
26
|
-
export declare function preflightGateLines(gate: PreflightGate): string[];
|
|
26
|
+
export declare function preflightGateLines(gate: PreflightGate, verbose?: boolean): string[];
|
|
27
27
|
export default class CommitmentsPreflight extends BaseCommand {
|
|
28
28
|
static description: string;
|
|
29
29
|
static examples: string[];
|
|
30
30
|
static args: {
|
|
31
|
-
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
31
|
+
id: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
32
32
|
};
|
|
33
33
|
static flags: {
|
|
34
34
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
35
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
35
36
|
next: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
37
|
+
'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
38
|
+
'event-fixture': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
36
39
|
};
|
|
37
40
|
run(): Promise<void>;
|
|
38
41
|
}
|
|
@@ -4,6 +4,7 @@ exports.preflightGateLines = preflightGateLines;
|
|
|
4
4
|
const core_1 = require("@oclif/core");
|
|
5
5
|
const base_command_1 = require("../../base-command");
|
|
6
6
|
const commitments_1 = require("../../lib/commitments");
|
|
7
|
+
const prompt_1 = require("../../lib/prompt");
|
|
7
8
|
/**
|
|
8
9
|
* The lines one preflight gate contributes.
|
|
9
10
|
*
|
|
@@ -21,9 +22,11 @@ const commitments_1 = require("../../lib/commitments");
|
|
|
21
22
|
* The note gets its own indented line. It is prose, and hanging it off the same
|
|
22
23
|
* dash as a short code puts two different kinds of thing in one slot.
|
|
23
24
|
*/
|
|
24
|
-
function preflightGateLines(gate) {
|
|
25
|
+
function preflightGateLines(gate, verbose = false) {
|
|
25
26
|
const mark = gate.verdict === 'pass' ? 'ok' : gate.verdict === 'block' ? 'BLOCK' : 'warn';
|
|
26
|
-
const lines = [
|
|
27
|
+
const lines = [
|
|
28
|
+
` ${mark.padEnd(5)} ${gate.label}${verbose && gate.reason ? ` — ${gate.reason}` : ''}`,
|
|
29
|
+
];
|
|
27
30
|
const note = gate.detail?.note;
|
|
28
31
|
if (typeof note === 'string' && note.trim()) {
|
|
29
32
|
lines.push(` ${note.trim()}`);
|
|
@@ -46,21 +49,43 @@ class CommitmentsPreflight extends base_command_1.BaseCommand {
|
|
|
46
49
|
'<%= config.bin %> commitments preflight <commitment-id> --json',
|
|
47
50
|
];
|
|
48
51
|
static args = {
|
|
49
|
-
id: core_1.Args.string({
|
|
52
|
+
id: core_1.Args.string({
|
|
53
|
+
description: 'Commitment ID (omit with --from-json to preview before creation)',
|
|
54
|
+
required: false,
|
|
55
|
+
ignoreStdin: true,
|
|
56
|
+
}),
|
|
50
57
|
};
|
|
51
58
|
static flags = {
|
|
52
59
|
json: core_1.Flags.boolean({ description: 'Output the complete preflight report as JSON' }),
|
|
60
|
+
verbose: core_1.Flags.boolean({ description: 'Include diagnostic gate codes' }),
|
|
53
61
|
next: core_1.Flags.integer({ description: 'Number of upcoming runs to project (1–10)' }),
|
|
62
|
+
'from-json': core_1.Flags.string({
|
|
63
|
+
description: 'Unsaved Commitment create body file, or - for stdin',
|
|
64
|
+
}),
|
|
65
|
+
'event-fixture': core_1.Flags.string({
|
|
66
|
+
description: 'Optional event fixture JSON file, or - for stdin',
|
|
67
|
+
}),
|
|
54
68
|
};
|
|
55
69
|
async run() {
|
|
56
70
|
this.requireAuth();
|
|
57
71
|
const { args, flags } = await this.parse(CommitmentsPreflight);
|
|
72
|
+
if (Boolean(args.id) === Boolean(flags['from-json'])) {
|
|
73
|
+
this.error('Pass either a commitment ID or --from-json <file|->.', { exit: 1 });
|
|
74
|
+
}
|
|
58
75
|
if (flags.next != null && (flags.next < 1 || flags.next > 10)) {
|
|
59
76
|
this.error('--next must be between 1 and 10', { exit: 1 });
|
|
60
77
|
}
|
|
61
78
|
let report;
|
|
62
79
|
try {
|
|
63
|
-
report =
|
|
80
|
+
report = args.id
|
|
81
|
+
? await commitments_1.commitmentApi.preflight(args.id, flags.next)
|
|
82
|
+
: await commitments_1.commitmentApi.draftPreflight({
|
|
83
|
+
commitment: (0, commitments_1.normalizeCreateBody)(await (0, prompt_1.readJsonBody)(flags['from-json'])),
|
|
84
|
+
...(flags['event-fixture']
|
|
85
|
+
? { eventFixture: await (0, prompt_1.readJsonBody)(flags['event-fixture']) }
|
|
86
|
+
: {}),
|
|
87
|
+
...(flags.next !== undefined ? { nextRunCount: flags.next } : {}),
|
|
88
|
+
});
|
|
64
89
|
}
|
|
65
90
|
catch (err) {
|
|
66
91
|
this.handleApiError(err);
|
|
@@ -70,12 +95,28 @@ class CommitmentsPreflight extends base_command_1.BaseCommand {
|
|
|
70
95
|
this.log(JSON.stringify(report, null, 2));
|
|
71
96
|
return;
|
|
72
97
|
}
|
|
73
|
-
this.log(
|
|
98
|
+
this.log(`${args.id ? 'Preflight' : 'Pre-create preview (nothing persisted)'}: ${report.verdict === 'ready' ? 'Ready to run' : report.verdict === 'blocked' ? 'Run is blocked' : 'A capability or configuration check is still needed'}`);
|
|
74
99
|
this.log('\nGates:');
|
|
75
100
|
for (const gate of report.gates || []) {
|
|
76
|
-
for (const line of preflightGateLines(gate))
|
|
101
|
+
for (const line of preflightGateLines(gate, flags.verbose))
|
|
77
102
|
this.log(line);
|
|
78
103
|
}
|
|
104
|
+
if (report.capabilities?.length) {
|
|
105
|
+
this.log('\nWhere access comes from:');
|
|
106
|
+
const sourceLabels = {
|
|
107
|
+
event_payload: 'Event facts',
|
|
108
|
+
platform_grant: 'Platform-attested access',
|
|
109
|
+
local_harness: 'This machine’s tooling',
|
|
110
|
+
cloud_runtime: 'Runtime-scoped access',
|
|
111
|
+
};
|
|
112
|
+
for (const capability of report.capabilities) {
|
|
113
|
+
this.log(` ${sourceLabels[capability.source]} · ${capability.provider} · ${capability.capability}${capability.scope ? ` · ${capability.scope}` : ''}: ${capability.status}`);
|
|
114
|
+
if (capability.testedAt)
|
|
115
|
+
this.log(` Tested: ${capability.testedAt}${capability.expiresAt ? ` · expires ${capability.expiresAt}` : ''}`);
|
|
116
|
+
if (capability.attestation === 'machine')
|
|
117
|
+
this.log(' Machine-attested; not platform-attested.');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
79
120
|
if (report.nextRuns?.length) {
|
|
80
121
|
this.log('\nNext runs:');
|
|
81
122
|
for (const run of report.nextRuns)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class CommitmentsReceipt extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
latest: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const commitments_1 = require("../../lib/commitments");
|
|
6
|
+
const commitment_product_1 = require("../../lib/commitment-product");
|
|
7
|
+
class CommitmentsReceipt extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Explain what happened from the event through work, delivery, and verification';
|
|
9
|
+
static examples = ['<%= config.bin %> commitments receipt <id> --latest'];
|
|
10
|
+
static args = { id: core_1.Args.string({ required: true, ignoreStdin: true }) };
|
|
11
|
+
static flags = {
|
|
12
|
+
latest: core_1.Flags.boolean({ description: 'Show the latest wake (default)' }),
|
|
13
|
+
limit: core_1.Flags.integer({ description: 'Number of receipts to show', min: 1, max: 100 }),
|
|
14
|
+
json: core_1.Flags.boolean({ description: 'Output projected receipts as JSON' }),
|
|
15
|
+
verbose: core_1.Flags.boolean({ description: 'Include source IDs and diagnostic traces' }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
this.requireAuth();
|
|
19
|
+
const { args, flags } = await this.parse(CommitmentsReceipt);
|
|
20
|
+
try {
|
|
21
|
+
const result = await commitments_1.commitmentApi.receipts(args.id, flags.latest ? 1 : flags.limit || 1);
|
|
22
|
+
if (flags.json)
|
|
23
|
+
return this.log(JSON.stringify(result, null, 2));
|
|
24
|
+
if (!result.receipts.length)
|
|
25
|
+
return this.log('No wake has been observed yet.');
|
|
26
|
+
for (const receipt of result.receipts)
|
|
27
|
+
(0, commitment_product_1.renderExecutionReceipt)(receipt, (line) => this.log(line), flags.verbose);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
this.handleApiError(error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.default = CommitmentsReceipt;
|
|
@@ -11,7 +11,6 @@ import { BaseCommand } from '../../base-command';
|
|
|
11
11
|
* pause_commitment stop the loop entirely
|
|
12
12
|
* mute_user_nudges keep watching, stop interrupting (max nudges → 0)
|
|
13
13
|
* reduce_nudge_frequency at most one nudge per day
|
|
14
|
-
* tighten_policy require approval for the risky action classes
|
|
15
14
|
* mark_noop record that this fired for no reason
|
|
16
15
|
*/
|
|
17
16
|
export default class CommitmentsRemediate extends BaseCommand {
|