@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.
- package/bin/dev-fallback.js +175 -4
- package/dist/base-command.js +46 -2
- package/dist/commands/agents/actions/create.js +18 -7
- package/dist/commands/agents/actions/delete.d.ts +1 -0
- package/dist/commands/agents/actions/delete.js +7 -0
- package/dist/commands/agents/actions/update.js +5 -3
- package/dist/commands/agents/api-actions/add.js +5 -2
- package/dist/commands/agents/api-actions/index.d.ts +11 -0
- package/dist/commands/agents/api-actions/index.js +27 -1
- package/dist/commands/agents/avatar/default/index.d.ts +11 -0
- package/dist/commands/agents/avatar/default/index.js +17 -0
- package/dist/commands/agents/avatar/default/set.d.ts +2 -1
- package/dist/commands/agents/avatar/default/set.js +32 -7
- package/dist/commands/agents/avatar/upload.js +7 -1
- package/dist/commands/agents/categories/delete.js +8 -0
- package/dist/commands/agents/categories/index.d.ts +21 -5
- package/dist/commands/agents/categories/index.js +68 -15
- package/dist/commands/agents/chat.d.ts +21 -0
- package/dist/commands/agents/chat.js +94 -7
- package/dist/commands/agents/create.js +11 -4
- package/dist/commands/agents/list.d.ts +15 -0
- package/dist/commands/agents/list.js +31 -1
- package/dist/commands/agents/scene-background/upload.d.ts +30 -0
- package/dist/commands/agents/scene-background/upload.js +97 -0
- package/dist/commands/agents/show.js +13 -0
- package/dist/commands/agents/tools/calls.d.ts +23 -5
- package/dist/commands/agents/tools/calls.js +81 -18
- package/dist/commands/agents/update.js +15 -5
- package/dist/commands/code/{oversky-agent.d.ts → skrr-agent.d.ts} +3 -3
- package/dist/commands/code/{oversky-agent.js → skrr-agent.js} +11 -8
- package/dist/commands/convos/messages.d.ts +13 -0
- package/dist/commands/convos/messages.js +40 -16
- package/dist/commands/daemon/index.js +8 -1
- package/dist/commands/daemon/logs.d.ts +26 -0
- package/dist/commands/daemon/logs.js +56 -0
- package/dist/commands/daemon/uninstall.js +1 -1
- package/dist/commands/followups/act.js +3 -2
- package/dist/commands/followups/cancel.d.ts +6 -3
- package/dist/commands/followups/cancel.js +16 -6
- package/dist/commands/followups/observability.d.ts +23 -0
- package/dist/commands/followups/observability.js +114 -0
- package/dist/commands/followups/reschedule.js +1 -1
- package/dist/commands/followups/resolve.js +3 -3
- package/dist/commands/followups/show.js +2 -1
- package/dist/commands/followups/watch.js +9 -5
- package/dist/commands/harnesses/forget.js +28 -0
- package/dist/commands/harnesses/install.d.ts +41 -0
- package/dist/commands/harnesses/install.js +165 -0
- package/dist/commands/harnesses/installers.d.ts +45 -0
- package/dist/commands/harnesses/installers.js +155 -0
- package/dist/commands/harnesses/list.d.ts +82 -1
- package/dist/commands/harnesses/list.js +104 -12
- package/dist/commands/harnesses/models.js +10 -1
- package/dist/commands/harnesses/show.d.ts +15 -0
- package/dist/commands/harnesses/show.js +44 -3
- package/dist/commands/harnesses/update.js +1 -1
- package/dist/commands/harnesses/usage.d.ts +25 -0
- package/dist/commands/harnesses/usage.js +24 -2
- package/dist/commands/instructions/status.js +13 -1
- package/dist/commands/machines/dedicated/catalog.js +4 -15
- package/dist/commands/machines/dedicated/create.d.ts +8 -0
- package/dist/commands/machines/dedicated/create.js +63 -2
- package/dist/commands/machines/dedicated/destroy.js +19 -5
- package/dist/commands/machines/dedicated/exec.js +3 -1
- package/dist/commands/machines/dedicated/list.js +9 -6
- package/dist/commands/machines/dedicated/price-book.d.ts +17 -0
- package/dist/commands/machines/dedicated/price-book.js +35 -0
- package/dist/commands/machines/hosted/list.js +12 -0
- package/dist/commands/machines/list.js +11 -0
- package/dist/commands/machines/show.d.ts +1 -0
- package/dist/commands/machines/show.js +40 -11
- package/dist/commands/profiles/list.d.ts +23 -0
- package/dist/commands/profiles/list.js +96 -0
- package/dist/commands/search/skills.d.ts +11 -1
- package/dist/commands/search/skills.js +26 -8
- package/dist/commands/skills/details.d.ts +2 -0
- package/dist/commands/skills/details.js +24 -1
- package/dist/commands/skills/import-as-actions.d.ts +32 -0
- package/dist/commands/skills/import-as-actions.js +175 -0
- package/dist/commands/skills/install.d.ts +2 -0
- package/dist/commands/skills/install.js +24 -1
- package/dist/commands/skills/invocable.js +6 -2
- package/dist/commands/skills/local.d.ts +40 -0
- package/dist/commands/skills/local.js +160 -0
- package/dist/commands/skills/search.d.ts +11 -1
- package/dist/commands/skills/search.js +29 -8
- package/dist/commands/spaces/actions/add.js +23 -5
- package/dist/commands/spaces/actions/available.js +3 -0
- package/dist/commands/spaces/actions/list.d.ts +5 -0
- package/dist/commands/spaces/actions/list.js +49 -3
- package/dist/commands/spaces/actions/run.d.ts +28 -0
- package/dist/commands/spaces/actions/run.js +146 -0
- package/dist/commands/spaces/actions/update.js +27 -5
- package/dist/commands/spaces/label-summaries.d.ts +27 -0
- package/dist/commands/spaces/label-summaries.js +64 -0
- package/dist/commands/spaces/task-rollups.d.ts +5 -0
- package/dist/commands/spaces/task-rollups.js +15 -4
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +63 -3
- package/dist/commands/tasks/actions/attach.js +32 -7
- package/dist/commands/tasks/complete.js +13 -0
- package/dist/commands/tasks/create.js +1 -1
- package/dist/commands/tasks/events/append.js +29 -6
- package/dist/commands/tasks/expectations/assess.d.ts +1 -0
- package/dist/commands/tasks/expectations/assess.js +43 -5
- package/dist/commands/tasks/expectations.js +77 -16
- package/dist/commands/tasks/follow-up.js +2 -2
- package/dist/commands/tasks/lifecycle/definitions.js +21 -2
- package/dist/commands/tasks/lifecycle/detach.d.ts +7 -0
- package/dist/commands/tasks/lifecycle/detach.js +43 -3
- package/dist/commands/tasks/lifecycle/migrate.d.ts +2 -0
- package/dist/commands/tasks/lifecycle/migrate.js +42 -3
- package/dist/commands/tasks/lifecycle/reopen.d.ts +2 -0
- package/dist/commands/tasks/lifecycle/reopen.js +40 -3
- package/dist/commands/tasks/lifecycle/transition.js +33 -2
- package/dist/commands/tasks/list.js +16 -9
- package/dist/commands/tasks/move.js +11 -13
- package/dist/commands/tasks/review-queue.d.ts +15 -0
- package/dist/commands/tasks/review-queue.js +180 -31
- package/dist/commands/tasks/show.d.ts +11 -0
- package/dist/commands/tasks/show.js +105 -12
- package/dist/commands/tasks/trust.js +7 -2
- package/dist/commands/tasks/update.js +46 -10
- package/dist/commands/tasks/updates/add.js +1 -1
- package/dist/commands/token/list.d.ts +22 -0
- package/dist/commands/token/list.js +68 -0
- package/dist/commands/token/revoke.d.ts +23 -0
- package/dist/commands/token/revoke.js +53 -0
- package/dist/lib/agent-actions.d.ts +57 -2
- package/dist/lib/agent-actions.js +113 -21
- package/dist/lib/agent-pin-mute.d.ts +10 -5
- package/dist/lib/agent-pin-mute.js +17 -4
- package/dist/lib/agent-visual-refs.d.ts +27 -0
- package/dist/lib/agent-visual-refs.js +127 -2
- package/dist/lib/agentic-stream.d.ts +6 -0
- package/dist/lib/agentic-stream.js +34 -3
- package/dist/lib/assignee-resolver.d.ts +1 -1
- package/dist/lib/assignee-resolver.js +8 -0
- package/dist/lib/bulk-task-targets.d.ts +12 -0
- package/dist/lib/bulk-task-targets.js +34 -1
- package/dist/lib/cli-installers.d.ts +130 -0
- package/dist/lib/cli-installers.js +145 -0
- package/dist/lib/command-miss.js +55 -7
- package/dist/lib/dedicated-lease-command.d.ts +16 -1
- package/dist/lib/dedicated-lease-command.js +26 -3
- package/dist/lib/dedicated-machines.d.ts +135 -1
- package/dist/lib/dedicated-machines.js +307 -3
- package/dist/lib/failed-lookup.d.ts +3 -0
- package/dist/lib/failed-lookup.js +40 -0
- package/dist/lib/first-party-harness-agent.js +9 -2
- package/dist/lib/first-party-harness-doctor.d.ts +15 -0
- package/dist/lib/first-party-harness-doctor.js +126 -27
- package/dist/lib/followups.d.ts +14 -6
- package/dist/lib/followups.js +31 -6
- package/dist/lib/harnesses.d.ts +8 -0
- package/dist/lib/instruction-input.d.ts +19 -1
- package/dist/lib/instruction-input.js +52 -1
- package/dist/lib/label-scope.d.ts +15 -0
- package/dist/lib/label-scope.js +25 -5
- package/dist/lib/local-skills.d.ts +98 -0
- package/dist/lib/local-skills.js +195 -0
- package/dist/lib/machines.d.ts +10 -10
- package/dist/lib/machines.js +23 -1
- package/dist/lib/search-query.d.ts +19 -0
- package/dist/lib/search-query.js +35 -0
- package/dist/lib/space-custom-actions.d.ts +72 -0
- package/dist/lib/space-custom-actions.js +117 -0
- package/dist/lib/space-resolver.d.ts +1 -21
- package/dist/lib/space-resolver.js +19 -10
- package/dist/lib/task-closure.d.ts +3 -2
- package/dist/lib/task-closure.js +18 -20
- package/dist/lib/task-lifecycle-output.js +117 -9
- package/dist/lib/task-ref-resolver.d.ts +1 -17
- package/dist/lib/task-ref-resolver.js +18 -8
- package/dist/lib/tasks.js +9 -3
- package/dist/node_modules/@skrr-ai/data-provider/index.js +5076 -4947
- package/oclif.manifest.json +15505 -14460
- package/package.json +9 -3
package/dist/lib/task-closure.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 (
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
161
|
-
|
|
162
|
-
|
|
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.';
|