@skrr-ai/cli 0.1.17 → 0.1.19

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.
Files changed (53) hide show
  1. package/README.md +7 -4
  2. package/dist/commands/commitments/action-proposals/decide.d.ts +13 -0
  3. package/dist/commands/commitments/action-proposals/decide.js +41 -0
  4. package/dist/commands/commitments/action-proposals/execute.d.ts +12 -0
  5. package/dist/commands/commitments/action-proposals/execute.js +29 -0
  6. package/dist/commands/commitments/action-proposals.d.ts +13 -0
  7. package/dist/commands/commitments/action-proposals.js +56 -0
  8. package/dist/commands/commitments/autonomy.d.ts +7 -11
  9. package/dist/commands/commitments/autonomy.js +16 -25
  10. package/dist/commands/commitments/bundle.d.ts +14 -0
  11. package/dist/commands/commitments/bundle.js +49 -0
  12. package/dist/commands/commitments/create.d.ts +25 -0
  13. package/dist/commands/commitments/create.js +200 -23
  14. package/dist/commands/commitments/delivery.d.ts +16 -0
  15. package/dist/commands/commitments/delivery.js +72 -0
  16. package/dist/commands/commitments/doctor.d.ts +1 -0
  17. package/dist/commands/commitments/doctor.js +33 -17
  18. package/dist/commands/commitments/effective-policy.d.ts +2 -0
  19. package/dist/commands/commitments/effective-policy.js +50 -5
  20. package/dist/commands/commitments/endpoints/connect.d.ts +3 -10
  21. package/dist/commands/commitments/endpoints/connect.js +6 -37
  22. package/dist/commands/commitments/endpoints/create.d.ts +2 -9
  23. package/dist/commands/commitments/endpoints/create.js +10 -23
  24. package/dist/commands/commitments/mode.d.ts +15 -0
  25. package/dist/commands/commitments/mode.js +58 -0
  26. package/dist/commands/commitments/pack/promote.d.ts +1 -1
  27. package/dist/commands/commitments/pack/promote.js +7 -3
  28. package/dist/commands/commitments/pack/shadow.d.ts +3 -2
  29. package/dist/commands/commitments/pack/shadow.js +6 -4
  30. package/dist/commands/commitments/patch.d.ts +14 -0
  31. package/dist/commands/commitments/patch.js +51 -0
  32. package/dist/commands/commitments/preflight.d.ts +2 -1
  33. package/dist/commands/commitments/preflight.js +23 -4
  34. package/dist/commands/commitments/receipt.d.ts +15 -0
  35. package/dist/commands/commitments/receipt.js +34 -0
  36. package/dist/commands/commitments/remediate.d.ts +0 -1
  37. package/dist/commands/commitments/remediate.js +5 -3
  38. package/dist/commands/commitments/reports.js +12 -3
  39. package/dist/commands/commitments/show.d.ts +1 -0
  40. package/dist/commands/commitments/show.js +22 -1
  41. package/dist/commands/commitments/update.js +4 -2
  42. package/dist/commands/commitments/wake-capabilities.d.ts +5 -0
  43. package/dist/commands/commitments/wake-capabilities.js +23 -7
  44. package/dist/commands/spaces/bootstrap.js +1 -1
  45. package/dist/lib/commitment-endpoints.d.ts +3 -2
  46. package/dist/lib/commitment-endpoints.js +12 -9
  47. package/dist/lib/commitment-product.d.ts +14 -0
  48. package/dist/lib/commitment-product.js +78 -0
  49. package/dist/lib/commitments.d.ts +39 -17
  50. package/dist/lib/commitments.js +70 -29
  51. package/dist/node_modules/@skrr-ai/data-provider/index.js +3551 -3461
  52. package/oclif.manifest.json +10132 -9461
  53. package/package.json +1 -1
