@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
|
@@ -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 SpacesLabelsRemove extends base_command_1.BaseCommand {
|
|
8
9
|
static description = 'Detach a label from a space';
|
|
@@ -15,16 +16,35 @@ class SpacesLabelsRemove extends base_command_1.BaseCommand {
|
|
|
15
16
|
};
|
|
16
17
|
static flags = {
|
|
17
18
|
json: core_1.Flags.boolean({ description: 'Output the updated space as JSON' }),
|
|
18
|
-
label: core_1.Flags.string({
|
|
19
|
+
label: core_1.Flags.string({
|
|
20
|
+
description: 'Label — id, or a name from `skrr labels list --applicable-to space`. An unknown name is refused, never created.',
|
|
21
|
+
required: true,
|
|
22
|
+
}),
|
|
19
23
|
};
|
|
20
24
|
async run() {
|
|
21
25
|
this.requireAuth();
|
|
22
26
|
const { args, flags } = await this.parse(SpacesLabelsRemove);
|
|
23
27
|
// Detach is intentionally permissive server-side: you can remove a label
|
|
24
28
|
// you can no longer read, so a revoked label never gets stuck on a space.
|
|
29
|
+
// A name is resolved against the DECLARED vocabulary; an unknown one is
|
|
30
|
+
// refused with the near misses named, never created. See lib/label-ref.
|
|
31
|
+
let labelId = flags.label;
|
|
32
|
+
try {
|
|
33
|
+
[labelId] = await (0, label_ref_1.resolveLabelRefs)([flags.label], {
|
|
34
|
+
applicableTo: 'space',
|
|
35
|
+
...(process.env.OVERSKY_WORKSPACE_ID
|
|
36
|
+
? { workspaceId: process.env.OVERSKY_WORKSPACE_ID }
|
|
37
|
+
: {}),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err instanceof label_ref_1.LabelRefError)
|
|
42
|
+
this.error(err.message, { exit: 1 });
|
|
43
|
+
this.handleApiError(err);
|
|
44
|
+
}
|
|
25
45
|
let result;
|
|
26
46
|
try {
|
|
27
|
-
result = await data_provider_1.dataService.removeLabelFromSpace({ spaceId: args.id, labelId
|
|
47
|
+
result = await data_provider_1.dataService.removeLabelFromSpace({ spaceId: args.id, labelId });
|
|
28
48
|
}
|
|
29
49
|
catch (err) {
|
|
30
50
|
this.handleApiError(err);
|
|
@@ -52,6 +52,8 @@ class SpacesShow extends base_command_1.BaseCommand {
|
|
|
52
52
|
this.log(`URL: ${url}`);
|
|
53
53
|
this.log(`Status: ${s.status ?? '-'}`);
|
|
54
54
|
this.log(`Color: ${s.color ?? '-'}`);
|
|
55
|
+
this.log(`Icon: ${s.icon ?? '-'}`);
|
|
56
|
+
this.log(`Icon Color: ${s.iconColor ?? '-'}`);
|
|
55
57
|
this.log(`Leader: ${s.leadAgentId ?? '-'}`);
|
|
56
58
|
this.log(`Target Date: ${s.targetDate ?? '-'}`);
|
|
57
59
|
this.log(`Goals: ${Array.isArray(s.goalIds) ? s.goalIds.length : 0}`);
|
|
@@ -3,6 +3,11 @@ import { BaseCommand } from '../../base-command';
|
|
|
3
3
|
* `skrr spaces task-rollups` — task-status counts for every Space you can view,
|
|
4
4
|
* in one request: the same rollup the Spaces sidebar row reads, counted by the
|
|
5
5
|
* project-rollup rules (`done` is done only; `open` excludes cancelled).
|
|
6
|
+
*
|
|
7
|
+
* The SIGNAL column is the derived work band (`spaces/derive.ts`) — what the
|
|
8
|
+
* board is actually doing, as opposed to the status somebody declared on it.
|
|
9
|
+
* Sorting puts the boards that want a person first, which is the reason to run
|
|
10
|
+
* this from a terminal at all.
|
|
6
11
|
*/
|
|
7
12
|
export default class SpacesTaskRollups extends BaseCommand {
|
|
8
13
|
static description: string;
|
|
@@ -7,6 +7,11 @@ const base_command_1 = require("../../base-command");
|
|
|
7
7
|
* `skrr spaces task-rollups` — task-status counts for every Space you can view,
|
|
8
8
|
* in one request: the same rollup the Spaces sidebar row reads, counted by the
|
|
9
9
|
* project-rollup rules (`done` is done only; `open` excludes cancelled).
|
|
10
|
+
*
|
|
11
|
+
* The SIGNAL column is the derived work band (`spaces/derive.ts`) — what the
|
|
12
|
+
* board is actually doing, as opposed to the status somebody declared on it.
|
|
13
|
+
* Sorting puts the boards that want a person first, which is the reason to run
|
|
14
|
+
* this from a terminal at all.
|
|
10
15
|
*/
|
|
11
16
|
class SpacesTaskRollups extends base_command_1.BaseCommand {
|
|
12
17
|
static description = 'Show task-status counts for every space you can view';
|
|
@@ -46,7 +51,11 @@ class SpacesTaskRollups extends base_command_1.BaseCommand {
|
|
|
46
51
|
// A partial walk is not the whole picture; say so before the numbers.
|
|
47
52
|
this.log(`Degraded: ${(response.warnings || []).join('; ') || 'some spaces were not counted'}`);
|
|
48
53
|
}
|
|
49
|
-
|
|
54
|
+
// Most-urgent first: a parked agent, then a blocked board, then a stalled
|
|
55
|
+
// one, then the rest by open count. The band order is the shared one, so
|
|
56
|
+
// this list and the web sidebar rank the same boards the same way.
|
|
57
|
+
const bandRank = (rollup) => data_provider_1.SPACE_ACTIVITY_BAND_ORDER.indexOf((0, data_provider_1.spaceWorkBand)(rollup));
|
|
58
|
+
const rows = [...(response.rollups || [])].sort((a, b) => bandRank(a.tasks) - bandRank(b.tasks) || b.tasks.open - a.tasks.open);
|
|
50
59
|
if (rows.length === 0) {
|
|
51
60
|
this.log('No spaces with tasks.');
|
|
52
61
|
return;
|
|
@@ -54,11 +63,13 @@ class SpacesTaskRollups extends base_command_1.BaseCommand {
|
|
|
54
63
|
const label = (spaceId) => {
|
|
55
64
|
const title = titles.get(spaceId);
|
|
56
65
|
const text = title ? `${title} (${spaceId.slice(0, 8)})` : spaceId;
|
|
57
|
-
return text.length >
|
|
66
|
+
return text.length > 44 ? `${text.slice(0, 41)}...` : text;
|
|
58
67
|
};
|
|
59
|
-
this.log(`${'SPACE'.padEnd(
|
|
68
|
+
this.log(`${'SPACE'.padEnd(44)} ${'SIGNAL'.padEnd(15)} ${'OPEN'.padStart(5)} ${'DONE'.padStart(5)} ${'BLOCKED'.padStart(7)} ${'TOTAL'.padStart(5)}`);
|
|
60
69
|
for (const { spaceId, tasks } of rows) {
|
|
61
|
-
|
|
70
|
+
const band = (0, data_provider_1.spaceWorkBand)(tasks);
|
|
71
|
+
this.log(`${label(spaceId).padEnd(44)} ${(data_provider_1.SPACE_ACTIVITY_BAND_LABELS[band] ?? band).padEnd(15)} ` +
|
|
72
|
+
`${String(tasks.open).padStart(5)} ${String(tasks.done).padStart(5)} ` +
|
|
62
73
|
`${String(tasks.blocked).padStart(7)} ${String(tasks.total).padStart(5)}`);
|
|
63
74
|
}
|
|
64
75
|
}
|
|
@@ -12,6 +12,8 @@ export default class SpacesUpdate extends BaseCommand {
|
|
|
12
12
|
description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
13
|
status: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
14
|
color: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
icon: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
|
+
'icon-color': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
17
|
'lead-agent': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
18
|
'target-date': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
19
|
goal: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -25,6 +27,9 @@ export default class SpacesUpdate extends BaseCommand {
|
|
|
25
27
|
'integration-branch': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
26
28
|
'auto-merge-tier': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
27
29
|
'worktree-isolation': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
30
|
+
'auto-start-on-backlog-exit': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
31
|
+
'triage-external-intake': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
32
|
+
'default-task-template': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
28
33
|
};
|
|
29
34
|
run(): Promise<void>;
|
|
30
35
|
}
|
|
@@ -6,11 +6,19 @@ const tasks_1 = require("../../lib/tasks");
|
|
|
6
6
|
const base_command_1 = require("../../base-command");
|
|
7
7
|
const web_url_1 = require("../../lib/web-url");
|
|
8
8
|
const prompt_1 = require("../../lib/prompt");
|
|
9
|
+
/**
|
|
10
|
+
* Nullable PATCH fields take `none`/`null` as the clear sentinel — the same
|
|
11
|
+
* spelling `goals update` uses for --target-date/--project. `undefined` means
|
|
12
|
+
* the flag was not passed and mergeDefined leaves the field untouched.
|
|
13
|
+
*/
|
|
14
|
+
const clearable = (value) => value === undefined ? undefined : ['none', 'null'].includes(value.toLowerCase()) ? null : value;
|
|
9
15
|
class SpacesUpdate extends base_command_1.BaseCommand {
|
|
10
16
|
static description = 'Update an existing space (partial patch)';
|
|
11
17
|
static examples = [
|
|
12
18
|
'<%= config.bin %> spaces update <space-id> --title "New title"',
|
|
13
19
|
'<%= config.bin %> spaces update <space-id> --status in_progress --color "#4f46e5"',
|
|
20
|
+
'<%= config.bin %> spaces update <space-id> --icon Rocket --icon-color "#2DD4BF"',
|
|
21
|
+
'<%= config.bin %> spaces update <space-id> --icon none',
|
|
14
22
|
'<%= config.bin %> spaces update <space-id> --lead-agent <agent-id>',
|
|
15
23
|
'<%= config.bin %> spaces update <space-id> --no-inherit-access',
|
|
16
24
|
'<%= config.bin %> spaces update <space-id> --from-json patch.json',
|
|
@@ -28,8 +36,18 @@ class SpacesUpdate extends base_command_1.BaseCommand {
|
|
|
28
36
|
description: core_1.Flags.string({ description: 'New description' }),
|
|
29
37
|
status: core_1.Flags.string({ description: 'New status', options: [...data_provider_1.SPACE_STATUSES] }),
|
|
30
38
|
color: core_1.Flags.string({ description: 'New color (hex)' }),
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
icon: core_1.Flags.string({
|
|
40
|
+
description: 'New space icon — a curated icon name or an emoji. Pass "none" to restore the default folder.',
|
|
41
|
+
}),
|
|
42
|
+
'icon-color': core_1.Flags.string({
|
|
43
|
+
description: 'New color applied to the space icon (hex). Pass "none" to restore the neutral color.',
|
|
44
|
+
}),
|
|
45
|
+
'lead-agent': core_1.Flags.string({
|
|
46
|
+
description: 'New Space Leader agent ID. Pass "none" to clear the Leader.',
|
|
47
|
+
}),
|
|
48
|
+
'target-date': core_1.Flags.string({
|
|
49
|
+
description: 'New target date (ISO string). Pass "none" to clear it.',
|
|
50
|
+
}),
|
|
33
51
|
goal: core_1.Flags.string({
|
|
34
52
|
description: 'Link a goal to this space by ID (repeatable; additive). Routed through the ' +
|
|
35
53
|
'atomic link endpoint — re-linking an already-linked goal is a no-op.',
|
|
@@ -103,6 +121,20 @@ class SpacesUpdate extends base_command_1.BaseCommand {
|
|
|
103
121
|
'tree/branch. A per-task --worktree override wins. Merged into deliveryPolicy without ' +
|
|
104
122
|
'clobbering its other fields.',
|
|
105
123
|
}),
|
|
124
|
+
'auto-start-on-backlog-exit': core_1.Flags.boolean({
|
|
125
|
+
allowNo: true,
|
|
126
|
+
description: 'Emit a nudge event when a task is dragged out of backlog, so the client can offer ' +
|
|
127
|
+
'a "Run now" toast. No silent execution.',
|
|
128
|
+
}),
|
|
129
|
+
'triage-external-intake': core_1.Flags.boolean({
|
|
130
|
+
allowNo: true,
|
|
131
|
+
description: 'Route externally sourced tasks (bots/channels) through the triage workflow state ' +
|
|
132
|
+
'instead of backlog. Enabling materializes the triage state server-side.',
|
|
133
|
+
}),
|
|
134
|
+
'default-task-template': core_1.Flags.string({
|
|
135
|
+
description: 'Default task template for new tasks in this space — a template id, reference, or ' +
|
|
136
|
+
'exact title (the server resolves it to the template). Pass "none" to clear.',
|
|
137
|
+
}),
|
|
106
138
|
};
|
|
107
139
|
async run() {
|
|
108
140
|
this.requireAuth();
|
|
@@ -119,9 +151,14 @@ class SpacesUpdate extends base_command_1.BaseCommand {
|
|
|
119
151
|
description: flags.description,
|
|
120
152
|
status: flags.status,
|
|
121
153
|
color: flags.color,
|
|
122
|
-
|
|
123
|
-
|
|
154
|
+
icon: clearable(flags.icon),
|
|
155
|
+
iconColor: clearable(flags['icon-color']),
|
|
156
|
+
leadAgentId: clearable(flags['lead-agent']),
|
|
157
|
+
targetDate: clearable(flags['target-date']),
|
|
124
158
|
inheritAccess: flags['inherit-access'],
|
|
159
|
+
autoStartOnBacklogExit: flags['auto-start-on-backlog-exit'],
|
|
160
|
+
triageExternalIntake: flags['triage-external-intake'],
|
|
161
|
+
defaultTaskTemplateId: clearable(flags['default-task-template']),
|
|
125
162
|
estimateScale: flags['estimate-scale'],
|
|
126
163
|
estimateScaleMigration: flags['estimate-migration'],
|
|
127
164
|
defaultEstimate: flags['default-estimate'],
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class SpacesWorkflowsLifecycleDiagnostics extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
spaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static flags: {
|
|
8
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
class SpacesWorkflowsLifecycleDiagnostics extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Bounded lifecycle operational counters for a Space — pending effect age, repairs, transition conflicts, orphan stages';
|
|
8
|
+
static args = {
|
|
9
|
+
spaceId: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Owning Space ID' }),
|
|
10
|
+
};
|
|
11
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output JSON' }) };
|
|
12
|
+
async run() {
|
|
13
|
+
this.requireAuth();
|
|
14
|
+
const { args, flags } = await this.parse(SpacesWorkflowsLifecycleDiagnostics);
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await data_provider_1.dataService.getSpaceLifecycleDiagnostics(args.spaceId);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
this.handleApiError(error);
|
|
21
|
+
}
|
|
22
|
+
if (flags.json)
|
|
23
|
+
return this.log(JSON.stringify(response, null, 2));
|
|
24
|
+
this.log(`Lifecycle diagnostics for space ${response.spaceId}:`);
|
|
25
|
+
this.log(` bindings: ${response.bindings.bound} bound, ${response.bindings.active} active` +
|
|
26
|
+
` (sampled ${response.sampledRuns} runs${response.truncated ? ', truncated' : ''})`);
|
|
27
|
+
const runStates = Object.entries(response.runs)
|
|
28
|
+
.map(([status, count]) => `${status}: ${count}`)
|
|
29
|
+
.join(', ');
|
|
30
|
+
this.log(` runs: ${runStates || 'none'}`);
|
|
31
|
+
this.log(` stages: ${response.stages.waiting} waiting` +
|
|
32
|
+
` (oldest ${Math.round(response.stages.oldestWaitingMs / 1000)}s)` +
|
|
33
|
+
`, ${response.stages.completed} completed` +
|
|
34
|
+
` (median ${Math.round(response.stages.durationMs.median / 1000)}s` +
|
|
35
|
+
`, max ${Math.round(response.stages.durationMs.max / 1000)}s)`);
|
|
36
|
+
/*
|
|
37
|
+
* The server's effect counters NEST — `pending` is every effect still owed,
|
|
38
|
+
* `repairs` the owed ones that hit an error, `exhausted` the owed ones that
|
|
39
|
+
* stopped retrying — so they must be printed as parts of one number, never
|
|
40
|
+
* side by side. Side by side, one stopped effect read as "1 pending (oldest
|
|
41
|
+
* 8h), 1 repaired, 1 stopped retrying": three effects, one of them
|
|
42
|
+
* apparently fixed, when there was exactly one and nothing was fixed.
|
|
43
|
+
*/
|
|
44
|
+
const { pending: owed, exhausted: stopped = 0, repairs: faulted } = response.effects;
|
|
45
|
+
const retrying = Math.max(0, owed - stopped);
|
|
46
|
+
this.log(owed
|
|
47
|
+
? ` effects: ${owed} owed (oldest ${Math.round(response.effects.oldestPendingMs / 1000)}s)` +
|
|
48
|
+
` — ${retrying} still retrying, ${stopped} stopped; ${faulted} hit an error`
|
|
49
|
+
: ' effects: none owed');
|
|
50
|
+
this.log(` transitions: ${response.transitions.applied} applied` +
|
|
51
|
+
`, ${response.transitions.gated} gated` +
|
|
52
|
+
`, ${response.transitions.superseded} superseded`);
|
|
53
|
+
this.log(` orphan stages: ${response.orphans}`);
|
|
54
|
+
/*
|
|
55
|
+
* WHAT TO DO. The counts above tell an operator how much; LC-13's bar is
|
|
56
|
+
* that each shape of "stuck" also names its repair, because "slow", "stuck"
|
|
57
|
+
* and "waiting for me" are three different facts and one undifferentiated
|
|
58
|
+
* number is not actionable. Only shapes that are actually present print,
|
|
59
|
+
* so a healthy Space says so instead of listing remedies for nothing.
|
|
60
|
+
*/
|
|
61
|
+
// Diagnostics are aggregate by design, so every repair that needs a Task
|
|
62
|
+
// must say how to FIND that Task — and in the Space the operator just
|
|
63
|
+
// named, so the command runs as printed rather than as a template.
|
|
64
|
+
const space = response.spaceId;
|
|
65
|
+
// Every owed effect places the lifecycle's exceptional hold, so this one
|
|
66
|
+
// query finds the Tasks behind both retrying and stopped effects. Holds
|
|
67
|
+
// other authors placed show up too; the NEXT column says which is which.
|
|
68
|
+
const findHeld = `skrr tasks list --space ${space} --actionability-reason exceptional_hold`;
|
|
69
|
+
const actions = [];
|
|
70
|
+
const waitingOn = response.stages.waitingOn;
|
|
71
|
+
if (waitingOn?.human) {
|
|
72
|
+
actions.push(`${waitingOn.human} stage(s) waiting on a person — nothing is broken; a person owes a decision. ` +
|
|
73
|
+
`Find them: skrr tasks list --space ${space} --actionable-by human`);
|
|
74
|
+
}
|
|
75
|
+
if (waitingOn?.agent) {
|
|
76
|
+
actions.push(`${waitingOn.agent} stage(s) waiting on an agent — an agent owes a turn. ` +
|
|
77
|
+
`Find them: skrr tasks list --space ${space} --actionable-by agent`);
|
|
78
|
+
}
|
|
79
|
+
if (response.bindings.drifted) {
|
|
80
|
+
actions.push(`${response.bindings.drifted} binding(s) whose Task status disagrees with its stage — ` +
|
|
81
|
+
'run "skrr tasks lifecycle reconcile <task-id>", or move the Task back to the stage\'s status');
|
|
82
|
+
}
|
|
83
|
+
if (stopped) {
|
|
84
|
+
actions.push(`${stopped} effect(s) stopped retrying — they will not run again on their own. Find them: ${findHeld}; ` +
|
|
85
|
+
'"skrr tasks lifecycle show <task-id>" names the error; fix the cause, then "skrr tasks lifecycle reconcile <task-id>"');
|
|
86
|
+
}
|
|
87
|
+
if (retrying) {
|
|
88
|
+
actions.push(`${retrying} effect(s) still retrying — usually transient. If they persist, find them: ${findHeld}; ` +
|
|
89
|
+
'"skrr tasks lifecycle show <task-id>" names the error');
|
|
90
|
+
}
|
|
91
|
+
if (response.orphans) {
|
|
92
|
+
actions.push(`${response.orphans} orphan stage(s) — a run waiting for a Task that moved on; ` +
|
|
93
|
+
'"skrr tasks lifecycle reconcile <task-id>" re-syncs it');
|
|
94
|
+
}
|
|
95
|
+
this.log('');
|
|
96
|
+
if (!actions.length) {
|
|
97
|
+
this.log('Nothing needs attention.');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
this.log('What to do:');
|
|
101
|
+
for (const action of actions)
|
|
102
|
+
this.log(` - ${action}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.default = SpacesWorkflowsLifecycleDiagnostics;
|
|
@@ -4,10 +4,35 @@ 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 bulk_task_targets_1 = require("../../../lib/bulk-task-targets");
|
|
7
|
+
/**
|
|
8
|
+
* Parse `<agentId>:<actionId>`, splitting on the FIRST colon only.
|
|
9
|
+
*
|
|
10
|
+
* Agent ids never contain a colon; action ids can. This used to split on every
|
|
11
|
+
* colon and keep segments 0 and 1, so `<agent>:<action>:ANYTHING` silently
|
|
12
|
+
* attached `<agent>:<action>` — the caller asked for one thing and got another,
|
|
13
|
+
* exit 0 (OSK-9636). Keeping the remainder as the action id means an extra
|
|
14
|
+
* segment reaches the server as part of an id that does not exist, and is
|
|
15
|
+
* refused there.
|
|
16
|
+
*
|
|
17
|
+
* A space custom action's projected id is `space-custom:<id>`. Read as a ref it
|
|
18
|
+
* became agent `space-custom`, and the server correctly answered "Agent
|
|
19
|
+
* space-custom not found" — true of a string nobody meant as an agent id, and
|
|
20
|
+
* no help (OSK-9637). Those actions run from the space and are deliberately not
|
|
21
|
+
* attachable, so say that instead.
|
|
22
|
+
*/
|
|
7
23
|
function parseRef(input) {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
24
|
+
const trimmed = input.trim();
|
|
25
|
+
const spaceCustom = `"${trimmed}" is a space custom action. Those run from the space and cannot be attached to a task — only agent quick actions can. List attachable ones with: skrr spaces actions available <space-id>`;
|
|
26
|
+
if ((0, data_provider_1.isSpaceCustomActionId)(trimmed))
|
|
27
|
+
return { problem: spaceCustom };
|
|
28
|
+
const colon = trimmed.indexOf(':');
|
|
29
|
+
const agentId = colon > 0 ? trimmed.slice(0, colon).trim() : '';
|
|
30
|
+
const actionId = colon > 0 ? trimmed.slice(colon + 1).trim() : '';
|
|
31
|
+
if (!agentId || !actionId) {
|
|
32
|
+
return { problem: `Invalid ref "${input}" — expected <agentId>:<actionId>.` };
|
|
33
|
+
}
|
|
34
|
+
if ((0, data_provider_1.isSpaceCustomActionId)(actionId))
|
|
35
|
+
return { problem: spaceCustom };
|
|
11
36
|
return { agentId, actionId };
|
|
12
37
|
}
|
|
13
38
|
const refKey = (ref) => `${ref.agentId}:${ref.actionId}`;
|
|
@@ -55,11 +80,11 @@ class TasksActionsAttach extends base_command_1.BaseCommand {
|
|
|
55
80
|
}
|
|
56
81
|
const incoming = [];
|
|
57
82
|
for (const raw of refPositionals) {
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
60
|
-
this.error(
|
|
83
|
+
const parsed = parseRef(raw);
|
|
84
|
+
if ('problem' in parsed) {
|
|
85
|
+
this.error(parsed.problem, { exit: 1 });
|
|
61
86
|
}
|
|
62
|
-
incoming.push(
|
|
87
|
+
incoming.push(parsed);
|
|
63
88
|
}
|
|
64
89
|
if (incoming.length === 0) {
|
|
65
90
|
this.error('At least one <agentId>:<actionId> ref is required. Discover refs with: skrr spaces actions available <space-id>', { exit: 1 });
|
|
@@ -31,6 +31,7 @@ export default class TasksComplete extends BaseCommand {
|
|
|
31
31
|
'run-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
32
32
|
'spec-version': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
33
33
|
'idempotency-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
34
|
+
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
34
35
|
'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
35
36
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
36
37
|
};
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.describePendingReview = describePendingReview;
|
|
4
4
|
const core_1 = require("@oclif/core");
|
|
5
5
|
const base_command_1 = require("../../base-command");
|
|
6
|
+
const task_closure_1 = require("../../lib/task-closure");
|
|
6
7
|
const api_fetch_1 = require("../../lib/api-fetch");
|
|
7
8
|
const outbox_1 = require("../../lib/outbox");
|
|
8
9
|
const prompt_1 = require("../../lib/prompt");
|
|
@@ -60,7 +61,9 @@ function describePendingReview({ statusType, taskId, resultId, bin, advisories,
|
|
|
60
61
|
}
|
|
61
62
|
return ('The Result was submitted, but the Task is not done yet. It is waiting on an independent ' +
|
|
62
63
|
`accepted Review — someone OTHER than the submitter runs: ${bin} tasks review ${taskId} ` +
|
|
63
|
-
`--result-id ${resultId || '<result-id>'} --decision accepted`
|
|
64
|
+
`--result-id ${resultId || '<result-id>'} --decision accepted. ` +
|
|
65
|
+
`(The Task owner, or a non-owner with ${bin} tasks move ${taskId} --status done --force, ` +
|
|
66
|
+
'may close without one — an override is recorded on the resolution.)');
|
|
64
67
|
}
|
|
65
68
|
class TasksComplete extends base_command_1.BaseCommand {
|
|
66
69
|
static description = 'Submit one versioned Result and advance the Task workflow';
|
|
@@ -101,6 +104,9 @@ class TasksComplete extends base_command_1.BaseCommand {
|
|
|
101
104
|
description: 'Task specification version this Result answers',
|
|
102
105
|
}),
|
|
103
106
|
'idempotency-key': core_1.Flags.string({ description: 'Stable retry key for this exact closeout' }),
|
|
107
|
+
force: core_1.Flags.boolean({
|
|
108
|
+
description: "Close past an owner-declared required Review as a non-owner; the override is recorded on the task's resolution",
|
|
109
|
+
}),
|
|
104
110
|
'from-json': core_1.Flags.string({
|
|
105
111
|
description: 'JSON file containing the same canonical Result fields; "-" for stdin',
|
|
106
112
|
}),
|
|
@@ -188,6 +194,7 @@ class TasksComplete extends base_command_1.BaseCommand {
|
|
|
188
194
|
expectedRunId: flags['run-id'],
|
|
189
195
|
expectedSpecVersion: flags['spec-version'],
|
|
190
196
|
idempotencyKey: flags['idempotency-key'],
|
|
197
|
+
force: flags.force === true ? true : undefined,
|
|
191
198
|
});
|
|
192
199
|
let status;
|
|
193
200
|
let summary;
|
|
@@ -224,6 +231,7 @@ class TasksComplete extends base_command_1.BaseCommand {
|
|
|
224
231
|
sourceRunIds: stringArray(input.sourceRunIds),
|
|
225
232
|
expectedRunId: optionalString(input.expectedRunId),
|
|
226
233
|
expectedSpecVersion: typeof input.expectedSpecVersion === 'number' ? input.expectedSpecVersion : undefined,
|
|
234
|
+
...(input.force === true ? { force: true } : {}),
|
|
227
235
|
};
|
|
228
236
|
const idempotencyKey = optionalString(input.idempotencyKey) ||
|
|
229
237
|
(0, outbox_1.idempotencyKeyFor)('task-complete', identity.id, JSON.stringify(payload));
|
|
@@ -264,6 +272,18 @@ class TasksComplete extends base_command_1.BaseCommand {
|
|
|
264
272
|
});
|
|
265
273
|
if (pending)
|
|
266
274
|
this.log(pending);
|
|
275
|
+
/*
|
|
276
|
+
* Say what was closed over, on the door that actually closes things.
|
|
277
|
+
*
|
|
278
|
+
* `tasks complete` reported nothing about the closure at all — no blockers,
|
|
279
|
+
* no `overrode` — so the person who forced past an owner-declared required
|
|
280
|
+
* Review was never told they had. Only `tasks move` read the field, and this
|
|
281
|
+
* is the more common way to finish a Task. Same renderer as `move` and
|
|
282
|
+
* `show`, so all three describe one close identically.
|
|
283
|
+
*/
|
|
284
|
+
for (const sentence of (0, task_closure_1.closureSnapshotLines)(result.task?.resolution?.closure)) {
|
|
285
|
+
this.log(sentence);
|
|
286
|
+
}
|
|
267
287
|
for (const advisory of result.advisories || [])
|
|
268
288
|
this.warn(advisory.message);
|
|
269
289
|
if (url)
|
|
@@ -66,6 +66,9 @@ export default class TasksCreate extends BaseCommand {
|
|
|
66
66
|
tag: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
67
67
|
'label-id': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
68
68
|
worktree: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
69
|
+
'lifecycle-definition': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
70
|
+
'lifecycle-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
71
|
+
'lifecycle-pack': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
69
72
|
};
|
|
70
73
|
run(): Promise<void>;
|
|
71
74
|
private createTaskOrRecover;
|
|
@@ -6,6 +6,7 @@ exports.taskMatchesCreateIdentity = taskMatchesCreateIdentity;
|
|
|
6
6
|
const core_1 = require("@oclif/core");
|
|
7
7
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
8
8
|
const base_command_1 = require("../../base-command");
|
|
9
|
+
const label_ref_1 = require("../../lib/label-ref");
|
|
9
10
|
const prompt_1 = require("../../lib/prompt");
|
|
10
11
|
const tasks_1 = require("../../lib/tasks");
|
|
11
12
|
const task_instruction_offer_1 = require("../../lib/task-instruction-offer");
|
|
@@ -220,8 +221,8 @@ class TasksCreate extends base_command_1.BaseCommand {
|
|
|
220
221
|
}),
|
|
221
222
|
tag: core_1.Flags.string({ description: 'Tag (repeatable)', multiple: true }),
|
|
222
223
|
'label-id': core_1.Flags.string({
|
|
223
|
-
description: 'Attach a task label
|
|
224
|
-
'
|
|
224
|
+
description: 'Attach a task label (repeatable) — id, or a name from `skrr labels list --applicable-to task`. ' +
|
|
225
|
+
'An unknown name is refused, never created. Manage labels with `skrr labels`.',
|
|
225
226
|
multiple: true,
|
|
226
227
|
}),
|
|
227
228
|
worktree: core_1.Flags.boolean({
|
|
@@ -230,6 +231,18 @@ class TasksCreate extends base_command_1.BaseCommand {
|
|
|
230
231
|
'or force the shared daemon tree (--no-worktree). Omit to inherit the space ' +
|
|
231
232
|
'policy / global default (shared).',
|
|
232
233
|
}),
|
|
234
|
+
'lifecycle-definition': core_1.Flags.string({
|
|
235
|
+
description: 'Bind the created task to a task_lifecycle Workflow definition in its space. ' +
|
|
236
|
+
'Validated before the write; attach failure rolls the task back.',
|
|
237
|
+
}),
|
|
238
|
+
'lifecycle-version': core_1.Flags.string({
|
|
239
|
+
description: 'Exact published version to bind (requires --lifecycle-definition). ' +
|
|
240
|
+
'Omit to pin the definition’s current published version at create time.',
|
|
241
|
+
}),
|
|
242
|
+
'lifecycle-pack': core_1.Flags.string({
|
|
243
|
+
description: 'Bind the created task to a built-in lifecycle pack (finding, doc_to_task). ' +
|
|
244
|
+
'Alternative to --lifecycle-definition.',
|
|
245
|
+
}),
|
|
233
246
|
};
|
|
234
247
|
async run() {
|
|
235
248
|
this.requireAuth();
|
|
@@ -260,8 +273,27 @@ class TasksCreate extends base_command_1.BaseCommand {
|
|
|
260
273
|
retryable: false,
|
|
261
274
|
});
|
|
262
275
|
}
|
|
276
|
+
// Resolve `--label-id` names before the create so a typo fails here, with
|
|
277
|
+
// the near misses named, rather than reaching the server as an id it will
|
|
278
|
+
// reject with no idea what was meant. Ids pass through untouched.
|
|
279
|
+
let resolvedLabelIds;
|
|
280
|
+
try {
|
|
281
|
+
const ids = await (0, label_ref_1.resolveLabelRefs)(flags['label-id'], {
|
|
282
|
+
applicableTo: 'task',
|
|
283
|
+
...(process.env.OVERSKY_WORKSPACE_ID
|
|
284
|
+
? { workspaceId: process.env.OVERSKY_WORKSPACE_ID }
|
|
285
|
+
: {}),
|
|
286
|
+
});
|
|
287
|
+
resolvedLabelIds = ids.length > 0 ? ids : undefined;
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
if (err instanceof label_ref_1.LabelRefError)
|
|
291
|
+
this.error(err.message, { exit: 1 });
|
|
292
|
+
this.handleApiError(err);
|
|
293
|
+
}
|
|
263
294
|
const payload = (0, tasks_1.buildTaskCreatePayload)(body, {
|
|
264
295
|
...flags,
|
|
296
|
+
'label-id': resolvedLabelIds,
|
|
265
297
|
expectations: parsedExpectations.ok && parsedExpectations.value.length > 0
|
|
266
298
|
? parsedExpectations.value
|
|
267
299
|
: undefined,
|
|
@@ -16,10 +16,20 @@ class TasksEventsAppend extends base_command_1.BaseCommand {
|
|
|
16
16
|
// the retired vocabulary read as the intended path — which is how it kept
|
|
17
17
|
// getting exercised.
|
|
18
18
|
static summary = 'DEPRECATED compatibility spelling for `tasks updates add` — append a legacy task event';
|
|
19
|
+
// The FULL mapping, not a sample of it. The previous description named
|
|
20
|
+
// `handoff`/`checkpoint` and `started|lifecycle` and stopped — so a caller
|
|
21
|
+
// passing `--kind evidence` had no way to learn, before writing, that it
|
|
22
|
+
// becomes a `verification` Update. Those are different claims: `evidence`
|
|
23
|
+
// says a flow was exercised, `verification` says a claim was CHECKED, and the
|
|
24
|
+
// typed-Update vocabulary exists precisely so the two cannot be confused.
|
|
25
|
+
// Mirrors `LEGACY_KIND_TO_UPDATE_TYPE` in `api/server/services/TaskWorkEvent.js`.
|
|
19
26
|
static description = 'DEPRECATED compatibility adapter for the historical Event vocabulary. Every kind is ' +
|
|
20
|
-
'stored as a canonical Update, so
|
|
21
|
-
'`
|
|
22
|
-
'
|
|
27
|
+
'stored as a canonical Update of a DIFFERENT name, so read this before relying on one: ' +
|
|
28
|
+
'`evidence` and `verification` both become `verification`; `checkpoint`, `changed`, ' +
|
|
29
|
+
'`completed` and `handoff` all become `progress`; `input_requested` and `failed` become ' +
|
|
30
|
+
'`blocker`; `decision` stays `decision`. `--kind started|lifecycle` writes only to the ' +
|
|
31
|
+
'Activity ledger and will NOT appear in `tasks updates list`. Use `tasks updates add` ' +
|
|
32
|
+
'instead, which writes the type you name.';
|
|
23
33
|
static examples = [
|
|
24
34
|
'<%= config.bin %> tasks events append <task-id> --kind checkpoint --idempotency-key "<task-id>:first-pass" --summary "Parser handles nested fences"',
|
|
25
35
|
'<%= config.bin %> tasks events append <task-id> --kind decision --idempotency-key "<task-id>:storage-choice" --summary "Chose the CRDT path" --evidence "A direct contentHtml write is reverted by the next render tick"',
|
|
@@ -53,7 +63,7 @@ class TasksEventsAppend extends base_command_1.BaseCommand {
|
|
|
53
63
|
// `Invalid request data` / HTTP_400. (OSK-4888)
|
|
54
64
|
kind: core_1.Flags.string({
|
|
55
65
|
required: true,
|
|
56
|
-
description: '
|
|
66
|
+
description: 'Legacy event kind. Stored as a canonical Update of a different name — see the mapping in the description above, and prefer `tasks updates add`',
|
|
57
67
|
options: [...tasks_1.TASK_WORK_EVENT_KINDS],
|
|
58
68
|
}),
|
|
59
69
|
summary: core_1.Flags.string({ required: true, description: 'What is newly true, in one sentence' }),
|
|
@@ -108,8 +118,21 @@ class TasksEventsAppend extends base_command_1.BaseCommand {
|
|
|
108
118
|
if (written.canonicalType) {
|
|
109
119
|
this.log(`Recorded on ${task.id} as a ${written.canonicalType} Update` +
|
|
110
120
|
`${written.id ? ` (${written.id})` : ''}.`);
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
/*
|
|
122
|
+
* Scope the claim to this KIND.
|
|
123
|
+
*
|
|
124
|
+
* "a compatibility spelling" reads as "same command, older name" — so a
|
|
125
|
+
* caller who has just used it successfully reaches for it again with a
|
|
126
|
+
* kind it does not take. The two vocabularies overlap in only three of
|
|
127
|
+
* fourteen values (`decision`, `blocker`, `verification`), and this line
|
|
128
|
+
* is printed on exactly those — confirming the general claim precisely
|
|
129
|
+
* where it happens to be true. `finding` and `progress` exist only on the
|
|
130
|
+
* canonical command; `evidence`, `checkpoint` and the rest only here.
|
|
131
|
+
*/
|
|
132
|
+
this.log(`\`tasks events append --kind ${written.canonicalType}\` maps onto ` +
|
|
133
|
+
`\`${this.config.bin} tasks updates add --type ${written.canonicalType}\`, which is the ` +
|
|
134
|
+
'canonical command. Their vocabularies differ otherwise — `--type ' +
|
|
135
|
+
'progress|finding` exist only there — and `tasks updates list` reads them back.');
|
|
113
136
|
return;
|
|
114
137
|
}
|
|
115
138
|
// `--kind started|lifecycle` produces no Update at all: it writes a
|
|
@@ -15,7 +15,19 @@ export default class TasksExpectationsAssess extends BaseCommand {
|
|
|
15
15
|
evidence: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
16
|
'spec-version': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
17
|
'idempotency-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
'include-unmet': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
20
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Which Expectations `--all` covers.
|
|
24
|
+
*
|
|
25
|
+
* ONLY the ones nothing has settled. An already-assessed Expectation carries
|
|
26
|
+
* somebody's judgement, and a bulk pass that overwrote it would silently
|
|
27
|
+
* replace a considered `unmet` with a blanket `met` — which is the one thing a
|
|
28
|
+
* batch verb must never do. Overriding an existing assessment stays a
|
|
29
|
+
* deliberate, single, named act.
|
|
30
|
+
*/
|
|
31
|
+
private awaitingIds;
|
|
20
32
|
run(): Promise<void>;
|
|
21
33
|
}
|