@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
|
@@ -0,0 +1,72 @@
|
|
|
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 TasksLifecycleDetach extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Detach the lifecycle from a Task — fences the generation, leaves the run as history';
|
|
8
|
+
/**
|
|
9
|
+
* oclif prints `description` in help and nothing else, so a one-liner that
|
|
10
|
+
* repeats the summary tells a reader nothing about an operation that is not
|
|
11
|
+
* obviously reversible. Say what it does to each thing it touches.
|
|
12
|
+
*/
|
|
13
|
+
static examples = [
|
|
14
|
+
'<%= config.bin %> tasks lifecycle detach OSK-1234 --dry-run',
|
|
15
|
+
'<%= config.bin %> tasks lifecycle detach OSK-1234 --reason "Wrong protocol for this work"',
|
|
16
|
+
];
|
|
17
|
+
static args = {
|
|
18
|
+
id: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Task ID or identifier' }),
|
|
19
|
+
};
|
|
20
|
+
static flags = {
|
|
21
|
+
reason: core_1.Flags.string({ description: 'Why the lifecycle is detaching; recorded in history' }),
|
|
22
|
+
'dry-run': core_1.Flags.boolean({
|
|
23
|
+
description: 'Describe what detaching would do and exit without writing',
|
|
24
|
+
}),
|
|
25
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
this.requireAuth();
|
|
29
|
+
const { args, flags } = await this.parse(TasksLifecycleDetach);
|
|
30
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
31
|
+
if (flags['dry-run']) {
|
|
32
|
+
let current;
|
|
33
|
+
try {
|
|
34
|
+
current = await data_provider_1.dataService.getTaskLifecycle(taskId);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.handleApiError(error);
|
|
38
|
+
}
|
|
39
|
+
if (flags.json)
|
|
40
|
+
return this.log(JSON.stringify({ dryRun: true, ...current }, null, 2));
|
|
41
|
+
const lifecycle = current.lifecycle;
|
|
42
|
+
if (!lifecycle)
|
|
43
|
+
return this.log('No lifecycle is attached to this Task — nothing to detach.');
|
|
44
|
+
this.log(`Would detach ${lifecycle.packId ? `pack ${lifecycle.packId}` : `definition ${lifecycle.definitionId}`}` +
|
|
45
|
+
` at generation ${lifecycle.generation}, stage ${lifecycle.currentStageKey ?? '—'}.`);
|
|
46
|
+
this.log(' The run is cancelled and kept as history; nothing already recorded is removed.');
|
|
47
|
+
this.log(' The generation is bumped, so no in-flight writer from the old run can land.');
|
|
48
|
+
this.log(' Re-attaching afterwards starts a NEW generation — it does not resume this one.');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
let response;
|
|
52
|
+
try {
|
|
53
|
+
response = await data_provider_1.dataService.detachTaskLifecycle({
|
|
54
|
+
taskId,
|
|
55
|
+
...(flags.reason ? { reason: flags.reason } : {}),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
this.handleApiError(error);
|
|
60
|
+
}
|
|
61
|
+
if (flags.json)
|
|
62
|
+
return this.log(JSON.stringify(response, null, 2));
|
|
63
|
+
const lifecycle = response.lifecycle;
|
|
64
|
+
// Name what changed. "Detached lifecycle from the Task." left the reader to
|
|
65
|
+
// diff the state afterwards to learn what had happened.
|
|
66
|
+
this.log(`Detached${lifecycle?.packId ? ` pack ${lifecycle.packId}` : ''} — the run is cancelled and` +
|
|
67
|
+
` kept as history, and the binding is now generation ${lifecycle?.generation ?? '?'}` +
|
|
68
|
+
` (${lifecycle?.status ?? 'detached'}).`);
|
|
69
|
+
this.log('Re-attach with: skrr tasks lifecycle attach <task-id> --pack <pack>');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.default = TasksLifecycleDetach;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksLifecycleHistory extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static flags: {
|
|
8
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
before: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 task_lifecycle_output_1 = require("../../../lib/task-lifecycle-output");
|
|
7
|
+
class TasksLifecycleHistory extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Show the durable lifecycle event stream for a Task — every generation, newest first';
|
|
9
|
+
static args = {
|
|
10
|
+
id: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Task ID' }),
|
|
11
|
+
};
|
|
12
|
+
static flags = {
|
|
13
|
+
limit: core_1.Flags.integer({ min: 1, max: 200, description: 'Maximum events to return (1-200)' }),
|
|
14
|
+
before: core_1.Flags.string({
|
|
15
|
+
description: 'ISO timestamp — only events recorded before it (pagination)',
|
|
16
|
+
}),
|
|
17
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
this.requireAuth();
|
|
21
|
+
const { args, flags } = await this.parse(TasksLifecycleHistory);
|
|
22
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
23
|
+
let response;
|
|
24
|
+
try {
|
|
25
|
+
response = await data_provider_1.dataService.getTaskLifecycleHistory(taskId, {
|
|
26
|
+
limit: flags.limit,
|
|
27
|
+
before: flags.before,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
this.handleApiError(error);
|
|
32
|
+
}
|
|
33
|
+
if (flags.json)
|
|
34
|
+
return this.log(JSON.stringify(response, null, 2));
|
|
35
|
+
(0, task_lifecycle_output_1.renderLifecycleHistory)(response, (line) => this.log(line));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.default = TasksLifecycleHistory;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksLifecycleMigrate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
version: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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 TasksLifecycleMigrate extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Migrate a bound lifecycle to a newer published version, fencing the old generation';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> tasks lifecycle definitions OSK-1234 # where a --version comes from',
|
|
10
|
+
'<%= config.bin %> tasks lifecycle migrate OSK-1234 --version wfv_… --dry-run',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
id: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Task ID or identifier' }),
|
|
14
|
+
};
|
|
15
|
+
static flags = {
|
|
16
|
+
version: core_1.Flags.string({
|
|
17
|
+
required: true,
|
|
18
|
+
description: 'Target published version id — `tasks lifecycle definitions <task-id>` prints it',
|
|
19
|
+
}),
|
|
20
|
+
'dry-run': core_1.Flags.boolean({
|
|
21
|
+
description: 'Describe what migrating would do and exit without writing',
|
|
22
|
+
}),
|
|
23
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
this.requireAuth();
|
|
27
|
+
const { args, flags } = await this.parse(TasksLifecycleMigrate);
|
|
28
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
29
|
+
// Moving a Task between published protocols is not obviously reversible,
|
|
30
|
+
// and the old output said only that a run had started. A flag rather than a
|
|
31
|
+
// prompt, so the command stays usable from a script.
|
|
32
|
+
if (flags['dry-run']) {
|
|
33
|
+
let current;
|
|
34
|
+
try {
|
|
35
|
+
current = await data_provider_1.dataService.getTaskLifecycle(taskId);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
this.handleApiError(error);
|
|
39
|
+
}
|
|
40
|
+
if (flags.json)
|
|
41
|
+
return this.log(JSON.stringify({ dryRun: true, ...current }, null, 2));
|
|
42
|
+
const lifecycle = current.lifecycle;
|
|
43
|
+
if (!lifecycle)
|
|
44
|
+
return this.log('No lifecycle is attached to this Task — nothing to migrate.');
|
|
45
|
+
this.log(`Would migrate from version ${lifecycle.versionId} to ${flags.version}, as generation ` +
|
|
46
|
+
`${Number(lifecycle.generation) + 1}.`);
|
|
47
|
+
this.log(` It re-enters at the CURRENT stage (${lifecycle.currentStageKey ?? '—'}) when that stage` +
|
|
48
|
+
" still exists on the target version; otherwise the protocol's entry stage decides.");
|
|
49
|
+
this.log(' The old generation is fenced — its run can no longer write.');
|
|
50
|
+
this.log(' Earlier generations stay readable in `tasks lifecycle history`.');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
let result;
|
|
54
|
+
try {
|
|
55
|
+
result = await data_provider_1.dataService.migrateTaskLifecycle({ taskId, versionId: flags.version });
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
this.handleApiError(error);
|
|
59
|
+
}
|
|
60
|
+
if (flags.json)
|
|
61
|
+
return this.log(JSON.stringify(result, null, 2));
|
|
62
|
+
const lifecycle = result.lifecycle;
|
|
63
|
+
this.log(`Migrated to version ${lifecycle?.versionId ?? flags.version} — now generation ` +
|
|
64
|
+
`${lifecycle?.generation ?? '?'} at stage ${lifecycle?.currentStageKey ?? '—'}` +
|
|
65
|
+
` (run ${result.run.id}, ${result.run.status}).`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.default = TasksLifecycleMigrate;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksLifecycleReconcile extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
id: 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,27 @@
|
|
|
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 task_lifecycle_output_1 = require("../../../lib/task-lifecycle-output");
|
|
7
|
+
class TasksLifecycleReconcile extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Re-sync the Task lifecycle projection with the authoritative Workflow run';
|
|
9
|
+
static args = { id: core_1.Args.string({ required: true, ignoreStdin: true }) };
|
|
10
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output JSON' }) };
|
|
11
|
+
async run() {
|
|
12
|
+
this.requireAuth();
|
|
13
|
+
const { args, flags } = await this.parse(TasksLifecycleReconcile);
|
|
14
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await data_provider_1.dataService.reconcileTaskLifecycle(taskId);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
this.handleApiError(error);
|
|
21
|
+
}
|
|
22
|
+
if (flags.json)
|
|
23
|
+
return this.log(JSON.stringify(response, null, 2));
|
|
24
|
+
(0, task_lifecycle_output_1.renderTaskLifecycleSummary)(response, (line) => this.log(line));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = TasksLifecycleReconcile;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksLifecycleReopen extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
stage: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
reason: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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 TasksLifecycleReopen extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Fence the current lifecycle generation and reopen at an earlier stage';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> tasks lifecycle reopen OSK-1234 --dry-run',
|
|
10
|
+
'<%= config.bin %> tasks lifecycle reopen OSK-1234 --stage fix --reason "The fix did not take"',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
id: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Task ID or identifier' }),
|
|
14
|
+
};
|
|
15
|
+
static flags = {
|
|
16
|
+
stage: core_1.Flags.string({ description: 'Stage key to re-enter at; defaults to the entry stage' }),
|
|
17
|
+
reason: core_1.Flags.string({ description: 'Why the lifecycle is reopening; recorded in history' }),
|
|
18
|
+
'dry-run': core_1.Flags.boolean({
|
|
19
|
+
description: 'Describe what reopening would do and exit without writing',
|
|
20
|
+
}),
|
|
21
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
22
|
+
};
|
|
23
|
+
async run() {
|
|
24
|
+
this.requireAuth();
|
|
25
|
+
const { args, flags } = await this.parse(TasksLifecycleReopen);
|
|
26
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
27
|
+
// Reopen advances a generation and is not obviously reversible. A preview
|
|
28
|
+
// that names the target stage is cheaper than learning what it did by
|
|
29
|
+
// diffing state afterwards, and a flag keeps the command scriptable where
|
|
30
|
+
// an interactive prompt would not.
|
|
31
|
+
if (flags['dry-run']) {
|
|
32
|
+
let current;
|
|
33
|
+
try {
|
|
34
|
+
current = await data_provider_1.dataService.getTaskLifecycle(taskId);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.handleApiError(error);
|
|
38
|
+
}
|
|
39
|
+
if (flags.json)
|
|
40
|
+
return this.log(JSON.stringify({ dryRun: true, ...current }, null, 2));
|
|
41
|
+
const lifecycle = current.lifecycle;
|
|
42
|
+
if (!lifecycle)
|
|
43
|
+
return this.log('No lifecycle is attached to this Task — nothing to reopen.');
|
|
44
|
+
const entry = flags.stage || current.stages?.[0]?.key;
|
|
45
|
+
this.log(`Would reopen at stage ${entry ?? '(entry stage)'} as generation ${Number(lifecycle.generation) + 1}` +
|
|
46
|
+
` (currently generation ${lifecycle.generation}, stage ${lifecycle.currentStageKey ?? '—'}).`);
|
|
47
|
+
this.log(' The current run is cancelled; its transitions stay readable in history.');
|
|
48
|
+
this.log(" A terminal Task is brought back to the entry stage's declared status.");
|
|
49
|
+
this.log(' Stages the earlier generation finished keep reading as done in that generation.');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let result;
|
|
53
|
+
try {
|
|
54
|
+
result = await data_provider_1.dataService.reopenTaskLifecycle({
|
|
55
|
+
taskId,
|
|
56
|
+
...(flags.stage ? { stageKey: flags.stage } : {}),
|
|
57
|
+
...(flags.reason ? { reason: flags.reason } : {}),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this.handleApiError(error);
|
|
62
|
+
}
|
|
63
|
+
if (flags.json)
|
|
64
|
+
return this.log(JSON.stringify(result, null, 2));
|
|
65
|
+
// Name where it landed, not just that it happened.
|
|
66
|
+
const lifecycle = result.lifecycle;
|
|
67
|
+
this.log(`Reopened at stage ${lifecycle?.currentStageKey ?? '—'} as generation ${lifecycle?.generation ?? '?'}` +
|
|
68
|
+
` — run ${result.run.id} (${result.run.status}). The previous generation stays in history.`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.default = TasksLifecycleReopen;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksLifecycleShow extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
id: 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,27 @@
|
|
|
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 task_lifecycle_output_1 = require("../../../lib/task-lifecycle-output");
|
|
7
|
+
class TasksLifecycleShow extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Show the Task Lifecycle bound to a Task — stages, position, and legal transitions';
|
|
9
|
+
static args = { id: core_1.Args.string({ required: true, ignoreStdin: true }) };
|
|
10
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output JSON' }) };
|
|
11
|
+
async run() {
|
|
12
|
+
this.requireAuth();
|
|
13
|
+
const { args, flags } = await this.parse(TasksLifecycleShow);
|
|
14
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await data_provider_1.dataService.getTaskLifecycle(taskId);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
this.handleApiError(error);
|
|
21
|
+
}
|
|
22
|
+
if (flags.json)
|
|
23
|
+
return this.log(JSON.stringify(response, null, 2));
|
|
24
|
+
(0, task_lifecycle_output_1.renderTaskLifecycleSummary)(response, (line) => this.log(line));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = TasksLifecycleShow;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksLifecycleStart extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static flags: {
|
|
8
|
+
'start-identity': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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 TasksLifecycleStart extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Start the lifecycle run bound to a Task';
|
|
8
|
+
static args = { id: core_1.Args.string({ required: true, ignoreStdin: true }) };
|
|
9
|
+
static flags = {
|
|
10
|
+
'start-identity': core_1.Flags.string({ description: 'Idempotency identity for this logical start' }),
|
|
11
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
12
|
+
};
|
|
13
|
+
async run() {
|
|
14
|
+
this.requireAuth();
|
|
15
|
+
const { args, flags } = await this.parse(TasksLifecycleStart);
|
|
16
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
17
|
+
let result;
|
|
18
|
+
try {
|
|
19
|
+
result = await data_provider_1.dataService.startTaskLifecycle(taskId, flags['start-identity']);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
this.handleApiError(error);
|
|
23
|
+
}
|
|
24
|
+
if (flags.json)
|
|
25
|
+
return this.log(JSON.stringify(result, null, 2));
|
|
26
|
+
this.log(`${result.reused ? 'Opened' : 'Started'} lifecycle run ${result.run.id} (${result.run.status}).`);
|
|
27
|
+
this.log(`Inspect: skrr tasks lifecycle show ${taskId}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.default = TasksLifecycleStart;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksLifecycleTransition extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
transition: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
payload: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
'idempotency-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
'expected-revision': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
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 task_lifecycle_output_1 = require("../../../lib/task-lifecycle-output");
|
|
7
|
+
class TasksLifecycleTransition extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Apply a declared lifecycle transition — records effects and advances the stage';
|
|
9
|
+
static args = {
|
|
10
|
+
id: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Task ID' }),
|
|
11
|
+
transition: core_1.Args.string({
|
|
12
|
+
required: true,
|
|
13
|
+
ignoreStdin: true,
|
|
14
|
+
description: 'Transition id declared by the waiting stage',
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
17
|
+
static flags = {
|
|
18
|
+
payload: core_1.Flags.string({
|
|
19
|
+
description: 'JSON payload the transition requires (fields, evidence, refs)',
|
|
20
|
+
}),
|
|
21
|
+
'idempotency-key': core_1.Flags.string({
|
|
22
|
+
description: 'Stable key for safe retries; defaults to a per-revision key derived from the Task and transition',
|
|
23
|
+
}),
|
|
24
|
+
'expected-revision': core_1.Flags.integer({
|
|
25
|
+
description: 'Optimistic CAS fence; defaults to the current lifecycle revision',
|
|
26
|
+
}),
|
|
27
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
28
|
+
};
|
|
29
|
+
async run() {
|
|
30
|
+
this.requireAuth();
|
|
31
|
+
const { args, flags } = await this.parse(TasksLifecycleTransition);
|
|
32
|
+
const taskId = await this.resolveTaskReference(args.id);
|
|
33
|
+
let payload;
|
|
34
|
+
if (flags.payload) {
|
|
35
|
+
try {
|
|
36
|
+
payload = JSON.parse(flags.payload);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
this.error('--payload must be valid JSON.', { exit: 2 });
|
|
40
|
+
}
|
|
41
|
+
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
42
|
+
this.error('--payload must be a JSON object.', { exit: 2 });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/*
|
|
46
|
+
* The fence only protects the interval it is given.
|
|
47
|
+
*
|
|
48
|
+
* `--expected-revision` is the caller's claim about the state they DECIDED
|
|
49
|
+
* against. When it is omitted this command re-reads the lifecycle and sends
|
|
50
|
+
* back what it just read — and a compare-and-set whose expected value was
|
|
51
|
+
* fetched microseconds before the write can only catch that microsecond,
|
|
52
|
+
* never the interval that matters, which is between the human's read and
|
|
53
|
+
* their write. So the default is a convenience, not protection, and it was
|
|
54
|
+
* silent about that: a `confirm` decided at revision 0 applied against
|
|
55
|
+
* revision 1 and closed a Task, with nothing in the output saying the world
|
|
56
|
+
* had moved in between.
|
|
57
|
+
*
|
|
58
|
+
* Kept as the default because requiring a number on every call would be
|
|
59
|
+
* paid by everyone to protect a minority of flows — but it now says what it
|
|
60
|
+
* fenced on and how to fence properly.
|
|
61
|
+
*/
|
|
62
|
+
let expectedRevision = flags['expected-revision'];
|
|
63
|
+
if (expectedRevision === undefined) {
|
|
64
|
+
let current;
|
|
65
|
+
try {
|
|
66
|
+
current = await data_provider_1.dataService.getTaskLifecycle(taskId);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
this.handleApiError(error);
|
|
70
|
+
}
|
|
71
|
+
if (!current.lifecycle) {
|
|
72
|
+
this.error('No lifecycle is attached to this Task.', { exit: 2 });
|
|
73
|
+
}
|
|
74
|
+
expectedRevision = current.lifecycle.revision;
|
|
75
|
+
if (!flags.json) {
|
|
76
|
+
this.log(`Fencing on revision ${expectedRevision}, read just now — not the revision you saw. ` +
|
|
77
|
+
'Pass --expected-revision <n> to fence on the state you decided against.');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const idempotencyKey = flags['idempotency-key'] ?? `cli-lifecycle:${taskId}:${args.transition}:r${expectedRevision}`;
|
|
81
|
+
let response;
|
|
82
|
+
try {
|
|
83
|
+
response = await data_provider_1.dataService.transitionTaskLifecycle({
|
|
84
|
+
taskId,
|
|
85
|
+
transitionId: args.transition,
|
|
86
|
+
idempotencyKey,
|
|
87
|
+
expectedRevision,
|
|
88
|
+
...(payload ? { payload } : {}),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
this.handleApiError(error);
|
|
93
|
+
}
|
|
94
|
+
if (flags.json)
|
|
95
|
+
this.log(JSON.stringify(response, null, 2));
|
|
96
|
+
else
|
|
97
|
+
(0, task_lifecycle_output_1.renderLifecycleTransitionResult)(response, (line) => this.log(line));
|
|
98
|
+
// Exit non-zero when the write did not land. `applied` is the only verdict
|
|
99
|
+
// that means the stage moved; `rejected`, `superseded` and `gated` all mean
|
|
100
|
+
// it did not. Exiting 0 on all four made
|
|
101
|
+
// `transition A && transition B` run B after A had been fenced off — which
|
|
102
|
+
// is precisely the lost update `expectedRevision` exists to prevent, waved
|
|
103
|
+
// through by the shell.
|
|
104
|
+
if (response.status !== 'applied') {
|
|
105
|
+
this.exit(1);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.default = TasksLifecycleTransition;
|
|
@@ -146,13 +146,13 @@ function buildListParams(flags, assigneeUserId) {
|
|
|
146
146
|
...(flag('actionability-reason')
|
|
147
147
|
? { actionabilityReason: flag('actionability-reason') }
|
|
148
148
|
: {}),
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
// This table always renders a NEXT column, so it always has to ask for the
|
|
150
|
+
// data behind it. Requesting it only alongside an actionability FILTER left
|
|
151
|
+
// the default board printing a header with nothing under it — and a plain
|
|
152
|
+
// `tasks list` is exactly where a person looks to find out what anything is
|
|
153
|
+
// waiting for. The server computes it in one batched read, so the cost is
|
|
154
|
+
// a column that works rather than a column that is there.
|
|
155
|
+
includeActionability: true,
|
|
156
156
|
...(flag('priority') ? { priority: flag('priority') } : {}),
|
|
157
157
|
...(flag('estimate') !== undefined ? { estimate: flag('estimate') } : {}),
|
|
158
158
|
...(flag('min-estimate') !== undefined
|
|
@@ -427,8 +427,13 @@ class TasksList extends base_command_1.BaseCommand {
|
|
|
427
427
|
priority: String(t.priority ?? '-'),
|
|
428
428
|
estimate: t.estimate === null || t.estimate === undefined ? '-' : String(t.estimate),
|
|
429
429
|
assignees,
|
|
430
|
+
// `reason` is the sentence the server wrote for a person; `reasonCode`
|
|
431
|
+
// is the enum it wrote for a machine. Printing the code rendered every
|
|
432
|
+
// stage of every lifecycle as `human:lifecycle_stage` — six different
|
|
433
|
+
// waits, one string — while the sentence naming the stage sat unread in
|
|
434
|
+
// the same payload.
|
|
430
435
|
next: actionability
|
|
431
|
-
? `${String(actionability.nextActor ?? '-')}
|
|
436
|
+
? `${String(actionability.nextActor ?? '-')}: ${String(actionability.reason || actionability.reasonCode || actionability.state || '-')}`
|
|
432
437
|
: String(t.executionMode ?? '-'),
|
|
433
438
|
match: String(t._matchField ?? '-'),
|
|
434
439
|
};
|
|
@@ -440,7 +445,9 @@ class TasksList extends base_command_1.BaseCommand {
|
|
|
440
445
|
{ key: 'priority', header: 'PRIORITY' },
|
|
441
446
|
{ key: 'estimate', header: 'ESTIMATE' },
|
|
442
447
|
{ key: 'assignees', header: 'ASSIGNEES' },
|
|
443
|
-
|
|
448
|
+
// Bounded: the reason is a sentence, and an unbounded column wraps the
|
|
449
|
+
// table into unreadability on a narrow terminal.
|
|
450
|
+
{ key: 'next', header: 'NEXT', maxWidth: 46 },
|
|
444
451
|
// Only meaningful on a search — the server computes it from the same
|
|
445
452
|
// relevance rank that orders the rows, and a plain listing has none.
|
|
446
453
|
...(flags.q ? [{ key: 'match', header: 'MATCH' }] : []),
|
|
@@ -21,6 +21,7 @@ export default class TasksMove extends BaseCommand {
|
|
|
21
21
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
22
|
reason: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
23
|
'resolution-actor': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
+
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
25
|
};
|
|
25
26
|
run(): Promise<void>;
|
|
26
27
|
/**
|