@@ -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>` start (or finish) the handshake.
8
- *
9
- * For a provider-backed endpoint this returns an AUTHORIZATION URL rather than a
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, finalize, or reconnect a commitment endpoint';
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
- finalize: core_1.Flags.boolean({
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.finalize) {
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
- * Supplying `--integration-provider` + `--toolkit` puts the endpoint on the real
11
- * OAuth lifecycle; without them the endpoint is confirmed manually via
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
- * Supplying `--integration-provider` + `--toolkit` puts the endpoint on the real
15
- * OAuth lifecycle; without them the endpoint is confirmed manually via
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" --provider slack --destination slack_channel --target C123 --capability push --capability reply',
22
- '<%= config.bin %> commitments endpoints create --agent agent_abc --label "My DM" --provider slack --destination slack_owner_dm --capability push --integration-provider slack --toolkit slack',
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: 'Channel-neutral destination, e.g. slack_channel / app_owner_dm / email',
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.provider,
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(`Next: skrr commitments endpoints connect ${endpoint.id}`);
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,58 @@
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
+ ignoreStdin: true,
16
+ options: [...commitment_product_1.COMMITMENT_PRODUCT_MODES],
17
+ }),
18
+ };
19
+ static flags = {
20
+ json: core_1.Flags.boolean({ description: 'Output the complete contract as JSON' }),
21
+ verbose: core_1.Flags.boolean({ description: 'Include compatibility values' }),
22
+ reason: core_1.Flags.string({ description: 'Reason recorded with this contract change' }),
23
+ };
24
+ async run() {
25
+ this.requireAuth();
26
+ const { args, flags } = await this.parse(CommitmentsMode);
27
+ try {
28
+ if (args.mode === 'off') {
29
+ this.error('Use commitments pause <id> to stop wakes; lifecycle is separate from mode.');
30
+ }
31
+ const result = await commitments_1.commitmentApi.mode(args.id, {
32
+ mode: (0, commitment_product_1.productMode)(args.mode),
33
+ ...(flags.reason ? { reason: flags.reason } : {}),
34
+ });
35
+ const linked = (0, web_url_1.withCommitmentUrl)(this.cliConfig.baseURL, result);
36
+ if (flags.json)
37
+ return this.log(JSON.stringify(linked, null, 2));
38
+ const stagingForPromotion = result.pack?.phase === 'shadow';
39
+ this.log(stagingForPromotion
40
+ ? `Promotion mode staged as ${(0, commitment_product_1.productModeLabel)(args.mode)}.`
41
+ : `Mode set to ${(0, commitment_product_1.productModeLabel)(args.mode)}.`);
42
+ if (stagingForPromotion) {
43
+ this.log('Live Pack Shadow remains Monitor until explicit promotion.');
44
+ }
45
+ if ((0, commitment_product_1.productMode)(args.mode) === 'monitor') {
46
+ this.log(`${stagingForPromotion ? 'Promotion delivery' : 'Delivery'} set to Report only. Monitor cannot create patches, branches, or pull requests.`);
47
+ }
48
+ (0, commitments_1.renderCommitmentSummary)(result, (line) => this.log(line));
49
+ if (flags.verbose)
50
+ this.log(`Compatibility value: ${result.policy?.autonomyMode}`);
51
+ this.log(`URL: ${linked.url}`);
52
+ }
53
+ catch (error) {
54
+ this.handleApiError(error);
55
+ }
56
+ }
57
+ }
58
+ 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 policy.
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 policy.
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 the policy saved at shadow activation';
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(`Autonomy restored to: ${mode}`);
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, but its
4
- * autonomy is forced to `off` and the prior policy is saved for `promote`.
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, but its
8
- * autonomy is forced to `off` and the prior policy is saved for `promote`.
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 mode: the Pack observes and checks, but takes no autonomous action';
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('\nAutonomy is forced off while in shadow. The policy in force before this call is saved,\nand `skrr commitments pack promote` restores it.');
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,7 +23,7 @@ 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[];
@@ -32,6 +32,7 @@ export default class CommitmentsPreflight extends BaseCommand {
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>;
36
37
  'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
37
38
  'event-fixture': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -22,9 +22,11 @@ const prompt_1 = require("../../lib/prompt");
22
22
  * The note gets its own indented line. It is prose, and hanging it off the same
23
23
  * dash as a short code puts two different kinds of thing in one slot.
24
24
  */
25
- function preflightGateLines(gate) {
25
+ function preflightGateLines(gate, verbose = false) {
26
26
  const mark = gate.verdict === 'pass' ? 'ok' : gate.verdict === 'block' ? 'BLOCK' : 'warn';
27
- const lines = [` ${mark.padEnd(5)} ${gate.label}${gate.reason ? ` — ${gate.reason}` : ''}`];
27
+ const lines = [
28
+ ` ${mark.padEnd(5)} ${gate.label}${verbose && gate.reason ? ` — ${gate.reason}` : ''}`,
29
+ ];
28
30
  const note = gate.detail?.note;
29
31
  if (typeof note === 'string' && note.trim()) {
30
32
  lines.push(` ${note.trim()}`);
@@ -55,6 +57,7 @@ class CommitmentsPreflight extends base_command_1.BaseCommand {
55
57
  };
56
58
  static flags = {
57
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' }),
58
61
  next: core_1.Flags.integer({ description: 'Number of upcoming runs to project (1–10)' }),
59
62
  'from-json': core_1.Flags.string({
60
63
  description: 'Unsaved Commitment create body file, or - for stdin',
@@ -92,12 +95,28 @@ class CommitmentsPreflight extends base_command_1.BaseCommand {
92
95
  this.log(JSON.stringify(report, null, 2));
93
96
  return;
94
97
  }
95
- this.log(`${args.id ? 'Preflight' : 'Pre-create preview (nothing persisted)'}: ${String(report.verdict).replace(/_/g, ' ')}`);
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'}`);
96
99
  this.log('\nGates:');
