@skrr-ai/cli 0.1.36 → 0.1.38

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 (266) hide show
  1. package/README.md +17 -4
  2. package/bin/dev-fallback.js +167 -4
  3. package/dist/base-command.js +46 -2
  4. package/dist/commands/agents/actions/create.d.ts +5 -0
  5. package/dist/commands/agents/actions/create.js +42 -5
  6. package/dist/commands/agents/actions/delete.d.ts +1 -0
  7. package/dist/commands/agents/actions/delete.js +7 -0
  8. package/dist/commands/agents/actions/update.d.ts +5 -0
  9. package/dist/commands/agents/actions/update.js +27 -1
  10. package/dist/commands/agents/api-actions/add.d.ts +41 -0
  11. package/dist/commands/agents/api-actions/add.js +205 -0
  12. package/dist/commands/agents/api-actions/index.d.ts +39 -0
  13. package/dist/commands/agents/api-actions/index.js +103 -0
  14. package/dist/commands/agents/api-actions/remove.d.ts +14 -0
  15. package/dist/commands/agents/api-actions/remove.js +36 -0
  16. package/dist/commands/agents/avatar/default/apply.d.ts +25 -0
  17. package/dist/commands/agents/avatar/default/apply.js +56 -0
  18. package/dist/commands/agents/avatar/default/index.d.ts +29 -0
  19. package/dist/commands/agents/avatar/default/index.js +61 -0
  20. package/dist/commands/agents/avatar/default/set.d.ts +24 -0
  21. package/dist/commands/agents/avatar/default/set.js +120 -0
  22. package/dist/commands/agents/avatar/library/delete.d.ts +20 -0
  23. package/dist/commands/agents/avatar/library/delete.js +47 -0
  24. package/dist/commands/agents/avatar/library/index.d.ts +16 -0
  25. package/dist/commands/agents/avatar/library/index.js +56 -0
  26. package/dist/commands/agents/avatar/presets.d.ts +19 -0
  27. package/dist/commands/agents/avatar/presets.js +56 -0
  28. package/dist/commands/agents/avatar/upload.js +7 -1
  29. package/dist/commands/agents/categories/create.d.ts +14 -0
  30. package/dist/commands/agents/categories/create.js +46 -0
  31. package/dist/commands/agents/categories/delete.d.ts +13 -0
  32. package/dist/commands/agents/categories/delete.js +41 -0
  33. package/dist/commands/agents/categories/index.d.ts +36 -0
  34. package/dist/commands/agents/categories/index.js +135 -0
  35. package/dist/commands/agents/categories/update.d.ts +22 -0
  36. package/dist/commands/agents/categories/update.js +59 -0
  37. package/dist/commands/agents/chat.d.ts +21 -0
  38. package/dist/commands/agents/chat.js +94 -7
  39. package/dist/commands/agents/create.d.ts +10 -0
  40. package/dist/commands/agents/create.js +64 -3
  41. package/dist/commands/agents/ensure-default.d.ts +27 -0
  42. package/dist/commands/agents/ensure-default.js +65 -0
  43. package/dist/commands/agents/list.d.ts +15 -0
  44. package/dist/commands/agents/list.js +31 -1
  45. package/dist/commands/agents/mute.d.ts +16 -0
  46. package/dist/commands/agents/mute.js +38 -0
  47. package/dist/commands/agents/pin.d.ts +16 -0
  48. package/dist/commands/agents/pin.js +38 -0
  49. package/dist/commands/agents/scene-background/upload.d.ts +30 -0
  50. package/dist/commands/agents/scene-background/upload.js +97 -0
  51. package/dist/commands/agents/show.js +13 -0
  52. package/dist/commands/agents/tools/auth.d.ts +19 -0
  53. package/dist/commands/agents/tools/auth.js +41 -0
  54. package/dist/commands/agents/tools/calls.d.ts +36 -0
  55. package/dist/commands/agents/tools/calls.js +117 -0
  56. package/dist/commands/agents/tools/index.d.ts +20 -0
  57. package/dist/commands/agents/tools/index.js +77 -0
  58. package/dist/commands/agents/unmute.d.ts +16 -0
  59. package/dist/commands/agents/unmute.js +38 -0
  60. package/dist/commands/agents/unpin.d.ts +16 -0
  61. package/dist/commands/agents/unpin.js +38 -0
  62. package/dist/commands/agents/update.d.ts +12 -0
  63. package/dist/commands/agents/update.js +74 -3
  64. package/dist/commands/code/{oversky-agent.d.ts → skrr-agent.d.ts} +3 -3
  65. package/dist/commands/code/{oversky-agent.js → skrr-agent.js} +11 -8
  66. package/dist/commands/convos/messages.d.ts +13 -0
  67. package/dist/commands/convos/messages.js +40 -16
  68. package/dist/commands/daemon/index.js +8 -1
  69. package/dist/commands/daemon/logs.d.ts +26 -0
  70. package/dist/commands/daemon/logs.js +56 -0
  71. package/dist/commands/daemon/uninstall.js +1 -1
  72. package/dist/commands/followups/act.d.ts +22 -0
  73. package/dist/commands/followups/act.js +103 -0
  74. package/dist/commands/followups/cancel.d.ts +20 -0
  75. package/dist/commands/followups/cancel.js +50 -0
  76. package/dist/commands/followups/checkin.d.ts +27 -0
  77. package/dist/commands/followups/checkin.js +107 -0
  78. package/dist/commands/followups/list.d.ts +24 -0
  79. package/dist/commands/followups/list.js +90 -0
  80. package/dist/commands/followups/observability.d.ts +23 -0
  81. package/dist/commands/followups/observability.js +114 -0
  82. package/dist/commands/followups/remind.d.ts +26 -0
  83. package/dist/commands/followups/remind.js +106 -0
  84. package/dist/commands/followups/reschedule.d.ts +15 -0
  85. package/dist/commands/followups/reschedule.js +48 -0
  86. package/dist/commands/followups/resolve.d.ts +23 -0
  87. package/dist/commands/followups/resolve.js +54 -0
  88. package/dist/commands/followups/show.d.ts +12 -0
  89. package/dist/commands/followups/show.js +46 -0
  90. package/dist/commands/followups/watch.d.ts +51 -0
  91. package/dist/commands/followups/watch.js +211 -0
  92. package/dist/commands/goals/labels/add.js +19 -2
  93. package/dist/commands/goals/labels/remove.js +22 -2
  94. package/dist/commands/harnesses/forget.js +28 -0
  95. package/dist/commands/harnesses/install.d.ts +41 -0
  96. package/dist/commands/harnesses/install.js +165 -0
  97. package/dist/commands/harnesses/installers.d.ts +45 -0
  98. package/dist/commands/harnesses/installers.js +155 -0
  99. package/dist/commands/harnesses/list.d.ts +82 -1
  100. package/dist/commands/harnesses/list.js +104 -12
  101. package/dist/commands/harnesses/models.js +10 -1
  102. package/dist/commands/harnesses/show.d.ts +15 -0
  103. package/dist/commands/harnesses/show.js +44 -3
  104. package/dist/commands/harnesses/update.js +1 -1
  105. package/dist/commands/harnesses/usage.d.ts +25 -0
  106. package/dist/commands/harnesses/usage.js +24 -2
  107. package/dist/commands/instructions/status.js +13 -1
  108. package/dist/commands/labels/list.d.ts +24 -1
  109. package/dist/commands/labels/list.js +62 -19
  110. package/dist/commands/machines/dedicated/catalog.js +4 -15
  111. package/dist/commands/machines/dedicated/create.d.ts +8 -0
  112. package/dist/commands/machines/dedicated/create.js +58 -1
  113. package/dist/commands/machines/dedicated/destroy.js +18 -4
  114. package/dist/commands/machines/dedicated/list.js +9 -6
  115. package/dist/commands/machines/hosted/list.js +12 -0
  116. package/dist/commands/machines/list.js +11 -0
  117. package/dist/commands/machines/show.d.ts +1 -0
  118. package/dist/commands/machines/show.js +40 -11
  119. package/dist/commands/memory/governance/index.d.ts +21 -0
  120. package/dist/commands/memory/governance/index.js +64 -0
  121. package/dist/commands/memory/governance/set.d.ts +24 -0
  122. package/dist/commands/memory/governance/set.js +95 -0
  123. package/dist/commands/memory/provenance.d.ts +18 -0
  124. package/dist/commands/memory/provenance.js +66 -0
  125. package/dist/commands/profiles/list.d.ts +23 -0
  126. package/dist/commands/profiles/list.js +96 -0
  127. package/dist/commands/search/skills.d.ts +11 -1
  128. package/dist/commands/search/skills.js +26 -8
  129. package/dist/commands/skills/details.d.ts +2 -0
  130. package/dist/commands/skills/details.js +24 -1
  131. package/dist/commands/skills/import-as-actions.d.ts +32 -0
  132. package/dist/commands/skills/import-as-actions.js +175 -0
  133. package/dist/commands/skills/install.d.ts +2 -0
  134. package/dist/commands/skills/install.js +24 -1
  135. package/dist/commands/skills/invocable.js +6 -2
  136. package/dist/commands/skills/local.d.ts +40 -0
  137. package/dist/commands/skills/local.js +160 -0
  138. package/dist/commands/skills/search.d.ts +11 -1
  139. package/dist/commands/skills/search.js +29 -8
  140. package/dist/commands/spaces/actions/add.js +23 -5
  141. package/dist/commands/spaces/actions/available.js +3 -0
  142. package/dist/commands/spaces/actions/list.d.ts +5 -0
  143. package/dist/commands/spaces/actions/list.js +49 -3
  144. package/dist/commands/spaces/actions/run.d.ts +28 -0
  145. package/dist/commands/spaces/actions/run.js +146 -0
  146. package/dist/commands/spaces/actions/update.js +27 -5
  147. package/dist/commands/spaces/create.d.ts +3 -0
  148. package/dist/commands/spaces/create.js +32 -2
  149. package/dist/commands/spaces/label-summaries.d.ts +27 -0
  150. package/dist/commands/spaces/label-summaries.js +64 -0
  151. package/dist/commands/spaces/labels/add.js +19 -2
  152. package/dist/commands/spaces/labels/remove.js +22 -2
  153. package/dist/commands/spaces/show.js +2 -0
  154. package/dist/commands/spaces/task-rollups.d.ts +5 -0
  155. package/dist/commands/spaces/task-rollups.js +15 -4
  156. package/dist/commands/spaces/update.d.ts +5 -0
  157. package/dist/commands/spaces/update.js +41 -4
  158. package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +11 -0
  159. package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +105 -0
  160. package/dist/commands/tasks/actions/attach.js +32 -7
  161. package/dist/commands/tasks/complete.d.ts +1 -0
  162. package/dist/commands/tasks/complete.js +21 -1
  163. package/dist/commands/tasks/create.d.ts +3 -0
  164. package/dist/commands/tasks/create.js +34 -2
  165. package/dist/commands/tasks/events/append.js +29 -6
  166. package/dist/commands/tasks/expectations/assess.d.ts +12 -0
  167. package/dist/commands/tasks/expectations/assess.js +123 -14
  168. package/dist/commands/tasks/expectations.js +95 -17
  169. package/dist/commands/tasks/follow-up.js +2 -2
  170. package/dist/commands/tasks/labels/attach.js +20 -3
  171. package/dist/commands/tasks/labels/detach.js +21 -3
  172. package/dist/commands/tasks/lifecycle/attach.d.ts +14 -0
  173. package/dist/commands/tasks/lifecycle/attach.js +47 -0
  174. package/dist/commands/tasks/lifecycle/definitions.d.ts +11 -0
  175. package/dist/commands/tasks/lifecycle/definitions.js +59 -0
  176. package/dist/commands/tasks/lifecycle/detach.d.ts +19 -0
  177. package/dist/commands/tasks/lifecycle/detach.js +72 -0
  178. package/dist/commands/tasks/lifecycle/history.d.ts +13 -0
  179. package/dist/commands/tasks/lifecycle/history.js +38 -0
  180. package/dist/commands/tasks/lifecycle/migrate.d.ts +14 -0
  181. package/dist/commands/tasks/lifecycle/migrate.js +68 -0
  182. package/dist/commands/tasks/lifecycle/reconcile.d.ts +11 -0
  183. package/dist/commands/tasks/lifecycle/reconcile.js +27 -0
  184. package/dist/commands/tasks/lifecycle/reopen.d.ts +15 -0
  185. package/dist/commands/tasks/lifecycle/reopen.js +71 -0
  186. package/dist/commands/tasks/lifecycle/show.d.ts +11 -0
  187. package/dist/commands/tasks/lifecycle/show.js +27 -0
  188. package/dist/commands/tasks/lifecycle/start.d.ts +12 -0
  189. package/dist/commands/tasks/lifecycle/start.js +30 -0
  190. package/dist/commands/tasks/lifecycle/transition.d.ts +15 -0
  191. package/dist/commands/tasks/lifecycle/transition.js +109 -0
  192. package/dist/commands/tasks/list.js +16 -9
  193. package/dist/commands/tasks/move.d.ts +1 -0
  194. package/dist/commands/tasks/move.js +29 -0
  195. package/dist/commands/tasks/result/submit.js +11 -1
  196. package/dist/commands/tasks/review-queue.d.ts +44 -0
  197. package/dist/commands/tasks/review-queue.js +314 -0
  198. package/dist/commands/tasks/show.d.ts +11 -0
  199. package/dist/commands/tasks/show.js +139 -4
  200. package/dist/commands/tasks/trust.js +7 -2
  201. package/dist/commands/tasks/update.d.ts +1 -0
  202. package/dist/commands/tasks/update.js +83 -0
  203. package/dist/commands/tasks/updates/add.js +1 -1
  204. package/dist/commands/token/list.d.ts +22 -0
  205. package/dist/commands/token/list.js +68 -0
  206. package/dist/commands/token/revoke.d.ts +23 -0
  207. package/dist/commands/token/revoke.js +53 -0
  208. package/dist/lib/agent-actions.d.ts +92 -11
  209. package/dist/lib/agent-actions.js +171 -25
  210. package/dist/lib/agent-config.d.ts +11 -0
  211. package/dist/lib/agent-config.js +85 -3
  212. package/dist/lib/agent-pin-mute.d.ts +29 -0
  213. package/dist/lib/agent-pin-mute.js +30 -0
  214. package/dist/lib/agent-visual-refs.d.ts +33 -0
  215. package/dist/lib/agent-visual-refs.js +267 -0
  216. package/dist/lib/agentic-stream.d.ts +6 -0
  217. package/dist/lib/agentic-stream.js +34 -3
  218. package/dist/lib/assignee-resolver.d.ts +1 -1
  219. package/dist/lib/assignee-resolver.js +8 -0
  220. package/dist/lib/bulk-task-targets.d.ts +12 -0
  221. package/dist/lib/bulk-task-targets.js +34 -1
  222. package/dist/lib/cli-installers.d.ts +130 -0
  223. package/dist/lib/cli-installers.js +145 -0
  224. package/dist/lib/command-miss.js +55 -7
  225. package/dist/lib/dedicated-lease-command.d.ts +13 -0
  226. package/dist/lib/dedicated-lease-command.js +22 -1
  227. package/dist/lib/dedicated-machines.d.ts +95 -1
  228. package/dist/lib/dedicated-machines.js +236 -2
  229. package/dist/lib/failed-lookup.d.ts +3 -0
  230. package/dist/lib/failed-lookup.js +40 -0
  231. package/dist/lib/first-party-harness-agent.js +16 -2
  232. package/dist/lib/first-party-harness-doctor.d.ts +15 -0
  233. package/dist/lib/first-party-harness-doctor.js +126 -27
  234. package/dist/lib/followups.d.ts +115 -0
  235. package/dist/lib/followups.js +127 -0
  236. package/dist/lib/harnesses.d.ts +8 -0
  237. package/dist/lib/instruction-input.d.ts +19 -1
  238. package/dist/lib/instruction-input.js +52 -1
  239. package/dist/lib/label-ref.d.ts +95 -0
  240. package/dist/lib/label-ref.js +163 -0
  241. package/dist/lib/label-scope.d.ts +17 -2
  242. package/dist/lib/label-scope.js +27 -7
  243. package/dist/lib/local-skills.d.ts +98 -0
  244. package/dist/lib/local-skills.js +195 -0
  245. package/dist/lib/machines.d.ts +10 -10
  246. package/dist/lib/machines.js +23 -1
  247. package/dist/lib/search-query.d.ts +19 -0
  248. package/dist/lib/search-query.js +35 -0
  249. package/dist/lib/space-custom-actions.d.ts +72 -0
  250. package/dist/lib/space-custom-actions.js +117 -0
  251. package/dist/lib/space-resolver.d.ts +1 -21
  252. package/dist/lib/space-resolver.js +19 -10
  253. package/dist/lib/task-closure.d.ts +33 -0
  254. package/dist/lib/task-closure.js +104 -0
  255. package/dist/lib/task-lifecycle-output.d.ts +14 -0
  256. package/dist/lib/task-lifecycle-output.js +209 -0
  257. package/dist/lib/task-ref-resolver.d.ts +1 -17
  258. package/dist/lib/task-ref-resolver.js +18 -8
  259. package/dist/lib/tasks.d.ts +3 -0
  260. package/dist/lib/tasks.js +40 -3
  261. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +4 -0
  262. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +4 -0
  263. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  264. package/dist/node_modules/@skrr-ai/data-provider/index.js +5559 -4897
  265. package/oclif.manifest.json +33890 -28690
  266. package/package.json +24 -6
