@skrr-ai/cli 0.1.60 → 0.1.62

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 (194) hide show
  1. package/dist/base-command.js +16 -0
  2. package/dist/commands/agents/create.d.ts +1 -0
  3. package/dist/commands/agents/create.js +8 -1
  4. package/dist/commands/agents/delete.d.ts +14 -0
  5. package/dist/commands/agents/delete.js +52 -4
  6. package/dist/commands/agents/eval/index.d.ts +38 -0
  7. package/dist/commands/agents/eval/index.js +157 -0
  8. package/dist/commands/agents/eval/list.d.ts +13 -0
  9. package/dist/commands/agents/eval/list.js +53 -0
  10. package/dist/commands/agents/eval/show.d.ts +13 -0
  11. package/dist/commands/agents/eval/show.js +36 -0
  12. package/dist/commands/agents/import.d.ts +37 -0
  13. package/dist/commands/agents/import.js +233 -0
  14. package/dist/commands/agents/pull.d.ts +27 -0
  15. package/dist/commands/agents/pull.js +82 -0
  16. package/dist/commands/agents/push.d.ts +28 -0
  17. package/dist/commands/agents/push.js +112 -0
  18. package/dist/commands/agents/releases/ci-publish.d.ts +32 -0
  19. package/dist/commands/agents/releases/ci-publish.js +99 -0
  20. package/dist/commands/agents/releases/create.d.ts +3 -0
  21. package/dist/commands/agents/releases/create.js +27 -6
  22. package/dist/commands/agents/releases/known-issues/add.d.ts +19 -0
  23. package/dist/commands/agents/releases/known-issues/add.js +43 -0
  24. package/dist/commands/agents/releases/known-issues/list.d.ts +17 -0
  25. package/dist/commands/agents/releases/known-issues/list.js +55 -0
  26. package/dist/commands/agents/releases/known-issues/update.d.ts +18 -0
  27. package/dist/commands/agents/releases/known-issues/update.js +47 -0
  28. package/dist/commands/agents/releases/list.js +25 -3
  29. package/dist/commands/agents/releases/rollback.js +12 -4
  30. package/dist/commands/agents/releases/test-install.d.ts +22 -0
  31. package/dist/commands/agents/releases/test-install.js +70 -0
  32. package/dist/commands/agents/releases/trusted-publishers/list.d.ts +17 -0
  33. package/dist/commands/agents/releases/trusted-publishers/list.js +55 -0
  34. package/dist/commands/agents/releases/trusted-publishers/remove.d.ts +17 -0
  35. package/dist/commands/agents/releases/trusted-publishers/remove.js +45 -0
  36. package/dist/commands/agents/releases/trusted-publishers/set.d.ts +27 -0
  37. package/dist/commands/agents/releases/trusted-publishers/set.js +82 -0
  38. package/dist/commands/agents/update.d.ts +1 -0
  39. package/dist/commands/agents/update.js +8 -1
  40. package/dist/commands/agents/usage-cap.d.ts +20 -0
  41. package/dist/commands/agents/usage-cap.js +76 -0
  42. package/dist/commands/agents/validate.d.ts +22 -0
  43. package/dist/commands/agents/validate.js +66 -0
  44. package/dist/commands/agents/visibility.d.ts +13 -0
  45. package/dist/commands/agents/visibility.js +84 -2
  46. package/dist/commands/commerce/fees/show.d.ts +19 -0
  47. package/dist/commands/commerce/fees/show.js +75 -0
  48. package/dist/commands/earnings/index.d.ts +15 -0
  49. package/dist/commands/earnings/index.js +46 -0
  50. package/dist/commands/earnings/payouts.d.ts +12 -0
  51. package/dist/commands/earnings/payouts.js +39 -0
  52. package/dist/commands/earnings/statements.d.ts +19 -0
  53. package/dist/commands/earnings/statements.js +70 -0
  54. package/dist/commands/goals/key-results/create.d.ts +1 -1
  55. package/dist/commands/goals/key-results/create.js +5 -1
  56. package/dist/commands/harnesses/show.js +11 -1
  57. package/dist/commands/logout.js +31 -0
  58. package/dist/commands/machines/show.js +10 -1
  59. package/dist/commands/managed-execution/show.d.ts +10 -0
  60. package/dist/commands/managed-execution/show.js +60 -0
  61. package/dist/commands/spaces/show.js +35 -1
  62. package/dist/commands/step-up.d.ts +23 -0
  63. package/dist/commands/step-up.js +96 -0
  64. package/dist/commands/store/acquisitions/approve.d.ts +30 -0
  65. package/dist/commands/store/acquisitions/approve.js +100 -0
  66. package/dist/commands/store/acquisitions/decline.d.ts +17 -0
  67. package/dist/commands/store/acquisitions/decline.js +47 -0
  68. package/dist/commands/store/acquisitions/show.d.ts +16 -0
  69. package/dist/commands/store/acquisitions/show.js +49 -0
  70. package/dist/commands/store/admissions/approve.d.ts +19 -0
  71. package/dist/commands/store/admissions/approve.js +50 -0
  72. package/dist/commands/store/admissions/list.d.ts +15 -0
  73. package/dist/commands/store/admissions/list.js +60 -0
  74. package/dist/commands/store/admissions/refuse.d.ts +18 -0
  75. package/dist/commands/store/admissions/refuse.js +49 -0
  76. package/dist/commands/store/advisories/artifact.d.ts +15 -0
  77. package/dist/commands/store/advisories/artifact.js +25 -0
  78. package/dist/commands/store/advisories/cancel.d.ts +13 -0
  79. package/dist/commands/store/advisories/cancel.js +34 -0
  80. package/dist/commands/store/advisories/close.d.ts +18 -0
  81. package/dist/commands/store/advisories/close.js +51 -0
  82. package/dist/commands/store/advisories/confirm.d.ts +17 -0
  83. package/dist/commands/store/advisories/confirm.js +40 -0
  84. package/dist/commands/store/advisories/issue.d.ts +20 -0
  85. package/dist/commands/store/advisories/issue.js +59 -0
  86. package/dist/commands/store/advisories/list.d.ts +15 -0
  87. package/dist/commands/store/advisories/list.js +49 -0
  88. package/dist/commands/store/advisories/show.d.ts +13 -0
  89. package/dist/commands/store/advisories/show.js +34 -0
  90. package/dist/commands/store/artifacts/release.d.ts +16 -0
  91. package/dist/commands/store/artifacts/release.js +31 -0
  92. package/dist/commands/store/artifacts/used-by.d.ts +12 -0
  93. package/dist/commands/store/artifacts/used-by.js +20 -0
  94. package/dist/commands/store/browse.d.ts +5 -0
  95. package/dist/commands/store/browse.js +28 -1
  96. package/dist/commands/store/channel.d.ts +21 -0
  97. package/dist/commands/store/channel.js +62 -0
  98. package/dist/commands/store/follow.d.ts +14 -0
  99. package/dist/commands/store/follow.js +45 -0
  100. package/dist/commands/store/governance/policy.d.ts +18 -5
  101. package/dist/commands/store/governance/policy.js +80 -12
  102. package/dist/commands/store/governance/requests.d.ts +28 -0
  103. package/dist/commands/store/governance/requests.js +116 -0
  104. package/dist/commands/store/install.d.ts +3 -0
  105. package/dist/commands/store/install.js +101 -2
  106. package/dist/commands/store/issues.d.ts +26 -0
  107. package/dist/commands/store/issues.js +118 -0
  108. package/dist/commands/store/maintainers/add.d.ts +13 -0
  109. package/dist/commands/store/maintainers/add.js +23 -0
  110. package/dist/commands/store/maintainers/remove.d.ts +13 -0
  111. package/dist/commands/store/maintainers/remove.js +22 -0
  112. package/dist/commands/store/publishers/approve.d.ts +11 -0
  113. package/dist/commands/store/publishers/approve.js +25 -0
  114. package/dist/commands/store/publishers/claim.d.ts +12 -0
  115. package/dist/commands/store/publishers/claim.js +20 -0
  116. package/dist/commands/store/publishers/confirm.d.ts +11 -0
  117. package/dist/commands/store/publishers/confirm.js +17 -0
  118. package/dist/commands/store/publishers/domains/begin.d.ts +12 -0
  119. package/dist/commands/store/publishers/domains/begin.js +20 -0
  120. package/dist/commands/store/publishers/domains/list.d.ts +9 -0
  121. package/dist/commands/store/publishers/domains/list.js +19 -0
  122. package/dist/commands/store/publishers/domains/verify.d.ts +12 -0
  123. package/dist/commands/store/publishers/domains/verify.js +20 -0
  124. package/dist/commands/store/publishers/namespaces.d.ts +8 -0
  125. package/dist/commands/store/publishers/namespaces.js +16 -0
  126. package/dist/commands/store/publishers/verified.d.ts +11 -0
  127. package/dist/commands/store/publishers/verified.js +34 -0
  128. package/dist/commands/store/refund.d.ts +22 -0
  129. package/dist/commands/store/refund.js +80 -0
  130. package/dist/commands/store/report.d.ts +20 -0
  131. package/dist/commands/store/report.js +59 -0
  132. package/dist/commands/store/reports.d.ts +11 -0
  133. package/dist/commands/store/reports.js +52 -0
  134. package/dist/commands/store/signals.d.ts +18 -0
  135. package/dist/commands/store/signals.js +43 -0
  136. package/dist/commands/store/star.d.ts +17 -0
  137. package/dist/commands/store/star.js +41 -0
  138. package/dist/commands/store/stars.d.ts +10 -0
  139. package/dist/commands/store/stars.js +33 -0
  140. package/dist/commands/store/trial.d.ts +11 -0
  141. package/dist/commands/store/trial.js +17 -0
  142. package/dist/commands/store/uninstall.d.ts +19 -0
  143. package/dist/commands/store/uninstall.js +118 -0
  144. package/dist/commands/store/update.d.ts +2 -0
  145. package/dist/commands/store/update.js +60 -2
  146. package/dist/commands/store/updates.d.ts +10 -4
  147. package/dist/commands/store/updates.js +60 -39
  148. package/dist/commands/store/watch.d.ts +18 -0
  149. package/dist/commands/store/watch.js +44 -0
  150. package/dist/commands/subscriptions/health.d.ts +12 -0
  151. package/dist/commands/subscriptions/health.js +39 -0
  152. package/dist/commands/subscriptions/list.js +3 -2
  153. package/dist/commands/subscriptions/status.js +7 -1
  154. package/dist/commands/subscriptions/subscribe.d.ts +9 -2
  155. package/dist/commands/subscriptions/subscribe.js +141 -12
  156. package/dist/commands/tasks/comments/list.js +9 -1
  157. package/dist/commands/tasks/labels/attach.js +15 -2
  158. package/dist/commands/tasks/show.js +17 -3
  159. package/dist/commands/tasks/update.js +15 -4
  160. package/dist/commands/tasks/updates/add.js +5 -1
  161. package/dist/lib/agent-config.js +1 -0
  162. package/dist/lib/agent-evals.d.ts +71 -0
  163. package/dist/lib/agent-evals.js +359 -0
  164. package/dist/lib/agent-spec.d.ts +28 -0
  165. package/dist/lib/agent-spec.js +58 -0
  166. package/dist/lib/auth-storage.d.ts +12 -0
  167. package/dist/lib/auth-storage.js +0 -33
  168. package/dist/lib/commerce.d.ts +8 -0
  169. package/dist/lib/commerce.js +10 -0
  170. package/dist/lib/earnings.d.ts +36 -0
  171. package/dist/lib/earnings.js +164 -0
  172. package/dist/lib/github-oidc.d.ts +13 -0
  173. package/dist/lib/github-oidc.js +41 -0
  174. package/dist/lib/governed-store.d.ts +43 -2
  175. package/dist/lib/governed-store.js +25 -1
  176. package/dist/lib/label-ref.js +16 -0
  177. package/dist/lib/managed-execution.d.ts +10 -0
  178. package/dist/lib/managed-execution.js +43 -0
  179. package/dist/lib/principal-display.d.ts +20 -0
  180. package/dist/lib/principal-display.js +64 -0
  181. package/dist/lib/space-template-source.d.ts +14 -0
  182. package/dist/lib/space-template-source.js +41 -0
  183. package/dist/lib/step-up.d.ts +21 -0
  184. package/dist/lib/step-up.js +44 -0
  185. package/dist/lib/store-acquisition.d.ts +11 -0
  186. package/dist/lib/store-acquisition.js +40 -0
  187. package/dist/lib/store-advisories.d.ts +50 -0
  188. package/dist/lib/store-advisories.js +62 -0
  189. package/dist/lib/task-closure.js +1 -1
  190. package/dist/lib/web-url.d.ts +11 -0
  191. package/dist/lib/web-url.js +14 -0
  192. package/dist/node_modules/@skrr-ai/data-provider/index.js +25471 -24177
  193. package/oclif.manifest.json +38931 -34119
  194. package/package.json +21 -3
