@skrr-ai/cli 0.1.37 → 0.1.39

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 (177) hide show
  1. package/bin/dev-fallback.js +175 -4
  2. package/dist/base-command.js +46 -2
  3. package/dist/commands/agents/actions/create.js +18 -7
  4. package/dist/commands/agents/actions/delete.d.ts +1 -0
  5. package/dist/commands/agents/actions/delete.js +7 -0
  6. package/dist/commands/agents/actions/update.js +5 -3
  7. package/dist/commands/agents/api-actions/add.js +5 -2
  8. package/dist/commands/agents/api-actions/index.d.ts +11 -0
  9. package/dist/commands/agents/api-actions/index.js +27 -1
  10. package/dist/commands/agents/avatar/default/index.d.ts +11 -0
  11. package/dist/commands/agents/avatar/default/index.js +17 -0
  12. package/dist/commands/agents/avatar/default/set.d.ts +2 -1
  13. package/dist/commands/agents/avatar/default/set.js +32 -7
  14. package/dist/commands/agents/avatar/upload.js +7 -1
  15. package/dist/commands/agents/categories/delete.js +8 -0
  16. package/dist/commands/agents/categories/index.d.ts +21 -5
  17. package/dist/commands/agents/categories/index.js +68 -15
  18. package/dist/commands/agents/chat.d.ts +21 -0
  19. package/dist/commands/agents/chat.js +94 -7
  20. package/dist/commands/agents/create.js +11 -4
  21. package/dist/commands/agents/list.d.ts +15 -0
  22. package/dist/commands/agents/list.js +31 -1
  23. package/dist/commands/agents/scene-background/upload.d.ts +30 -0
  24. package/dist/commands/agents/scene-background/upload.js +97 -0
  25. package/dist/commands/agents/show.js +13 -0
  26. package/dist/commands/agents/tools/calls.d.ts +23 -5
  27. package/dist/commands/agents/tools/calls.js +81 -18
  28. package/dist/commands/agents/update.js +15 -5
  29. package/dist/commands/code/{oversky-agent.d.ts → skrr-agent.d.ts} +3 -3
  30. package/dist/commands/code/{oversky-agent.js → skrr-agent.js} +11 -8
  31. package/dist/commands/convos/messages.d.ts +13 -0
  32. package/dist/commands/convos/messages.js +40 -16
  33. package/dist/commands/daemon/index.js +8 -1
  34. package/dist/commands/daemon/logs.d.ts +26 -0
  35. package/dist/commands/daemon/logs.js +56 -0
  36. package/dist/commands/daemon/uninstall.js +1 -1
  37. package/dist/commands/followups/act.js +3 -2
  38. package/dist/commands/followups/cancel.d.ts +6 -3
  39. package/dist/commands/followups/cancel.js +16 -6
  40. package/dist/commands/followups/observability.d.ts +23 -0
  41. package/dist/commands/followups/observability.js +114 -0
  42. package/dist/commands/followups/reschedule.js +1 -1
  43. package/dist/commands/followups/resolve.js +3 -3
  44. package/dist/commands/followups/show.js +2 -1
  45. package/dist/commands/followups/watch.js +9 -5
  46. package/dist/commands/harnesses/forget.js +28 -0
  47. package/dist/commands/harnesses/install.d.ts +41 -0
  48. package/dist/commands/harnesses/install.js +165 -0
  49. package/dist/commands/harnesses/installers.d.ts +45 -0
  50. package/dist/commands/harnesses/installers.js +155 -0
  51. package/dist/commands/harnesses/list.d.ts +82 -1
  52. package/dist/commands/harnesses/list.js +104 -12
  53. package/dist/commands/harnesses/models.js +10 -1
  54. package/dist/commands/harnesses/show.d.ts +15 -0
  55. package/dist/commands/harnesses/show.js +44 -3
  56. package/dist/commands/harnesses/update.js +1 -1
  57. package/dist/commands/harnesses/usage.d.ts +25 -0
  58. package/dist/commands/harnesses/usage.js +24 -2
  59. package/dist/commands/instructions/status.js +13 -1
  60. package/dist/commands/machines/dedicated/catalog.js +4 -15
  61. package/dist/commands/machines/dedicated/create.d.ts +8 -0
  62. package/dist/commands/machines/dedicated/create.js +63 -2
  63. package/dist/commands/machines/dedicated/destroy.js +19 -5
  64. package/dist/commands/machines/dedicated/exec.js +3 -1
  65. package/dist/commands/machines/dedicated/list.js +9 -6
  66. package/dist/commands/machines/dedicated/price-book.d.ts +17 -0
  67. package/dist/commands/machines/dedicated/price-book.js +35 -0
  68. package/dist/commands/machines/hosted/list.js +12 -0
  69. package/dist/commands/machines/list.js +11 -0
  70. package/dist/commands/machines/show.d.ts +1 -0
  71. package/dist/commands/machines/show.js +40 -11
  72. package/dist/commands/profiles/list.d.ts +23 -0
  73. package/dist/commands/profiles/list.js +96 -0
  74. package/dist/commands/search/skills.d.ts +11 -1
  75. package/dist/commands/search/skills.js +26 -8
  76. package/dist/commands/skills/details.d.ts +2 -0
  77. package/dist/commands/skills/details.js +24 -1
  78. package/dist/commands/skills/import-as-actions.d.ts +32 -0
  79. package/dist/commands/skills/import-as-actions.js +175 -0
  80. package/dist/commands/skills/install.d.ts +2 -0
  81. package/dist/commands/skills/install.js +24 -1
  82. package/dist/commands/skills/invocable.js +6 -2
  83. package/dist/commands/skills/local.d.ts +40 -0
  84. package/dist/commands/skills/local.js +160 -0
  85. package/dist/commands/skills/search.d.ts +11 -1
  86. package/dist/commands/skills/search.js +29 -8
  87. package/dist/commands/spaces/actions/add.js +23 -5
  88. package/dist/commands/spaces/actions/available.js +3 -0
  89. package/dist/commands/spaces/actions/list.d.ts +5 -0
  90. package/dist/commands/spaces/actions/list.js +49 -3
  91. package/dist/commands/spaces/actions/run.d.ts +28 -0
  92. package/dist/commands/spaces/actions/run.js +146 -0
  93. package/dist/commands/spaces/actions/update.js +27 -5
  94. package/dist/commands/spaces/label-summaries.d.ts +27 -0
  95. package/dist/commands/spaces/label-summaries.js +64 -0
  96. package/dist/commands/spaces/task-rollups.d.ts +5 -0
  97. package/dist/commands/spaces/task-rollups.js +15 -4
  98. package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +63 -3
  99. package/dist/commands/tasks/actions/attach.js +32 -7
  100. package/dist/commands/tasks/complete.js +13 -0
  101. package/dist/commands/tasks/create.js +1 -1
  102. package/dist/commands/tasks/events/append.js +29 -6
  103. package/dist/commands/tasks/expectations/assess.d.ts +1 -0
  104. package/dist/commands/tasks/expectations/assess.js +43 -5
  105. package/dist/commands/tasks/expectations.js +77 -16
  106. package/dist/commands/tasks/follow-up.js +2 -2
  107. package/dist/commands/tasks/lifecycle/definitions.js +21 -2
  108. package/dist/commands/tasks/lifecycle/detach.d.ts +7 -0
  109. package/dist/commands/tasks/lifecycle/detach.js +43 -3
  110. package/dist/commands/tasks/lifecycle/migrate.d.ts +2 -0
  111. package/dist/commands/tasks/lifecycle/migrate.js +42 -3
  112. package/dist/commands/tasks/lifecycle/reopen.d.ts +2 -0
  113. package/dist/commands/tasks/lifecycle/reopen.js +40 -3
  114. package/dist/commands/tasks/lifecycle/transition.js +33 -2
  115. package/dist/commands/tasks/list.js +16 -9
  116. package/dist/commands/tasks/move.js +11 -13
  117. package/dist/commands/tasks/review-queue.d.ts +15 -0
  118. package/dist/commands/tasks/review-queue.js +180 -31
  119. package/dist/commands/tasks/show.d.ts +11 -0
  120. package/dist/commands/tasks/show.js +105 -12
  121. package/dist/commands/tasks/trust.js +7 -2
  122. package/dist/commands/tasks/update.js +46 -10
  123. package/dist/commands/tasks/updates/add.js +1 -1
  124. package/dist/commands/token/list.d.ts +22 -0
  125. package/dist/commands/token/list.js +68 -0
  126. package/dist/commands/token/revoke.d.ts +23 -0
  127. package/dist/commands/token/revoke.js +53 -0
  128. package/dist/lib/agent-actions.d.ts +57 -2
  129. package/dist/lib/agent-actions.js +113 -21
  130. package/dist/lib/agent-pin-mute.d.ts +10 -5
  131. package/dist/lib/agent-pin-mute.js +17 -4
  132. package/dist/lib/agent-visual-refs.d.ts +27 -0
  133. package/dist/lib/agent-visual-refs.js +127 -2
  134. package/dist/lib/agentic-stream.d.ts +6 -0
  135. package/dist/lib/agentic-stream.js +34 -3
  136. package/dist/lib/assignee-resolver.d.ts +1 -1
  137. package/dist/lib/assignee-resolver.js +8 -0
  138. package/dist/lib/bulk-task-targets.d.ts +12 -0
  139. package/dist/lib/bulk-task-targets.js +34 -1
  140. package/dist/lib/cli-installers.d.ts +130 -0
  141. package/dist/lib/cli-installers.js +145 -0
  142. package/dist/lib/command-miss.js +55 -7
  143. package/dist/lib/dedicated-lease-command.d.ts +16 -1
  144. package/dist/lib/dedicated-lease-command.js +26 -3
  145. package/dist/lib/dedicated-machines.d.ts +135 -1
  146. package/dist/lib/dedicated-machines.js +307 -3
  147. package/dist/lib/failed-lookup.d.ts +3 -0
  148. package/dist/lib/failed-lookup.js +40 -0
  149. package/dist/lib/first-party-harness-agent.js +9 -2
  150. package/dist/lib/first-party-harness-doctor.d.ts +15 -0
  151. package/dist/lib/first-party-harness-doctor.js +126 -27
  152. package/dist/lib/followups.d.ts +14 -6
  153. package/dist/lib/followups.js +31 -6
  154. package/dist/lib/harnesses.d.ts +8 -0
  155. package/dist/lib/instruction-input.d.ts +19 -1
  156. package/dist/lib/instruction-input.js +52 -1
  157. package/dist/lib/label-scope.d.ts +15 -0
  158. package/dist/lib/label-scope.js +25 -5
  159. package/dist/lib/local-skills.d.ts +98 -0
  160. package/dist/lib/local-skills.js +195 -0
  161. package/dist/lib/machines.d.ts +10 -10
  162. package/dist/lib/machines.js +23 -1
  163. package/dist/lib/search-query.d.ts +19 -0
  164. package/dist/lib/search-query.js +35 -0
  165. package/dist/lib/space-custom-actions.d.ts +72 -0
  166. package/dist/lib/space-custom-actions.js +117 -0
  167. package/dist/lib/space-resolver.d.ts +1 -21
  168. package/dist/lib/space-resolver.js +19 -10
  169. package/dist/lib/task-closure.d.ts +3 -2
  170. package/dist/lib/task-closure.js +18 -20
  171. package/dist/lib/task-lifecycle-output.js +117 -9
  172. package/dist/lib/task-ref-resolver.d.ts +1 -17
  173. package/dist/lib/task-ref-resolver.js +18 -8
  174. package/dist/lib/tasks.js +9 -3
  175. package/dist/node_modules/@skrr-ai/data-provider/index.js +5076 -4947
  176. package/oclif.manifest.json +15505 -14460
  177. package/package.json +9 -3