97
100
  for (const gate of report.gates || []) {
98
- for (const line of preflightGateLines(gate))
101
+ for (const line of preflightGateLines(gate, flags.verbose))
99
102
  this.log(line);
100
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
+ }
101
120
  if (report.nextRuns?.length) {
102
121
  this.log('\nNext runs:');
103
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 {
@@ -15,7 +15,6 @@ const commitments_1 = require("../../lib/commitments");
15
15
  * pause_commitment stop the loop entirely
16
16
  * mute_user_nudges keep watching, stop interrupting (max nudges → 0)
17
17
  * reduce_nudge_frequency at most one nudge per day
18
- * tighten_policy require approval for the risky action classes
19
18
  * mark_noop record that this fired for no reason
20
19
  */
21
20
  class CommitmentsRemediate extends base_command_1.BaseCommand {
@@ -30,8 +29,11 @@ class CommitmentsRemediate extends base_command_1.BaseCommand {
30
29
  static flags = {
31
30
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
32
31
  action: core_1.Flags.string({
33
- description: 'Remediation action',
34
- options: [...commitments_1.COMMITMENT_REMEDIATION_ACTIONS],
32
+ description: 'Remediation action. Change work authority with commitments mode; Workspace approval rules belong in Workspace governance.',
33
+ // `tighten_policy` remains a REST compatibility value for legacy rows. It
34
+ // is deliberately absent from the product CLI: v2 authority changes are
35
+ // explicit Mode changes, never a hidden risk/approval tier.
36
+ options: commitments_1.COMMITMENT_REMEDIATION_ACTIONS.filter((action) => action !== 'tighten_policy'),
35
37
  required: true,
36
38
  }),
37
39
  reason: core_1.Flags.string({ description: 'Why (recorded on the boundary-change ledger)' }),
@@ -6,7 +6,16 @@ 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(['slack_channel', 'email']);
9
+ const DESTINATIONS_NEEDING_TARGET = new Set(['slack_channel']);
10
+ /**
11
+ * Keep the CLI safe across a rolling data-provider build. Older installed
12
+ * packages expose the compatibility destination list but not the narrowed
13
+ * authoring list; derive the same restriction instead of crashing command
14
+ * discovery or accidentally offering the inert email transport.
15
+ */
16
+ const AUTHORABLE_REPORT_DESTINATIONS = Array.isArray(data_provider_1.COMMITMENT_AUTHORABLE_REPORT_DESTINATIONS)
17
+ ? data_provider_1.COMMITMENT_AUTHORABLE_REPORT_DESTINATIONS
18
+ : data_provider_1.COMMITMENT_REPORT_DESTINATIONS.filter((destination) => destination !== 'email');
10
19
  /**
11
20
  * Identity of a report target = destination + its target id. The same channel
12
21
  * may legitimately appear twice with different `on` conditions (a digest on
@@ -41,10 +50,10 @@ class CommitmentsReports extends base_command_1.BaseCommand {
41
50
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
42
51
  add: core_1.Flags.string({
43
52
  description: 'Destination to add',
44
- options: [...data_provider_1.COMMITMENT_REPORT_DESTINATIONS],
53
+ options: [...AUTHORABLE_REPORT_DESTINATIONS],
45
54
  }),
46
55
  target: core_1.Flags.string({
47
- description: 'Channel id or address, for destinations that address one (slack_channel, email)',
56
+ description: 'Channel id for slack_channel. App and owner-DM destinations need no target.',
48
57
  }),
49
58
  on: core_1.Flags.string({
50
59
  description: 'When to report (default: material_change)',
@@ -15,6 +15,7 @@ export default class CommitmentsShow extends BaseCommand {
15
15
  };
16
16
  static flags: {
17
17
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
+ verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
19
  };
19
20
  run(): Promise<void>;
20
21
  }