@@ -5,6 +5,7 @@ const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const api_fetch_1 = require("../../lib/api-fetch");
6
6
  const session_task_endpoints_1 = require("../../lib/session-task-endpoints");
7
7
  const base_command_1 = require("../../base-command");
8
+ const task_closure_1 = require("../../lib/task-closure");
8
9
  const web_url_1 = require("../../lib/web-url");
9
10
  const task_resolver_1 = require("../../lib/task-resolver");
10
11
  const projects_1 = require("../../lib/projects");
@@ -52,6 +53,9 @@ class TasksMove extends base_command_1.BaseCommand {
52
53
  description: 'Who can resolve the exceptional hold',
53
54
  options: ['human', 'agent', 'system', 'external'],
54
55
  }),
56
+ force: core_1.Flags.boolean({
57
+ description: "Close past an owner-declared required Review as a non-owner; the override is recorded on the task's resolution",
58
+ }),
55
59
  };
56
60
  async run() {
57
61
  this.requireAuth();
@@ -100,6 +104,7 @@ class TasksMove extends base_command_1.BaseCommand {
100
104
  status: flags.status,
101
105
  ...(flags.reason ? { reason: flags.reason } : {}),
102
106
  ...(flags['resolution-actor'] ? { resolutionActor: flags['resolution-actor'] } : {}),
107
+ ...(flags.force ? { force: true } : {}),
103
108
  },
104
109
  }));