@@ -1,17 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.closureSnapshotLines = exports.describeAssessor = void 0;
3
4
  exports.closureReport = closureReport;
4
- exports.describeAssessor = describeAssessor;
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  function isUnavailable(closure) {
6
7
  return Boolean(closure && closure.unavailable);
7
8
  }
8
- const SHORT_BLOCKER = {
9
- TASK_RESULT_REQUIRED: 'no Result submitted',
10
- TASK_CURRENT_RESULT_MISSING: 'the current Result does not resolve',
11
- TASK_RESULT_SPEC_VERSION_MISMATCH: 'the Result answers an older specification',
12
- TASK_RESULT_CHANGES_REQUESTED: 'a reviewer requested changes',
13
- TASK_RESULT_REVIEW_REQUIRED: 'an independent accepted Review is required',
14
- };
9
+ // One phrase table, shared with the web through data-provider. Two copies is how
10
+ // the same blocker came to read differently depending on which surface you asked.
11
+ const SHORT_BLOCKER = data_provider_1.CLOSURE_BLOCKER_PHRASE;
15
12
  /**
16
13
  * The full account, for the moment a caller has just written something and is
17
14
  * deciding what to do next.
@@ -85,18 +82,9 @@ function closureReport(closure) {
85
82
  : 'Closing anyway is allowed — all of this is recorded on resolution.closure.');
86
83
  return lines;
87
84
  }
88
- /** `met (agent)` vs `met (you)` — whose judgement settled it, never hidden. */
89
- function describeAssessor(kind) {
90
- if (kind === 'agent')
91
- return 'agent';
92
- if (kind === 'human')
93
- return 'person';
94
- if (kind === 'system')
95
- return 'system';
96
- if (kind === 'integration')
97
- return 'integration';
98
- return 'unattributed';
99
- }
85
+ /** `met (agent)` vs `met (person)` — shared with the web through data-provider. */
86
+ var data_provider_2 = require("@skrr-ai/data-provider");
87
+ Object.defineProperty(exports, "describeAssessor", { enumerable: true, get: function () { return data_provider_2.describeAssessorKind; } });
100
88
  function truncate(value, max) {
101
89
  const flat = value.replace(/\s+/g, ' ').trim();
102
90
  return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
@@ -104,3 +92,13 @@ function truncate(value, max) {
104
92
  function capitalize(value) {
105
93
  return value.charAt(0).toUpperCase() + value.slice(1);
106
94
  }
95
+ /*
96
+ * The snapshot renderer moved to `@skrr-ai/data-provider`.
97
+ *
98
+ * It lived here, and "here" is `cli/` — so the web could not reach it, and the
99
+ * web is where most people read a finished Task. A single renderer that only one
100
+ * client can import is not a single renderer; it is the first copy. Re-exported
101
+ * under the old names so this module stays the CLI's one door to closure copy.
102
+ */
103
+ var data_provider_3 = require("@skrr-ai/data-provider");
104
+ Object.defineProperty(exports, "closureSnapshotLines", { enumerable: true, get: function () { return data_provider_3.describeClosure; } });
@@ -14,15 +14,25 @@ function renderTaskLifecycleSummary(response, log) {
14
14
  log('Attach one: skrr tasks lifecycle attach <task-id> --pack finding');
15
15
  return;
16
16
  }
17
- log(`Lifecycle: ${lifecycle.status} (v${lifecycle.version}, generation ${lifecycle.generation}, revision ${lifecycle.revision})` +
18
- (lifecycle.packId ? ` — pack ${lifecycle.packId}` : ''));
17
+ // Two different version numbers used to share one label. `v1` next to
18
+ // `pack finding` reads as "finding v1", and `finding` is pack v2 — `version`
19
+ // is the installed definition's WorkflowVersion. Name each one.
20
+ const protocol = lifecycle.packId
21
+ ? `pack ${lifecycle.packId}${lifecycle.packVersion ? ` v${lifecycle.packVersion}` : ''}`
22
+ : `definition ${lifecycle.definitionId}`;
23
+ log(`Lifecycle: ${lifecycle.status} — ${protocol}, protocol version ${lifecycle.version}, generation ${lifecycle.generation}, revision ${lifecycle.revision}`);
19
24
  if (response.run)
20
25
  log(`Run: ${response.run.id} — ${response.run.status}`);
21
26
  for (const stage of response.stages || []) {
22
27
  const marker = stage.key === lifecycle.currentStageKey ? '>' : ' ';
23
- const state = stage.status
24
- ? ` — ${stage.status}${stage.outcome ? `/${stage.outcome}` : ''}`
25
- : '';
28
+ // A reopen marks everything behind its entry stage `skipped` in the NEW
29
+ // run. Saying so unqualified told the reader that work nobody skipped had
30
+ // never happened; say which generation did it instead.
31
+ const state = stage.completedInGeneration
32
+ ? ` — done in generation ${stage.completedInGeneration}${stage.priorOutcome ? `/${stage.priorOutcome}` : ''}`
33
+ : stage.status
34
+ ? ` — ${stage.status}${stage.outcome ? `/${stage.outcome}` : ''}`
35
+ : '';
26
36
  log(`${marker} ${stage.label || stage.key}${state}`);
27
37
  }
28
38
  if (response.gate) {
@@ -43,28 +53,122 @@ function renderTaskLifecycleSummary(response, log) {
43
53
  : undefined,
44
54
  transition.requires?.deliverableRef ? 'deliverable ref' : undefined,
45
55
  ].filter(Boolean);
46
- log(` ${transition.id} -> ${transition.outcome}${transition.label ? ` (${transition.label})` : ''}${needs.length ? ` — needs ${needs.join(', ')}` : ''}`);
56
+ // Lead with what it DOES and say where it goes. This printed
57
+ // `id -> outcome`, and `outcome` is an edge name: at triage that read
58
+ // `accept -> accept`, with nothing to separate the branch that continues
59
+ // to Diagnose from the one that ends the finding.
60
+ const destination = transition.endsLifecycle
61
+ ? 'ends the lifecycle'
62
+ : transition.toStageLabel || transition.toStageKey;
63
+ log(` ${transition.id}${transition.label ? ` — ${transition.label}` : ''}${destination ? ` -> ${destination}` : ''}${needs.length ? ` — needs ${needs.join(', ')}` : ''}`);
64
+ // A copyable skeleton. Naming the update TYPE and a count of evidence
65
+ // told nobody which keys to put where, so every payload shape was
66
+ // guesswork against a contract only the server could see.
67
+ const skeleton = transitionPayloadSkeleton(transition);
68
+ if (skeleton)
69
+ log(` --payload '${skeleton}'`);
47
70
  }
48
71
  }
49
72
  if (response.pendingEffects?.length) {
50
73
  log('');
74
+ const exhausted = response.pendingEffects.filter((effect) => effect.status === 'failed');
51
75
  log(`${response.pendingEffects.length} effect(s) pending repair:`);
52
76
  for (const effect of response.pendingEffects) {
53
- log(` ${effect.kind}${effect.lastError ? ` — ${effect.lastError}` : ''}`);
77
+ // Say whether it is still trying. A row that has given up and a row
78
+ // mid-retry need different things from the reader.
79
+ const state = effect.status === 'failed' ? ' [stopped retrying]' : '';
80
+ log(` ${effect.kind}${state}${effect.attempts ? ` after ${effect.attempts} attempt(s)` : ''}${effect.lastError ? ` — ${effect.lastError}` : ''}`);
81
+ }
82
+ // Any row carrying an error is already actionable — waiting for it to
83
+ // exhaust its retries before naming the repair leaves the reader staring at
84
+ // a stage that cannot move and a transition list that offers nothing.
85
+ if (response.pendingEffects.some((effect) => effect.lastError)) {
86
+ log(exhausted.length
87
+ ? 'Fix what the error names, then re-arm them: skrr tasks lifecycle reconcile <task-id>'
88
+ : 'Still retrying. Fix what the error names, then: skrr tasks lifecycle reconcile <task-id>');
54
89
  }
55
90
  }
56
91
  if (lifecycle.statusDrift) {
57
92
  log(`Status drift: stage expects ${lifecycle.statusDrift.expected}, Task shows ${lifecycle.statusDrift.actual}.`);
58
93
  }
59
94
  }
