@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
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SKILL_CONVENTION_DISCOVERY_SINCE = void 0;
|
|
4
|
+
exports.chooseDaemon = chooseDaemon;
|
|
5
|
+
exports.isUserInvocable = isUserInvocable;
|
|
6
|
+
exports.resolveLocalSkillRefs = resolveLocalSkillRefs;
|
|
7
|
+
exports.withSkillInvocations = withSkillInvocations;
|
|
8
|
+
exports.looksLikeSkillPath = looksLikeSkillPath;
|
|
9
|
+
exports.findLocalSkillsNamed = findLocalSkillsNamed;
|
|
10
|
+
exports.describeStoreSkillMiss = describeStoreSkillMiss;
|
|
11
|
+
exports.daemonPredates = daemonPredates;
|
|
12
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
13
|
+
/**
|
|
14
|
+
* Which machine to ask, or why there is no single answer.
|
|
15
|
+
*
|
|
16
|
+
* Resolves rather than guesses: picking one of several machines and reporting
|
|
17
|
+
* its skills as "the" answer is the same silent narrowing the listing exists
|
|
18
|
+
* to remove.
|
|
19
|
+
*/
|
|
20
|
+
function chooseDaemon(active) {
|
|
21
|
+
if (active.length === 1)
|
|
22
|
+
return { daemonId: active[0].daemonId };
|
|
23
|
+
if (active.length === 0) {
|
|
24
|
+
return {
|
|
25
|
+
problem: 'No connected machine. Start one with `skrr daemon start`, then try again.',
|
|
26
|
+
candidates: [],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
problem: `${active.length} machines are connected. Pick one with --daemon:`,
|
|
31
|
+
candidates: [...active],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** A skill with no declared triggers is invocable both ways — the walker's default. */
|
|
35
|
+
function isUserInvocable(skill) {
|
|
36
|
+
return !skill.triggers || skill.triggers.includes('user');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Turn requested names into the references the server resolves.
|
|
40
|
+
*
|
|
41
|
+
* A request is `name`, or `<root>/<name>` when the same name exists under more
|
|
42
|
+
* than one root (`.claude/skills/review` vs `.agents/skills/review`). Each
|
|
43
|
+
* problem is reported in words that say what to type instead; nothing is
|
|
44
|
+
* dropped, because the server's own rule is that a skill the user picked and
|
|
45
|
+
* the turn did not load must fail the turn rather than run without it.
|
|
46
|
+
*/
|
|
47
|
+
function resolveLocalSkillRefs(inventory, requested) {
|
|
48
|
+
const refs = [];
|
|
49
|
+
const problems = [];
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
for (const raw of requested) {
|
|
52
|
+
const request = raw.trim().replace(/^\//, '');
|
|
53
|
+
const slash = request.lastIndexOf('/');
|
|
54
|
+
const root = slash > 0 ? request.slice(0, slash) : null;
|
|
55
|
+
const name = slash > 0 ? request.slice(slash + 1) : request;
|
|
56
|
+
const named = inventory.filter((skill) => skill.name === name);
|
|
57
|
+
const matches = root ? named.filter((skill) => skill.source === root) : named;
|
|
58
|
+
if (matches.length === 0) {
|
|
59
|
+
problems.push(named.length > 0
|
|
60
|
+
? `No skill "${name}" under ${root}. It is under: ${named.map((s) => s.source ?? '?').join(', ')}.`
|
|
61
|
+
: `No skill named "${name}" on this machine. See \`skrr skills local\`.`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (matches.length > 1) {
|
|
65
|
+
problems.push(`"${name}" exists under ${matches.length} roots. Name one: ` +
|
|
66
|
+
matches.map((s) => `--local-skill ${s.source ?? '?'}/${name}`).join(' | '));
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const [skill] = matches;
|
|
70
|
+
if (!isUserInvocable(skill)) {
|
|
71
|
+
problems.push(`"${name}" declares it is for the agent to reach for, not to invoke (triggers: model).`);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (seen.has(skill.pathHash))
|
|
75
|
+
continue;
|
|
76
|
+
seen.add(skill.pathHash);
|
|
77
|
+
refs.push({ name: skill.name, pathHash: skill.pathHash });
|
|
78
|
+
}
|
|
79
|
+
return { refs, problems };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The prompt with a `/name` for every invoked skill it does not already name.
|
|
83
|
+
*
|
|
84
|
+
* The web composer sends the `/name` in the text beside the reference, and
|
|
85
|
+
* drops a reference whose `/name` is gone; a CLI turn carries the same pair so
|
|
86
|
+
* the agent reads the same invocation either way.
|
|
87
|
+
*/
|
|
88
|
+
function withSkillInvocations(prompt, refs) {
|
|
89
|
+
const missing = refs.filter((ref) => !new RegExp(`(^|\\s)/${ref.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?=\\s|$)`).test(prompt));
|
|
90
|
+
if (missing.length === 0)
|
|
91
|
+
return prompt;
|
|
92
|
+
return `${missing.map((ref) => `/${ref.name}`).join(' ')} ${prompt}`;
|
|
93
|
+
}
|
|
94
|
+
/** Whether a skill argument names a place on disk rather than a store id. */
|
|
95
|
+
function looksLikeSkillPath(arg) {
|
|
96
|
+
return /[\\/]/.test(arg) || arg.startsWith('.') || arg.startsWith('~');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Where a skill with this name exists on the caller's connected machines.
|
|
100
|
+
*
|
|
101
|
+
* Best-effort by design: it runs only to word an error that is already going
|
|
102
|
+
* to be reported, so a machine that cannot be asked contributes nothing rather
|
|
103
|
+
* than replacing the real error with a second one.
|
|
104
|
+
*/
|
|
105
|
+
async function findLocalSkillsNamed(name) {
|
|
106
|
+
const bare = name.replace(/^\//, '');
|
|
107
|
+
let active = [];
|
|
108
|
+
try {
|
|
109
|
+
active = (await data_provider_1.dataService.getDaemons()).active ?? [];
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
const sightings = await Promise.all(active.map(async (daemon) => {
|
|
115
|
+
try {
|
|
116
|
+
const { skills } = await data_provider_1.dataService.getDaemonSkills(daemon.daemonId);
|
|
117
|
+
return (skills ?? [])
|
|
118
|
+
.filter((skill) => skill.name === bare)
|
|
119
|
+
.map((skill) => ({
|
|
120
|
+
daemonId: daemon.daemonId,
|
|
121
|
+
deviceName: daemon.deviceName,
|
|
122
|
+
source: skill.source,
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
}));
|
|
129
|
+
return sightings.flat();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* The error for a skill argument a STORE command could not use.
|
|
133
|
+
*
|
|
134
|
+
* `skills install <name>` and `skills details <name>` answered a local skill's
|
|
135
|
+
* name or path with "Skill not found / NOT_FOUND": true of the store, and no
|
|
136
|
+
* help to someone the product had just told it reads their `.claude/skills`
|
|
137
|
+
* (OSK-9412). The answer depends on what the argument was, so it says which:
|
|
138
|
+
* a path (never a store id), a name found on a connected machine (needs no
|
|
139
|
+
* install), or neither (look the id up in the store).
|
|
140
|
+
*/
|
|
141
|
+
function describeStoreSkillMiss(arg, sightings, command) {
|
|
142
|
+
const verb = command === 'install' ? 'installs' : 'shows';
|
|
143
|
+
if (looksLikeSkillPath(arg)) {
|
|
144
|
+
return [
|
|
145
|
+
`\`skills ${command}\` ${verb} a skill from the store by its id; "${arg}" is a path.`,
|
|
146
|
+
"A skill in one of your machine's skill roots needs no install.",
|
|
147
|
+
'→ See what your machine has: skrr skills local',
|
|
148
|
+
'→ Use one on a turn: skrr agents chat <agent-id> --local-skill <name>',
|
|
149
|
+
].join('\n');
|
|
150
|
+
}
|
|
151
|
+
if (sightings.length > 0) {
|
|
152
|
+
const where = sightings
|
|
153
|
+
.map((s) => `${s.daemonId}${s.deviceName ? ` (${s.deviceName})` : ''}${s.source ? `, ${s.source}` : ''}`)
|
|
154
|
+
.join('; ');
|
|
155
|
+
return [
|
|
156
|
+
`No store skill has the id "${arg}", but a skill named "${arg}" is on your machine: ${where}.`,
|
|
157
|
+
'It needs no install.',
|
|
158
|
+
`→ Use it on a turn: skrr agents chat <agent-id> --local-skill ${arg.replace(/^\//, '')}`,
|
|
159
|
+
].join('\n');
|
|
160
|
+
}
|
|
161
|
+
return [
|
|
162
|
+
`No store skill has the id "${arg}".`,
|
|
163
|
+
'→ Find a store id: skrr skills search <term>',
|
|
164
|
+
'→ Skills on your machine are not in the store: skrr skills local',
|
|
165
|
+
].join('\n');
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The first daemon release whose walker scans the skill conventions — the
|
|
169
|
+
* project's `.claude/skills`, `.agents/skills`, `.devin/skills`,
|
|
170
|
+
* `.windsurf/skills` and the global `~/.claude/skills`. It arrived in
|
|
171
|
+
* `e9dfa732cd` and first shipped in 0.8.44; an older daemon scans only
|
|
172
|
+
* `claudeSession.skillsDir`, which is empty unless someone set it by hand.
|
|
173
|
+
*/
|
|
174
|
+
exports.SKILL_CONVENTION_DISCOVERY_SINCE = '0.8.44';
|
|
175
|
+
/**
|
|
176
|
+
* Whether a daemon's reported version is older than `floor`.
|
|
177
|
+
*
|
|
178
|
+
* Unknown or unparseable versions answer false: this decides only whether to
|
|
179
|
+
* add an explanation, and claiming an unknown daemon is old would be a guess.
|
|
180
|
+
*/
|
|
181
|
+
function daemonPredates(version, floor) {
|
|
182
|
+
const parse = (value) => {
|
|
183
|
+
const match = /^(\d+)\.(\d+)\.(\d+)/.exec(String(value ?? '').trim());
|
|
184
|
+
return match ? match.slice(1).map(Number) : null;
|
|
185
|
+
};
|
|
186
|
+
const have = parse(version);
|
|
187
|
+
const need = parse(floor);
|
|
188
|
+
if (!have || !need)
|
|
189
|
+
return false;
|
|
190
|
+
for (let i = 0; i < 3; i += 1) {
|
|
191
|
+
if (have[i] !== need[i])
|
|
192
|
+
return have[i] < need[i];
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
package/dist/lib/machines.d.ts
CHANGED
|
@@ -59,6 +59,16 @@ export interface Machine {
|
|
|
59
59
|
identityKind: MachineIdentityKind;
|
|
60
60
|
name: string;
|
|
61
61
|
status: 'online' | 'offline' | 'degraded';
|
|
62
|
+
/**
|
|
63
|
+
* One sentence naming what decided the status, or null when nothing needs
|
|
64
|
+
* explaining. Optional because the CLI ships separately from the server.
|
|
65
|
+
*
|
|
66
|
+
* `degraded` alone is unactionable, and on a laptop it is usually permanent —
|
|
67
|
+
* one offline row for a provider that was uninstalled holds the verdict
|
|
68
|
+
* forever, because supersession needs a NEWER row for the same provider and
|
|
69
|
+
* none will ever arrive.
|
|
70
|
+
*/
|
|
71
|
+
statusReason?: string | null;
|
|
62
72
|
machineUuid: string | null;
|
|
63
73
|
stableDaemonId: string | null;
|
|
64
74
|
daemonId: string | null;
|
|
@@ -135,14 +145,4 @@ export declare function listMachines(): Promise<Machine[]>;
|
|
|
135
145
|
export declare function getMachine(machineId: string): Promise<Machine | null>;
|
|
136
146
|
export declare function updateMachine(machineId: string, patch: MachinePreferencesPatch): Promise<Machine | null>;
|
|
137
147
|
export declare function disconnectMachine(machineId: string): Promise<Record<string, unknown> | null>;
|
|
138
|
-
/**
|
|
139
|
-
* Resolve a user-supplied reference to exactly one machine.
|
|
140
|
-
*
|
|
141
|
-
* A machine is addressable by several ids (`id`, `machineUuid`,
|
|
142
|
-
* `stableDaemonId`, `daemonId`) and `skrr harnesses list` prints a TRUNCATED
|
|
143
|
-
* uuid, so the id a user has to hand is often a prefix of the one the API
|
|
144
|
-
* wants. Resolving here keeps every command accepting the same references, and
|
|
145
|
-
* makes an ambiguous prefix an error rather than a silent pick of the first
|
|
146
|
-
* match.
|
|
147
|
-
*/
|
|
148
148
|
export declare function resolveMachineRef(machines: Machine[], ref: string): Machine;
|
package/dist/lib/machines.js
CHANGED
|
@@ -93,13 +93,35 @@ async function disconnectMachine(machineId) {
|
|
|
93
93
|
* makes an ambiguous prefix an error rather than a silent pick of the first
|
|
94
94
|
* match.
|
|
95
95
|
*/
|
|
96
|
+
/**
|
|
97
|
+
* The daemon ids a hosted machine's sandbox id can appear inside.
|
|
98
|
+
*
|
|
99
|
+
* `machines hosted list` prints `sbs_…`; the machine row carries
|
|
100
|
+
* `hosted-machine-sbs_…` as its daemon id. Composed rather than matched by
|
|
101
|
+
* substring so a longer id cannot be resolved by a shorter one's text.
|
|
102
|
+
*/
|
|
103
|
+
function hostedSandboxDaemonIds(ref) {
|
|
104
|
+
if (!ref.startsWith('sbs_'))
|
|
105
|
+
return [];
|
|
106
|
+
return [`hosted-machine-${ref}`, `hosted-job-machine-${ref}`];
|
|
107
|
+
}
|
|
96
108
|
function resolveMachineRef(machines, ref) {
|
|
97
109
|
const needle = ref.trim();
|
|
98
110
|
const lower = needle.toLowerCase();
|
|
99
111
|
const exact = machines.filter((m) => m.id === needle ||
|
|
100
112
|
m.machineUuid === needle ||
|
|
101
113
|
m.stableDaemonId === needle ||
|
|
102
|
-
m.daemonId === needle
|
|
114
|
+
m.daemonId === needle ||
|
|
115
|
+
// The sandbox id, which is the ONLY id `machines hosted list` prints.
|
|
116
|
+
// One hosted machine carries five identifiers and, before this, the one
|
|
117
|
+
// its own list showed you was the one `machines show` refused: the
|
|
118
|
+
// sandbox id appears here only INSIDE the daemon id, as
|
|
119
|
+
// `hosted-machine-<sbs_…>`, while `machines list --all` shows the same
|
|
120
|
+
// box as `lease:rtl_…` — a different random string entirely. Two lists,
|
|
121
|
+
// two unrelated-looking ids, no way on screen to tell they are one
|
|
122
|
+
// machine. Exact composition, not a substring search, so this cannot
|
|
123
|
+
// match a machine that merely contains the text.
|
|
124
|
+
hostedSandboxDaemonIds(needle).some((candidate) => m.daemonId === candidate));
|
|
103
125
|
if (exact.length === 1)
|
|
104
126
|
return exact[0];
|
|
105
127
|
const byName = machines.filter((m) => m.name?.toLowerCase() === lower);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The search term, from a positional or `--query`, resolved the same way by
|
|
3
|
+
* both spellings of the same search.
|
|
4
|
+
*
|
|
5
|
+
* `skills search` and `search skills` run the identical store search. Neither
|
|
6
|
+
* accepted the obvious invocation — `skrr skills search git` — so the single
|
|
7
|
+
* most natural way to call a search command failed on both, and `--query` was
|
|
8
|
+
* `required` on both, which is what made it fail rather than prompt.
|
|
9
|
+
*
|
|
10
|
+
* Shared rather than copied because the two spellings staying in step is the
|
|
11
|
+
* whole point: the reason a reader could not tell them apart was that they had
|
|
12
|
+
* drifted (different one-liners, short flags on one of them), and a second copy
|
|
13
|
+
* of this is how that starts again.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveSearchQuery(cmd: {
|
|
16
|
+
error: (message: string, options?: {
|
|
17
|
+
exit?: number;
|
|
18
|
+
}) => never;
|
|
19
|
+
}, positional: string | undefined, flag: string | undefined, command: string): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveSearchQuery = resolveSearchQuery;
|
|
4
|
+
/**
|
|
5
|
+
* The search term, from a positional or `--query`, resolved the same way by
|
|
6
|
+
* both spellings of the same search.
|
|
7
|
+
*
|
|
8
|
+
* `skills search` and `search skills` run the identical store search. Neither
|
|
9
|
+
* accepted the obvious invocation — `skrr skills search git` — so the single
|
|
10
|
+
* most natural way to call a search command failed on both, and `--query` was
|
|
11
|
+
* `required` on both, which is what made it fail rather than prompt.
|
|
12
|
+
*
|
|
13
|
+
* Shared rather than copied because the two spellings staying in step is the
|
|
14
|
+
* whole point: the reason a reader could not tell them apart was that they had
|
|
15
|
+
* drifted (different one-liners, short flags on one of them), and a second copy
|
|
16
|
+
* of this is how that starts again.
|
|
17
|
+
*/
|
|
18
|
+
function resolveSearchQuery(cmd, positional, flag, command) {
|
|
19
|
+
const fromPositional = positional?.trim();
|
|
20
|
+
const fromFlag = flag?.trim();
|
|
21
|
+
// Both given and DIFFERENT is a real ambiguity — refuse rather than pick.
|
|
22
|
+
// Both given and identical is a script that passes belt and braces; that is
|
|
23
|
+
// not an error and silently accepting it costs nobody anything.
|
|
24
|
+
if (fromPositional && fromFlag && fromPositional !== fromFlag) {
|
|
25
|
+
cmd.error(`Two different search terms: "${fromPositional}" and --query "${fromFlag}". Pass one.`, { exit: 2 });
|
|
26
|
+
}
|
|
27
|
+
const query = fromPositional || fromFlag;
|
|
28
|
+
if (!query) {
|
|
29
|
+
// `--query` used to be `required`, so oclif refused with its own generic
|
|
30
|
+
// sentence. Naming the shape people actually type is the point of the
|
|
31
|
+
// change, so the error names it too.
|
|
32
|
+
cmd.error(`What should I search for? Try \`skrr ${command} <term>\`.`, { exit: 2 });
|
|
33
|
+
}
|
|
34
|
+
return query;
|
|
35
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shape for `skrr spaces actions add|update`.
|
|
3
|
+
*
|
|
4
|
+
* Both commands describe the same stored object, and they had drifted from the
|
|
5
|
+
* server that validates it (`spaceCustomActionSchema` in api/server/routes/spaces.js).
|
|
6
|
+
*/
|
|
7
|
+
import type { SpaceCustomAction, SpaceMemberActionsResponse } from '@skrr-ai/data-provider';
|
|
8
|
+
/**
|
|
9
|
+
* The server's limit on `icon`, which is `z.string().max(4)`.
|
|
10
|
+
*
|
|
11
|
+
* The flag used to be documented as "Lucide icon name". It is not one: the web
|
|
12
|
+
* settings page renders `action.icon` as literal text, and almost no Lucide name
|
|
13
|
+
* fits in four characters, so following the help produced a 400 with a raw Zod
|
|
14
|
+
* message and no hint that an emoji was wanted (OSK-9631).
|
|
15
|
+
*
|
|
16
|
+
* Zod's `max` counts UTF-16 code units, not visible characters, so the check
|
|
17
|
+
* below uses `String.prototype.length` to agree with it exactly. Counting
|
|
18
|
+
* graphemes instead would accept a family emoji the server then refuses.
|
|
19
|
+
*/
|
|
20
|
+
export declare const SPACE_CUSTOM_ACTION_ICON_MAX = 4;
|
|
21
|
+
export declare const spaceCustomActionIconFlag: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
export declare const spaceCustomActionLabelFlag: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
/** Refuse an icon the server would refuse, with a message that says what fits. */
|
|
24
|
+
export declare function spaceCustomActionIconProblem(icon: unknown): string | null;
|
|
25
|
+
type SpaceWithActions = {
|
|
26
|
+
id: string;
|
|
27
|
+
title?: string;
|
|
28
|
+
leadAgentId?: string | null;
|
|
29
|
+
customActions?: SpaceCustomAction[] | null;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Why a space's OWN actions cannot run, or null when they can.
|
|
33
|
+
*
|
|
34
|
+
* A space custom action runs as a task assigned to the Space Leader, so on a
|
|
35
|
+
* space with no Leader every one of them is dead on arrival. That fact used to
|
|
36
|
+
* live only in a tooltip on a disabled web button: `spaces actions add` reported
|
|
37
|
+
* success, `spaces actions list` listed the action happily, and nothing on the
|
|
38
|
+
* CLI said it could never run (OSK-9641).
|
|
39
|
+
*/
|
|
40
|
+
export declare function spaceActionsNotRunnableReason(space: Pick<SpaceWithActions, 'id' | 'leadAgentId'>, bin: string): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Find a space custom action by the id `spaces actions list` prints, or by the
|
|
43
|
+
* `space-custom:<id>` form the projected quick-action surfaces use.
|
|
44
|
+
*/
|
|
45
|
+
export declare function findSpaceCustomAction(space: SpaceWithActions, ref: string): {
|
|
46
|
+
customAction: SpaceCustomAction;
|
|
47
|
+
index: number;
|
|
48
|
+
} | {
|
|
49
|
+
problem: string;
|
|
50
|
+
};
|
|
51
|
+
export type SpaceQuickActionRow = {
|
|
52
|
+
source: 'space' | 'agent';
|
|
53
|
+
title: string;
|
|
54
|
+
owner: string;
|
|
55
|
+
type: string;
|
|
56
|
+
ref: string;
|
|
57
|
+
run: string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Everything a space's action panel offers, in the order the web shows it: the
|
|
61
|
+
* space's own actions first, then the actions of member agents the caller can
|
|
62
|
+
* view, filtered by scope with the same predicate the web and server use.
|
|
63
|
+
*
|
|
64
|
+
* `spaces actions list` showed only the first half and `spaces actions
|
|
65
|
+
* available` a wider second half (every member agent, including ones the caller
|
|
66
|
+
* cannot run), so "what can I run here?" had no answer on the CLI (OSK-9641).
|
|
67
|
+
* Every row's `run` is a command `spaces actions run` accepts.
|
|
68
|
+
*/
|
|
69
|
+
export declare function spaceQuickActionRows(space: SpaceWithActions & {
|
|
70
|
+
labelIds?: string[] | null;
|
|
71
|
+
}, members: SpaceMemberActionsResponse['agents'], bin: string): SpaceQuickActionRow[];
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared shape for `skrr spaces actions add|update`.
|
|
4
|
+
*
|
|
5
|
+
* Both commands describe the same stored object, and they had drifted from the
|
|
6
|
+
* server that validates it (`spaceCustomActionSchema` in api/server/routes/spaces.js).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.spaceCustomActionLabelFlag = exports.spaceCustomActionIconFlag = exports.SPACE_CUSTOM_ACTION_ICON_MAX = void 0;
|
|
10
|
+
exports.spaceCustomActionIconProblem = spaceCustomActionIconProblem;
|
|
11
|
+
exports.spaceActionsNotRunnableReason = spaceActionsNotRunnableReason;
|
|
12
|
+
exports.findSpaceCustomAction = findSpaceCustomAction;
|
|
13
|
+
exports.spaceQuickActionRows = spaceQuickActionRows;
|
|
14
|
+
const core_1 = require("@oclif/core");
|
|
15
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
16
|
+
/**
|
|
17
|
+
* The server's limit on `icon`, which is `z.string().max(4)`.
|
|
18
|
+
*
|
|
19
|
+
* The flag used to be documented as "Lucide icon name". It is not one: the web
|
|
20
|
+
* settings page renders `action.icon` as literal text, and almost no Lucide name
|
|
21
|
+
* fits in four characters, so following the help produced a 400 with a raw Zod
|
|
22
|
+
* message and no hint that an emoji was wanted (OSK-9631).
|
|
23
|
+
*
|
|
24
|
+
* Zod's `max` counts UTF-16 code units, not visible characters, so the check
|
|
25
|
+
* below uses `String.prototype.length` to agree with it exactly. Counting
|
|
26
|
+
* graphemes instead would accept a family emoji the server then refuses.
|
|
27
|
+
*/
|
|
28
|
+
exports.SPACE_CUSTOM_ACTION_ICON_MAX = 4;
|
|
29
|
+
exports.spaceCustomActionIconFlag = core_1.Flags.string({
|
|
30
|
+
description: `Emoji shown on the button, e.g. ✨ (at most ${exports.SPACE_CUSTOM_ACTION_ICON_MAX} UTF-16 units). Not an icon name.`,
|
|
31
|
+
});
|
|
32
|
+
exports.spaceCustomActionLabelFlag = core_1.Flags.string({
|
|
33
|
+
description: 'Button text shown in the space. Not a Label entity — to offer an agent action in every space carrying a Label, use `agents actions create --label`.',
|
|
34
|
+
});
|
|
35
|
+
/** Refuse an icon the server would refuse, with a message that says what fits. */
|
|
36
|
+
function spaceCustomActionIconProblem(icon) {
|
|
37
|
+
if (icon === undefined || icon === null)
|
|
38
|
+
return null;
|
|
39
|
+
if (typeof icon !== 'string')
|
|
40
|
+
return '--icon must be text.';
|
|
41
|
+
if (icon.length > exports.SPACE_CUSTOM_ACTION_ICON_MAX) {
|
|
42
|
+
return (`--icon "${icon}" is too long: it is shown as text on the button and must be an emoji ` +
|
|
43
|
+
`(at most ${exports.SPACE_CUSTOM_ACTION_ICON_MAX} UTF-16 units), e.g. --icon ✨. ` +
|
|
44
|
+
'Icon names such as "Sparkles" are not accepted here.');
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Why a space's OWN actions cannot run, or null when they can.
|
|
50
|
+
*
|
|
51
|
+
* A space custom action runs as a task assigned to the Space Leader, so on a
|
|
52
|
+
* space with no Leader every one of them is dead on arrival. That fact used to
|
|
53
|
+
* live only in a tooltip on a disabled web button: `spaces actions add` reported
|
|
54
|
+
* success, `spaces actions list` listed the action happily, and nothing on the
|
|
55
|
+
* CLI said it could never run (OSK-9641).
|
|
56
|
+
*/
|
|
57
|
+
function spaceActionsNotRunnableReason(space, bin) {
|
|
58
|
+
if (space.leadAgentId)
|
|
59
|
+
return null;
|
|
60
|
+
return (`This space has no Space Leader, so its own actions cannot run: each runs as a task ` +
|
|
61
|
+
`assigned to the Leader. Set one with \`${bin} spaces update ${space.id} --lead-agent <agent-id>\`.`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Find a space custom action by the id `spaces actions list` prints, or by the
|
|
65
|
+
* `space-custom:<id>` form the projected quick-action surfaces use.
|
|
66
|
+
*/
|
|
67
|
+
function findSpaceCustomAction(space, ref) {
|
|
68
|
+
const actions = space.customActions ?? [];
|
|
69
|
+
const id = (0, data_provider_1.spaceCustomActionSourceId)(ref) ?? ref;
|
|
70
|
+
const index = actions.findIndex((action) => action.id === id);
|
|
71
|
+
if (index >= 0)
|
|
72
|
+
return { customAction: actions[index], index };
|
|
73
|
+
if (actions.length === 0) {
|
|
74
|
+
return { problem: `Space ${space.id} has no custom actions.` };
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
problem: `No custom action ${ref} in space ${space.id}. It has: ` +
|
|
78
|
+
actions.map((action) => `${action.id} (${action.label})`).join(', ') +
|
|
79
|
+
'.',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Everything a space's action panel offers, in the order the web shows it: the
|
|
84
|
+
* space's own actions first, then the actions of member agents the caller can
|
|
85
|
+
* view, filtered by scope with the same predicate the web and server use.
|
|
86
|
+
*
|
|
87
|
+
* `spaces actions list` showed only the first half and `spaces actions
|
|
88
|
+
* available` a wider second half (every member agent, including ones the caller
|
|
89
|
+
* cannot run), so "what can I run here?" had no answer on the CLI (OSK-9641).
|
|
90
|
+
* Every row's `run` is a command `spaces actions run` accepts.
|
|
91
|
+
*/
|
|
92
|
+
function spaceQuickActionRows(space, members, bin) {
|
|
93
|
+
const subject = { spaceId: space.id, labelIds: space.labelIds ?? [] };
|
|
94
|
+
const leaderMissing = !space.leadAgentId;
|
|
95
|
+
return [
|
|
96
|
+
...(space.customActions ?? []).map((action) => ({
|
|
97
|
+
source: 'space',
|
|
98
|
+
title: action.label,
|
|
99
|
+
owner: 'Space Leader',
|
|
100
|
+
type: 'prompt',
|
|
101
|
+
ref: action.id,
|
|
102
|
+
run: leaderMissing
|
|
103
|
+
? '(needs a Space Leader)'
|
|
104
|
+
: `${bin} spaces actions run ${space.id} ${action.id}`,
|
|
105
|
+
})),
|
|
106
|
+
...members.flatMap(({ agent }) => (agent.agentActions ?? [])
|
|
107
|
+
.filter((action) => (0, data_provider_1.isAgentActionAvailableInSpace)(action, subject))
|
|
108
|
+
.map((action) => ({
|
|
109
|
+
source: 'agent',
|
|
110
|
+
title: action.title,
|
|
111
|
+
owner: agent.name ?? agent.id,
|
|
112
|
+
type: (0, data_provider_1.isBuiltinAgentAction)(action) ? `builtin:${action.builtinType}` : 'prompt',
|
|
113
|
+
ref: `${agent.id}:${action.id}`,
|
|
114
|
+
run: `${bin} spaces actions run ${space.id} ${agent.id}:${action.id}`,
|
|
115
|
+
}))),
|
|
116
|
+
];
|
|
117
|
+
}
|
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Space reference resolution — turn what a person typed into exactly one
|
|
3
|
-
* space id, or an actionable failure.
|
|
4
|
-
*
|
|
5
|
-
* Every `--space` flag in the CLI (35 commands at last count) took a raw UUID
|
|
6
|
-
* and nothing else. Passing a name did not error — it filtered on a UUID that
|
|
7
|
-
* matches no space and returned an empty result:
|
|
8
|
-
*
|
|
9
|
-
* skrr tasks list --space "Always on" → "No tasks."
|
|
10
|
-
*
|
|
11
|
-
* A person retries. An agent concludes the space is empty and proceeds on a
|
|
12
|
-
* false premise, which is the failure mode this module exists to remove. The
|
|
13
|
-
* contract is deliberately narrow: a value that already looks like an id is
|
|
14
|
-
* forwarded untouched (no request, no behavior change for existing scripts);
|
|
15
|
-
* anything else must resolve to exactly one space or the command fails.
|
|
16
|
-
*
|
|
17
|
-
* Modeled on `assignee-resolver.ts`, which already does this for people and
|
|
18
|
-
* agents — `--assignee-user frank` has worked for a while. Spaces were the
|
|
19
|
-
* outlier, not the exception.
|
|
20
|
-
*/
|
|
21
1
|
export type SpaceRef = {
|
|
22
2
|
/** The space UUID — what every `--space` flag ultimately wants. */
|
|
23
3
|
id: string;
|
|
@@ -36,7 +16,7 @@ export type SpaceResolutionFailure = {
|
|
|
36
16
|
* hides. Distinct from NOT_FOUND because the fix is different:
|
|
37
17
|
* pass --include-archived (or the id), not a different name.
|
|
38
18
|
*/
|
|
39
|
-
code: 'NOT_FOUND' | 'AMBIGUOUS' | 'ARCHIVED';
|
|
19
|
+
code: 'NOT_FOUND' | 'AMBIGUOUS' | 'ARCHIVED' | 'NOT_A_REFERENCE';
|
|
40
20
|
query: string;
|
|
41
21
|
candidates: SpaceRef[];
|
|
42
22
|
};
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SPACE_CLI_ERROR_CODE = void 0;
|
|
4
|
+
exports.looksLikeSpaceId = looksLikeSpaceId;
|
|
5
|
+
exports.looksLikeCanonicalSpaceId = looksLikeCanonicalSpaceId;
|
|
6
|
+
exports.normalizeSpaceRef = normalizeSpaceRef;
|
|
7
|
+
exports.spaceRefFrom = spaceRefFrom;
|
|
8
|
+
exports.resolveSpaceRef = resolveSpaceRef;
|
|
9
|
+
exports.describeSpace = describeSpace;
|
|
10
|
+
exports.describeSpaceCandidates = describeSpaceCandidates;
|
|
11
|
+
exports.formatSpaceResolutionFailure = formatSpaceResolutionFailure;
|
|
12
|
+
const failed_lookup_1 = require("./failed-lookup");
|
|
2
13
|
/**
|
|
3
14
|
* Space reference resolution — turn what a person typed into exactly one
|
|
4
15
|
* space id, or an actionable failure.
|
|
@@ -19,16 +30,6 @@
|
|
|
19
30
|
* agents — `--assignee-user frank` has worked for a while. Spaces were the
|
|
20
31
|
* outlier, not the exception.
|
|
21
32
|
*/
|
|
22
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.SPACE_CLI_ERROR_CODE = void 0;
|
|
24
|
-
exports.looksLikeSpaceId = looksLikeSpaceId;
|
|
25
|
-
exports.looksLikeCanonicalSpaceId = looksLikeCanonicalSpaceId;
|
|
26
|
-
exports.normalizeSpaceRef = normalizeSpaceRef;
|
|
27
|
-
exports.spaceRefFrom = spaceRefFrom;
|
|
28
|
-
exports.resolveSpaceRef = resolveSpaceRef;
|
|
29
|
-
exports.describeSpace = describeSpace;
|
|
30
|
-
exports.describeSpaceCandidates = describeSpaceCandidates;
|
|
31
|
-
exports.formatSpaceResolutionFailure = formatSpaceResolutionFailure;
|
|
32
33
|
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}$/;
|
|
33
34
|
const OBJECT_ID_RE = /^[0-9a-fA-F]{24}$/;
|
|
34
35
|
/**
|
|
@@ -106,6 +107,11 @@ function resolveSpaceRef(query, spaces) {
|
|
|
106
107
|
if (!q) {
|
|
107
108
|
return { ok: false, code: 'NOT_FOUND', query: raw, candidates: spaces };
|
|
108
109
|
}
|
|
110
|
+
// A failed lookup's output is refused before the name tiers can match it.
|
|
111
|
+
// See `failed-lookup.ts`.
|
|
112
|
+
if ((0, failed_lookup_1.isFailedLookupValue)(raw)) {
|
|
113
|
+
return { ok: false, code: 'NOT_A_REFERENCE', query: raw, candidates: [] };
|
|
114
|
+
}
|
|
109
115
|
// An exact id or ref wins over everything, archived or not: both are
|
|
110
116
|
// explicit and unambiguous, so there is nothing to protect the caller from.
|
|
111
117
|
// Names are matched against live spaces only — see the ARCHIVED branch.
|
|
@@ -159,6 +165,8 @@ function describeSpaceCandidates(candidates, limit = 10) {
|
|
|
159
165
|
/** One human-readable block per failure, suitable for a CLI error body. */
|
|
160
166
|
function formatSpaceResolutionFailure(failure, bin = 'skrr') {
|
|
161
167
|
switch (failure.code) {
|
|
168
|
+
case 'NOT_A_REFERENCE':
|
|
169
|
+
return (0, failed_lookup_1.describeFailedLookupValue)(failure.query, 'Space');
|
|
162
170
|
case 'AMBIGUOUS':
|
|
163
171
|
return (`"${failure.query}" matches ${failure.candidates.length} spaces:\n` +
|
|
164
172
|
`${describeSpaceCandidates(failure.candidates)}\n` +
|
|
@@ -178,4 +186,5 @@ exports.SPACE_CLI_ERROR_CODE = {
|
|
|
178
186
|
AMBIGUOUS: 'SPACE_AMBIGUOUS',
|
|
179
187
|
ARCHIVED: 'SPACE_ARCHIVED',
|
|
180
188
|
NOT_FOUND: 'SPACE_NOT_FOUND',
|
|
189
|
+
NOT_A_REFERENCE: 'SPACE_NOT_A_REFERENCE',
|
|
181
190
|
};
|
|
@@ -28,5 +28,6 @@ export type ClosureLike = TaskClosureEvaluation | {
|
|
|
28
28
|
* the whole point is to be able to act without a second lookup.
|
|
29
29
|
*/
|
|
30
30
|
export declare function closureReport(closure: ClosureLike): string[];
|
|
31
|
-
/** `met (agent)` vs `met (
|
|
32
|
-
export
|
|
31
|
+
/** `met (agent)` vs `met (person)` — shared with the web through data-provider. */
|
|
32
|
+
export { describeAssessorKind as describeAssessor } from '@skrr-ai/data-provider';
|
|
33
|
+
export { describeClosure as closureSnapshotLines, type TaskClosureSnapshot as ClosureSnapshot, } from '@skrr-ai/data-provider';
|