105
110
  updated = res.task;
@@ -110,6 +115,7 @@ class TasksMove extends base_command_1.BaseCommand {
110
115
  status: flags.status,
111
116
  reason: flags.reason,
112
117
  resolutionActor: flags['resolution-actor'],
118
+ force: flags.force === true ? true : undefined,
113
119
  });
114
120
  }
115
121
  }
@@ -138,6 +144,29 @@ class TasksMove extends base_command_1.BaseCommand {
138
144
  destinations.push(await this.describeProjectDestination(projectId, t));
139
145
  }
140
146
  this.log(`Moved task ${t.id ?? t._id ?? taskIdentity.id}${ref ? ` (${ref})` : ''} → ${destinations.join(', ')}`);
147
+ /*
148
+ * Closing is the actor's call — the server does not refuse outstanding
149
+ * work, it records it on `resolution.closure`. If the close just written
150
+ * left things unsettled, say so here so the output and the durable record
151
+ * tell the same story rather than letting "done" launder open items.
152
+ */
153
+ // Read through the SHARED vocabulary. This carried a local structural cast
154
+ // while `overrode` was missing from `Task['resolution']['closure']` — which
155
+ // is exactly how one surface comes to know a field the type does not. `t` is
156
+ // the loosely-typed receipt, so the narrowing cast stays; what matters is
157
+ // that the shape it names is the one data-provider owns.
158
+ const resolutionClosure = t.resolution?.closure;
159
+ /*
160
+ * Through the shared renderer. This hand-rolled the rendering and pushed
161
+ * blocker CODES at a human — `Closed over TASK_RESULT_REQUIRED`, which is a
162
+ * wire identifier and, read plainly, the opposite of what just happened. The
163
+ * worst instance was the one this batch cares most about: a Task closed over
164
+ * a reviewer's objection printed `TASK_RESULT_CHANGES_REQUESTED`, rendering
165
+ * "somebody looked and objected" as an identifier.
166
+ */
167
+ for (const sentence of (0, task_closure_1.closureSnapshotLines)(resolutionClosure)) {
168
+ this.log(` ${sentence}`);
169
+ }
141
170
  }
