@skrr-ai/cli 0.1.19 → 0.1.21

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/dist/base-command.d.ts +12 -9
  2. package/dist/base-command.js +27 -26
  3. package/dist/commands/commitments/action-proposals/decide.js +22 -5
  4. package/dist/commands/commitments/action-proposals/execute.js +7 -3
  5. package/dist/commands/commitments/action-proposals/propose.d.ts +32 -0
  6. package/dist/commands/commitments/action-proposals/propose.js +111 -0
  7. package/dist/commands/commitments/action-proposals.js +6 -4
  8. package/dist/commands/commitments/create.d.ts +2 -0
  9. package/dist/commands/commitments/create.js +42 -2
  10. package/dist/commands/commitments/doctor.js +11 -0
  11. package/dist/commands/commitments/update.d.ts +2 -0
  12. package/dist/commands/commitments/update.js +40 -5
  13. package/dist/commands/store/browse.d.ts +14 -0
  14. package/dist/commands/store/browse.js +71 -0
  15. package/dist/commands/store/install.d.ts +16 -0
  16. package/dist/commands/store/install.js +54 -0
  17. package/dist/commands/store/releases.d.ts +19 -0
  18. package/dist/commands/store/releases.js +60 -0
  19. package/dist/commands/store/update.d.ts +15 -0
  20. package/dist/commands/store/update.js +69 -0
  21. package/dist/commands/store/updates.d.ts +24 -0
  22. package/dist/commands/store/updates.js +113 -0
  23. package/dist/commands/subscriptions/cancel.d.ts +14 -0
  24. package/dist/commands/subscriptions/cancel.js +47 -0
  25. package/dist/commands/subscriptions/health.d.ts +24 -0
  26. package/dist/commands/subscriptions/health.js +62 -0
  27. package/dist/commands/subscriptions/list.d.ts +9 -0
  28. package/dist/commands/subscriptions/list.js +52 -0
  29. package/dist/commands/subscriptions/status.d.ts +12 -0
  30. package/dist/commands/subscriptions/status.js +49 -0
  31. package/dist/commands/subscriptions/subscribe.d.ts +15 -0
  32. package/dist/commands/subscriptions/subscribe.js +59 -0
  33. package/dist/commands/tasks/complete.d.ts +10 -4
  34. package/dist/commands/tasks/complete.js +7 -5
  35. package/dist/commands/tasks/self-schedule.d.ts +30 -0
  36. package/dist/commands/tasks/self-schedule.js +114 -0
  37. package/dist/commands/triggers/disable.js +3 -1
  38. package/dist/commands/triggers/enable.js +3 -1
  39. package/dist/commands/triggers/rotate-secret.js +5 -0
  40. package/dist/commands/triggers/show.js +3 -1
  41. package/dist/lib/commitment-product.js +9 -0
  42. package/dist/lib/commitments.d.ts +21 -1
  43. package/dist/lib/commitments.js +62 -1
  44. package/dist/lib/node-adapter.js +4 -0
  45. package/dist/lib/task-extras.d.ts +18 -0
  46. package/dist/lib/task-extras.js +19 -1
  47. package/dist/lib/triggers.d.ts +21 -2
  48. package/dist/lib/triggers.js +48 -1
  49. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refreshClassification.js +9 -2
  50. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refreshClassification.js +9 -2
  51. package/dist/node_modules/@skrr-ai/data-provider/index.js +4073 -3904
  52. package/oclif.manifest.json +18424 -17362
  53. package/package.json +1 -1