@@ -3,12 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
+ const http_error_1 = require("../../lib/http-error");
6
7
  class StoreUpdate extends base_command_1.BaseCommand {
7
8
  static description = 'Update an installed agent to a published release, keeping the edits you made to your copy';
8
9
  static examples = [
9
10
  '<%= config.bin %> store update agent_abc123',
10
11
  '<%= config.bin %> store update agent_abc123 --release ar_def456',
11
12
  '<%= config.bin %> store update agent_abc123 --strategy replace',
13
+ '<%= config.bin %> store update agent_abc123 --accept-capabilities',
14
+ '<%= config.bin %> store update agent_abc123 --decline',
12
15
  ];
13
16
  static args = {
14
17
  agentId: core_1.Args.string({
@@ -25,10 +28,33 @@ class StoreUpdate extends base_command_1.BaseCommand {
25
28
  description: 'merge (default) keeps your edits and refuses on a conflict; replace takes the publisher version',
26
29
  options: ['merge', 'replace'],
27
30
  }),
31
+ 'accept-capabilities': core_1.Flags.boolean({
32
+ description: 'Consent to the new powers a pending "capability_widened" update grants your copy',
33
+ }),
34
+ decline: core_1.Flags.boolean({
35
+ description: 'Decline the waiting update and clear the reminder; your copy stays as it is',
36
+ }),
28
37
  };
29
38
  async run() {
30
39
  this.requireAuth();
31
40
  const { args, flags } = await this.parse(StoreUpdate);
41
+ // A status read first: what this command would move, and whether anything
42
+ // already waits on it. It doubles as the friendly refusal for a listing
43
+ // that was never installed.
44
+ let status;
45
+ try {
46
+ status = await data_provider_1.dataService.getAgentPurchaseStatus(args.agentId);
47
+ }
48
+ catch (err) {
49
+ this.handleApiError(err);
50
+ }
51
+ if (!status?.purchased) {
52
+ this.error(`${args.agentId} is not installed from the Store. Install it first: skrr store install ${args.agentId}`, { exit: 1 });
53
+ }
54
+ if (status.pendingUpdate && !flags.decline) {
55
+ this.log(`A ${status.pendingUpdate.versionLabel ?? 'new'} release is waiting for review ` +
56
+ `(${status.pendingUpdate.reason}).`);
57
+ }
32
58
  let response;
33
59
  try {
34
60
  response = await data_provider_1.dataService.updateInstalledStoreAgent({
@@ -36,13 +62,41 @@ class StoreUpdate extends base_command_1.BaseCommand {
36
62
  ...(flags.installed ? { installedAgentId: flags.installed } : {}),
37
63
  ...(flags.release ? { targetReleaseId: flags.release } : {}),
38
64
  ...(flags.strategy ? { strategy: flags.strategy } : {}),
65
+ ...(flags['accept-capabilities'] ? { acceptCapabilities: true } : {}),
66
+ ...(flags.decline ? { decline: true } : {}),
39
67
  });
40
68
  }
41
69
  catch (err) {
70
+ // Read the refusal the way every transport carries it: the node adapter
71
+ // hands back the body as TEXT, so reading `err.body` as an object never
72
+ // saw a code at all and both answers below fell through to a bare error.
73
+ const body = (0, http_error_1.httpBodyOf)(err);
74
+ // Not an update: a new major is a separate purchase. Say which version
75
+ // keeps its free updates, and offer no command — none sells a second
76
+ // major of a listing yet, and `store install` refuses one you own.
77
+ if (body?.code === 'MAJOR_UPDATE_REQUIRES_PURCHASE') {
78
+ this.log(body.error ?? 'A new major version is a separate purchase.');
79
+ this.log(body.installedVersionLabel
80
+ ? `You own ${body.installedVersionLabel}, and it keeps getting free updates within its major.`
81
+ : 'The version you own keeps getting free updates within its major.');
82
+ this.error('Update not applied.', { exit: 1 });
83
+ }
84
+ // A conflict is not a failure of the update; it is the update asking a
85
+ // question. Print the fields, and the one command that answers it.
86
+ // A widened capability set is a consent question (OSK-12257): name what
87
+ // the release adds, and the two answers — grant it, or decline the update.
88
+ if (body?.code === 'UPDATE_CAPABILITY_WIDENED') {
89
+ this.log(body.error ?? 'This update grants your copy new powers.');
90
+ for (const row of body.capabilities ?? []) {
91
+ this.log(` ${row.field}: ${row.added.join(', ')}`);
92
+ }
93
+ this.log('');
94
+ this.log(`Accept: skrr store update ${args.agentId} --accept-capabilities`);
95
+ this.log(`Decline: skrr store update ${args.agentId} --decline`);
96
+ this.error('Update not applied.', { exit: 1 });
97
+ }
42
98
  // A conflict is not a failure of the update; it is the update asking a
43
99
  // question. Print the fields, and the one command that answers it.
44
- const conflict = err;
45
- const body = conflict?.body;
46
100
  if (body?.code === 'UPDATE_CONFLICT' || body?.code === 'UPDATE_NO_BASE') {
47
101
  this.log(body.error ?? 'This update needs a decision.');
48
102
  if (body.conflicts?.length) {
@@ -58,6 +112,10 @@ class StoreUpdate extends base_command_1.BaseCommand {
58
112
  this.log(JSON.stringify(response, null, 2));
59
113
  return;
60
114
  }
115
+ if (response?.declined) {
116
+ this.log('Update declined. Your copy stays on the version it runs.');
117
+ return;
118
+ }
61
119
  const merge = response
62
120
  ?.merge;
63
121
  this.log(`Updated to ${response?.targetVersionLabel ?? response?.targetReleaseId ?? ''}.`);
@@ -2,17 +2,23 @@ import { BaseCommand } from '../../base-command';
2
2
  /**
3
3
  * What is waiting on you across everything you installed.
4
4
  *
5
+ * Reads `GET /api/store/installs` — the one read model the web Installed page
6
+ * shows too (OSK-12287). It used to loop `purchased` × `purchase-status`, so
7
+ * every row was a second request and a stopped copy arrived as "unreadable".
8
+ * Now the server answers every install with its own waiting state.
9
+ *
5
10
  * Three states, kept apart because they ask for three different things:
6
11
  *
7
12
  * ready a same-major release that will apply cleanly
8
13
  * review one that could not be applied on its own — you and the publisher
9
- * both changed the same field, or the version your copy came from is
10
- * unknown so your edits cannot be told apart from theirs
14
+ * both changed the same field, the release widened capabilities, or
15
+ * the version your copy came from is unknown
11
16
  * buy a new major, which under the channel decision is a fresh purchase
12
17
  * rather than an update
13
18
  *
14
- * Collapsing them into "update available" is what makes a person ignore the
15
- * whole column: two of the three cannot be resolved by pressing update.
19
+ * Plus two row states that are not updates at all: `stopped` (a quarantined,
20
+ * revoked or uninstalled copy — its reason, not silence) and `advisory`
21
+ * (an active security advisory on a release you run).
16
22
  */
17
23
  export default class StoreUpdates extends BaseCommand {
18
24
  static description: string;
@@ -7,17 +7,23 @@ const format_1 = require("../../lib/format");
7
7
  /**
8
8
  * What is waiting on you across everything you installed.
9
9
  *
10
+ * Reads `GET /api/store/installs` — the one read model the web Installed page
11
+ * shows too (OSK-12287). It used to loop `purchased` × `purchase-status`, so
12
+ * every row was a second request and a stopped copy arrived as "unreadable".
13
+ * Now the server answers every install with its own waiting state.
14
+ *
10
15
  * Three states, kept apart because they ask for three different things:
11
16
  *
12
17
  * ready a same-major release that will apply cleanly
13
18
  * review one that could not be applied on its own — you and the publisher
14
- * both changed the same field, or the version your copy came from is
15
- * unknown so your edits cannot be told apart from theirs
19
+ * both changed the same field, the release widened capabilities, or
20
+ * the version your copy came from is unknown
16
21
  * buy a new major, which under the channel decision is a fresh purchase
17
22
  * rather than an update
18
23
  *
19
- * Collapsing them into "update available" is what makes a person ignore the
20
- * whole column: two of the three cannot be resolved by pressing update.
24
+ * Plus two row states that are not updates at all: `stopped` (a quarantined,
25
+ * revoked or uninstalled copy — its reason, not silence) and `advisory`
26
+ * (an active security advisory on a release you run).
21
27
  */
22
28
  class StoreUpdates extends base_command_1.BaseCommand {
23
29
  static description = 'Show what is waiting across the agents you installed';
@@ -31,63 +37,74 @@ class StoreUpdates extends base_command_1.BaseCommand {
31
37
  async run() {
32
38
  this.requireAuth();
33
39
  const { flags } = await this.parse(StoreUpdates);
34
- let purchased;
40
+ let installs;
35
41
  try {
36
- purchased = await data_provider_1.dataService.getPurchasedAgents();
42
+ installs = await data_provider_1.dataService.getStoreInstalls();
37
43
  }
38
44
  catch (err) {
39
45
  this.handleApiError(err);
40
46
  }
41
- const items = purchased?.data ?? [];
42
47
  const rows = [];
43
- for (const item of items) {
44
- const agentId = String(item.sourceAgentId ?? item.id ?? '');
45
- if (!agentId) {
46
- continue;
47
- }
48
- let status;
49
- try {
50
- status = await data_provider_1.dataService.getAgentPurchaseStatus(agentId);
51
- }
52
- catch {
53
- // One unreadable listing must not hide the rest. A row we could not
54
- // read is reported as such rather than silently dropped.
55
- rows.push({ agent: agentId, state: 'unreadable', have: '-', waiting: '-', detail: '' });
56
- continue;
57
- }
58
- if (!status?.purchased) {
59
- continue;
60
- }
61
- const have = status.installedVersionLabel ?? '-';
62
- if (status.pendingUpdate) {
48
+ for (const install of installs?.installs ?? []) {
49
+ const have = install.installedVersionLabel ?? '-';
50
+ const update = install.update;
51
+ if (update?.state === 'review') {
52
+ const pending = install.pendingUpdate;
63
53
  rows.push({
64
- agent: agentId,
54
+ agent: install.agentId,
65
55
  state: 'review',
56
+ channel: install.updatePolicy ?? 'manual',
66
57
  have,
67
- waiting: status.pendingUpdate.versionLabel ?? '-',
68
- detail: status.pendingUpdate.reason === 'conflict'
69
- ? `you both changed ${(status.pendingUpdate.conflicts ?? []).join(', ') || 'a field'}`
70
- : 'the version your copy came from is unknown',
58
+ waiting: update.versionLabel ?? '-',
59
+ detail: pending?.reason === 'conflict'
60
+ ? `you both changed ${(pending.conflicts ?? []).join(', ') || 'a field'}`
61
+ : pending?.reason === 'capability_widened'
62
+ ? `adds capabilities: ${(pending.capabilities ?? [])
63
+ .map((row) => `${row.field} (${row.added.join(', ')})`)
64
+ .join('; ') || 'new powers'}`
65
+ : 'the version your copy came from is unknown',
71
66
  });
72
67
  }
73
- if (status.availableMajor) {
68
+ if (update?.state === 'buy') {
74
69
  rows.push({
75
- agent: agentId,
70
+ agent: install.agentId,
76
71
  state: 'buy',
72
+ channel: install.updatePolicy ?? 'manual',
77
73
  have,
78
- waiting: status.availableMajor.versionLabel ?? '-',
74
+ waiting: update.versionLabel ?? '-',
79
75
  detail: 'a new major is a separate purchase',
80
76
  });
81
77
  }
82
- if (!status.pendingUpdate && status.updateAvailable && status.updateKind === 'minor') {
78
+ if (update?.state === 'ready') {
83
79
  rows.push({
84
- agent: agentId,
80
+ agent: install.agentId,
85
81
  state: 'ready',
82
+ channel: install.updatePolicy ?? 'manual',
86
83
  have,
87
- waiting: status.latestVersionLabel ?? '-',
84
+ waiting: update.versionLabel ?? '-',
88
85
  detail: 'applies cleanly',
89
86
  });
90
87
  }
88
+ if (install.stopReason) {
89
+ rows.push({
90
+ agent: install.agentId,
91
+ state: 'stopped',
92
+ channel: install.updatePolicy ?? 'manual',
93
+ have,
94
+ waiting: '-',
95
+ detail: install.stopReason,
96
+ });
97
+ }
98
+ if (install.advisory) {
99
+ rows.push({
100
+ agent: install.agentId,
101
+ state: 'advisory',
102
+ channel: install.updatePolicy ?? 'manual',
103
+ have,
104
+ waiting: '-',
105
+ detail: install.advisory.summary ?? 'security advisory on this release',
106
+ });
107
+ }
91
108
  }
92
109
  if (flags.json) {
93
110
  this.log(JSON.stringify({ object: 'list', data: rows }, null, 2));
@@ -107,7 +124,11 @@ class StoreUpdates extends base_command_1.BaseCommand {
107
124
  this.log('');
108
125
  this.log('ready → skrr store update <agent>');
109
126
  this.log('review → skrr store update <agent> --strategy replace (takes the publisher version)');
110
- this.log('buy → skrr store install <agent>');
127
+ this.log('widened → skrr store update <agent> --accept-capabilities (or --decline to keep yours)');
128
+ // No command: `store install` refuses a listing you already own, and
129
+ // `store update` refuses a new major (§11 D2/D13). Naming either here sent
130
+ // a buyer to a refusal.
131
+ this.log('buy → a separate purchase; not yet on sale to owners of an earlier major');
111
132
  }
112
133
  }
113
134
  exports.default = StoreUpdates;
@@ -0,0 +1,18 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * Watch a store listing (OSK-12309): the one relation that delivers —
4
+ * every public release that lands pings the watcher. Star and Follow are
5
+ * separate intent signals; neither sends anything.
6
+ */
7
+ export default class StoreWatch extends BaseCommand {
8
+ static description: string;
9
+ static examples: string[];
10
+ static args: {
11
+ agentId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ static flags: {
14
+ undo: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ };
17
+ run(): Promise<void>;
18
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../base-command");
6
+ /**
7
+ * Watch a store listing (OSK-12309): the one relation that delivers —
8
+ * every public release that lands pings the watcher. Star and Follow are
9
+ * separate intent signals; neither sends anything.
10
+ */
11
+ class StoreWatch extends base_command_1.BaseCommand {
12
+ static description = 'Get a notification when a store agent publishes a release — or stop watching with --undo';
13
+ static examples = [
14
+ '<%= config.bin %> store watch agent_abc123',
15
+ '<%= config.bin %> store watch agent_abc123 --undo',
16
+ ];
17
+ static args = {
18
+ agentId: core_1.Args.string({ description: 'The store agent id', required: true, ignoreStdin: true }),
19
+ };
20
+ static flags = {
21
+ undo: core_1.Flags.boolean({ description: 'Stop watching this listing' }),
22
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
23
+ };
24
+ async run() {
25
+ this.requireAuth();
26
+ const { args, flags } = await this.parse(StoreWatch);
27
+ try {
28
+ const result = flags.undo
29
+ ? await data_provider_1.dataService.unwatchStoreListing(args.agentId)
30
+ : await data_provider_1.dataService.watchStoreListing(args.agentId);
31
+ if (flags.json) {
32
+ this.log(JSON.stringify(result, null, 2));
33
+ return;
34
+ }
35
+ this.log(flags.undo
36
+ ? 'Not watching this listing.'
37
+ : 'Watching — a release publishes, you hear about it.');
38
+ }
39
+ catch (err) {
40
+ this.handleApiError(err);
41
+ }
42
+ }
43
+ }
44
+ exports.default = StoreWatch;
@@ -1,3 +1,4 @@
1
+ import type { StoreSubscriptionObligations } from '@skrr-ai/data-provider';
1
2
  import { BaseCommand } from '../../base-command';
2
3
  /**
3
4
  * Has this service actually delivered?
@@ -22,3 +23,14 @@ export default class SubscriptionsHealth extends BaseCommand {
22
23
  };
23
24
  run(): Promise<void>;
24
25
  }
26
+ /**
27
+ * What the service owes, as bought. Four answers that must never print alike:
28
+ * the list itself; a service that declared nothing; a subscription whose
29
+ * Commitment does not exist yet, so nothing holds the service to what was
30
+ * bought (NOT "declared nothing" — the release may declare plenty); and a
31
+ * contract that could not be read. `undefined` is an older server that does not
32
+ * report it, so nothing is said.
33
+ *
34
+ * Exported for tests.
35
+ */
36
+ export declare function obligationLines(obligations: StoreSubscriptionObligations | undefined): string[];
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.obligationLines = obligationLines;
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../base-command");
@@ -54,6 +55,11 @@ class SubscriptionsHealth extends base_command_1.BaseCommand {
54
55
  this.log('');
55
56
  this.log(`delivered ${response.delivered} / ${response.tasks}`);
56
57
  this.log(`waiting on you ${response.awaitingConfirmation}`);
58
+ // A delivery somebody assessed as not delivered (the subscriber, or the
59
+ // service's own agent reporting it could not deliver or verify) — never
60
+ // folded into "owed", which means nobody has done it yet. An older server
61
+ // does not send it.
62
+ this.log(`judged not delivered ${response.unmet ?? 0}`);
57
63
  this.log(`still owed ${response.owed}`);
58
64
  this.log(`blocked ${response.blocked}`);
59
65
  if (response.noContract > 0) {
@@ -61,6 +67,39 @@ class SubscriptionsHealth extends base_command_1.BaseCommand {
61
67
  // about what you are paying for.
62
68
  this.log(`no stated contract ${response.noContract}`);
63
69
  }
70
+ for (const line of obligationLines(response.obligations))
71
+ this.log(line);
64
72
  }
65
73
  }
66
74
  exports.default = SubscriptionsHealth;
75
+ /**
76
+ * What the service owes, as bought. Four answers that must never print alike:
77
+ * the list itself; a service that declared nothing; a subscription whose
78
+ * Commitment does not exist yet, so nothing holds the service to what was
79
+ * bought (NOT "declared nothing" — the release may declare plenty); and a
80
+ * contract that could not be read. `undefined` is an older server that does not
81
+ * report it, so nothing is said.
82
+ *
83
+ * Exported for tests.
84
+ */
85
+ function obligationLines(obligations) {
86
+ if (!obligations)
87
+ return [];
88
+ if (obligations.state === 'unreadable') {
89
+ return ['', 'What it owes you: could not be read right now.'];
90
+ }
91
+ if (obligations.state === 'not_recorded') {
92
+ return [
93
+ '',
94
+ 'What it owes you: not recorded on your subscription yet. It has not started work, so nothing holds the service to the obligations you bought.',
95
+ ];
96
+ }
97
+ if (obligations.rows.length === 0) {
98
+ return ['', 'What it owes you: this service declared no delivery obligations.'];
99
+ }
100
+ return [
101
+ '',
102
+ 'What it owes you, on each delivery:',
103
+ ...obligations.rows.map((row) => ` - ${row.text}`),
104
+ ];
105
+ }
@@ -37,8 +37,9 @@ class SubscriptionsList extends base_command_1.BaseCommand {
37
37
  service: s.sourceAgentId,
38
38
  instance: s.instanceAgentId ?? '-',
39
39
  // Who pays for the work is part of what you bought, so it is a column
40
- // rather than something you have to ask for with --json.
41
- pays: s.billingMode,
40
+ // rather than something you have to ask for with --json. It is who is
41
+ // actually CHARGED (the server's resolver), not the declared mode.
42
+ pays: s.computePayer?.label ?? 'unknown',
42
43
  expires: s.expiresAt ? String(s.expiresAt).slice(0, 10) : 'no end date',
43
44
  })), [
44
45
  { key: 'entitlementId', header: 'ENTITLEMENT' },
@@ -43,8 +43,14 @@ class SubscriptionsStatus extends base_command_1.BaseCommand {
43
43
  }
44
44
  this.log(`Live. Entitlement ${response.entitlementId} (v${response.version})`);
45
45
  this.log(`Your instance: ${response.instanceAgentId ?? '-'}`);
46
- this.log(`Compute paid by: ${response.billingMode}`);
46
+ this.log(`Compute paid by: ${(0, data_provider_1.describeStoreComputePayer)(response.computePayer)}`);
47
47
  this.log(`Expires: ${response.expiresAt ? String(response.expiresAt) : 'no end date'}`);
48
+ // The same line the web card shows: whose turn it is when a period could
49
+ // not be charged. Only a balance that could not pay is told to top up.
50
+ this.log(`Billing: ${(0, data_provider_1.describeStoreServiceBilling)(response).text}`);
51
+ if (response.billingIssueCode) {
52
+ this.log(`Last charge failed with: ${response.billingIssueCode}`);
53
+ }
48
54
  if (response.commitmentId) {
49
55
  this.log(`Obligation: ${response.commitmentId}`);
50
56
  }
@@ -7,9 +7,16 @@ export default class SubscriptionsSubscribe extends BaseCommand {
7
7
  };
8
8
  static flags: {
9
9
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
- 'billing-mode': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
- 'expires-at': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
10
  space: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ grant: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ trial: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
14
  };
14
15
  run(): Promise<void>;
16
+ /**
17
+ * The card-free trial path (OSK-12281). The trial's own terms — days, the
18
+ * platform compute budget — come from the quote's `trial` block the server
19
+ * computed for this caller, so what is printed is what the write will do.
20
+ */
21
+ private startTrial;
15
22
  }