142
171
  /**
143
172
  * Name the project the receipt lands in, resolving its title from the task's
@@ -7,6 +7,7 @@ const outbox_1 = require("../../../lib/outbox");
7
7
  const task_resolver_1 = require("../../../lib/task-resolver");
8
8
  const web_url_1 = require("../../../lib/web-url");
9
9
  const api_fetch_1 = require("../../../lib/api-fetch");
10
+ const task_closure_1 = require("../../../lib/task-closure");
10
11
  const session_task_endpoints_1 = require("../../../lib/session-task-endpoints");
11
12
  function parseJson(value, label) {
12
13
  if (!value)
@@ -126,7 +127,16 @@ class TasksResultSubmit extends base_command_1.BaseCommand {
126
127
  const url = (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, { id: task.id });
127
128
  if (flags.json)
128
129
  return this.log(JSON.stringify({ ...result, url }, null, 2));
129
- this.log(`Submitted Result v${result.result.version} for ${task.id}; it is ready for review.`);
130
+ // Say what came back, never what we hope came back.
131
+ //
132
+ // This line used to read "...; it is ready for review." unconditionally,
133
+ // which was false for every Task with an unassessed Expectation — and the
134
+ // managed instructions told the agent to read the status the call returns,
135
+ // which the call did not carry. Submitting a Result is not closing a Task;
136
+ // the response now reports where it stands and this prints exactly that.
137
+ this.log(`Submitted Result v${result.result.version} for ${task.id}.`);
138
+ for (const line of (0, task_closure_1.closureReport)(result.closure))
139
+ this.log(line);
130
140
  if (url)
131
141
  this.log(`Task: ${url}`);
132
142
  }
@@ -0,0 +1,44 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * Everything in one Space that is waiting on a judgement, in one pass.
4
+ *
5
+ * WHY THIS EXISTS
6
+ * ---------------
7
+ * An agent fans out. One session routinely produces nine Tasks carrying twenty
8
+ * or more Expectations, and every surface for settling them was built for one
9
+ * Task at a time — so the cost of CLOSING the work grew linearly with how well
10
+ * the work was DECOMPOSED, which punishes exactly the decomposition the product
11
+ * wants. Finding what was owed meant knowing that `tasks expectations` exists
12
+ * and running it per Task, having first worked out which Tasks to run it on.
13
+ *
14
+ * This is a read. It changes nothing, it names every outstanding judgement in
15
+ * the Space with the evidence already bound to it, and it prints the exact
16
+ * command that settles each one — so a reviewer can work down a list instead of
17
+ * reconstructing it.
18
+ */
19
+ export default class TasksReviewQueue extends BaseCommand {
20
+ static description: string;
21
+ static examples: string[];
22
+ static flags: {
23
+ space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ actionable: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
25
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
26
+ 'include-closed': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
27
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
28
+ };
29
+ run(): Promise<void>;
30
+ /**
31
+ * An empty queue must not be how you learn a Space id is wrong.
32
+ *
33
+ * A UUID-shaped ref is accepted without a lookup (`base-command` short-circuits
34
+ * on the SHAPE, which is a cheap and correct optimisation nearly everywhere),
35
+ * and the list route deliberately never 404s — an unknown Space falls back to
36
+ * the ACL enumeration and returns an honest empty page. Those two reasonable
37
+ * decisions compose into "Nothing is awaiting a judgement", exit 0, for a
38
+ * Space that does not exist. A typo read as done.
39
+ *
40
+ * So the existence check is paid for ONLY on the path that is about to make
41
+ * the completeness claim — never on the path that found work.
42
+ */
43
+ private assertSpaceExists;
44
+ }
@@ -0,0 +1,314 @@
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
+ const task_closure_1 = require("../../lib/task-closure");
7
+ const web_url_1 = require("../../lib/web-url");
8
+ /**
9
+ * Everything in one Space that is waiting on a judgement, in one pass.
10
+ *
11
+ * WHY THIS EXISTS
12
+ * ---------------
13
+ * An agent fans out. One session routinely produces nine Tasks carrying twenty
14
+ * or more Expectations, and every surface for settling them was built for one
15
+ * Task at a time — so the cost of CLOSING the work grew linearly with how well
16
+ * the work was DECOMPOSED, which punishes exactly the decomposition the product
17
+ * wants. Finding what was owed meant knowing that `tasks expectations` exists
18
+ * and running it per Task, having first worked out which Tasks to run it on.
19
+ *
20
+ * This is a read. It changes nothing, it names every outstanding judgement in
21
+ * the Space with the evidence already bound to it, and it prints the exact
22
+ * command that settles each one — so a reviewer can work down a list instead of
23
+ * reconstructing it.
24
+ */
25
+ class TasksReviewQueue extends base_command_1.BaseCommand {
26
+ static description = 'Every Expectation in a Space still awaiting a judgement, with its evidence and the command that settles it';
27
+ static examples = [
28
+ '<%= config.bin %> tasks review-queue --space <space-id>',
29
+ '<%= config.bin %> tasks review-queue --space <space-id> --json',
30
+ '<%= config.bin %> tasks review-queue --space <space-id> --actionable',
31
+ ];
32
+ static flags = {
33
+ space: core_1.Flags.string({ description: 'Space id', required: true }),
34
+ actionable: core_1.Flags.boolean({
35
+ description: 'Only Tasks where a Result is already in — the ones a reviewer can act on',
36
+ }),
37
+ limit: core_1.Flags.integer({ description: 'Maximum Tasks to inspect (default 100)', default: 100 }),
38
+ 'include-closed': core_1.Flags.boolean({
39
+ description: 'Also list Tasks already closed — for auditing what was closed over',
40
+ }),
41
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
42
+ };
43
+ async run() {
44
+ this.requireAuth();
45
+ const { flags } = await this.parse(TasksReviewQueue);
46
+ /**
47
+ * `response.data`, read from the TYPE rather than guessed.
48
+ *
49
+ * The first version of this read `response.tasks`, which does not exist —
50
+ * and the failure was silent in the worst possible direction: an empty array
51
+ * printed "Nothing is awaiting a judgement" for a Space with twenty-three
52
+ * unassessed Expectations. A reviewer would have believed they were done.
53
+ *
54
+ * `COMMAND_INDEX.md` warns about exactly this ("read the wrong key and you
55
+ * get an empty result rather than an error, which looks exactly like 'no
56
+ * rows matched'"). So the shape is taken from `TaskListResponse` and a
57
+ * missing envelope is an ERROR, never an empty queue: this command's whole
58
+ * value is telling someone there is nothing left, and it may only say that
59
+ * when it actually looked.
60
+ */
61
+ /*
62
+ * Follow the cursor — a truncated list is the same silent false negative
63
+ * as a misread envelope, one page later. This command's whole value is
64
+ * "there is nothing left," and a tail it never saw breaks that claim.
65
+ * `--limit` caps how many Tasks get inspected, not how many pages get read.
66
+ */
67
+ if (flags.limit < 1) {
68
+ // Inspecting zero Tasks and then saying "nothing is owed" is the exact
69
+ // unlooked-for empty answer this command refuses to give.
70
+ this.error('--limit must be at least 1.', { exit: 1 });
71
+ }
72
+ /*
73
+ * oclif's `required: true` asserts the flag was SUPPLIED, not that it says
74
+ * anything. `--space ""` — an unset shell variable, which is how it happens
75
+ * — satisfied it, and the empty string was then dropped from the query
76
+ * string as falsy, so the command silently widened from one Space to every
77
+ * Space the caller can see and reported that as the answer.
78
+ */
79
+ if (!flags.space.trim()) {
80
+ this.error('--space needs a Space id; it was given an empty value.', { exit: 1 });
81
+ }
82
+ const tasks = [];
83
+ /*
84
+ * Whether the scan actually reached the end.
85
+ *
86
+ * The loop already followed the cursor, and then stopped at `--limit` with
87
+ * `has_more` still true and threw that fact away — so a Space with 95 owed
88
+ * Expectations reported on the first 11 and printed the same sentence it
89
+ * prints for a Space that owes nothing. The comment above states the
90
+ * principle this had to satisfy; nothing recorded whether it had.
91
+ */
92
+ let truncated = false;
93
+ try {
94
+ let cursor;
95
+ for (;;) {
96
+ const response = await data_provider_1.dataService.listTasks({
97
+ spaceId: flags.space,
98
+ limit: Math.min(100, flags.limit - tasks.length),
99
+ ...(cursor ? { cursor } : {}),
100
+ });
101
+ if (!response || !Array.isArray(response.data)) {
102
+ this.error('The task list came back in a shape this command does not recognise, so it cannot ' +
103
+ 'say whether anything is owed. Refusing to report an empty queue.', { exit: 1 });
104
+ }
105
+ tasks.push(...response.data);
106
+ if (!response.has_more || !response.next_cursor)
107
+ break;
108
+ if (tasks.length >= flags.limit) {
109
+ truncated = true;
110
+ break;
111
+ }
112
+ cursor = response.next_cursor;
113
+ }
114
+ }
115
+ catch (error) {
116
+ this.handleApiError(error);
117
+ return;
118
+ }
119
+ /**
120
+ * Acceptance is read per Task, and a Task whose acceptance cannot be read is
121
+ * REPORTED rather than dropped. A queue that silently omitted a row would be
122
+ * worse than no queue: the reviewer would believe they had seen everything.
123
+ */
124
+ const rows = [];
125
+ /*
126
+ * A finished Task is not a worklist item.
127
+ *
128
+ * Closing is the closer's call now, so a Task can reach `done` over
129
+ * Expectations nobody judged — and those rows stayed in the queue forever,
130
+ * captioned in the present tense ("settling these will not close it") about
131
+ * something already closed. Every forced close permanently added noise to
132
+ * the list a reviewer is supposed to work down. `--include-closed` keeps the
133
+ * old view for anyone auditing what was closed over.
134
+ */
135
+ const CLOSED_STATUS_TYPES = new Set(['completed', 'cancelled']);
136
+ const candidates = tasks.filter((task) => flags['include-closed'] || !CLOSED_STATUS_TYPES.has(String(task.statusType ?? '')));
137
+ const skippedClosed = tasks.length - candidates.length;
138
+ /*
139
+ * Acceptance is one request per Task and there is no batch endpoint, so the
140
+ * serial loop this replaces took 61 seconds on 100 Tasks and printed nothing
141
+ * at all until it finished. Bounded rather than `Promise.all`: 100
142
+ * simultaneous authorized reads hit the same cascade the `/cards` endpoint
143
+ * exists to avoid. Results are written by INDEX so output order stays the
144
+ * list's order regardless of which request returns first.
145
+ */
146
+ const ACCEPTANCE_CONCURRENCY = 6;
147
+ const settled = new Array(candidates.length).fill(null);
148
+ let next = 0;
149
+ const worker = async () => {
150
+ for (;;) {
151
+ const index = next;
152
+ next += 1;
153
+ if (index >= candidates.length)
154
+ return;
155
+ const task = candidates[index];
156
+ const taskId = String(task.id ?? task._id ?? '');
157
+ if (!taskId)
158
+ continue;
159
+ const base = {
160
+ taskId,
161
+ identifier: String(task.identifier ?? taskId),
162
+ title: String(task.title ?? '(untitled)'),
163
+ status: String(task.status ?? '-'),
164
+ hasResult: Boolean(task.currentResultId),
165
+ };
166
+ try {
167
+ const acceptance = await data_provider_1.dataService.getTaskAcceptance(taskId);
168
+ const awaiting = acceptance.expectations.filter((e) => e.gating && !e.met);
169
+ if (awaiting.length > 0)
170
+ settled[index] = { ...base, awaiting };
171
+ }
172
+ catch (error) {
173
+ settled[index] = {
174
+ ...base,
175
+ awaiting: [],
176
+ error: error?.message || 'unreadable',
177
+ };
178
+ }
179
+ }
180
+ };
181
+ await Promise.all(Array.from({ length: Math.min(ACCEPTANCE_CONCURRENCY, candidates.length) }, worker));
182
+ rows.push(...settled.filter((row) => row !== null));
183
+ const visible = flags.actionable ? rows.filter((row) => row.hasResult || row.error) : rows;
184
+ if (flags.json) {
185
+ this.log(JSON.stringify({
186
+ space: flags.space,
187
+ inspected: candidates.length,
188
+ truncated,
189
+ ...(skippedClosed > 0 ? { skippedClosed } : {}),
190
+ owedTasks: rows.length,
191
+ tasks: visible,
192
+ }, null, 2));
193
+ return;
194
+ }
195
+ /*
196
+ * "Nothing is owed" may only be said by a scan that reached the end.
197
+ *
198
+ * One sentence used to cover four different states — a clean queue, a
199
+ * truncated scan, a filter that emptied the list, and a Space that does not
200
+ * exist — and in three of them it was false. Each now says its own thing,
201
+ * and the two that cannot support the claim refuse to make it, in the same
202
+ * shape as the misread-envelope guard above.
203
+ */
204
+ if (truncated && rows.length === 0) {
205
+ this.error(`Inspected only the first ${candidates.length} Task(s) of a longer list in ${flags.space}, ` +
206
+ 'so it cannot say whether anything is owed. Refusing to report an empty queue. ' +
207
+ 'Re-run with a larger --limit.', { exit: 1 });
208
+ }
209
+ if (rows.length === 0) {
210
+ await this.assertSpaceExists(flags.space);
211
+ this.log(`Nothing in ${flags.space} is awaiting a judgement.`);
212
+ if (skippedClosed > 0) {
213
+ this.log(` (${skippedClosed} closed Task(s) skipped — see them with --include-closed.)`);
214
+ }
215
+ return;
216
+ }
217
+ if (visible.length === 0) {
218
+ this.log(`${rows.length} Task(s) in ${flags.space} owe judgements, but none has a Result yet — ` +
219
+ 're-run without --actionable to see them.');
220
+ return;
221
+ }
222
+ let total = 0;
223
+ for (const row of visible) {
224
+ this.log('');
225
+ this.log(`${row.identifier} ${row.title}`);
226
+ if (row.error) {
227
+ this.log(` could not read its Expectations: ${row.error}`);
228
+ continue;
229
+ }
230
+ /*
231
+ * State the fact, not a gate. This read "no Result submitted yet — settling
232
+ * these will not close it", which implied that a Result is what stands
233
+ * between these judgements and a close. Since `56a6ded703` it is not: a
234
+ * Task closes without one and the absence is recorded on
235
+ * `resolution.closure`. What a reviewer needs to know is only that there is
236
+ * no Result to judge the work against yet.
237
+ */
238
+ if (!row.hasResult) {
239
+ this.log(' no Result submitted yet — nothing to judge the work against');
240
+ }
241
+ for (const expectation of row.awaiting) {
242
+ total += 1;
243
+ this.log(` ${expectation.id} ${expectation.sentence || expectation.text || ''}`);
244
+ /*
245
+ * The judgement itself, not just the KIND of judge.
246
+ *
247
+ * `[last judged by person]` named no person, no decision, no date and no
248
+ * reason — so a reviewer working down this list could see that someone
249
+ * had looked and not what they concluded, which is the one thing they
250
+ * need before looking again. The acceptance projection carries all of it
251
+ * now; this is where it was being dropped.
252
+ */
253
+ if (expectation.assessedByKind) {
254
+ const decision = expectation.decision || 'judged';
255
+ const when = expectation.assessedAt
256
+ ? ` on ${String(expectation.assessedAt).slice(0, 10)}`
257
+ : '';
258
+ const why = expectation.reason ? `: ${expectation.reason}` : '';
259
+ this.log(` ${decision} by ${(0, task_closure_1.describeAssessor)(expectation.assessedByKind)}${when}${why}`);
260
+ }
261
+ if (expectation.evidenceLevel) {
262
+ this.log(` evidence: ${expectation.evidenceLevel}${expectation.requiredEvidence ? ` (asked for ${expectation.requiredEvidence})` : ''}`);
263
+ }
264
+ }
265
+ const url = (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, { id: row.taskId });
266
+ if (url)
267
+ this.log(` ${url}`);
268
+ }
269
+ this.log('');
270
+ this.log(`${total} Expectation(s) awaiting a judgement across ${visible.length} Task(s).`);
271
+ if (truncated) {
272
+ this.log(`Only the first ${candidates.length} Task(s) were inspected and more remain — ` +
273
+ 're-run with a larger --limit to see the rest.');
274
+ }
275
+ if (skippedClosed > 0) {
276
+ this.log(`${skippedClosed} closed Task(s) skipped — see them with --include-closed.`);
277
+ }
278
+ this.log('');
279
+ this.log('Settle one: skrr tasks expectations assess <task-id> <expectation-id> \\');
280
+ this.log(' --decision met --reason "..."');
281
+ this.log('Settle a Task: skrr tasks expectations assess <task-id> --all \\');
282
+ this.log(' --decision met --reason "..."');
283
+ }
284
+ /**
285
+ * An empty queue must not be how you learn a Space id is wrong.
286
+ *
287
+ * A UUID-shaped ref is accepted without a lookup (`base-command` short-circuits
288
+ * on the SHAPE, which is a cheap and correct optimisation nearly everywhere),
289
+ * and the list route deliberately never 404s — an unknown Space falls back to
290
+ * the ACL enumeration and returns an honest empty page. Those two reasonable
291
+ * decisions compose into "Nothing is awaiting a judgement", exit 0, for a
292
+ * Space that does not exist. A typo read as done.
293
+ *
294
+ * So the existence check is paid for ONLY on the path that is about to make
295
+ * the completeness claim — never on the path that found work.
296
+ */
297
+ async assertSpaceExists(spaceId) {
298
+ try {
299
+ await data_provider_1.dataService.getSpace(spaceId);
300
+ }
301
+ catch (error) {
302
+ // The status rides the error itself here, the way `base-command` reads it
303
+ // (`e.status === 404`) — not on a nested `response`.
304
+ const status = error?.status;
305
+ if (status === 404 || status === 403) {
306
+ this.error(`No Space ${spaceId} is visible to you, so there is nothing to report on. ` +
307
+ 'Check the id with `skrr spaces list`.', { exit: 2 });
308
+ }
309
+ // Any other failure is about this read, not about the Space. Let the
310
+ // empty answer stand rather than turning a blip into a false "not found".
311
+ }
312
+ }
313
+ }
314
+ exports.default = TasksReviewQueue;
@@ -1,4 +1,15 @@
1
1
  import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * Where to look next — as COMMANDS, not as facts about the task.