95
+ /**
96
+ * A copyable `--payload` skeleton for one transition, built from what the
97
+ * server says the transition requires.
98
+ *
99
+ * Deliberately built from the RESPONSE rather than from a table in the CLI: the
100
+ * field list per update type is the server's to own, and a second copy here
101
+ * would drift the moment a pack changed.
102
+ */
103
+ function transitionPayloadSkeleton(transition) {
104
+ const requires = transition.requires;
105
+ if (!requires)
106
+ return undefined;
107
+ const payload = {};
108
+ for (const field of requires.fields || [])
109
+ payload[field] = `<${field}>`;
110
+ if (requires.deliverableRef)
111
+ payload.resourceLinkId = '<resource-link-id>';
112
+ if (requires.updateType) {
113
+ const data = {};
114
+ for (const field of requires.updateFields || []) {
115
+ data[field] = placeholderFor(field, requires.updateFieldShapes?.[field]);
116
+ }
117
+ if (requires.evidence) {
118
+ data.evidenceRefs = [{ kind: 'task', id: '<task-id>' }];
119
+ }
120
+ payload.update = { summary: '<one line about the work>', data };
121
+ }
122
+ return Object.keys(payload).length ? JSON.stringify(payload) : undefined;
123
+ }
124
+ /**
125
+ * A placeholder that has the field's SHAPE, taken from what the server declared.
126
+ * A list field shown as a string led people to write one comma-joined item
127
+ * where they meant several.
128
+ */
129
+ function placeholderFor(field, shape) {
130
+ if (!shape)
131
+ return `<${field}>`;
132
+ if (shape === 'string[]')
133
+ return [`<${field} item>`];
134
+ if (shape === 'reference[]')
135
+ return [];
136
+ if (shape === 'principal')
137
+ return { kind: 'human', userId: '<user-id>' };
138
+ // An enum: show the legal values rather than a name to guess at.
139
+ if (shape.includes('|'))
140
+ return `<${shape}>`;
141
+ return `<${field}>`;
142
+ }
60
143
  /** Render the outcome of a lifecycle transition call. */
