@skrr-ai/cli 0.1.95 → 0.1.97

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 (200) hide show
  1. package/README.md +22 -0
  2. package/dist/commands/agent/message/send.d.ts +2 -0
  3. package/dist/commands/agent/message/send.js +75 -5
  4. package/dist/commands/agents/chat.js +1 -1
  5. package/dist/commands/agents/create.d.ts +0 -3
  6. package/dist/commands/agents/create.js +0 -26
  7. package/dist/commands/agents/egress.d.ts +17 -0
  8. package/dist/commands/agents/egress.js +84 -0
  9. package/dist/commands/agents/mailbox/messages.d.ts +14 -0
  10. package/dist/commands/agents/mailbox/messages.js +52 -0
  11. package/dist/commands/agents/mailbox/show.d.ts +13 -0
  12. package/dist/commands/agents/mailbox/show.js +52 -0
  13. package/dist/commands/agents/operating-plan.js +8 -0
  14. package/dist/commands/agents/roles/capture.d.ts +16 -0
  15. package/dist/commands/agents/roles/capture.js +53 -0
  16. package/dist/commands/agents/roles/install.d.ts +1 -0
  17. package/dist/commands/agents/roles/install.js +8 -1
  18. package/dist/commands/agents/roles/preview.d.ts +2 -0
  19. package/dist/commands/agents/roles/preview.js +27 -3
  20. package/dist/commands/agents/update.d.ts +0 -3
  21. package/dist/commands/agents/update.js +1 -31
  22. package/dist/commands/agents/usage-cap.d.ts +4 -1
  23. package/dist/commands/agents/usage-cap.js +49 -10
  24. package/dist/commands/code/jobs/show.js +12 -0
  25. package/dist/commands/commitments/action-proposals/decide.d.ts +2 -0
  26. package/dist/commands/commitments/action-proposals/decide.js +12 -0
  27. package/dist/commands/commitments/action-proposals.js +7 -0
  28. package/dist/commands/commitments/create.d.ts +1 -0
  29. package/dist/commands/commitments/create.js +17 -1
  30. package/dist/commands/commitments/delivery.d.ts +1 -0
  31. package/dist/commands/commitments/delivery.js +11 -1
  32. package/dist/commands/commitments/doctor.js +4 -0
  33. package/dist/commands/commitments/effective-policy.js +26 -0
  34. package/dist/commands/commitments/endpoints/create.js +5 -2
  35. package/dist/commands/commitments/observations.d.ts +10 -0
  36. package/dist/commands/commitments/observations.js +88 -0
  37. package/dist/commands/commitments/pause.d.ts +1 -1
  38. package/dist/commands/commitments/pause.js +4 -3
  39. package/dist/commands/commitments/preflight.js +2 -1
  40. package/dist/commands/commitments/reports.d.ts +2 -0
  41. package/dist/commands/commitments/reports.js +22 -4
  42. package/dist/commands/commitments/update.d.ts +1 -0
  43. package/dist/commands/commitments/update.js +35 -5
  44. package/dist/commands/daemon/install.js +1 -1
  45. package/dist/commands/grants/create.d.ts +1 -0
  46. package/dist/commands/grants/create.js +8 -0
  47. package/dist/commands/grants/rotate.d.ts +5 -0
  48. package/dist/commands/grants/rotate.js +13 -1
  49. package/dist/commands/grants/update.d.ts +12 -0
  50. package/dist/commands/grants/update.js +27 -0
  51. package/dist/commands/machines/hosted/start.js +7 -1
  52. package/dist/commands/machines/list.js +4 -4
  53. package/dist/commands/measures/confirm.d.ts +1 -7
  54. package/dist/commands/measures/confirm.js +15 -14
  55. package/dist/commands/measures/list.d.ts +1 -7
  56. package/dist/commands/measures/list.js +1 -7
  57. package/dist/commands/measures/record.js +4 -4
  58. package/dist/commands/measures/show.d.ts +11 -0
  59. package/dist/commands/measures/show.js +26 -0
  60. package/dist/commands/northstars/governance/configure.d.ts +1 -0
  61. package/dist/commands/northstars/governance/configure.js +8 -1
  62. package/dist/commands/proposals/discard.d.ts +5 -0
  63. package/dist/commands/proposals/discard.js +8 -0
  64. package/dist/commands/proposals/keep.d.ts +5 -0
  65. package/dist/commands/proposals/keep.js +8 -0
  66. package/dist/commands/proposals/list.d.ts +15 -0
  67. package/dist/commands/proposals/list.js +74 -0
  68. package/dist/commands/proposals/show.d.ts +12 -0
  69. package/dist/commands/proposals/show.js +27 -0
  70. package/dist/commands/proposals/snooze.d.ts +5 -0
  71. package/dist/commands/proposals/snooze.js +8 -0
  72. package/dist/commands/signals/monitors/create.d.ts +9 -0
  73. package/dist/commands/signals/monitors/create.js +29 -0
  74. package/dist/commands/signals/monitors/list.d.ts +8 -0
  75. package/dist/commands/signals/monitors/list.js +16 -0
  76. package/dist/commands/signals/monitors/pause.d.ts +11 -0
  77. package/dist/commands/signals/monitors/pause.js +17 -0
  78. package/dist/commands/signals/monitors/resume.d.ts +11 -0
  79. package/dist/commands/signals/monitors/resume.js +17 -0
  80. package/dist/commands/signals/monitors/revise.d.ts +12 -0
  81. package/dist/commands/signals/monitors/revise.js +25 -0
  82. package/dist/commands/signals/monitors/show.d.ts +11 -0
  83. package/dist/commands/signals/monitors/show.js +17 -0
  84. package/dist/commands/signals/monitors/test.d.ts +12 -0
  85. package/dist/commands/signals/monitors/test.js +25 -0
  86. package/dist/commands/signals/monitors/transitions.d.ts +11 -0
  87. package/dist/commands/signals/monitors/transitions.js +17 -0
  88. package/dist/commands/signals/monitors/validate.d.ts +9 -0
  89. package/dist/commands/signals/monitors/validate.js +24 -0
  90. package/dist/commands/signals/schemas/list.d.ts +8 -0
  91. package/dist/commands/signals/schemas/list.js +16 -0
  92. package/dist/commands/signals/schemas/show.d.ts +11 -0
  93. package/dist/commands/signals/schemas/show.js +17 -0
  94. package/dist/commands/signals/sources/list.d.ts +8 -0
  95. package/dist/commands/signals/sources/list.js +16 -0
  96. package/dist/commands/signals/sources/receipts.d.ts +11 -0
  97. package/dist/commands/signals/sources/receipts.js +17 -0
  98. package/dist/commands/signals/sources/show.d.ts +11 -0
  99. package/dist/commands/signals/sources/show.js +17 -0
  100. package/dist/commands/spaces/usage.d.ts +12 -0
  101. package/dist/commands/spaces/usage.js +28 -0
  102. package/dist/commands/spaces/workflows/run.js +3 -0
  103. package/dist/commands/spaces/workflows/runs.js +2 -1
  104. package/dist/commands/spaces/workflows/update.d.ts +6 -1
  105. package/dist/commands/spaces/workflows/update.js +34 -2
  106. package/dist/commands/tasks/cascade-status.d.ts +2 -0
  107. package/dist/commands/tasks/cascade-status.js +27 -1
  108. package/dist/commands/tasks/comments/add.js +29 -20
  109. package/dist/commands/tasks/complete.js +7 -4
  110. package/dist/commands/tasks/create.d.ts +4 -0
  111. package/dist/commands/tasks/create.js +16 -0
  112. package/dist/commands/tasks/deliverable/add.js +17 -7
  113. package/dist/commands/tasks/economics-compare.d.ts +15 -0
  114. package/dist/commands/tasks/economics-compare.js +60 -0
  115. package/dist/commands/tasks/events/append.js +6 -5
  116. package/dist/commands/tasks/expectations/assess.js +4 -4
  117. package/dist/commands/tasks/expectations/evaluate.d.ts +13 -0
  118. package/dist/commands/tasks/expectations/evaluate.js +43 -0
  119. package/dist/commands/tasks/list.d.ts +1 -0
  120. package/dist/commands/tasks/list.js +44 -1
  121. package/dist/commands/tasks/move.js +15 -11
  122. package/dist/commands/tasks/report.js +19 -11
  123. package/dist/commands/tasks/result/submit.js +5 -4
  124. package/dist/commands/tasks/resume/save.js +5 -4
  125. package/dist/commands/tasks/review.js +4 -4
  126. package/dist/commands/tasks/show.d.ts +5 -0
  127. package/dist/commands/tasks/show.js +17 -0
  128. package/dist/commands/tasks/update.d.ts +4 -0
  129. package/dist/commands/tasks/update.js +9 -0
  130. package/dist/commands/tasks/updates/add.js +5 -4
  131. package/dist/commands/tasks/workflow-findings.js +2 -2
  132. package/dist/commands/triggers/create.d.ts +2 -0
  133. package/dist/commands/triggers/create.js +15 -0
  134. package/dist/commands/workspaces/grants.d.ts +12 -0
  135. package/dist/commands/workspaces/grants.js +31 -0
  136. package/dist/commands/workspaces/stewardship.d.ts +13 -0
  137. package/dist/commands/workspaces/stewardship.js +34 -0
  138. package/dist/lib/agent-config.d.ts +0 -12
  139. package/dist/lib/agent-config.js +1 -27
  140. package/dist/lib/agent-mailbox.d.ts +35 -0
  141. package/dist/lib/agent-mailbox.js +55 -0
  142. package/dist/lib/commitment-endpoints.d.ts +2 -1
  143. package/dist/lib/commitment-endpoints.js +2 -5
  144. package/dist/lib/commitment-product.d.ts +3 -1
  145. package/dist/lib/commitment-product.js +10 -0
  146. package/dist/lib/commitment-terms.js +1 -1
  147. package/dist/lib/commitments.d.ts +17 -7
  148. package/dist/lib/commitments.js +173 -85
  149. package/dist/lib/compasses.d.ts +14 -0
  150. package/dist/lib/compasses.js +25 -11
  151. package/dist/lib/grants.d.ts +5 -1
  152. package/dist/lib/grants.js +9 -1
  153. package/dist/lib/hosted-machines.d.ts +7 -0
  154. package/dist/lib/mailbox-human-command.d.ts +11 -0
  155. package/dist/lib/mailbox-human-command.js +41 -0
  156. package/dist/lib/measures.d.ts +28 -2
  157. package/dist/lib/measures.js +38 -14
  158. package/dist/lib/message-intent.d.ts +6 -2
  159. package/dist/lib/message-intent.js +1 -0
  160. package/dist/lib/northstars.js +2 -1
  161. package/dist/lib/proposal-decision-command.d.ts +19 -0
  162. package/dist/lib/proposal-decision-command.js +64 -0
  163. package/dist/lib/proposals.d.ts +8 -0
  164. package/dist/lib/proposals.js +22 -0
  165. package/dist/lib/roles.d.ts +141 -6
  166. package/dist/lib/roles.js +8 -2
  167. package/dist/lib/session-task-write.d.ts +18 -0
  168. package/dist/lib/session-task-write.js +43 -0
  169. package/dist/lib/signals.d.ts +20 -0
  170. package/dist/lib/signals.js +24 -0
  171. package/dist/lib/space-usage.d.ts +3 -0
  172. package/dist/lib/space-usage.js +17 -0
  173. package/dist/lib/stewardship-output.d.ts +4 -0
  174. package/dist/lib/stewardship-output.js +82 -0
  175. package/dist/lib/task-asset-upload.d.ts +3 -1
  176. package/dist/lib/task-asset-upload.js +19 -22
  177. package/dist/lib/task-economics.d.ts +16 -0
  178. package/dist/lib/task-economics.js +22 -0
  179. package/dist/lib/triggers.d.ts +11 -3
  180. package/dist/lib/triggers.js +58 -1
  181. package/dist/lib/unsupported-managed-task-write.d.ts +2 -0
  182. package/dist/lib/unsupported-managed-task-write.js +12 -0
  183. package/dist/lib/usage-discovery.d.ts +10 -0
  184. package/dist/lib/usage-discovery.js +24 -3
  185. package/dist/lib/workflow-run-budget.d.ts +12 -0
  186. package/dist/lib/workflow-run-budget.js +37 -0
  187. package/dist/lib/workspaces.d.ts +48 -0
  188. package/dist/lib/workspaces.js +8 -0
  189. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.d.ts +4 -0
  190. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.js +14 -1
  191. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/githubPushRefusal.d.ts +9 -0
  192. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/githubPushRefusal.js +49 -0
  193. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.d.ts +4 -0
  194. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.js +12 -0
  195. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/githubPushRefusal.d.ts +9 -0
  196. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/githubPushRefusal.js +44 -0
  197. package/dist/node_modules/@skrr-ai/auth-core/package.json +10 -0
  198. package/dist/node_modules/@skrr-ai/data-provider/index.js +8017 -7086
  199. package/oclif.manifest.json +3872 -1167
  200. package/package.json +22 -1
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../base-command';
2
+ /**
3
+ * Mailbox reads belong to the person operating the account. Check before
4
+ * BaseCommand.init can redeem a delegated credential or read stored auth;
5
+ * the API independently verifies the actual principal and workspace ACL.
6
+ */
7
+ export declare abstract class MailboxHumanCommand extends BaseCommand {
8
+ init(): Promise<void>;
9
+ protected requireHumanMailboxAuth(): void;
10
+ private refuseAgentContext;
11
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MailboxHumanCommand = void 0;
4
+ const base_command_1 = require("../base-command");
5
+ const harness_context_1 = require("./harness-context");
6
+ /**
7
+ * Mailbox reads belong to the person operating the account. Check before
8
+ * BaseCommand.init can redeem a delegated credential or read stored auth;
9
+ * the API independently verifies the actual principal and workspace ACL.
10
+ */
11
+ class MailboxHumanCommand extends base_command_1.BaseCommand {
12
+ async init() {
13
+ this.refuseAgentContext();
14
+ await super.init();
15
+ }
16
+ requireHumanMailboxAuth() {
17
+ this.refuseAgentContext();
18
+ this.requireAuth();
19
+ }
20
+ refuseAgentContext() {
21
+ if ((0, harness_context_1.isHarnessCliContext)() ||
22
+ this.credentialProvenance?.kind === 'agent-session' ||
23
+ this.credentialProvenance?.kind === 'daemon-delegated') {
24
+ this.failWithCliError({
25
+ message: 'Mailbox metadata is available only to a human operator. Run this command in your own terminal.',
26
+ code: 'MAILBOX_HUMAN_REQUIRED',
27
+ exit: 2,
28
+ retryable: false,
29
+ });
30
+ }
31
+ if (this.credentialProvenance?.kind === 'daemon-handoff') {
32
+ this.failWithCliError({
33
+ message: 'Mailbox metadata requires a direct human CLI sign-in. Run `skrr login --device-code` in your own terminal to skip the daemon broker, then try again.',
34
+ code: 'MAILBOX_HUMAN_CLI_REQUIRED',
35
+ exit: 2,
36
+ retryable: false,
37
+ });
38
+ }
39
+ }
40
+ }
41
+ exports.MailboxHumanCommand = MailboxHumanCommand;
@@ -1,13 +1,32 @@
1
+ /**
2
+ * measures.ts — client for numeric outcomes (`/api/measures/*`).
3
+ *
4
+ * Gap analysis 2026-07-28 §B5. A **Measure** is a number with a unit, a
5
+ * baseline, a direction, and a target — the thing that makes
6
+ * `$12,400/mo → $9,100/mo` storable. Before it, the only value signal was
7
+ * `estimatedValueMinutes`: one unit, an LLM self-estimate, and a confirmation
8
+ * endpoint with zero callers.
9
+ *
10
+ * `rollup` is computed server-side on every read, never stored, so it cannot go
11
+ * stale the way a denormalized `progress` column does.
12
+ */
13
+ import { type MeasureReadingProvenance, type MeasureProvenanceRollup, type MeasureRevision } from '@skrr-ai/data-provider';
1
14
  export declare const MEASURE_UNITS: readonly ["usd", "usd_per_month", "usd_per_year", "count", "percent", "minutes", "hours", "days", "bytes", "requests", "ratio", "score", "custom"];
2
15
  export declare const MEASURE_DIRECTIONS: readonly ["decrease", "increase", "maintain"];
3
- export declare const MEASURE_OBSERVATION_SOURCES: readonly ["manual", "agent_reported", "integration", "computed"];
16
+ /**
17
+ * What a caller may write. `integration` and `computed` are platform-only: the
18
+ * server answers 400 `measure_source_reserved`, so offering them here would
19
+ * advertise a provenance label nobody can assert.
20
+ */
21
+ export declare const MEASURE_WRITABLE_SOURCES: readonly ["manual", "agent_reported"];
4
22
  export interface MeasureObservation {
5
23
  value: number;
6
24
  observedAt: string;
7
25
  source: string;
8
- /** An agent_reported value is a CLAIM until a human confirms it. */
26
+ /** Retained legacy stamp; provenance carries credential attribution. */
9
27
  confirmed: boolean;
10
28
  confirmedAt?: string;
29
+ provenance?: MeasureReadingProvenance;
11
30
  evidence?: string;
12
31
  note?: string;
13
32
  }
@@ -25,6 +44,7 @@ export interface Measure {
25
44
  };
26
45
  status: string;
27
46
  observations: MeasureObservation[];
47
+ revisions?: MeasureRevision[];
28
48
  rollup: {
29
49
  latest: number | null;
30
50
  baseline: number | null;
@@ -35,6 +55,7 @@ export interface Measure {
35
55
  observationCount: number;
36
56
  confirmedCount: number;
37
57
  unitLabel: string;
58
+ provenance?: MeasureProvenanceRollup;
38
59
  };
39
60
  }
40
61
  export type MeasureRecordConfirmation = {
@@ -43,6 +64,11 @@ export type MeasureRecordConfirmation = {
43
64
  };
44
65
  /** Explain the server's confirmation policy at the point a reading is written. */
45
66
  export declare function recordConfirmationForSource(source: string): MeasureRecordConfirmation;
67
+ export declare function recordConfirmationForObservation(observation?: MeasureObservation): {
68
+ status: string;
69
+ message: string;
70
+ };
71
+ export declare function latestSelfReportedObservation(measure: Measure): MeasureObservation | undefined;
46
72
  export declare const measureApi: {
47
73
  list: (path: string) => Promise<{
48
74
  measures: Measure[];
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.measureApi = exports.MEASURE_OBSERVATION_SOURCES = exports.MEASURE_DIRECTIONS = exports.MEASURE_UNITS = void 0;
3
+ exports.measureApi = exports.MEASURE_WRITABLE_SOURCES = exports.MEASURE_DIRECTIONS = exports.MEASURE_UNITS = void 0;
4
4
  exports.recordConfirmationForSource = recordConfirmationForSource;
5
+ exports.recordConfirmationForObservation = recordConfirmationForObservation;
6
+ exports.latestSelfReportedObservation = latestSelfReportedObservation;
5
7
  exports.renderMeasureList = renderMeasureList;
6
8
  /**
7
9
  * measures.ts — client for numeric outcomes (`/api/measures/*`).
@@ -33,25 +35,45 @@ exports.MEASURE_UNITS = [
33
35
  'custom',
34
36
  ];
35
37
  exports.MEASURE_DIRECTIONS = ['decrease', 'increase', 'maintain'];
36
- exports.MEASURE_OBSERVATION_SOURCES = [
37
- 'manual',
38
- 'agent_reported',
39
- 'integration',
40
- 'computed',
41
- ];
38
+ /**
39
+ * What a caller may write. `integration` and `computed` are platform-only: the
40
+ * server answers 400 `measure_source_reserved`, so offering them here would
41
+ * advertise a provenance label nobody can assert.
42
+ */
43
+ exports.MEASURE_WRITABLE_SOURCES = ['manual', 'agent_reported'];
42
44
  /** Explain the server's confirmation policy at the point a reading is written. */
43
45
  function recordConfirmationForSource(source) {
44
46
  if (source === 'manual') {
45
47
  return {
46
48
  status: 'confirmed',
47
- message: 'Confirmed as ground truth: a manual reading is an owner confirmation.',
49
+ message: 'Marked confirmed: the current API automatically confirms manual readings.',
48
50
  };
49
51
  }
50
52
  return {
51
53
  status: 'pending_confirmation',
52
- message: 'Recorded as a claim — confirm it with `skrr measures confirm` before using it as ground truth.',
54
+ message: 'Recorded unconfirmed — review it with `skrr measures confirm`. Confirmation does not prove measurement or causation.',
53
55
  };
54
56
  }
57
+ function recordConfirmationForObservation(observation) {
58
+ const provenance = observation?.provenance;
59
+ const level = provenance?.level;
60
+ let message = 'Before provenance tracking; confirmation attribution unavailable.';
61
+ if (provenance)
62
+ message = (0, data_provider_1.describeMeasureEvidence)(provenance.level, provenance.confirmedBy || provenance.recordedBy);
63
+ if (level === 'system_observed')
64
+ message = `Platform-observed; ${(0, data_provider_1.personConfirmedMeasureReading)(observation) ? 'person-confirmed' : 'not confirmed by a person'}. Confirmation does not prove units or causal savings.`;
65
+ return {
66
+ status: level === 'human_confirmed' || (0, data_provider_1.personConfirmedMeasureReading)(observation)
67
+ ? 'confirmed'
68
+ : 'pending_confirmation',
69
+ message,
70
+ };
71
+ }
72
+ function latestSelfReportedObservation(measure) {
73
+ return measure.observations
74
+ .filter((o) => (o.provenance ? o.provenance.level === 'self_reported' : !o.confirmed))
75
+ .sort((a, b) => Date.parse(b.observedAt) - Date.parse(a.observedAt))[0];
76
+ }
55
77
  exports.measureApi = {
56
78
  list: (path) => data_provider_1.request.get(path),
57
79
  get: (id) => data_provider_1.request.get(`/api/measures/${id}`),
@@ -79,17 +101,19 @@ function renderMeasureList(rows, log) {
79
101
  target: fmt(r.rollup.target, r.rollup.unitLabel),
80
102
  // Direction is STORED, so this reports the committed direction rather
81
103
  // than inferring good/bad from the sign.
82
- moving: r.rollup.improved === null ? '-' : r.rollup.improved ? 'right way' : 'wrong way',
83
- // Ground truth vs claim, kept as separate numbers on purpose.
84
- confirmed: `${r.rollup.confirmedCount}/${r.rollup.observationCount}`,
104
+ moving: `${r.rollup.improved === null ? '-' : r.rollup.improved ? 'right way' : 'wrong way'}${r.rollup.provenance?.latestLevel === 'self_reported' ? ' (self-reported)' : ''}`,
105
+ // Evidence attribution is separate from the retained legacy stamp count.
106
+ evidence: r.rollup.provenance
107
+ ? `${(0, data_provider_1.describeMeasureProvenanceCounts)(r.rollup.provenance.byLevel)}${r.rollup.provenance.unattributedCount ? `; ${r.rollup.provenance.unattributedCount} before provenance tracking` : ''}`
108
+ : 'Before provenance tracking',
85
109
  })), [
86
110
  { key: 'label', header: 'MEASURE', maxWidth: 28 },
87
111
  { key: 'latest', header: 'LATEST', maxWidth: 14 },
88
112
  { key: 'baseline', header: 'BASELINE', maxWidth: 14 },
89
113
  { key: 'delta', header: 'DELTA', maxWidth: 12 },
90
114
  { key: 'target', header: 'TARGET', maxWidth: 14 },
91
- { key: 'moving', header: 'MOVING', maxWidth: 10 },
92
- { key: 'confirmed', header: 'CONFIRMED', maxWidth: 10 },
115
+ { key: 'moving', header: 'MOVING', maxWidth: 30 },
116
+ { key: 'evidence', header: 'EVIDENCE', maxWidth: 60 },
93
117
  { key: 'id', header: 'ID', verbatim: true },
94
118
  ], log);
95
119
  }
@@ -1,6 +1,6 @@
1
1
  import { type ResolvedCredential } from '@skrr-ai/auth-core';
2
2
  import type { AgentMessageSequence, EntityEmbed } from '@skrr-ai/data-provider';
3
- export declare const CANONICAL_DESTINATION_KINDS: readonly ["app_owner_dm", "slack_owner_dm", "slack_channel"];
3
+ export declare const CANONICAL_DESTINATION_KINDS: readonly ["app_owner_dm", "slack_owner_dm", "slack_channel", "agent_email"];
4
4
  export type CanonicalDestinationKind = (typeof CANONICAL_DESTINATION_KINDS)[number];
5
5
  export type CanonicalMessageDestination = {
6
6
  kind: 'app_owner_dm';
@@ -10,6 +10,10 @@ export type CanonicalMessageDestination = {
10
10
  kind: 'slack_channel';
11
11
  channelId: string;
12
12
  threadTs?: string;
13
+ } | {
14
+ kind: 'agent_email';
15
+ recipients: string[];
16
+ subject: string;
13
17
  };
14
18
  /**
15
19
  * The durable, user-facing taxonomy for deliberate Agent Updates. Keep this
@@ -78,7 +82,7 @@ export type CanonicalMessageIntentRequest = {
78
82
  export type CanonicalMessageIntentResponse = {
79
83
  ok: boolean;
80
84
  intentId?: string;
81
- status?: 'submitted' | 'held' | 'approval_required' | 'authorized' | 'dispatching' | 'delivered' | 'failed' | 'dropped' | 'expired' | 'cancelled' | 'duplicate' | 'queued_offline';
85
+ status?: 'submitted' | 'held' | 'approval_required' | 'authorized' | 'dispatching' | 'delivered' | 'accepted' | 'unknown' | 'refused' | 'failed' | 'dropped' | 'expired' | 'cancelled' | 'duplicate' | 'queued_offline';
82
86
  reason?: string;
83
87
  retryAfter?: string;
84
88
  retryable?: boolean;
@@ -20,6 +20,7 @@ exports.CANONICAL_DESTINATION_KINDS = [
20
20
  'app_owner_dm',
21
21
  'slack_owner_dm',
22
22
  'slack_channel',
23
+ 'agent_email',
23
24
  ];
24
25
  /**
25
26
  * The durable, user-facing taxonomy for deliberate Agent Updates. Keep this
@@ -215,7 +215,8 @@ function renderGovernance(status, log) {
215
215
  log(`Protected ${g.protectedCommitmentIds.join(', ')}`);
216
216
  }
217
217
  const eb = status.executionBudget ?? {};
218
- log(`Exec budget runs/day ${eb.maxRunsPerDay ?? '—'} · concurrent ${eb.maxConcurrentRuns ?? '—'} · critical reserve ${eb.reserveWeightForCritical ?? '—'}`);
218
+ log(`Exec budget action runs/day ${eb.maxRunsPerDay ?? '—'} · concurrent ${eb.maxConcurrentRuns ?? '—'} · critical reserve ${eb.reserveWeightForCritical ?? '—'}`);
219
+ log(`Observation runs/day ${eb.maxObservationRunsPerDay ?? '—'} · daily budgets reset at 00:00 UTC`);
219
220
  log('');
220
221
  log(`Review trigger ${status.reviewTrigger.scheduled ? 'scheduled' : 'manual'} every ${humanMs(status.reviewTrigger.intervalMs)} next ${shortDate(status.reviewTrigger.nextFireAt)}`);
221
222
  if (status.latestReview) {
@@ -0,0 +1,19 @@
1
+ import type { ProposalDecision } from '@skrr-ai/data-provider';
2
+ import { BaseCommand } from '../base-command';
3
+ /** The caller supplies the revision from show/list. Fetching a NEW card just
4
+ * before an old decision would approve content the caller never reviewed. */
5
+ export declare abstract class ProposalDecisionCommand extends BaseCommand {
6
+ static decision: ProposalDecision;
7
+ static args: {
8
+ kind: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
9
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
10
+ };
11
+ static flags: {
12
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ expected: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ reason: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
15
+ 'reason-code': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ until: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
17
+ };
18
+ run(): Promise<void>;
19
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProposalDecisionCommand = void 0;
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../base-command");
7
+ const proposals_1 = require("./proposals");
8
+ /** The caller supplies the revision from show/list. Fetching a NEW card just
9
+ * before an old decision would approve content the caller never reviewed. */
10
+ class ProposalDecisionCommand extends base_command_1.BaseCommand {
11
+ static decision;
12
+ static args = {
13
+ kind: core_1.Args.string({ required: true, options: [...data_provider_1.PROPOSAL_KINDS], ignoreStdin: true }),
14
+ id: core_1.Args.string({ required: true, ignoreStdin: true }),
15
+ };
16
+ static flags = {
17
+ json: core_1.Flags.boolean(),
18
+ expected: core_1.Flags.string({
19
+ required: true,
20
+ description: 'Exact revision JSON from proposals show/list',
21
+ }),
22
+ reason: core_1.Flags.string(),
23
+ 'reason-code': core_1.Flags.string({ options: [...data_provider_1.PROPOSAL_DISCARD_REASON_CODES] }),
24
+ until: core_1.Flags.string({ description: 'Snooze-until ISO timestamp' }),
25
+ };
26
+ async run() {
27
+ this.requireAuth();
28
+ const { args, flags } = await this.parse(this.constructor);
29
+ let expected;
30
+ try {
31
+ expected = JSON.parse(flags.expected);
32
+ }
33
+ catch {
34
+ this.error('--expected must be revision JSON from the reviewed proposal.');
35
+ }
36
+ const decision = this.constructor.decision;
37
+ if (decision === 'snooze' && !flags.until)
38
+ this.error('Snooze requires --until.');
39
+ if (decision === 'snooze') {
40
+ const until = Date.parse(flags.until);
41
+ if (Number.isNaN(until))
42
+ this.error('--until must be an ISO timestamp.');
43
+ if (until < Date.now() + data_provider_1.PROPOSAL_SNOOZE_MIN_SECONDS * 1000)
44
+ this.error('--until must be at least a minute from now.');
45
+ if (until > Date.now() + data_provider_1.PROPOSAL_SNOOZE_MAX_DAYS * 86400000)
46
+ this.error(`--until may be at most ${data_provider_1.PROPOSAL_SNOOZE_MAX_DAYS} days ahead.`);
47
+ }
48
+ let result;
49
+ try {
50
+ result = await proposals_1.proposalApi.decide(args.kind, args.id, {
51
+ decision,
52
+ expected,
53
+ reason: flags.reason,
54
+ reasonCode: flags['reason-code'],
55
+ snoozedUntil: flags.until,
56
+ });
57
+ }
58
+ catch (error) {
59
+ this.handleApiError(error);
60
+ }
61
+ this.log(flags.json ? JSON.stringify(result, null, 2) : `Proposal ${decision} decision recorded.`);
62
+ }
63
+ }
64
+ exports.ProposalDecisionCommand = ProposalDecisionCommand;
@@ -0,0 +1,8 @@
1
+ import type { ProposalDecisionParams, ProposalDecisionResponse, ProposalKind, ProposalListParams, ProposalListResponse, ProposalView } from '@skrr-ai/data-provider';
2
+ /** The unified, read-time proposal inbox. Decisions are routed by the server to
3
+ * each family's own writer; the CLI never writes a source row. */
4
+ export declare const proposalApi: {
5
+ list(params?: ProposalListParams): Promise<ProposalListResponse>;
6
+ show(kind: ProposalKind, id: string): Promise<ProposalView>;
7
+ decide(kind: ProposalKind, id: string, input: ProposalDecisionParams): Promise<ProposalDecisionResponse>;
8
+ };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.proposalApi = void 0;
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const triggers_1 = require("./triggers");
6
+ const MOUNT = '/api/proposals';
7
+ /** The unified, read-time proposal inbox. Decisions are routed by the server to
8
+ * each family's own writer; the CLI never writes a source row. */
9
+ exports.proposalApi = {
10
+ list(params = {}) {
11
+ return data_provider_1.request.get((0, triggers_1.withQuery)(MOUNT, { ...params }));
12
+ },
13
+ show(kind, id) {
14
+ return data_provider_1.request.get(`${MOUNT}/${encodeURIComponent(kind)}/${encodeURIComponent(id)}`);
15
+ },
16
+ decide(kind, id, input) {
17
+ return data_provider_1.request.post(`${MOUNT}/${encodeURIComponent(kind)}/${encodeURIComponent(id)}/decision`, {
18
+ ...input,
19
+ via: 'cli',
20
+ });
21
+ },
22
+ };
@@ -1,4 +1,4 @@
1
- import type { InstalledRole, RolePlanPreview, RoleInstallation, AgentOperatingPlan } from '@skrr-ai/data-provider';
1
+ import type { InstalledRole, RoleOperatingSpec, RolePlanPreview, RoleInstallation, AgentOperatingPlan } from '@skrr-ai/data-provider';
2
2
  export declare const roleBase: (agentId: string) => string;
3
3
  export declare const roleApi: {
4
4
  list: (id: string) => Promise<{
@@ -13,10 +13,10 @@ export declare const roleApi: {
13
13
  }>;
14
14
  };
15
15
  }>;
16
- preview: (id: string, spec: unknown, contextBindings?: unknown) => Promise<RolePlanPreview>;
17
- install: (id: string, preview: RolePlanPreview) => Promise<RoleInstallation>;
16
+ preview: (id: string, spec: unknown, contextBindings?: unknown, parameterValues?: unknown, endpointBindings?: unknown) => Promise<RolePlanPreview>;
17
+ install: (id: string, preview: RolePlanPreview, confirmRuleConflicts?: string[]) => Promise<RoleInstallation>;
18
18
  export: (id: string, key: string) => Promise<{
19
- kind: "oversky.role-operating-spec";
19
+ kind: "role-operating-spec" | "oversky.role-operating-spec";
20
20
  schemaVersion: 1;
21
21
  key: string;
22
22
  revision: number;
@@ -49,11 +49,11 @@ export declare const roleApi: {
49
49
  successCriteria: {
50
50
  id: string;
51
51
  label: string;
52
- evaluator?: "manual" | "metric" | "source_state" | "task_state" | "goal_state" | "llm_review" | undefined;
52
+ evaluator?: "manual" | "task_state" | "goal_state" | "metric" | "llm_review" | "source_state" | undefined;
53
53
  config?: Record<string, unknown> | undefined;
54
54
  }[];
55
55
  sources: {
56
- source: "space" | "tasks" | "email" | "goal" | "files" | "local" | "daemon" | "browser" | "conversations" | "memory" | "slack" | "github" | "messages" | "metrics" | "monitor" | "agent_initiatives" | "docs" | "documents" | "calendar" | "product_metrics" | "business_metrics" | "state_monitor" | "agent_run";
56
+ source: "space" | "tasks" | "email" | "goal" | "files" | "local" | "daemon" | "browser" | "conversations" | "slack" | "memory" | "github" | "messages" | "calendar" | "docs" | "metrics" | "agent_run" | "agent_initiatives" | "documents" | "product_metrics" | "business_metrics" | "state_monitor" | "monitor";
57
57
  enabled: boolean;
58
58
  config?: Record<string, unknown> | undefined;
59
59
  }[];
@@ -81,7 +81,47 @@ export declare const roleApi: {
81
81
  roles: ("home" | "delivery" | "watch" | "advance")[];
82
82
  }[];
83
83
  directive?: string | undefined;
84
+ subject?: {
85
+ type: string;
86
+ externalKey: string;
87
+ label?: string | undefined;
88
+ } | undefined;
89
+ governance?: {
90
+ quietHours?: {
91
+ enabled: boolean;
92
+ start?: string | undefined;
93
+ end?: string | undefined;
94
+ timezone?: string | undefined;
95
+ } | undefined;
96
+ nudges?: {
97
+ maxPerDay?: number | null | undefined;
98
+ minIntervalMs?: number | undefined;
99
+ } | undefined;
100
+ attention?: {
101
+ severityLoudness?: {
102
+ low?: "standard" | "quiet" | "loud" | undefined;
103
+ medium?: "standard" | "quiet" | "loud" | undefined;
104
+ high?: "standard" | "quiet" | "loud" | undefined;
105
+ } | undefined;
106
+ escalation?: {
107
+ minimumSeverity?: "low" | "medium" | "high" | undefined;
108
+ channel?: "push" | "none" | "email" | "cli" | "app" | "slack" | undefined;
109
+ } | undefined;
110
+ noReply?: {
111
+ enabled?: boolean | undefined;
112
+ afterNudges?: number | undefined;
113
+ } | undefined;
114
+ } | undefined;
115
+ proactiveMessaging?: {
116
+ posture: "quiet" | "agent_discretion" | "first_material_blocker" | "high_visibility";
117
+ } | undefined;
118
+ } | undefined;
119
+ reports?: {
120
+ slot: string;
121
+ on: "completion" | "escalation" | "material_change" | "every_check";
122
+ }[] | undefined;
84
123
  deadlineAt?: string | undefined;
124
+ taskReviewPolicy?: "none" | "required" | undefined;
85
125
  freshness?: {
86
126
  staleAfterMs?: number | undefined;
87
127
  blockedAfterMs?: number | undefined;
@@ -90,9 +130,104 @@ export declare const roleApi: {
90
130
  evaluationPolicy?: Record<string, unknown> | undefined;
91
131
  learningPolicy?: Record<string, unknown> | undefined;
92
132
  }[];
133
+ rules?: ({
134
+ kind: "text_required";
135
+ text: string;
136
+ effect: "append";
137
+ id: string;
138
+ status: "active" | "proposed" | "retired";
139
+ reason?: string | undefined;
140
+ source?: {
141
+ kind: "owner" | "role_spec" | "correction";
142
+ ref?: {
143
+ conversationId: string;
144
+ messageId: string;
145
+ } | undefined;
146
+ } | undefined;
147
+ createdAt?: string | undefined;
148
+ createdBy?: string | undefined;
149
+ } | {
150
+ kind: "text_forbidden";
151
+ phrases: string[];
152
+ effect: "refuse" | "require_approval";
153
+ id: string;
154
+ status: "active" | "proposed" | "retired";
155
+ reason?: string | undefined;
156
+ source?: {
157
+ kind: "owner" | "role_spec" | "correction";
158
+ ref?: {
159
+ conversationId: string;
160
+ messageId: string;
161
+ } | undefined;
162
+ } | undefined;
163
+ createdAt?: string | undefined;
164
+ createdBy?: string | undefined;
165
+ })[] | undefined;
166
+ governance?: {
167
+ quietHours?: {
168
+ enabled: boolean;
169
+ start?: string | undefined;
170
+ end?: string | undefined;
171
+ timezone?: string | undefined;
172
+ } | undefined;
173
+ nudges?: {
174
+ maxPerDay?: number | null | undefined;
175
+ minIntervalMs?: number | undefined;
176
+ } | undefined;
177
+ attention?: {
178
+ severityLoudness?: {
179
+ low?: "standard" | "quiet" | "loud" | undefined;
180
+ medium?: "standard" | "quiet" | "loud" | undefined;
181
+ high?: "standard" | "quiet" | "loud" | undefined;
182
+ } | undefined;
183
+ escalation?: {
184
+ minimumSeverity?: "low" | "medium" | "high" | undefined;
185
+ channel?: "push" | "none" | "email" | "cli" | "app" | "slack" | undefined;
186
+ } | undefined;
187
+ noReply?: {
188
+ enabled?: boolean | undefined;
189
+ afterNudges?: number | undefined;
190
+ } | undefined;
191
+ } | undefined;
192
+ proactiveMessaging?: {
193
+ posture: "quiet" | "agent_discretion" | "first_material_blocker" | "high_visibility";
194
+ } | undefined;
195
+ } | undefined;
196
+ parameters?: {
197
+ key: string;
198
+ label: string;
199
+ type: "string" | "number" | "boolean" | "enum" | "string_list";
200
+ required: boolean;
201
+ default?: unknown;
202
+ options?: string[] | undefined;
203
+ maxLength?: number | undefined;
204
+ min?: number | undefined;
205
+ max?: number | undefined;
206
+ maxItems?: number | undefined;
207
+ }[] | undefined;
208
+ endpointSlots?: {
209
+ key: string;
210
+ label: string;
211
+ required: boolean;
212
+ destinations: ("app_owner_dm" | "slack_owner_dm" | "slack_channel")[];
213
+ }[] | undefined;
93
214
  }>;
94
215
  withdraw: (id: string, key: string, expectedCompassVersion: number) => Promise<RoleInstallation>;
95
216
  plan: (id: string) => Promise<AgentOperatingPlan>;
217
+ capture: (id: string, input: {
218
+ key: string;
219
+ title: string;
220
+ compassId?: string;
221
+ commitmentIds: string[];
222
+ }) => Promise<{
223
+ spec: RoleOperatingSpec;
224
+ omitted: Array<{
225
+ responsibilityKey?: string;
226
+ field: string;
227
+ reason: string;
228
+ }>;
229
+ prerequisites: string[];
230
+ }>;
96
231
  };
97
232
  export declare function readRoleJson(file: string): unknown;
98
233
  export declare function assertRolePreview(value: unknown): asserts value is RolePlanPreview;
package/dist/lib/roles.js CHANGED
@@ -9,23 +9,29 @@ const roleBase = (agentId) => `/api/agents/${encodeURIComponent(agentId)}`;
9
9
  exports.roleBase = roleBase;
10
10
  exports.roleApi = {
11
11
  list: (id) => data_provider_1.request.get(`${(0, exports.roleBase)(id)}/roles`),
12
- preview: (id, spec, contextBindings = {}) => data_provider_1.request.post(`${(0, exports.roleBase)(id)}/roles/preview`, {
12
+ preview: (id, spec, contextBindings = {}, parameterValues = {}, endpointBindings = {}) => data_provider_1.request.post(`${(0, exports.roleBase)(id)}/roles/preview`, {
13
13
  spec,
14
14
  contextBindings,
15
+ parameterValues,
16
+ endpointBindings,
15
17
  }),
16
- install: (id, preview) => data_provider_1.request.post(`${(0, exports.roleBase)(id)}/roles/install`, {
18
+ install: (id, preview, confirmRuleConflicts = []) => data_provider_1.request.post(`${(0, exports.roleBase)(id)}/roles/install`, {
17
19
  spec: preview.spec,
18
20
  fingerprint: preview.fingerprint,
19
21
  reviewFingerprint: preview.reviewFingerprint,
20
22
  expectedCompassVersion: preview.expectedCompassVersion,
21
23
  expectedVersions: preview.expectedVersions,
22
24
  contextBindings: preview.contextBindings || {},
25
+ parameterValues: preview.parameterValues || {},
26
+ endpointBindings: preview.endpointBindings || {},
27
+ ...(confirmRuleConflicts.length ? { confirmRuleConflicts } : {}),
23
28
  }),
24
29
  export: (id, key) => data_provider_1.request.get(`${(0, exports.roleBase)(id)}/roles/${encodeURIComponent(key)}/export`),
25
30
  withdraw: (id, key, expectedCompassVersion) => data_provider_1.request.post(`${(0, exports.roleBase)(id)}/roles/${encodeURIComponent(key)}/withdraw`, {
26
31
  expectedCompassVersion,
27
32
  }),
28
33
  plan: (id) => data_provider_1.request.get(`${(0, exports.roleBase)(id)}/operating-plan`),
34
+ capture: (id, input) => data_provider_1.request.post(`${(0, exports.roleBase)(id)}/roles/capture`, input),
29
35
  };
30
36
  function readRoleJson(file) {
31
37
  return JSON.parse((0, node_fs_1.readFileSync)(file, 'utf8'));
@@ -0,0 +1,18 @@
1
+ import type { SessionTaskOperation } from './session-task-endpoints';
2
+ /**
3
+ * A canonical Task write must retain its authenticated session actor even if
4
+ * the daemon also grants the CLI a wide credential. The wide credential names
5
+ * its account, not the Agent that is executing this Task. Passing the trusted
6
+ * session credential explicitly makes apiFetch keep the server's bound actor.
7
+ * Human invocations continue through their ordinary Task endpoints.
8
+ */
9
+ export declare function sessionTaskWrite(operation: Exclude<SessionTaskOperation, 'read'>, requestedTask: string, env?: Record<string, string | undefined>): Promise<{
10
+ path: string;
11
+ credential: import("@skrr-ai/auth-core/dist/esm/credentialResolver").ResolvedCredential;
12
+ taskId: string;
13
+ task: {
14
+ id?: string;
15
+ _id?: string;
16
+ identifier?: string;
17
+ } & Record<string, unknown>;
18
+ } | null>;