@@ -18,7 +18,7 @@ export declare const TRIGGER_SCOPE_KINDS: readonly ["agent", "group_chat_subscri
18
18
  * capability was live and unreachable. `watch_until` and `sensor_poll` had been
19
19
  * in that state for longer.
20
20
  */
21
- export declare const TRIGGER_EXECUTOR_MODES: readonly ["send_message", "run_only", "enqueue_group_chat_agent_turn", "enqueue_assistant_turn", "enqueue_space_assistant_turn", "proactive_orchestrator_check", "auto_dream_orchestrator", "task_schedule_fire", "goal_planner_tick", "morning_briefing", "builtin_action", "watch_until", "sensor_poll", "external_work_task", "notify_user", "space_cycle_rollover"];
21
+ export declare const TRIGGER_EXECUTOR_MODES: readonly ["send_message", "run_only", "enqueue_group_chat_agent_turn", "enqueue_assistant_turn", "enqueue_space_assistant_turn", "proactive_orchestrator_check", "auto_dream_orchestrator", "task_schedule_fire", "goal_planner_tick", "morning_briefing", "builtin_action", "task_execute", "watch_until", "sensor_poll", "external_work_task", "notify_user", "space_cycle_rollover"];
22
22
  export declare const TRIGGER_EVENT_FILTER_MODES: readonly ["equals", "contains", "in_set"];
23
23
  export declare const TRIGGER_CONCURRENCY_POLICIES: readonly ["coalesce_if_active", "allow_parallel"];
24
24
  export declare const TRIGGER_FORM_RESPONSE_MODES: readonly ["thank_you_page", "redirect_url", "run_complete"];
@@ -95,6 +95,16 @@ export interface TriggerDefinition {
95
95
  chatMessage?: Record<string, unknown>;
96
96
  audit?: Record<string, unknown>;
97
97
  webhook?: Record<string, unknown>;
98
+ /**
99
+ * Server-DERIVED: maintained by a managed producer, so the mutation routes
100
+ * refuse to edit or remove it. Optional because a server predating the field
101
+ * omits it, which correctly reads as "not producer-owned".
102
+ *
103
+ * Declared here rather than inferred, and never re-derived from an id prefix
104
+ * or an execution mode — the route owns that policy and a local copy is free
105
+ * to disagree with the route that does the refusing.
106
+ */
107
+ producerOwned?: boolean;
98
108
  createdAt?: string;
99
109
  updatedAt?: string;
100
110
  }
@@ -327,7 +337,16 @@ export declare function armedStateLabel(enabled: boolean | undefined): string;
327
337
  * parentheses for scripts.
328
338
  */
329
339
  export declare function writeModeLabel(writeMode: string): string;
330
- export declare function renderTriggerSummary(trigger: TriggerDefinition, log: (line: string) => void): void;
340
+ /**
341
+ * Where an external caller POSTs to fire this trigger.
342
+ *
343
+ * Same origin as every other `/api/...` call the CLI makes, so it is built from
344
+ * the configured base URL rather than guessed.
345
+ */
346
+ export declare function webhookIngestUrl(baseURL: string, triggerId: string): string;
347
+ export declare function renderTriggerSummary(trigger: TriggerDefinition, log: (line: string) => void, options?: {
348
+ baseURL?: string;
349
+ }): void;
331
350
  export declare function renderLegacyRuns(runs: LegacyTriggerRun[], log: (line: string) => void): void;
332
351
  export declare function renderFireAudit(fires: TriggerFireRecord[], log: (line: string) => void): void;
333
352
  /**
@@ -32,6 +32,7 @@ exports.renderTriggerList = renderTriggerList;
32
32
  exports.formatDuplicateSubscriptionWarning = formatDuplicateSubscriptionWarning;
33
33
  exports.armedStateLabel = armedStateLabel;
34
34
  exports.writeModeLabel = writeModeLabel;
35
+ exports.webhookIngestUrl = webhookIngestUrl;
35
36
  exports.renderTriggerSummary = renderTriggerSummary;
36
37
  exports.renderLegacyRuns = renderLegacyRuns;
37
38
  exports.renderFireAudit = renderFireAudit;
@@ -86,6 +87,11 @@ exports.TRIGGER_EXECUTOR_MODES = [
86
87
  'goal_planner_tick',
87
88
  'morning_briefing',
88
89
  'builtin_action',
90
+ // The author-visible way to run a Task from a trigger. Its internal sibling
91
+ // `task_schedule_fire` sits two lines up and the server refuses it from any
92
+ // non-managed caller, so without this entry a headless operator could author
93
+ // every kind of task watcher except one that does the task.
94
+ 'task_execute',
89
95
  // User-authorable capabilities the server allows on the agent scope.
90
96
  'watch_until',
91
97
  'sensor_poll',
@@ -784,11 +790,40 @@ function writeModeLabel(writeMode) {
784
790
  return writeMode;
785
791
  }
786
792
  }
787
- function renderTriggerSummary(trigger, log) {
793
+ /**
794
+ * Kinds that expose a signed inbound HTTP channel. Mirrors `WEBHOOK_KINDS` in
795
+ * `api/server/routes/triggers.js`, which is what actually decides — this copy
796
+ * only chooses whether to PRINT a URL, so being behind costs a missing hint
797
+ * rather than a wrong answer.
798
+ */
799
+ const WEBHOOK_INGEST_KINDS = new Set(['on_demand', 'form', 'chat_message']);
800
+ /**
801
+ * Where an external caller POSTs to fire this trigger.
802
+ *
803
+ * Same origin as every other `/api/...` call the CLI makes, so it is built from
804
+ * the configured base URL rather than guessed.
805
+ */
806
+ function webhookIngestUrl(baseURL, triggerId) {
807
+ return `${String(baseURL).replace(/\/+$/, '')}/api/triggers/webhook/${encodeURIComponent(triggerId)}`;
808
+ }
809
+ function renderTriggerSummary(trigger, log, options = {}) {
788
810
  log(`ID: ${trigger.id ?? '-'}`);
789
811
  log(`Kind: ${trigger.kind ?? '-'}`);
790
812
  log(`Armed: ${armedStateLabel(trigger.enabled)}`);
791
813
  log(`Scope: ${scopeLabel(trigger)}`);
814
+ /*
815
+ * Say when the row is not yours to change.
816
+ *
817
+ * `producerOwned` is derived by the server and reported on every trigger read.
818
+ * Without it a headless operator reads `skrr triggers show task-schedule:<id>`,
819
+ * sees an ordinary-looking trigger, runs `triggers delete`, and learns from a
820
+ * 409 — for a row that was never editable. Same argument the `Contract:` /
821
+ * `Writes:` lines below were added under: a trigger with a property this
822
+ * consequential should state it at the moment it is read.
823
+ */
824
+ if (trigger.producerOwned === true) {
825
+ log('Managed: by the platform — not editable here; change the object that owns it');
826
+ }
792
827
  if (trigger.label)
793
828
  log(`Label: ${trigger.label}`);
794
829
  if (trigger.execution?.mode)
@@ -809,6 +844,18 @@ function renderTriggerSummary(trigger, log) {
809
844
  if (trigger.webhook?.configured !== undefined) {
810
845
  log(`Webhook: ${trigger.webhook.configured ? 'configured' : 'not configured'}`);
811
846
  }
847
+ /*
848
+ * The endpoint, not just "configured".
849
+ *
850
+ * An `on_demand` trigger exists so something outside the platform can fire it,
851
+ * and the CLI could report that a secret was set while never saying where to
852
+ * send it — the one fact the integration cannot be built without. Printed for
853
+ * every webhook-bearing kind, whether or not a secret has been minted yet, so
854
+ * "what is my URL" never requires a rotate.
855
+ */
856
+ if (options.baseURL && trigger.id && WEBHOOK_INGEST_KINDS.has(String(trigger.kind))) {
857
+ log(`Webhook URL: POST ${webhookIngestUrl(options.baseURL, trigger.id)}`);
858
+ }
812
859
  }
813
860
  function renderLegacyRuns(runs, log) {
814
861
  if (runs.length === 0) {
@@ -22,8 +22,9 @@ Object.defineProperty(exports, "PermanentAuthFailure", { enumerable: true, get:
22
22
  Object.defineProperty(exports, "TransientAuthFailure", { enumerable: true, get: function () { return types_js_1.TransientAuthFailure; } });
23
23
  /**
24
24
  * Maps server-supplied error codes to the canonical PermanentAuthReason values
25
- * exported from types.ts. Only the four values present in PermanentAuthReason
26
- * are listed; anything else falls through to 'REFRESH_INVALID'.
25
+ * exported from types.ts. `REFRESH_MISSING` is a server protocol code rather
26
+ * than a user-facing reason; it maps to `REFRESH_INVALID` because an identical
27
+ * retry cannot gain the credential the server says was absent.
27
28
  */
28
29
  const PERMANENT_CODE_SET = new Set([
29
30
  'REFRESH_INVALID',
@@ -63,6 +64,12 @@ function classifyRefreshResponse(status, body) {
63
64
  }
64
65
  // 401 — auth failure; check for known permanent code
65
66
  if (status === 401) {
67
+ if (body?.code === 'REFRESH_MISSING') {
68
+ return {
69
+ kind: 'failure',
70
+ failure: new types_js_1.PermanentAuthFailure('REFRESH_INVALID', body.message ?? 'Refresh token missing'),
71
+ };
72
+ }
66
73
  const code = body?.code;
67
74
  if (code && PERMANENT_CODE_SET.has(code)) {
68
75
  return {
@@ -23,8 +23,9 @@ import { PermanentAuthFailure, TransientAuthFailure } from './types.js';
23
23
  export { PermanentAuthFailure, TransientAuthFailure };
24
24
  /**
25
25
  * Maps server-supplied error codes to the canonical PermanentAuthReason values
26
- * exported from types.ts. Only the four values present in PermanentAuthReason
27
- * are listed; anything else falls through to 'REFRESH_INVALID'.
26
+ * exported from types.ts. `REFRESH_MISSING` is a server protocol code rather
27
+ * than a user-facing reason; it maps to `REFRESH_INVALID` because an identical
28
+ * retry cannot gain the credential the server says was absent.
28
29
  */
29
30
  const PERMANENT_CODE_SET = new Set([
30
31
  'REFRESH_INVALID',
@@ -64,6 +65,12 @@ export function classifyRefreshResponse(status, body) {
64
65
  }
65
66
  // 401 — auth failure; check for known permanent code
66
67
  if (status === 401) {
68
+ if (body?.code === 'REFRESH_MISSING') {
69
+ return {
70
+ kind: 'failure',
71
+ failure: new PermanentAuthFailure('REFRESH_INVALID', body.message ?? 'Refresh token missing'),
72
+ };
73
+ }
67
74
  const code = body?.code;
68
75
  if (code && PERMANENT_CODE_SET.has(code)) {
69
76
  return {