61
144
  function renderLifecycleTransitionResult(response, log) {
62
- log(`Transition ${response.status}${response.code ? ` (${response.code})` : ''}.`);
145
+ // A replay is not an apply. Retrying is the NORMAL path here — the default
146
+ // idempotency key is derived, so a re-run of the same command replays — and
147
+ // this printed "Transition applied / effect record_update: applied" either
148
+ // way, so the one question a retry asks (did I just do that, or had I
149
+ // already?) had no answer in the output.
150
+ const replayed = response.idempotent === true;
151
+ // A transition can be `applied` while one of its declared effects did not
152
+ // run. The headline said "Transition applied." and the reader had to notice a
153
+ // per-effect `pending` several lines down, so a capture whose source was
154
+ // never recorded read as a success.
155
+ const owed = (response.effects || []).filter((effect) => effect.status !== 'applied');
156
+ log(`Transition ${response.status}${replayed ? ' (replayed — the recorded outcome, no new work)' : ''}${response.code ? ` (${response.code})` : ''}${owed.length ? ` — ${owed.length} of ${response.effects?.length} effect(s) did NOT run` : ''}.`);
63
157
  if (response.message)
64
158
  log(response.message);
65
159
  for (const effect of response.effects || []) {
66
160
  log(` effect ${effect.kind}: ${effect.status}${effect.ref ? ` -> ${effect.ref}` : ''}${effect.error ? ` — ${effect.error}` : ''}`);
67
161
  }
162
+ // The server names the legal transitions when it refuses an unknown id, and
163
+ // the human renderer dropped them — so a sequencing mistake ("not from this
164
+ // stage") and a typo read identically.
165
+ const allowed = response.details?.allowed;
166
+ if (Array.isArray(allowed) && allowed.length) {
167
+ log(`Legal from this stage: ${allowed.join(', ')}`);
168
+ }
169
+ const actualRevision = response.details?.actualRevision;
170
+ if (actualRevision !== undefined)
171
+ log(`Current revision is ${String(actualRevision)}.`);
68
172
  if (response.gate)
69
173
  log(`Gate: ${response.gate.message}`);
70
174
  if (response.lifecycle) {
@@ -85,7 +189,11 @@ function renderLifecycleHistory(response, log) {
85
189
  const parts = [
86
190
  event.at,
87
191
  event.type,
88
- event.generation !== undefined ? `gen ${event.generation}` : undefined,
192
+ // Name the protocol beside the generation. A Task that wore two packs
193
+ // across a detach and re-attach rendered both passes identically.
194
+ event.generation !== undefined
195
+ ? `gen ${event.generation}${event.packId ? ` (${event.packId})` : ''}`
196
+ : undefined,
89
197
  event.transitionId,
90
198
  event.status,
91
199
  event.outcome,
@@ -1,19 +1,3 @@
1
- /**
2
- * Task reference resolution — turn what a person typed into exactly one task
3
- * id, or an actionable failure.
4
- *
5
- * Distinct from `task-resolver.ts`, which is about WHICH INPUT WINS among the
6
- * positional arg, `--task`, `--from-json` and the daemon runtime context. That
7
- * module does no lookup at all: it picks a string and hands it to the API. This
8
- * one runs after it and answers a different question — what does that string
9
- * refer to?
10
- *
11
- * Two shapes already work without a lookup. A UUID is the canonical id, and an
12
- * `OSK-2423` ref resolves server-side (`getTask` special-cases the pattern in
13
- * api/models/Task.js). A title did not work, which is the gap here: the ref is
14
- * printed in every listing but a person reading a task board out loud has the
15
- * title, not the number.
16
- */
17
1
  export type TaskRef = {
18
2
  id: string;
19
3
  /** The human-readable ref, e.g. `OSK-2423`. */
@@ -23,7 +7,7 @@ export type TaskRef = {
23
7
  };
24
8
  export type TaskResolutionRefFailure = {
25
9
  ok: false;
26
- code: 'NOT_FOUND' | 'AMBIGUOUS';
10
+ code: 'NOT_FOUND' | 'AMBIGUOUS' | 'NOT_A_REFERENCE';
27
11
  query: string;
28
12
  candidates: TaskRef[];
29
13
  };
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TASK_REF_CLI_ERROR_CODE = void 0;
4
+ exports.directTaskRef = directTaskRef;
5
+ exports.taskRefFrom = taskRefFrom;
6
+ exports.resolveTaskRef = resolveTaskRef;
7
+ exports.describeTask = describeTask;
8
+ exports.describeTaskCandidates = describeTaskCandidates;
9
+ exports.formatTaskRefFailure = formatTaskRefFailure;
10
+ const failed_lookup_1 = require("./failed-lookup");
2
11
  /**
3
12
  * Task reference resolution — turn what a person typed into exactly one task
4
13
  * id, or an actionable failure.
@@ -15,14 +24,6 @@
15
24
  * printed in every listing but a person reading a task board out loud has the
16
25
  * title, not the number.
17
26
  */
18
- Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.TASK_REF_CLI_ERROR_CODE = void 0;
20
- exports.directTaskRef = directTaskRef;
21
- exports.taskRefFrom = taskRefFrom;
22
- exports.resolveTaskRef = resolveTaskRef;
23
- exports.describeTask = describeTask;
24
- exports.describeTaskCandidates = describeTaskCandidates;
25
- exports.formatTaskRefFailure = formatTaskRefFailure;
26
27
  const UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
27
28
  /** The server's identifier pattern, relaxed to accept a lowercase prefix. */
28
29
  const IDENTIFIER_RE = /^[A-Za-z]+-\d+$/;
@@ -78,6 +79,11 @@ function resolveTaskRef(query, tasks) {
78
79
  if (!q) {
79
80
  return { ok: false, code: 'NOT_FOUND', query: raw, candidates: tasks };
80
81
  }
82
+ // A failed lookup's output is refused before the title tiers can match it.
83
+ // See `failed-lookup.ts`.
84
+ if ((0, failed_lookup_1.isFailedLookupValue)(raw)) {
85
+ return { ok: false, code: 'NOT_A_REFERENCE', query: raw, candidates: [] };
86
+ }
81
87
  const tiers = [
82
88
  // 1. Exact id.
83
89
  (t) => t.id === raw,
@@ -118,6 +124,9 @@ function describeTaskCandidates(candidates, limit = 10) {
118
124
  return shown.join('\n');
119
125
  }
120
126
  function formatTaskRefFailure(failure, bin = 'skrr') {
127
+ if (failure.code === 'NOT_A_REFERENCE') {
128
+ return (0, failed_lookup_1.describeFailedLookupValue)(failure.query, 'task');
129
+ }
121
130
  if (failure.code === 'AMBIGUOUS') {
122
131
  return (`"${failure.query}" matches ${failure.candidates.length} tasks by title:\n` +
123
132
  `${describeTaskCandidates(failure.candidates)}\n` +
@@ -130,4 +139,5 @@ function formatTaskRefFailure(failure, bin = 'skrr') {
130
139
  exports.TASK_REF_CLI_ERROR_CODE = {
131
140
  AMBIGUOUS: 'TASK_REF_AMBIGUOUS',
132
141
  NOT_FOUND: 'TASK_REF_NOT_FOUND',
142
+ NOT_A_REFERENCE: 'TASK_REF_NOT_A_REFERENCE',
133
143
  };
package/dist/lib/tasks.js CHANGED
@@ -157,9 +157,15 @@ const kindsForHelp = Array.isArray(data_provider_1.TASK_OUTCOME_KINDS)
157
157
  const presetsForHelp = Array.isArray(data_provider_1.EXPECTATION_PRESETS)
158
158
  ? data_provider_1.EXPECTATION_PRESETS.map((preset) => `@${preset.key}`).join(', ')
159
159
  : '@merged-to-main, @pdf-delivered';
160
- exports.EXPECT_FLAG_HELP = 'What this task must produce. Each one GATES closure: the Task cannot enter a ' +
161
- 'completed state until every Expectation is assessed met or waived ' +
162
- '(`tasks expectations assess`). Form: <kind>[/<format>][:<target>] or @<preset> — ' +
160
+ exports.EXPECT_FLAG_HELP =
161
+ // Not a gate. `56a6ded703` made unmet Expectations advisory: the Task closes
162
+ // and what stood open is stamped onto `resolution.closure`. The help said the
163
+ // Task "cannot enter a completed state" until every one was settled, which was
164
+ // a promise the product had stopped keeping — and the kind of promise someone
165
+ // relies on when deciding whether an Expectation is worth declaring.
166
+ 'What this task must produce. Each one is RECORDED against closure: settle them with ' +
167
+ '`tasks expectations assess`, and any left unsettled are stamped onto the resolution ' +
168
+ 'when the Task closes. Form: <kind>[/<format>][:<target>] or @<preset> — ' +
163
169
  `e.g. 'code:origin/main', 'file/pdf:Drive/Reports', '@merged-to-main'. ` +
164
170
  `Kinds: ${kindsForHelp}. Presets: ${presetsForHelp}. ` +
165
171
  'Anything else is stored as a plain-language expectation a person settles. Repeatable.';