@skrr-ai/cli 0.1.36 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -4
- package/bin/dev-fallback.js +167 -4
- package/dist/base-command.js +46 -2
- package/dist/commands/agents/actions/create.d.ts +5 -0
- package/dist/commands/agents/actions/create.js +42 -5
- 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.d.ts +5 -0
- package/dist/commands/agents/actions/update.js +27 -1
- package/dist/commands/agents/api-actions/add.d.ts +41 -0
- package/dist/commands/agents/api-actions/add.js +205 -0
- package/dist/commands/agents/api-actions/index.d.ts +39 -0
- package/dist/commands/agents/api-actions/index.js +103 -0
- package/dist/commands/agents/api-actions/remove.d.ts +14 -0
- package/dist/commands/agents/api-actions/remove.js +36 -0
- package/dist/commands/agents/avatar/default/apply.d.ts +25 -0
- package/dist/commands/agents/avatar/default/apply.js +56 -0
- package/dist/commands/agents/avatar/default/index.d.ts +29 -0
- package/dist/commands/agents/avatar/default/index.js +61 -0
- package/dist/commands/agents/avatar/default/set.d.ts +24 -0
- package/dist/commands/agents/avatar/default/set.js +120 -0
- package/dist/commands/agents/avatar/library/delete.d.ts +20 -0
- package/dist/commands/agents/avatar/library/delete.js +47 -0
- package/dist/commands/agents/avatar/library/index.d.ts +16 -0
- package/dist/commands/agents/avatar/library/index.js +56 -0
- package/dist/commands/agents/avatar/presets.d.ts +19 -0
- package/dist/commands/agents/avatar/presets.js +56 -0
- package/dist/commands/agents/avatar/upload.js +7 -1
- package/dist/commands/agents/categories/create.d.ts +14 -0
- package/dist/commands/agents/categories/create.js +46 -0
- package/dist/commands/agents/categories/delete.d.ts +13 -0
- package/dist/commands/agents/categories/delete.js +41 -0
- package/dist/commands/agents/categories/index.d.ts +36 -0
- package/dist/commands/agents/categories/index.js +135 -0
- package/dist/commands/agents/categories/update.d.ts +22 -0
- package/dist/commands/agents/categories/update.js +59 -0
- package/dist/commands/agents/chat.d.ts +21 -0
- package/dist/commands/agents/chat.js +94 -7
- package/dist/commands/agents/create.d.ts +10 -0
- package/dist/commands/agents/create.js +64 -3
- package/dist/commands/agents/ensure-default.d.ts +27 -0
- package/dist/commands/agents/ensure-default.js +65 -0
- package/dist/commands/agents/list.d.ts +15 -0
- package/dist/commands/agents/list.js +31 -1
- package/dist/commands/agents/mute.d.ts +16 -0
- package/dist/commands/agents/mute.js +38 -0
- package/dist/commands/agents/pin.d.ts +16 -0
- package/dist/commands/agents/pin.js +38 -0
- 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/auth.d.ts +19 -0
- package/dist/commands/agents/tools/auth.js +41 -0
- package/dist/commands/agents/tools/calls.d.ts +36 -0
- package/dist/commands/agents/tools/calls.js +117 -0
- package/dist/commands/agents/tools/index.d.ts +20 -0
- package/dist/commands/agents/tools/index.js +77 -0
- package/dist/commands/agents/unmute.d.ts +16 -0
- package/dist/commands/agents/unmute.js +38 -0
- package/dist/commands/agents/unpin.d.ts +16 -0
- package/dist/commands/agents/unpin.js +38 -0
- package/dist/commands/agents/update.d.ts +12 -0
- package/dist/commands/agents/update.js +74 -3
- 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.d.ts +22 -0
- package/dist/commands/followups/act.js +103 -0
- package/dist/commands/followups/cancel.d.ts +20 -0
- package/dist/commands/followups/cancel.js +50 -0
- package/dist/commands/followups/checkin.d.ts +27 -0
- package/dist/commands/followups/checkin.js +107 -0
- package/dist/commands/followups/list.d.ts +24 -0
- package/dist/commands/followups/list.js +90 -0
- package/dist/commands/followups/observability.d.ts +23 -0
- package/dist/commands/followups/observability.js +114 -0
- package/dist/commands/followups/remind.d.ts +26 -0
- package/dist/commands/followups/remind.js +106 -0
- package/dist/commands/followups/reschedule.d.ts +15 -0
- package/dist/commands/followups/reschedule.js +48 -0
- package/dist/commands/followups/resolve.d.ts +23 -0
- package/dist/commands/followups/resolve.js +54 -0
- package/dist/commands/followups/show.d.ts +12 -0
- package/dist/commands/followups/show.js +46 -0
- package/dist/commands/followups/watch.d.ts +51 -0
- package/dist/commands/followups/watch.js +211 -0
- package/dist/commands/goals/labels/add.js +19 -2
- package/dist/commands/goals/labels/remove.js +22 -2
- 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/labels/list.d.ts +24 -1
- package/dist/commands/labels/list.js +62 -19
- 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 +58 -1
- package/dist/commands/machines/dedicated/destroy.js +18 -4
- package/dist/commands/machines/dedicated/list.js +9 -6
- 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/memory/governance/index.d.ts +21 -0
- package/dist/commands/memory/governance/index.js +64 -0
- package/dist/commands/memory/governance/set.d.ts +24 -0
- package/dist/commands/memory/governance/set.js +95 -0
- package/dist/commands/memory/provenance.d.ts +18 -0
- package/dist/commands/memory/provenance.js +66 -0
- 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/create.d.ts +3 -0
- package/dist/commands/spaces/create.js +32 -2
- package/dist/commands/spaces/label-summaries.d.ts +27 -0
- package/dist/commands/spaces/label-summaries.js +64 -0
- package/dist/commands/spaces/labels/add.js +19 -2
- package/dist/commands/spaces/labels/remove.js +22 -2
- package/dist/commands/spaces/show.js +2 -0
- package/dist/commands/spaces/task-rollups.d.ts +5 -0
- package/dist/commands/spaces/task-rollups.js +15 -4
- package/dist/commands/spaces/update.d.ts +5 -0
- package/dist/commands/spaces/update.js +41 -4
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +11 -0
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +105 -0
- package/dist/commands/tasks/actions/attach.js +32 -7
- package/dist/commands/tasks/complete.d.ts +1 -0
- package/dist/commands/tasks/complete.js +21 -1
- package/dist/commands/tasks/create.d.ts +3 -0
- package/dist/commands/tasks/create.js +34 -2
- package/dist/commands/tasks/events/append.js +29 -6
- package/dist/commands/tasks/expectations/assess.d.ts +12 -0
- package/dist/commands/tasks/expectations/assess.js +123 -14
- package/dist/commands/tasks/expectations.js +95 -17
- package/dist/commands/tasks/follow-up.js +2 -2
- package/dist/commands/tasks/labels/attach.js +20 -3
- package/dist/commands/tasks/labels/detach.js +21 -3
- package/dist/commands/tasks/lifecycle/attach.d.ts +14 -0
- package/dist/commands/tasks/lifecycle/attach.js +47 -0
- package/dist/commands/tasks/lifecycle/definitions.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/definitions.js +59 -0
- package/dist/commands/tasks/lifecycle/detach.d.ts +19 -0
- package/dist/commands/tasks/lifecycle/detach.js +72 -0
- package/dist/commands/tasks/lifecycle/history.d.ts +13 -0
- package/dist/commands/tasks/lifecycle/history.js +38 -0
- package/dist/commands/tasks/lifecycle/migrate.d.ts +14 -0
- package/dist/commands/tasks/lifecycle/migrate.js +68 -0
- package/dist/commands/tasks/lifecycle/reconcile.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/reconcile.js +27 -0
- package/dist/commands/tasks/lifecycle/reopen.d.ts +15 -0
- package/dist/commands/tasks/lifecycle/reopen.js +71 -0
- package/dist/commands/tasks/lifecycle/show.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/show.js +27 -0
- package/dist/commands/tasks/lifecycle/start.d.ts +12 -0
- package/dist/commands/tasks/lifecycle/start.js +30 -0
- package/dist/commands/tasks/lifecycle/transition.d.ts +15 -0
- package/dist/commands/tasks/lifecycle/transition.js +109 -0
- package/dist/commands/tasks/list.js +16 -9
- package/dist/commands/tasks/move.d.ts +1 -0
- package/dist/commands/tasks/move.js +29 -0
- package/dist/commands/tasks/result/submit.js +11 -1
- package/dist/commands/tasks/review-queue.d.ts +44 -0
- package/dist/commands/tasks/review-queue.js +314 -0
- package/dist/commands/tasks/show.d.ts +11 -0
- package/dist/commands/tasks/show.js +139 -4
- package/dist/commands/tasks/trust.js +7 -2
- package/dist/commands/tasks/update.d.ts +1 -0
- package/dist/commands/tasks/update.js +83 -0
- 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 +92 -11
- package/dist/lib/agent-actions.js +171 -25
- package/dist/lib/agent-config.d.ts +11 -0
- package/dist/lib/agent-config.js +85 -3
- package/dist/lib/agent-pin-mute.d.ts +29 -0
- package/dist/lib/agent-pin-mute.js +30 -0
- package/dist/lib/agent-visual-refs.d.ts +33 -0
- package/dist/lib/agent-visual-refs.js +267 -0
- 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 +13 -0
- package/dist/lib/dedicated-lease-command.js +22 -1
- package/dist/lib/dedicated-machines.d.ts +95 -1
- package/dist/lib/dedicated-machines.js +236 -2
- 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 +16 -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 +115 -0
- package/dist/lib/followups.js +127 -0
- 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-ref.d.ts +95 -0
- package/dist/lib/label-ref.js +163 -0
- package/dist/lib/label-scope.d.ts +17 -2
- package/dist/lib/label-scope.js +27 -7
- 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 +33 -0
- package/dist/lib/task-closure.js +104 -0
- package/dist/lib/task-lifecycle-output.d.ts +14 -0
- package/dist/lib/task-lifecycle-output.js +209 -0
- package/dist/lib/task-ref-resolver.d.ts +1 -17
- package/dist/lib/task-ref-resolver.js +18 -8
- package/dist/lib/tasks.d.ts +3 -0
- package/dist/lib/tasks.js +40 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +5559 -4897
- package/oclif.manifest.json +33890 -28690
- package/package.json +24 -6
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_crypto_1 = require("node:crypto");
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
6
|
const base_command_1 = require("../../../base-command");
|
|
6
7
|
const prompt_1 = require("../../../lib/prompt");
|
|
7
8
|
const space_output_1 = require("../../../lib/space-output");
|
|
9
|
+
const space_custom_actions_1 = require("../../../lib/space-custom-actions");
|
|
8
10
|
class SpacesActionsAdd extends base_command_1.BaseCommand {
|
|
9
11
|
static description = 'Add a custom action to a space';
|
|
10
12
|
static args = {
|
|
@@ -13,11 +15,11 @@ class SpacesActionsAdd extends base_command_1.BaseCommand {
|
|
|
13
15
|
static flags = {
|
|
14
16
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
15
17
|
'from-json': core_1.Flags.string({ description: 'JSON action body' }),
|
|
16
|
-
id: core_1.Flags.string({ description: 'Action ID' }),
|
|
17
|
-
label:
|
|
18
|
+
id: core_1.Flags.string({ description: 'Action ID (generated when omitted)' }),
|
|
19
|
+
label: space_custom_actions_1.spaceCustomActionLabelFlag,
|
|
18
20
|
prompt: core_1.Flags.string({ description: 'Prompt sent when the action runs' }),
|
|
19
21
|
color: core_1.Flags.string({ description: 'Color hex' }),
|
|
20
|
-
icon:
|
|
22
|
+
icon: space_custom_actions_1.spaceCustomActionIconFlag,
|
|
21
23
|
skill: core_1.Flags.string({ description: 'Optional skill ID' }),
|
|
22
24
|
};
|
|
23
25
|
async run() {
|
|
@@ -31,7 +33,10 @@ class SpacesActionsAdd extends base_command_1.BaseCommand {
|
|
|
31
33
|
this.error(err.message, { exit: 1 });
|
|
32
34
|
}
|
|
33
35
|
const payload = (0, prompt_1.mergeDefined)(body, {
|
|
34
|
-
|
|
36
|
+
// Generated when omitted, as `agents actions create` does. Demanding the
|
|
37
|
+
// caller invent an id — with only "Action id is required." to go on — was
|
|
38
|
+
// the one required field nothing else could supply.
|
|
39
|
+
id: flags.id ?? (typeof body.id === 'string' && body.id ? body.id : `act_${(0, node_crypto_1.randomUUID)()}`),
|
|
35
40
|
label: flags.label,
|
|
36
41
|
prompt: flags.prompt,
|
|
37
42
|
color: flags.color,
|
|
@@ -41,6 +46,9 @@ class SpacesActionsAdd extends base_command_1.BaseCommand {
|
|
|
41
46
|
for (const field of ['id', 'label', 'prompt', 'color'])
|
|
42
47
|
if (!payload[field] || typeof payload[field] !== 'string')
|
|
43
48
|
this.error(`Action ${field} is required.`, { exit: 1 });
|
|
49
|
+
const iconProblem = (0, space_custom_actions_1.spaceCustomActionIconProblem)(payload.icon);
|
|
50
|
+
if (iconProblem)
|
|
51
|
+
this.error(iconProblem, { exit: 1 });
|
|
44
52
|
let result;
|
|
45
53
|
try {
|
|
46
54
|
result = await data_provider_1.dataService.addSpaceCustomAction({
|
|
@@ -51,10 +59,20 @@ class SpacesActionsAdd extends base_command_1.BaseCommand {
|
|
|
51
59
|
catch (err) {
|
|
52
60
|
this.handleApiError(err);
|
|
53
61
|
}
|
|
62
|
+
// `--json` returns the action that was added, not the whole Space. The
|
|
63
|
+
// server answers with the full Space document — 117 lines in which the
|
|
64
|
+
// five-field action is buried — while `agents actions create --json`
|
|
65
|
+
// returns just the action. A create returns the thing it created.
|
|
66
|
+
const stored = (result?.customActions ?? []).find((action) => action.id === payload.id) ?? payload;
|
|
54
67
|
if (flags.json)
|
|
55
|
-
this.log(JSON.stringify((0, space_output_1.withSpaceResourceUrls)(this.cliConfig.baseURL, args.id, 'actions',
|
|
68
|
+
this.log(JSON.stringify((0, space_output_1.withSpaceResourceUrls)(this.cliConfig.baseURL, args.id, 'actions', stored, ['id']), null, 2));
|
|
56
69
|
else
|
|
57
70
|
this.log(`Added custom action ${String(payload.id)}.`);
|
|
71
|
+
// On stderr, so `--json` stays parseable: the action was saved, and still
|
|
72
|
+
// cannot run until the space has a Leader (OSK-9641).
|
|
73
|
+
const unrunnable = (0, space_custom_actions_1.spaceActionsNotRunnableReason)({ id: args.id, leadAgentId: result?.leadAgentId }, this.config.bin);
|
|
74
|
+
if (unrunnable)
|
|
75
|
+
this.warn(unrunnable);
|
|
58
76
|
}
|
|
59
77
|
}
|
|
60
78
|
exports.default = SpacesActionsAdd;
|
|
@@ -51,7 +51,10 @@ class SpacesActionsAvailable extends base_command_1.BaseCommand {
|
|
|
51
51
|
{ key: 'ref', header: 'REF (agentId:actionId)' },
|
|
52
52
|
], (line) => this.log(line));
|
|
53
53
|
this.log('');
|
|
54
|
+
// The REF is for two commands, and they need different rights: attaching
|
|
55
|
+
// works for any space member, running needs VIEW on the agent (OSK-9663).
|
|
54
56
|
this.log('Attach to a task: skrr tasks actions attach <task-id> <agentId>:<actionId>');
|
|
57
|
+
this.log(`Run one in this space: skrr spaces actions run ${args.id} <agentId>:<actionId> (needs access to the agent; see what you can run with: skrr spaces actions list ${args.id} --all)`);
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
exports.default = SpacesActionsAvailable;
|
|
@@ -4,8 +4,13 @@ export default class SpacesActionsList extends BaseCommand {
|
|
|
4
4
|
static args: {
|
|
5
5
|
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
6
|
};
|
|
7
|
+
static examples: string[];
|
|
7
8
|
static flags: {
|
|
8
9
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
11
|
};
|
|
10
12
|
run(): Promise<void>;
|
|
13
|
+
/** Say, on stderr, when none of the listed space actions can run. */
|
|
14
|
+
private noteUnrunnable;
|
|
15
|
+
private listAll;
|
|
11
16
|
}
|
|
@@ -4,13 +4,23 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
5
|
const base_command_1 = require("../../../base-command");
|
|
6
6
|
const format_1 = require("../../../lib/format");
|
|
7
|
+
const space_custom_actions_1 = require("../../../lib/space-custom-actions");
|
|
7
8
|
const space_output_1 = require("../../../lib/space-output");
|
|
8
9
|
class SpacesActionsList extends base_command_1.BaseCommand {
|
|
9
10
|
static description = 'List custom actions configured for a space';
|
|
10
11
|
static args = {
|
|
11
12
|
id: core_1.Args.string({ description: 'Space ID', required: true, ignoreStdin: true }),
|
|
12
13
|
};
|
|
13
|
-
static
|
|
14
|
+
static examples = [
|
|
15
|
+
'<%= config.bin %> spaces actions list <space-id>',
|
|
16
|
+
'<%= config.bin %> spaces actions list <space-id> --all',
|
|
17
|
+
];
|
|
18
|
+
static flags = {
|
|
19
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
20
|
+
all: core_1.Flags.boolean({
|
|
21
|
+
description: "Everything the space's action panel offers: its own actions and those of member agents you can view, each with the command that runs it",
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
14
24
|
async run() {
|
|
15
25
|
this.requireAuth();
|
|
16
26
|
const { args, flags } = await this.parse(SpacesActionsList);
|
|
@@ -22,12 +32,17 @@ class SpacesActionsList extends base_command_1.BaseCommand {
|
|
|
22
32
|
this.handleApiError(err);
|
|
23
33
|
}
|
|
24
34
|
const actions = space.customActions ?? [];
|
|
35
|
+
if (flags.all)
|
|
36
|
+
return this.listAll(space, flags.json);
|
|
25
37
|
if (flags.json)
|
|
26
38
|
return void this.log(JSON.stringify((0, space_output_1.withSpaceResourceUrls)(this.cliConfig.baseURL, args.id, 'actions', { data: actions }, [
|
|
27
39
|
'id',
|
|
28
40
|
]), null, 2));
|
|
29
|
-
if (!actions.length)
|
|
30
|
-
|
|
41
|
+
if (!actions.length) {
|
|
42
|
+
this.log('No custom actions.');
|
|
43
|
+
this.log(`Agent actions offered here: ${this.config.bin} spaces actions list ${args.id} --all`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
31
46
|
(0, format_1.renderTable)(actions.map((a) => ({
|
|
32
47
|
id: a.id,
|
|
33
48
|
label: a.label,
|
|
@@ -41,6 +56,37 @@ class SpacesActionsList extends base_command_1.BaseCommand {
|
|
|
41
56
|
{ key: 'skill', header: 'SKILL' },
|
|
42
57
|
{ key: 'id', header: 'ID' },
|
|
43
58
|
], (line) => this.log(line));
|
|
59
|
+
this.noteUnrunnable(space);
|
|
60
|
+
this.log(`Agent actions offered here too: ${this.config.bin} spaces actions list ${args.id} --all`);
|
|
61
|
+
}
|
|
62
|
+
/** Say, on stderr, when none of the listed space actions can run. */
|
|
63
|
+
noteUnrunnable(space) {
|
|
64
|
+
const reason = (0, space_custom_actions_1.spaceActionsNotRunnableReason)(space, this.config.bin);
|
|
65
|
+
if (reason)
|
|
66
|
+
this.warn(reason);
|
|
67
|
+
}
|
|
68
|
+
async listAll(space, json) {
|
|
69
|
+
let members;
|
|
70
|
+
try {
|
|
71
|
+
members = await data_provider_1.dataService.listSpaceMemberActions(space.id);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
this.handleApiError(err);
|
|
75
|
+
}
|
|
76
|
+
const rows = (0, space_custom_actions_1.spaceQuickActionRows)(space, members.agents, this.config.bin);
|
|
77
|
+
if (json)
|
|
78
|
+
return void this.log(JSON.stringify({ spaceId: space.id, data: rows }, null, 2));
|
|
79
|
+
if (!rows.length)
|
|
80
|
+
return void this.log('This space offers no quick actions.');
|
|
81
|
+
(0, format_1.renderTable)(rows, [
|
|
82
|
+
{ key: 'source', header: 'SOURCE' },
|
|
83
|
+
{ key: 'title', header: 'TITLE', maxWidth: 36 },
|
|
84
|
+
{ key: 'owner', header: 'RUNS AS', maxWidth: 24 },
|
|
85
|
+
{ key: 'type', header: 'TYPE' },
|
|
86
|
+
{ key: 'run', header: 'RUN' },
|
|
87
|
+
], (line) => this.log(line));
|
|
88
|
+
if (rows.some((row) => row.source === 'space'))
|
|
89
|
+
this.noteUnrunnable(space);
|
|
44
90
|
}
|
|
45
91
|
}
|
|
46
92
|
exports.default = SpacesActionsList;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Fire one of a space's quick actions, the way its Actions tab does.
|
|
4
|
+
*
|
|
5
|
+
* `spaces actions add` could create a space action and nothing on the CLI could
|
|
6
|
+
* run it (OSK-9641), and a space member handed `agentId:actionId` refs by
|
|
7
|
+
* `spaces actions available` had only `agents actions run`, which answers a
|
|
8
|
+
* member with 403 and opens a chat rather than working in the space (OSK-9663).
|
|
9
|
+
*
|
|
10
|
+
* The routing is the web runner's (`useSpaceQuickActionRunner`), not a new one:
|
|
11
|
+
* a prompt action runs as a task in this space, assigned to the Space Leader for
|
|
12
|
+
* a space's own action and to its agent for an agent's; a built-in action runs
|
|
13
|
+
* through the agent-action route. The task text comes from the same
|
|
14
|
+
* `spaceQuickActionTaskSpec` the web uses, so both surfaces hand the agent the
|
|
15
|
+
* same work.
|
|
16
|
+
*/
|
|
17
|
+
export default class SpacesActionsRun extends BaseCommand {
|
|
18
|
+
static description: string;
|
|
19
|
+
static examples: string[];
|
|
20
|
+
static args: {
|
|
21
|
+
space: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
22
|
+
action: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
23
|
+
};
|
|
24
|
+
static flags: {
|
|
25
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
|
+
};
|
|
27
|
+
run(): Promise<void>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../../base-command");
|
|
6
|
+
const space_custom_actions_1 = require("../../../lib/space-custom-actions");
|
|
7
|
+
const web_url_1 = require("../../../lib/web-url");
|
|
8
|
+
/**
|
|
9
|
+
* Fire one of a space's quick actions, the way its Actions tab does.
|
|
10
|
+
*
|
|
11
|
+
* `spaces actions add` could create a space action and nothing on the CLI could
|
|
12
|
+
* run it (OSK-9641), and a space member handed `agentId:actionId` refs by
|
|
13
|
+
* `spaces actions available` had only `agents actions run`, which answers a
|
|
14
|
+
* member with 403 and opens a chat rather than working in the space (OSK-9663).
|
|
15
|
+
*
|
|
16
|
+
* The routing is the web runner's (`useSpaceQuickActionRunner`), not a new one:
|
|
17
|
+
* a prompt action runs as a task in this space, assigned to the Space Leader for
|
|
18
|
+
* a space's own action and to its agent for an agent's; a built-in action runs
|
|
19
|
+
* through the agent-action route. The task text comes from the same
|
|
20
|
+
* `spaceQuickActionTaskSpec` the web uses, so both surfaces hand the agent the
|
|
21
|
+
* same work.
|
|
22
|
+
*/
|
|
23
|
+
class SpacesActionsRun extends base_command_1.BaseCommand {
|
|
24
|
+
static description = "Run a space quick action: the space's own (by id) or a member agent's (agentId:actionId)";
|
|
25
|
+
static examples = [
|
|
26
|
+
'<%= config.bin %> spaces actions run <space-id> <action-id>',
|
|
27
|
+
'<%= config.bin %> spaces actions run <space-id> <agent-id>:<action-id> --json',
|
|
28
|
+
];
|
|
29
|
+
static args = {
|
|
30
|
+
space: core_1.Args.string({ description: 'Space ID', required: true, ignoreStdin: true }),
|
|
31
|
+
action: core_1.Args.string({
|
|
32
|
+
description: "A space action id from 'spaces actions list', or agentId:actionId, both as 'spaces actions list --all' prints them",
|
|
33
|
+
required: true,
|
|
34
|
+
ignoreStdin: true,
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output as JSON' }) };
|
|
38
|
+
async run() {
|
|
39
|
+
this.requireAuth();
|
|
40
|
+
const { args, flags } = await this.parse(SpacesActionsRun);
|
|
41
|
+
const bin = this.config.bin;
|
|
42
|
+
let space;
|
|
43
|
+
try {
|
|
44
|
+
space = await data_provider_1.dataService.getSpace(args.space);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
this.handleApiError(err);
|
|
48
|
+
}
|
|
49
|
+
const colon = args.action.indexOf(':');
|
|
50
|
+
const agentRef = colon > 0 && !args.action.startsWith('space-custom:')
|
|
51
|
+
? { agentId: args.action.slice(0, colon), actionId: args.action.slice(colon + 1) }
|
|
52
|
+
: null;
|
|
53
|
+
let action;
|
|
54
|
+
let assigneeAgentId;
|
|
55
|
+
if (!agentRef) {
|
|
56
|
+
const found = (0, space_custom_actions_1.findSpaceCustomAction)(space, args.action);
|
|
57
|
+
if ('problem' in found)
|
|
58
|
+
this.error(found.problem, { exit: 4 });
|
|
59
|
+
const leaderProblem = (0, space_custom_actions_1.spaceActionsNotRunnableReason)(space, bin);
|
|
60
|
+
if (leaderProblem || !space.leadAgentId)
|
|
61
|
+
this.error(leaderProblem ?? '', { exit: 1 });
|
|
62
|
+
action = (0, data_provider_1.spaceCustomActionToAgentAction)(found.customAction, space, found.index);
|
|
63
|
+
assigneeAgentId = space.leadAgentId;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
let members;
|
|
67
|
+
try {
|
|
68
|
+
members = await data_provider_1.dataService.listSpaceMemberActions(args.space);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
this.handleApiError(err);
|
|
72
|
+
}
|
|
73
|
+
const member = members.agents.find(({ agent }) => agent.id === agentRef.agentId);
|
|
74
|
+
if (!member) {
|
|
75
|
+
this.error(`Agent ${agentRef.agentId} is not a member of this space that you can view, so you cannot ` +
|
|
76
|
+
`run its actions here. Attaching one to a task needs only the space: ` +
|
|
77
|
+
`\`${bin} tasks actions attach <task-id> ${args.action}\`. To run it, its owner has to share the agent with you.`, { exit: 1 });
|
|
78
|
+
}
|
|
79
|
+
const found = (member.agent.agentActions ?? []).find((a) => a.id === agentRef.actionId);
|
|
80
|
+
if (!found) {
|
|
81
|
+
this.error(`No action ${agentRef.actionId} on agent ${agentRef.agentId}. List what this space offers: \`${bin} spaces actions list ${args.space} --all\`.`, { exit: 4 });
|
|
82
|
+
}
|
|
83
|
+
if (!(0, data_provider_1.isAgentActionAvailableInSpace)(found, { spaceId: space.id, labelIds: space.labelIds })) {
|
|
84
|
+
this.error(`Action ${found.title} is not offered in this space (its scope is another space or a Label this space does not carry).`, { exit: 1 });
|
|
85
|
+
}
|
|
86
|
+
action = found;
|
|
87
|
+
assigneeAgentId = agentRef.agentId;
|
|
88
|
+
}
|
|
89
|
+
if ((0, data_provider_1.isBuiltinAgentAction)(action)) {
|
|
90
|
+
// A built-in is a typed platform operation owned by its agent, and runs
|
|
91
|
+
// through the agent-action route exactly as the web runner sends it.
|
|
92
|
+
let result;
|
|
93
|
+
try {
|
|
94
|
+
result = await data_provider_1.dataService.runAgentAction({
|
|
95
|
+
agent_id: assigneeAgentId,
|
|
96
|
+
action_id: action.id,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
this.handleApiError(err);
|
|
101
|
+
}
|
|
102
|
+
if (flags.json)
|
|
103
|
+
return void this.log(JSON.stringify(result, null, 2));
|
|
104
|
+
if (!result.ok)
|
|
105
|
+
this.error(result.error || result.reason || 'Action failed.', { exit: 1 });
|
|
106
|
+
this.log(`${action.title} ran.`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const outcome = (0, data_provider_1.agentActionOutcome)(action);
|
|
110
|
+
const spec = (0, data_provider_1.spaceQuickActionTaskSpec)(action, { id: space.id, title: space.title });
|
|
111
|
+
let created;
|
|
112
|
+
try {
|
|
113
|
+
created = await data_provider_1.dataService.createAndStartTask({
|
|
114
|
+
...spec,
|
|
115
|
+
spaceId: space.id,
|
|
116
|
+
assigneeAgentIds: [assigneeAgentId],
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
this.handleApiError(err, { subject: `Action ${action.title}` });
|
|
121
|
+
}
|
|
122
|
+
const taskUrl = (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, created.task);
|
|
123
|
+
if (flags.json) {
|
|
124
|
+
this.log(JSON.stringify({ ...created, outcome, assigneeAgentId, ...(taskUrl ? { taskUrl } : {}) }, null, 2));
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const identifier = created.task.identifier ?? created.task.id;
|
|
128
|
+
this.log(created.started
|
|
129
|
+
? `Started ${action.title} as task ${identifier}.`
|
|
130
|
+
: `Created task ${identifier} for ${action.title}, but it did not start: ${created.startError ?? 'no reason given'}.`);
|
|
131
|
+
if (taskUrl)
|
|
132
|
+
this.log(`Task: ${taskUrl}`);
|
|
133
|
+
if (created.conversationId)
|
|
134
|
+
this.log(`Conversation: ${created.conversationId}`);
|
|
135
|
+
if (created.started && outcome === 'ephemeral') {
|
|
136
|
+
// The web hides an ephemeral action's task when the run finishes, from
|
|
137
|
+
// the tab that fired it. The CLI does not wait for the run, so say what
|
|
138
|
+
// will be different rather than let the task's staying look like a bug.
|
|
139
|
+
this.log(`This action is ephemeral. The web app hides its task when the run finishes; from the CLI it stays until you hide it: \`${bin} tasks move ${created.task.id} --status hidden\`.`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (!created.started)
|
|
143
|
+
this.exit(1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.default = SpacesActionsRun;
|
|
@@ -5,6 +5,7 @@ const data_provider_1 = require("@skrr-ai/data-provider");
|
|
|
5
5
|
const base_command_1 = require("../../../base-command");
|
|
6
6
|
const prompt_1 = require("../../../lib/prompt");
|
|
7
7
|
const space_output_1 = require("../../../lib/space-output");
|
|
8
|
+
const space_custom_actions_1 = require("../../../lib/space-custom-actions");
|
|
8
9
|
class SpacesActionsUpdate extends base_command_1.BaseCommand {
|
|
9
10
|
static description = 'Update a custom action in a space';
|
|
10
11
|
static args = {
|
|
@@ -14,10 +15,10 @@ class SpacesActionsUpdate extends base_command_1.BaseCommand {
|
|
|
14
15
|
static flags = {
|
|
15
16
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
16
17
|
'from-json': core_1.Flags.string({ description: 'JSON action patch' }),
|
|
17
|
-
label:
|
|
18
|
+
label: space_custom_actions_1.spaceCustomActionLabelFlag,
|
|
18
19
|
prompt: core_1.Flags.string({ description: 'Prompt sent when the action runs' }),
|
|
19
20
|
color: core_1.Flags.string({ description: 'Color hex' }),
|
|
20
|
-
icon:
|
|
21
|
+
icon: space_custom_actions_1.spaceCustomActionIconFlag,
|
|
21
22
|
skill: core_1.Flags.string({ description: 'Optional skill ID' }),
|
|
22
23
|
};
|
|
23
24
|
async run() {
|
|
@@ -30,21 +31,39 @@ class SpacesActionsUpdate extends base_command_1.BaseCommand {
|
|
|
30
31
|
catch (err) {
|
|
31
32
|
this.error(err.message, { exit: 1 });
|
|
32
33
|
}
|
|
33
|
-
const
|
|
34
|
+
const patch = (0, prompt_1.mergeDefined)(body, {
|
|
34
35
|
label: flags.label,
|
|
35
36
|
prompt: flags.prompt,
|
|
36
37
|
color: flags.color,
|
|
37
38
|
icon: flags.icon,
|
|
38
39
|
skillId: flags.skill,
|
|
39
40
|
});
|
|
40
|
-
if (!Object.keys(
|
|
41
|
+
if (!Object.keys(patch).length)
|
|
41
42
|
this.error('Nothing to update.', { exit: 1 });
|
|
43
|
+
const iconProblem = (0, space_custom_actions_1.spaceCustomActionIconProblem)(patch.icon);
|
|
44
|
+
if (iconProblem)
|
|
45
|
+
this.error(iconProblem, { exit: 1 });
|
|
42
46
|
let result;
|
|
47
|
+
let leadAgentId;
|
|
43
48
|
try {
|
|
49
|
+
// The server replaces the WHOLE element (`$set: {'customActions.$': action}`)
|
|
50
|
+
// and validates a complete action — `id`, `label`, `prompt`, `color` — whose
|
|
51
|
+
// `id` must equal the path's. This command sent only the changed flags, so
|
|
52
|
+
// every call failed that validation: `--label` alone, `--prompt` alone, all
|
|
53
|
+
// of them together, 400 "Invalid request data" every time (OSK-9646). The
|
|
54
|
+
// web editor never hit it because it always sends the full action.
|
|
55
|
+
//
|
|
56
|
+
// So the patch is applied over the stored action here and sent whole.
|
|
57
|
+
const space = await data_provider_1.dataService.getSpace(args.space);
|
|
58
|
+
leadAgentId = space.leadAgentId;
|
|
59
|
+
const current = (space.customActions ?? []).find((action) => action.id === args.id);
|
|
60
|
+
if (!current) {
|
|
61
|
+
this.error(`No custom action ${args.id} in space ${args.space}. List them with \`spaces actions list ${args.space}\`.`, { exit: 1 });
|
|
62
|
+
}
|
|
44
63
|
result = await data_provider_1.dataService.updateSpaceCustomAction({
|
|
45
64
|
spaceId: args.space,
|
|
46
65
|
actionId: args.id,
|
|
47
|
-
action:
|
|
66
|
+
action: { ...current, ...patch, id: args.id },
|
|
48
67
|
});
|
|
49
68
|
}
|
|
50
69
|
catch (err) {
|
|
@@ -54,6 +73,9 @@ class SpacesActionsUpdate extends base_command_1.BaseCommand {
|
|
|
54
73
|
this.log(JSON.stringify((0, space_output_1.withSpaceResourceUrls)(this.cliConfig.baseURL, args.space, 'actions', result, ['id']), null, 2));
|
|
55
74
|
else
|
|
56
75
|
this.log(`Updated custom action ${args.id}.`);
|
|
76
|
+
const unrunnable = (0, space_custom_actions_1.spaceActionsNotRunnableReason)({ id: args.space, leadAgentId }, this.config.bin);
|
|
77
|
+
if (unrunnable)
|
|
78
|
+
this.warn(unrunnable);
|
|
57
79
|
}
|
|
58
80
|
}
|
|
59
81
|
exports.default = SpacesActionsUpdate;
|
|
@@ -9,7 +9,10 @@ export default class SpacesCreate extends BaseCommand {
|
|
|
9
9
|
description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
10
|
status: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
11
|
color: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
icon: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
'icon-color': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
14
|
'lead-agent': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
team: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
16
|
'target-date': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
17
|
goal: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
18
|
label: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -5,6 +5,7 @@ const data_provider_1 = require("@skrr-ai/data-provider");
|
|
|
5
5
|
const outbox_1 = require("../../lib/outbox");
|
|
6
6
|
const api_fetch_1 = require("../../lib/api-fetch");
|
|
7
7
|
const base_command_1 = require("../../base-command");
|
|
8
|
+
const label_ref_1 = require("../../lib/label-ref");
|
|
8
9
|
const web_url_1 = require("../../lib/web-url");
|
|
9
10
|
const prompt_1 = require("../../lib/prompt");
|
|
10
11
|
const created_line_1 = require("../../lib/created-line");
|
|
@@ -13,6 +14,7 @@ class SpacesCreate extends base_command_1.BaseCommand {
|
|
|
13
14
|
static examples = [
|
|
14
15
|
'<%= config.bin %> spaces create --title "Q2 Launch"',
|
|
15
16
|
'<%= config.bin %> spaces create --title "Support" --status in_progress --color "#4f46e5"',
|
|
17
|
+
'<%= config.bin %> spaces create --title "Launch" --icon Rocket --icon-color "#2DD4BF"',
|
|
16
18
|
'<%= config.bin %> spaces create --title "Research" --lead-agent <agent-id>',
|
|
17
19
|
'<%= config.bin %> spaces create --title "Frontend" --parent <space-id>',
|
|
18
20
|
'<%= config.bin %> spaces create --title "Private notes" --parent <space-id> --no-inherit-access',
|
|
@@ -27,11 +29,18 @@ class SpacesCreate extends base_command_1.BaseCommand {
|
|
|
27
29
|
description: core_1.Flags.string({ description: 'Space description' }),
|
|
28
30
|
status: core_1.Flags.string({ description: 'Space status', options: [...data_provider_1.SPACE_STATUSES] }),
|
|
29
31
|
color: core_1.Flags.string({ description: 'Space color (hex, e.g. #4f46e5)' }),
|
|
32
|
+
icon: core_1.Flags.string({
|
|
33
|
+
description: 'Space icon — a curated icon name (e.g. Rocket, Star) or an emoji',
|
|
34
|
+
}),
|
|
35
|
+
'icon-color': core_1.Flags.string({
|
|
36
|
+
description: 'Color applied to the space icon (hex, e.g. #2DD4BF)',
|
|
37
|
+
}),
|
|
30
38
|
'lead-agent': core_1.Flags.string({ description: 'Space Leader agent ID' }),
|
|
39
|
+
team: core_1.Flags.string({ description: 'Team ID to attach this space to' }),
|
|
31
40
|
'target-date': core_1.Flags.string({ description: 'Target date (ISO string)' }),
|
|
32
41
|
goal: core_1.Flags.string({ description: 'Goal ID to link (repeatable)', multiple: true }),
|
|
33
42
|
label: core_1.Flags.string({
|
|
34
|
-
description: 'Label
|
|
43
|
+
description: 'Label to attach (repeatable, max 50) — id, or a name from `skrr labels list --applicable-to space`. An unknown name is refused, never created. After creation use `spaces labels add/remove`.',
|
|
35
44
|
multiple: true,
|
|
36
45
|
}),
|
|
37
46
|
'group-chat': core_1.Flags.string({ description: 'Group chat ID to link this space to' }),
|
|
@@ -53,15 +62,36 @@ class SpacesCreate extends base_command_1.BaseCommand {
|
|
|
53
62
|
catch (err) {
|
|
54
63
|
this.error(err.message, { exit: 1 });
|
|
55
64
|
}
|
|
65
|
+
// A name is resolved against the DECLARED vocabulary before the create, so
|
|
66
|
+
// a typo fails here — cheaply, with the near misses named — rather than
|
|
67
|
+
// minting a second spelling of a label somebody already has.
|
|
68
|
+
let resolvedLabelIds;
|
|
69
|
+
try {
|
|
70
|
+
const ids = await (0, label_ref_1.resolveLabelRefs)(flags.label, {
|
|
71
|
+
applicableTo: 'space',
|
|
72
|
+
...(process.env.OVERSKY_WORKSPACE_ID
|
|
73
|
+
? { workspaceId: process.env.OVERSKY_WORKSPACE_ID }
|
|
74
|
+
: {}),
|
|
75
|
+
});
|
|
76
|
+
resolvedLabelIds = ids.length > 0 ? ids : undefined;
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
if (err instanceof label_ref_1.LabelRefError)
|
|
80
|
+
this.error(err.message, { exit: 1 });
|
|
81
|
+
this.handleApiError(err);
|
|
82
|
+
}
|
|
56
83
|
const payload = (0, prompt_1.mergeDefined)(body, {
|
|
57
84
|
title: flags.title,
|
|
58
85
|
description: flags.description,
|
|
59
86
|
status: flags.status,
|
|
60
87
|
color: flags.color,
|
|
88
|
+
icon: flags.icon,
|
|
89
|
+
iconColor: flags['icon-color'],
|
|
61
90
|
leadAgentId: flags['lead-agent'],
|
|
91
|
+
teamId: flags.team,
|
|
62
92
|
targetDate: flags['target-date'],
|
|
63
93
|
goalIds: flags.goal,
|
|
64
|
-
labelIds:
|
|
94
|
+
labelIds: resolvedLabelIds,
|
|
65
95
|
groupChatId: flags['group-chat'],
|
|
66
96
|
parentSpaceId: flags.parent,
|
|
67
97
|
inheritAccess: flags['inherit-access'],
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr spaces label-summaries` — the label DEFINITIONS carried by every Space
|
|
4
|
+
* you can view, in one request.
|
|
5
|
+
*
|
|
6
|
+
* The third of the sidebar's batch reads, beside `spaces member-summaries` and
|
|
7
|
+
* `spaces task-rollups`, and the one that was never bound. `Space.labelIds`
|
|
8
|
+
* already says which Space carries which label, so what a caller holding a list
|
|
9
|
+
* of Spaces is missing is only the name and colour to resolve those ids
|
|
10
|
+
* against — and `GET /api/labels` takes exactly ONE (scope, scopeId) pair, so
|
|
11
|
+
* resolving them otherwise costs a request per row.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately a flat list, matching the endpoint: one map, not one map per row.
|
|
14
|
+
*
|
|
15
|
+
* A label whose row is not returned is one the caller genuinely cannot read —
|
|
16
|
+
* another user's private label attached to a shared Space. It is reported as
|
|
17
|
+
* unresolved rather than hidden, because "this Space has a label you cannot
|
|
18
|
+
* see" and "this Space has no labels" are different facts.
|
|
19
|
+
*/
|
|
20
|
+
export default class SpacesLabelSummaries extends BaseCommand {
|
|
21
|
+
static description: string;
|
|
22
|
+
static examples: string[];
|
|
23
|
+
static flags: {
|
|
24
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
};
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
/**
|
|
7
|
+
* `skrr spaces label-summaries` — the label DEFINITIONS carried by every Space
|
|
8
|
+
* you can view, in one request.
|
|
9
|
+
*
|
|
10
|
+
* The third of the sidebar's batch reads, beside `spaces member-summaries` and
|
|
11
|
+
* `spaces task-rollups`, and the one that was never bound. `Space.labelIds`
|
|
12
|
+
* already says which Space carries which label, so what a caller holding a list
|
|
13
|
+
* of Spaces is missing is only the name and colour to resolve those ids
|
|
14
|
+
* against — and `GET /api/labels` takes exactly ONE (scope, scopeId) pair, so
|
|
15
|
+
* resolving them otherwise costs a request per row.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately a flat list, matching the endpoint: one map, not one map per row.
|
|
18
|
+
*
|
|
19
|
+
* A label whose row is not returned is one the caller genuinely cannot read —
|
|
20
|
+
* another user's private label attached to a shared Space. It is reported as
|
|
21
|
+
* unresolved rather than hidden, because "this Space has a label you cannot
|
|
22
|
+
* see" and "this Space has no labels" are different facts.
|
|
23
|
+
*/
|
|
24
|
+
class SpacesLabelSummaries extends base_command_1.BaseCommand {
|
|
25
|
+
static description = 'Show the label definitions used across every space you can view';
|
|
26
|
+
static examples = [
|
|
27
|
+
'<%= config.bin %> spaces label-summaries',
|
|
28
|
+
'<%= config.bin %> spaces label-summaries --json',
|
|
29
|
+
];
|
|
30
|
+
static flags = {
|
|
31
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
32
|
+
};
|
|
33
|
+
async run() {
|
|
34
|
+
this.requireAuth();
|
|
35
|
+
const { flags } = await this.parse(SpacesLabelSummaries);
|
|
36
|
+
let response;
|
|
37
|
+
try {
|
|
38
|
+
response = await data_provider_1.dataService.listSpaceLabelSummaries();
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
this.handleApiError(err);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (flags.json) {
|
|
45
|
+
this.log(JSON.stringify(response, null, 2));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const labels = response.labels || [];
|
|
49
|
+
if (labels.length === 0) {
|
|
50
|
+
this.log('No labels on any space you can view.');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const clip = (text, width) => text.length > width ? `${text.slice(0, width - 3)}...` : text;
|
|
54
|
+
this.log(`${'LABEL'.padEnd(28)} ${'SCOPE'.padEnd(10)} ${'COLOR'.padEnd(9)} ${'APPLIES TO'.padEnd(24)} ID`);
|
|
55
|
+
for (const label of labels) {
|
|
56
|
+
// `applicableTo` is what the label may be attached to, which is not the
|
|
57
|
+
// same as its scope — a workspace-scoped label can still be task-only.
|
|
58
|
+
const appliesTo = (label.applicableTo || []).join(', ') || '-';
|
|
59
|
+
this.log(`${clip(label.name, 28).padEnd(28)} ${String(label.scope ?? '-').padEnd(10)} ` +
|
|
60
|
+
`${String(label.color ?? '-').padEnd(9)} ${clip(appliesTo, 24).padEnd(24)} ${label.id}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.default = SpacesLabelSummaries;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
5
|
const base_command_1 = require("../../../base-command");
|
|
6
|
+
const label_ref_1 = require("../../../lib/label-ref");
|
|
6
7
|
const web_url_1 = require("../../../lib/web-url");
|
|
7
8
|
class SpacesLabelsAdd extends base_command_1.BaseCommand {
|
|
8
9
|
static description = 'Attach a label to a space';
|
|
@@ -16,7 +17,7 @@ class SpacesLabelsAdd extends base_command_1.BaseCommand {
|
|
|
16
17
|
static flags = {
|
|
17
18
|
json: core_1.Flags.boolean({ description: 'Output the updated space as JSON' }),
|
|
18
19
|
label: core_1.Flags.string({
|
|
19
|
-
description: 'Label
|
|
20
|
+
description: 'Label — id, or a name from `skrr labels list --applicable-to space`. An unknown name is refused, never created.',
|
|
20
21
|
required: true,
|
|
21
22
|
}),
|
|
22
23
|
};
|
|
@@ -26,9 +27,25 @@ class SpacesLabelsAdd extends base_command_1.BaseCommand {
|
|
|
26
27
|
// `spaces update` deliberately refuses labelIds — the server routes label
|
|
27
28
|
// changes through this atomic $addToSet endpoint so concurrent edits can't
|
|
28
29
|
// clobber each other. Re-attaching an already-attached label is a no-op.
|
|
30
|
+
// A name is resolved against the DECLARED vocabulary; an unknown one is
|
|
31
|
+
// refused with the near misses named, never created. See lib/label-ref.
|
|
32
|
+
let labelId = flags.label;
|
|
33
|
+
try {
|
|
34
|
+
[labelId] = await (0, label_ref_1.resolveLabelRefs)([flags.label], {
|
|
35
|
+
applicableTo: 'space',
|
|
36
|
+
...(process.env.OVERSKY_WORKSPACE_ID
|
|
37
|
+
? { workspaceId: process.env.OVERSKY_WORKSPACE_ID }
|
|
38
|
+
: {}),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
if (err instanceof label_ref_1.LabelRefError)
|
|
43
|
+
this.error(err.message, { exit: 1 });
|
|
44
|
+
this.handleApiError(err);
|
|
45
|
+
}
|
|
29
46
|
let result;
|
|
30
47
|
try {
|
|
31
|
-
result = await data_provider_1.dataService.addLabelToSpace({ spaceId: args.id, labelId
|
|
48
|
+
result = await data_provider_1.dataService.addLabelToSpace({ spaceId: args.id, labelId });
|
|
32
49
|
}
|
|
33
50
|
catch (err) {
|
|
34
51
|
this.handleApiError(err);
|