4
+ *
5
+ * These used to print as `What the agent produced: skrr tasks output <ref>`,
6
+ * in the same `Label: value` grammar as every line above them, so the line read
7
+ * as a statement of what the agent had produced. It also printed on tasks no
8
+ * agent had ever run, asserting output that did not exist (OSK-9669). They are
9
+ * now a visibly separate list, and only once a run, a conversation or a Result
10
+ * exists for them to show.
11
+ */
12
+ export declare function taskPointerLines(t: Record<string, unknown>, ref: string, bin?: string): string[];
2
13
  /**
3
14
  * The failure rows of `tasks show`, when there are any. (S3 dogfood finding)
4
15
  *
@@ -1,14 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.taskPointerLines = taskPointerLines;
3
4
  exports.taskFailureLines = taskFailureLines;
4
5
  const core_1 = require("@oclif/core");
5
6
  const data_provider_1 = require("@skrr-ai/data-provider");
6
7
  const api_fetch_1 = require("../../lib/api-fetch");
7
8
  const session_task_endpoints_1 = require("../../lib/session-task-endpoints");
8
9
  const base_command_1 = require("../../base-command");
10
+ const task_closure_1 = require("../../lib/task-closure");
9
11
  const task_resolver_1 = require("../../lib/task-resolver");
10
12
  const web_url_1 = require("../../lib/web-url");
11
13
  const html_text_1 = require("../../lib/html-text");
14
+ /**
15
+ * Where to look next — as COMMANDS, not as facts about the task.
16
+ *
17
+ * These used to print as `What the agent produced: skrr tasks output <ref>`,
18
+ * in the same `Label: value` grammar as every line above them, so the line read
19
+ * as a statement of what the agent had produced. It also printed on tasks no
20
+ * agent had ever run, asserting output that did not exist (OSK-9669). They are
21
+ * now a visibly separate list, and only once a run, a conversation or a Result
22
+ * exists for them to show.
23
+ */
24
+ function taskPointerLines(t, ref, bin = 'skrr') {
25
+ const hasSomethingToShow = Boolean(t.conversationId || t.lastFinalizedRunId || t.checkoutRunId || t.currentResultId);
26
+ if (!hasSomethingToShow)
27
+ return [];
28
+ const pointers = [
29
+ [`${bin} tasks output ${ref}`, 'what the agent produced'],
30
+ ];
31
+ if (t.conversationId) {
32
+ pointers.push([`${bin} tasks transcript ${ref}`, 'the full agent transcript']);
33
+ }
34
+ const width = Math.max(...pointers.map(([command]) => command.length));
35
+ return [
36
+ '',
37
+ 'See also:',
38
+ ...pointers.map(([command, what]) => ` ${command.padEnd(width)} ${what}`),
39
+ ];
40
+ }
12
41
  /**
13
42
  * The failure rows of `tasks show`, when there are any. (S3 dogfood finding)
14
43
  *
@@ -173,6 +202,87 @@ class TasksShow extends base_command_1.BaseCommand {
173
202
  // question and this is the answer to it.
174
203
  for (const line of taskFailureLines(t, this.config.bin))
175
204
  this.log(line);
205
+ /*
206
+ * Closing is the actor's call — a Task may be `done` with work still
207
+ * outstanding, and `resolution.closure` is where the server recorded what
208
+ * it stood on at close. Show it so a bare "done" never reads as "clean."
209
+ */
210
+ const resolution = t.resolution;
211
+ /*
212
+ * Same renderer as the `tasks move` receipt, so the two cannot disagree
213
+ * about a Task they are both describing.
214
+ *
215
+ * This copy showed an owner's ordinary close as an override:
216
+ * `TASK_RESULT_REVIEW_REQUIRED` lands in `blockers` whenever the policy is
217
+ * unsatisfied — including when the owner, who is not bound by the Review
218
+ * they declared, closes it themselves — and this rendered it identically to
219
+ * a genuine forced close. So the only read surface for "was this gate
220
+ * overridden?" could not answer the question.
221
+ */
222
+ if (resolution?.closure) {
223
+ const sentences = (0, task_closure_1.closureSnapshotLines)(resolution.closure);
224
+ if (sentences.length > 0) {
225
+ this.log(`Resolution: ${resolution.kind ?? '-'} — ${sentences.join(' ')}`);
226
+ }
227
+ }
228
+ /*
229
+ * A Result orphaned by a spec edit is not the same as no Result.
230
+ *
231
+ * Editing a `description` or an Expectation advances `specVersion`, which
232
+ * unsets `currentResultId` by design — the old answer replied to a question
233
+ * that has changed. But every CLI surface then reported the Task as though
234
+ * nothing had ever been submitted, and the prior Result is still there. The
235
+ * web already says this correctly ("No Result answers the current Task spec
236
+ * vN", plus the previous one); the CLI said nothing at all.
237
+ *
238
+ * The extra request is paid only in the ambiguous case — when there is no
239
+ * current Result — and `tasks show` is a detail view, so one call to
240
+ * distinguish "nobody answered" from "the answer is out of date" is worth
241
+ * it. A failed lookup degrades to silence rather than to a claim.
242
+ */
243
+ const taskSpecVersion = Number(t.specVersion) || 1;
244
+ if (t.currentResultId) {
245
+ this.log(`Result: ${String(t.currentResultId)} (answers spec v${taskSpecVersion})`);
246
+ /*
247
+ * The Review on that Result, with its REASON.
248
+ *
249
+ * Closing over a `changes_requested` Review is allowed and recorded, and
250
+ * the closure line says "a reviewer requested changes" — the verdict. What
251
+ * they asked for lived only on the Review row, which no text surface
252
+ * printed, so the objection survived as a fact and lost its content. One
253
+ * read, on a detail view, only when there is a Result to have been
254
+ * reviewed; a failed read says nothing rather than implying no Review.
255
+ */
256
+ try {
257
+ const history = await data_provider_1.dataService.listTaskResults(taskIdentity.id);
258
+ const review = (history?.reviews || []).find((row) => row.resultId === String(t.currentResultId));
259
+ if (review) {
260
+ const who = (0, task_closure_1.describeAssessor)(review.reviewedBy?.kind);
261
+ const when = review.reviewedAt ? ` on ${String(review.reviewedAt).slice(0, 10)}` : '';
262
+ const why = review.rationale ? `: ${review.rationale}` : '';
263
+ this.log(`Review: ${review.decision} by ${who}${when}${why}`);
264
+ }
265
+ }
266
+ catch {
267
+ // Silence, not "no Review": this read failing is not evidence of absence.
268
+ }
269
+ }
270
+ else {
271
+ let priorLine = 'none submitted';
272
+ try {
273
+ const history = await data_provider_1.dataService.listTaskResults(taskIdentity.id);
274
+ const prior = history?.results?.[0];
275
+ if (prior) {
276
+ priorLine =
277
+ `none answers spec v${taskSpecVersion} — previous v${prior.version} ` +
278
+ `answered spec v${prior.specVersion ?? '?'}`;
279
+ }
280
+ }
281
+ catch {
282
+ priorLine = 'none answers the current spec (earlier Results could not be read)';
283
+ }
284
+ this.log(`Result: ${priorLine}`);
285
+ }
176
286
  this.log(`Executor: ${t.executionMode ?? 'legacy / inferred'}`);
177
287
  this.log(`Priority: ${t.priority ?? '-'}`);
178
288
  this.log(`Parent: ${t.parentId ?? '-'}`);
@@ -291,11 +401,36 @@ class TasksShow extends base_command_1.BaseCommand {
291
401
  }
292
402
  }
293
403
  const ref = String(t.id ?? t._id ?? taskIdentity.id);
294
- this.log('');
295
- this.log(`What the agent produced: skrr tasks output ${ref}`);
296
- if (t.conversationId) {
297
- this.log(`Full agent transcript: skrr tasks transcript ${ref}`);
404
+ /**
405
+ * Where this Task stands, on the surface people already open.
406
+ *
407
+ * `tasks expectations <id>` answers this well and is reachable only if you
408
+ * already know it exists — its one pointer lives in the `--expect` help of
409
+ * `tasks create`, which you read while AUTHORING and not while closing. So
410
+ * an agent that submitted a Result had no cheap way to learn the Task was
411
+ * still owed, and reasonably concluded from the CLI's own output that it was
412
+ * not. Say it here, where the question is actually asked.
413
+ *
414
+ * Read, not recomputed, and never fatal: a Task page must still render when
415
+ * the acceptance read fails, and it must not invent a state it could not
416
+ * fetch.
417
+ */
418
+ try {
419
+ const acceptance = await data_provider_1.dataService.getTaskAcceptance(ref);
420
+ const gating = acceptance.expectations.filter((e) => e.gating);
421
+ if (gating.length > 0) {
422
+ const settled = gating.filter((e) => e.met).length;
423
+ this.log('');
424
+ this.log(`Expectations: ${settled} of ${gating.length} settled · overall: ${acceptance.state}` +
425
+ (settled < gating.length ? ` — skrr tasks expectations ${ref}` : ''));
426
+ }
298
427
  }
428
+ catch {
429
+ // Silent: a Task this caller can VIEW but whose acceptance they cannot
430
+ // read is a permissions shape, not something to shout about mid-page.
431
+ }
432
+ for (const line of taskPointerLines(t, ref, this.config.bin))
433
+ this.log(line);
299
434
  }
300
435
  }
301
436
  exports.default = TasksShow;
@@ -41,8 +41,13 @@ class TasksTrust extends base_command_1.BaseCommand {
41
41
  level: core_1.Flags.string({
42
42
  options: [...data_provider_1.DELIVERABLE_AUTHORITIES],
43
43
  required: true,
44
- description: 'How well evidenced the answer must be: self_reported (the doer says so), ' +
45
- 'human_confirmed (someone else looked), observation_backed (the platform saw it).',
44
+ description:
45
+ // `observation_backed` is a RETIRED rung name for this domain — the flag
46
+ // rejects it, so the only two values the help explained were one real one
47
+ // and one the command refuses. The four the enum actually accepts:
48
+ 'How well evidenced the answer must be: self_reported (the doer says so), ' +
49
+ 'human_confirmed (a person confirmed it), system_observed (the platform saw it), ' +
50
+ 'external_receipt (a provider receipt proves it).',
46
51
  }),
47
52
  reason: core_1.Flags.string({
48
53
  required: true,
@@ -10,6 +10,7 @@ export default class TasksUpdate extends BaseCommand {
10
10
  task: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
11
  'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
12
  title: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
14
  expect: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
15
  description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
15
16
  'description-format': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;