@skrr-ai/cli 0.1.119 → 0.1.120
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/dist/base-command.d.ts +31 -0
- package/dist/base-command.js +106 -4
- package/dist/commands/commands.js +11 -0
- package/dist/commands/commitments/action-proposal.d.ts +13 -0
- package/dist/commands/commitments/action-proposal.js +39 -0
- package/dist/commands/commitments/action-proposals/decide.js +8 -1
- package/dist/commands/commitments/action-proposals/execute.js +11 -1
- package/dist/commands/commitments/create.js +2 -2
- package/dist/commands/commitments/doctor.d.ts +8 -0
- package/dist/commands/commitments/doctor.js +22 -0
- package/dist/commands/commitments/execute-remediation.js +12 -1
- package/dist/commands/commitments/observations.js +2 -2
- package/dist/commands/commitments/pack/bind.d.ts +18 -1
- package/dist/commands/commitments/pack/bind.js +66 -8
- package/dist/commands/commitments/pack/plan.d.ts +4 -1
- package/dist/commands/commitments/pack/plan.js +30 -2
- package/dist/commands/commitments/update.js +8 -2
- package/dist/commands/completion/index.js +1 -1
- package/dist/commands/completion/values.js +1 -1
- package/dist/commands/computer-use/audio.d.ts +1 -0
- package/dist/commands/computer-use/audio.js +1 -0
- package/dist/commands/computer-use/browser.d.ts +1 -0
- package/dist/commands/computer-use/browser.js +1 -0
- package/dist/commands/computer-use/disable.d.ts +1 -0
- package/dist/commands/computer-use/disable.js +1 -0
- package/dist/commands/computer-use/enable.d.ts +1 -0
- package/dist/commands/computer-use/enable.js +1 -0
- package/dist/commands/computer-use/index.d.ts +1 -0
- package/dist/commands/computer-use/index.js +1 -0
- package/dist/commands/computer-use/install.d.ts +1 -0
- package/dist/commands/computer-use/install.js +1 -0
- package/dist/commands/computer-use/recover.d.ts +1 -0
- package/dist/commands/computer-use/recover.js +1 -0
- package/dist/commands/computer-use/status.d.ts +1 -0
- package/dist/commands/computer-use/status.js +1 -0
- package/dist/commands/computer-use/stop.d.ts +1 -0
- package/dist/commands/computer-use/stop.js +1 -0
- package/dist/commands/context.js +16 -11
- package/dist/commands/convos/recovery.js +1 -1
- package/dist/commands/daemon/diagnostics.d.ts +9 -0
- package/dist/commands/daemon/diagnostics.js +53 -0
- package/dist/commands/daemon/index.js +2 -0
- package/dist/commands/daemon/maintenance/attest.d.ts +15 -0
- package/dist/commands/daemon/maintenance/attest.js +52 -0
- package/dist/commands/daemon/maintenance/hold.d.ts +17 -0
- package/dist/commands/daemon/maintenance/hold.js +70 -0
- package/dist/commands/daemon/maintenance/index.d.ts +12 -0
- package/dist/commands/daemon/maintenance/index.js +30 -0
- package/dist/commands/daemon/maintenance/resume.d.ts +13 -0
- package/dist/commands/daemon/maintenance/resume.js +36 -0
- package/dist/commands/daemon/maintenance/status.d.ts +13 -0
- package/dist/commands/daemon/maintenance/status.js +36 -0
- package/dist/commands/doctor.d.ts +4 -1
- package/dist/commands/doctor.js +50 -6
- package/dist/commands/followups/plans/cancel-batch.js +6 -3
- package/dist/commands/followups/plans/capacity.js +7 -3
- package/dist/commands/followups/plans/observability.js +11 -3
- package/dist/commands/followups/plans/preferences/set.js +26 -8
- package/dist/commands/followups/plans/preferences.js +1 -1
- package/dist/commands/followups/plans/show.js +1 -1
- package/dist/commands/goals/key-results/assess.d.ts +36 -0
- package/dist/commands/goals/key-results/assess.js +110 -0
- package/dist/commands/goals/key-results/history.d.ts +30 -0
- package/dist/commands/goals/key-results/history.js +104 -0
- package/dist/commands/goals/key-results/list.d.ts +5 -4
- package/dist/commands/goals/key-results/list.js +12 -6
- package/dist/commands/goals/key-results/show.d.ts +4 -2
- package/dist/commands/goals/key-results/show.js +25 -4
- package/dist/commands/goals/key-results/update.d.ts +4 -0
- package/dist/commands/goals/key-results/update.js +18 -24
- package/dist/commands/goals/plan-now.js +12 -1
- package/dist/commands/goals/planner-compare.d.ts +30 -0
- package/dist/commands/goals/planner-compare.js +136 -0
- package/dist/commands/machines/dedicated/service/exec.d.ts +3 -0
- package/dist/commands/machines/dedicated/service/exec.js +70 -11
- package/dist/commands/machines/hosted/destroy.d.ts +1 -0
- package/dist/commands/machines/hosted/destroy.js +11 -1
- package/dist/commands/machines/hosted/exec.d.ts +1 -0
- package/dist/commands/machines/hosted/exec.js +12 -1
- package/dist/commands/machines/hosted/index.js +1 -0
- package/dist/commands/machines/hosted/operation.d.ts +14 -0
- package/dist/commands/machines/hosted/operation.js +51 -0
- package/dist/commands/machines/hosted/pull.js +1 -1
- package/dist/commands/machines/hosted/start.js +6 -2
- package/dist/commands/spaces/auto-executor/compare.d.ts +18 -0
- package/dist/commands/spaces/auto-executor/compare.js +139 -0
- package/dist/commands/spaces/auto-executor/runs.d.ts +3 -0
- package/dist/commands/spaces/auto-executor/runs.js +13 -1
- package/dist/commands/spaces/charter/create-from-description.d.ts +21 -0
- package/dist/commands/spaces/charter/create-from-description.js +77 -0
- package/dist/commands/spaces/charter/show.d.ts +22 -0
- package/dist/commands/spaces/charter/show.js +61 -0
- package/dist/commands/spaces/heartbeats/list.d.ts +1 -16
- package/dist/commands/spaces/heartbeats/list.js +13 -0
- package/dist/commands/spaces/install-template.js +3 -0
- package/dist/commands/spaces/loops/migrate.d.ts +32 -0
- package/dist/commands/spaces/loops/migrate.js +103 -0
- package/dist/commands/spaces/loops/release.d.ts +14 -0
- package/dist/commands/spaces/loops/release.js +59 -0
- package/dist/commands/spaces/notebook.d.ts +25 -0
- package/dist/commands/spaces/notebook.js +75 -0
- package/dist/commands/spaces/proposals/discard.d.ts +17 -0
- package/dist/commands/spaces/proposals/discard.js +17 -0
- package/dist/commands/spaces/proposals/keep.d.ts +17 -0
- package/dist/commands/spaces/proposals/keep.js +17 -0
- package/dist/commands/spaces/proposals/list.d.ts +24 -0
- package/dist/commands/spaces/proposals/list.js +89 -0
- package/dist/commands/spaces/skills/propose.d.ts +29 -0
- package/dist/commands/spaces/skills/propose.js +82 -0
- package/dist/commands/spaces/templates/fork.js +3 -0
- package/dist/commands/spaces/triggers/show.js +6 -0
- package/dist/commands/spaces/workflows/retry.d.ts +1 -0
- package/dist/commands/spaces/workflows/retry.js +8 -1
- package/dist/commands/spaces/workflows/triggers/create.js +3 -2
- package/dist/commands/spaces/workflows/triggers/fire.js +4 -0
- package/dist/commands/spaces/workflows/triggers/update.js +2 -1
- package/dist/commands/spaces/write-policy/set.d.ts +22 -0
- package/dist/commands/spaces/write-policy/set.js +82 -0
- package/dist/commands/spaces/write-policy/show.d.ts +19 -0
- package/dist/commands/spaces/write-policy/show.js +49 -0
- package/dist/commands/store/artifacts/receipt.d.ts +14 -0
- package/dist/commands/store/artifacts/receipt.js +34 -0
- package/dist/commands/store/artifacts/release.d.ts +2 -0
- package/dist/commands/store/artifacts/release.js +11 -0
- package/dist/commands/store/governance/publish-release.d.ts +2 -0
- package/dist/commands/store/governance/publish-release.js +30 -1
- package/dist/commands/store/governance/release-receipt.d.ts +12 -0
- package/dist/commands/store/governance/release-receipt.js +32 -0
- package/dist/commands/tasks/approvals/list.d.ts +11 -5
- package/dist/commands/tasks/approvals/list.js +13 -6
- package/dist/commands/tasks/attachments/facts.d.ts +12 -0
- package/dist/commands/tasks/attachments/facts.js +29 -0
- package/dist/commands/tasks/attachments/upload.d.ts +1 -0
- package/dist/commands/tasks/attachments/upload.js +16 -0
- package/dist/commands/tasks/bulk-update.js +35 -1
- package/dist/commands/tasks/context.d.ts +15 -0
- package/dist/commands/tasks/context.js +69 -0
- package/dist/commands/tasks/copy.d.ts +18 -0
- package/dist/commands/tasks/copy.js +85 -0
- package/dist/commands/tasks/create-tree.js +97 -23
- package/dist/commands/tasks/create.js +9 -1
- package/dist/commands/tasks/deliverable/add.js +20 -10
- package/dist/commands/tasks/move.js +8 -1
- package/dist/commands/tasks/operations/show.d.ts +16 -0
- package/dist/commands/tasks/operations/show.js +98 -0
- package/dist/commands/tasks/operations/wait.d.ts +22 -0
- package/dist/commands/tasks/operations/wait.js +114 -0
- package/dist/commands/tasks/preflight.d.ts +1 -0
- package/dist/commands/tasks/preflight.js +11 -1
- package/dist/commands/tasks/rearm-recurrence.js +4 -0
- package/dist/commands/tasks/result/show.js +22 -0
- package/dist/commands/tasks/result/submit.d.ts +1 -0
- package/dist/commands/tasks/result/submit.js +3 -0
- package/dist/commands/tasks/retry-receipt.d.ts +15 -0
- package/dist/commands/tasks/retry-receipt.js +89 -0
- package/dist/commands/tasks/retry-review.d.ts +16 -0
- package/dist/commands/tasks/retry-review.js +66 -0
- package/dist/commands/tasks/retry.d.ts +4 -8
- package/dist/commands/tasks/retry.js +34 -68
- package/dist/commands/tasks/runs.d.ts +21 -0
- package/dist/commands/tasks/runs.js +95 -0
- package/dist/commands/tasks/show.d.ts +2 -0
- package/dist/commands/tasks/show.js +15 -1
- package/dist/commands/tasks/start-receipt.d.ts +15 -0
- package/dist/commands/tasks/start-receipt.js +95 -0
- package/dist/commands/tasks/start.d.ts +4 -0
- package/dist/commands/tasks/start.js +49 -3
- package/dist/commands/tasks/update.js +3 -0
- package/dist/commands/tasks/upsert.js +17 -3
- package/dist/commands/tasks/watch.d.ts +3 -0
- package/dist/commands/tasks/watch.js +85 -20
- package/dist/commands/wiki/history.d.ts +33 -0
- package/dist/commands/wiki/history.js +134 -0
- package/dist/commands/wiki/ls.d.ts +2 -0
- package/dist/commands/wiki/ls.js +8 -0
- package/dist/commands/wiki/update.d.ts +3 -1
- package/dist/commands/wiki/update.js +24 -2
- package/dist/commands/wiki/write.d.ts +22 -0
- package/dist/commands/wiki/write.js +144 -6
- package/dist/generated/agent-guides.json +81 -81
- package/dist/generated/managed-instruction-guides.json +1 -1
- package/dist/lib/agent-guides.d.ts +9 -0
- package/dist/lib/agent-guides.js +23 -1
- package/dist/lib/agentic-stream.d.ts +5 -0
- package/dist/lib/agentic-stream.js +122 -3
- package/dist/lib/auth-diagnostics.d.ts +39 -0
- package/dist/lib/auth-diagnostics.js +71 -0
- package/dist/lib/cli-client-identity.d.ts +6 -0
- package/dist/lib/cli-client-identity.js +16 -0
- package/dist/lib/cli-installation-diagnostics.d.ts +52 -0
- package/dist/lib/cli-installation-diagnostics.js +254 -0
- package/dist/lib/command-hygiene.d.ts +45 -0
- package/dist/lib/command-hygiene.js +413 -0
- package/dist/lib/commitments.d.ts +64 -3
- package/dist/lib/commitments.js +34 -6
- package/dist/lib/completion-index.d.ts +16 -4
- package/dist/lib/completion-index.js +50 -14
- package/dist/lib/config.js +7 -1
- package/dist/lib/daemon-maintenance-command.d.ts +22 -0
- package/dist/lib/daemon-maintenance-command.js +39 -0
- package/dist/lib/daemon-maintenance.d.ts +275 -0
- package/dist/lib/daemon-maintenance.js +1035 -0
- package/dist/lib/dedicated-service.d.ts +3 -2
- package/dist/lib/dedicated-service.js +11 -3
- package/dist/lib/governed-store.d.ts +8 -0
- package/dist/lib/governed-store.js +5 -0
- package/dist/lib/hosted-machines.d.ts +33 -2
- package/dist/lib/hosted-machines.js +19 -1
- package/dist/lib/json-output.d.ts +1 -1
- package/dist/lib/machines.d.ts +9 -1
- package/dist/lib/machines.js +15 -1
- package/dist/lib/node-adapter.js +13 -0
- package/dist/lib/record-output.d.ts +22 -0
- package/dist/lib/record-output.js +78 -0
- package/dist/lib/roles.d.ts +3 -3
- package/dist/lib/scoped-memory-command.d.ts +18 -0
- package/dist/lib/scoped-memory-command.js +53 -2
- package/dist/lib/space-charter.d.ts +49 -0
- package/dist/lib/space-charter.js +78 -0
- package/dist/lib/space-loop-migration.d.ts +18 -0
- package/dist/lib/space-loop-migration.js +128 -0
- package/dist/lib/space-notebook.d.ts +22 -0
- package/dist/lib/space-notebook.js +140 -0
- package/dist/lib/space-proposal-decision-command.d.ts +36 -0
- package/dist/lib/space-proposal-decision-command.js +108 -0
- package/dist/lib/space-proposals.d.ts +44 -0
- package/dist/lib/space-proposals.js +186 -0
- package/dist/lib/space-templates.d.ts +8 -0
- package/dist/lib/space-templates.js +17 -0
- package/dist/lib/space-write-policy.d.ts +24 -0
- package/dist/lib/space-write-policy.js +103 -0
- package/dist/lib/task-agent-context-capabilities.d.ts +10 -0
- package/dist/lib/task-agent-context-capabilities.js +22 -0
- package/dist/lib/task-agent-context-compatibility.d.ts +9 -0
- package/dist/lib/task-agent-context-compatibility.js +30 -0
- package/dist/lib/task-asset-upload.d.ts +22 -0
- package/dist/lib/task-asset-upload.js +257 -29
- package/dist/lib/task-batch.d.ts +15 -1
- package/dist/lib/task-batch.js +35 -2
- package/dist/lib/task-operation-watch.d.ts +66 -0
- package/dist/lib/task-operation-watch.js +159 -0
- package/dist/lib/task-resolver.d.ts +1 -1
- package/dist/lib/task-resolver.js +4 -3
- package/dist/lib/task-work.d.ts +1 -1
- package/dist/lib/task-work.js +35 -1
- package/dist/lib/task-write-attribution.d.ts +14 -0
- package/dist/lib/task-write-attribution.js +35 -2
- package/dist/lib/triggers.d.ts +11 -0
- package/dist/lib/triggers.js +7 -0
- package/dist/lib/wiki-update.d.ts +1 -0
- package/dist/lib/wiki-update.js +10 -1
- package/dist/lib/wiki.js +4 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +9 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +31 -15
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +1 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.js +13 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/guidedUpdate.d.ts +370 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/guidedUpdate.js +315 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/maintenanceReportWire.d.ts +178 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/maintenanceReportWire.js +262 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.d.ts +51 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.js +106 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +9 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +32 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +1 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.js +33 -14
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/guidedUpdate.d.ts +370 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/guidedUpdate.js +404 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/maintenanceReportWire.d.ts +178 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/maintenanceReportWire.js +342 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.d.ts +51 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.js +138 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +20 -0
- package/dist/node_modules/@skrr-ai/data-provider/index.js +27085 -20250
- package/oclif.manifest.json +10566 -7247
- package/package.json +20 -2
|
@@ -205,7 +205,10 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
205
205
|
description: 'After applying, reread every confirmed Task and report declared structured-field mismatches and read failures. This checks declarations, not whether Expectations are met. No repair or retry is performed by the readback.',
|
|
206
206
|
exclusive: ['verify', 'verify-spec', 'dry-run'],
|
|
207
207
|
}),
|
|
208
|
-
unassigned: core_1.Flags.boolean({
|
|
208
|
+
unassigned: core_1.Flags.boolean({
|
|
209
|
+
description: 'Explicitly clear assignees on every node, suppressing session/parent/Space defaults while retaining any declared executor intent. Does not start tasks.',
|
|
210
|
+
exclusive: ['default-agent'],
|
|
211
|
+
}),
|
|
209
212
|
'external-key-prefix': core_1.Flags.string({
|
|
210
213
|
description: 'Generate externalKey for nodes that omit one; enables idempotent re-runs. Defaults to a prefix derived from the file content (see --fresh)',
|
|
211
214
|
}),
|
|
@@ -232,10 +235,18 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
232
235
|
async run() {
|
|
233
236
|
this.requireAuth();
|
|
234
237
|
const { flags } = await this.parse(TasksCreateTree);
|
|
235
|
-
this.setJsonOperation({
|
|
238
|
+
this.setJsonOperation({
|
|
239
|
+
command: 'tasks:create-tree',
|
|
240
|
+
mode: flags['verify-spec'] || flags.verify ? 'verify' : flags['dry-run'] ? 'dry_run' : 'execute',
|
|
241
|
+
});
|
|
236
242
|
const unassignmentError = (0, tasks_1.taskUnassignmentFlagError)(flags);
|
|
237
243
|
if (unassignmentError)
|
|
238
|
-
this.failWithCliError({
|
|
244
|
+
this.failWithCliError({
|
|
245
|
+
message: unassignmentError,
|
|
246
|
+
code: 'TASK_UNASSIGNED_CONFLICT',
|
|
247
|
+
exit: 2,
|
|
248
|
+
retryable: false,
|
|
249
|
+
});
|
|
239
250
|
let input = {};
|
|
240
251
|
try {
|
|
241
252
|
input = await (0, prompt_1.readJsonBody)(flags['from-json']);
|
|
@@ -287,7 +298,9 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
287
298
|
for (const item of planned) {
|
|
288
299
|
try {
|
|
289
300
|
(0, tasks_1.applyExplicitTaskUnassignment)(item.payload, Boolean(flags.unassigned));
|
|
290
|
-
const parentSpace = item.parentKey
|
|
301
|
+
const parentSpace = item.parentKey
|
|
302
|
+
? plannedByKey.get(item.parentKey)?.payload.spaceId
|
|
303
|
+
: undefined;
|
|
291
304
|
if (!item.payload.spaceId && typeof parentSpace === 'string')
|
|
292
305
|
item.payload.spaceId = parentSpace;
|
|
293
306
|
await this.resolveTaskResourceReferences(item.payload);
|
|
@@ -424,7 +437,9 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
424
437
|
// Say so before anything is written, not only inside a dry run (OSK-S-440 #9).
|
|
425
438
|
const agentAssignment = describeDefaultAgentAssignment(defaultAgentResolutions);
|
|
426
439
|
const noteworthyAssignment = agentAssignment ? [agentAssignment] : [];
|
|
427
|
-
const target = await this.assertWriteTarget(flags['expect-target'], {
|
|
440
|
+
const target = await this.assertWriteTarget(flags['expect-target'], {
|
|
441
|
+
preview: flags['dry-run'],
|
|
442
|
+
});
|
|
428
443
|
if (flags['dry-run']) {
|
|
429
444
|
const result = {
|
|
430
445
|
object: 'task_create_tree_dry_run',
|
|
@@ -483,6 +498,9 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
483
498
|
// a request can continue on the server after its client is interrupted.
|
|
484
499
|
const mapping = {};
|
|
485
500
|
const results = [];
|
|
501
|
+
// Nodes the Space write policy held for approval (OSK-17988), and the nodes
|
|
502
|
+
// waiting on them: not written, not failed.
|
|
503
|
+
const heldRows = [];
|
|
486
504
|
const startedAt = Date.now();
|
|
487
505
|
let rounds = 0;
|
|
488
506
|
const next = this.nextCommand(flags);
|
|
@@ -501,11 +519,26 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
501
519
|
(0, node_fs_1.writeSync)(2, `Confirmed mapping: ${JSON.stringify(mapping)}\n`);
|
|
502
520
|
if (flags.json)
|
|
503
521
|
(0, node_fs_1.writeSync)(1, JSON.stringify((0, json_output_1.withCliOperation)({
|
|
504
|
-
object: 'task_create_tree_result',
|
|
505
|
-
|
|
506
|
-
|
|
522
|
+
object: 'task_create_tree_result',
|
|
523
|
+
ok: false,
|
|
524
|
+
interrupted: true,
|
|
525
|
+
signal,
|
|
526
|
+
total: planned.length,
|
|
527
|
+
count: confirmed,
|
|
528
|
+
mapping: { ...mapping },
|
|
529
|
+
target,
|
|
530
|
+
summary: {
|
|
531
|
+
confirmed,
|
|
532
|
+
unknown,
|
|
533
|
+
notAttempted: planned.length - confirmed - unknown,
|
|
534
|
+
},
|
|
507
535
|
recovery,
|
|
508
|
-
}, {
|
|
536
|
+
}, {
|
|
537
|
+
command: 'tasks:create-tree',
|
|
538
|
+
mode: 'execute',
|
|
539
|
+
outcome: 'failed',
|
|
540
|
+
writeState: 'unknown',
|
|
541
|
+
}), null, 2) + '\n');
|
|
509
542
|
}
|
|
510
543
|
finally {
|
|
511
544
|
process.exit(signal === 'SIGINT' ? 130 : 143);
|
|
@@ -519,15 +552,25 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
519
552
|
// A half-applied tree reports the ids it did create; the only way back.
|
|
520
553
|
const reportPartial = (item, failure, err, failures) => {
|
|
521
554
|
if (failure.code === 'PROJECT_NOT_FOUND') {
|
|
522
|
-
failure = {
|
|
555
|
+
failure = {
|
|
556
|
+
...failure,
|
|
557
|
+
message: `Project '${String(item.payload.projectId)}' was not found in space '${String(item.payload.spaceId)}'. Correct --project or the node's projectId`,
|
|
558
|
+
};
|
|
523
559
|
}
|
|
524
|
-
const failureRows = failures ?? [
|
|
560
|
+
const failureRows = failures ?? [
|
|
561
|
+
{
|
|
525
562
|
tempId: item.key,
|
|
526
563
|
externalKey: item.payload.externalKey,
|
|
527
|
-
outcome: !failure.status || failure.status === 408 || failure.status >= 500
|
|
564
|
+
outcome: !failure.status || failure.status === 408 || failure.status >= 500
|
|
565
|
+
? 'unknown'
|
|
566
|
+
: 'failed',
|
|
528
567
|
error: failure,
|
|
529
|
-
}
|
|
530
|
-
|
|
568
|
+
},
|
|
569
|
+
];
|
|
570
|
+
const accountedFor = new Set([
|
|
571
|
+
...Object.keys(mapping),
|
|
572
|
+
...failureRows.map((row) => String(row.tempId)),
|
|
573
|
+
]);
|
|
531
574
|
for (const node of planned) {
|
|
532
575
|
if (accountedFor.has(node.key))
|
|
533
576
|
continue;
|
|
@@ -535,7 +578,10 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
535
578
|
tempId: node.key,
|
|
536
579
|
externalKey: node.payload.externalKey,
|
|
537
580
|
outcome: 'not_attempted',
|
|
538
|
-
error: {
|
|
581
|
+
error: {
|
|
582
|
+
message: 'Not attempted because an earlier node stopped the tree',
|
|
583
|
+
retryable: true,
|
|
584
|
+
},
|
|
539
585
|
});
|
|
540
586
|
}
|
|
541
587
|
const partial = partialFailureResult({
|
|
@@ -555,7 +601,10 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
555
601
|
},
|
|
556
602
|
});
|
|
557
603
|
if (flags.json) {
|
|
558
|
-
this.printJsonOperation({ ...partial, target }, {
|
|
604
|
+
this.printJsonOperation({ ...partial, target }, {
|
|
605
|
+
outcome: 'failed',
|
|
606
|
+
writeState: partial.summary.unknown > 0 ? 'unknown' : 'confirmed',
|
|
607
|
+
});
|
|
559
608
|
process.exitCode = partial.failedAt.error.retryable ? 5 : 1;
|
|
560
609
|
this.exit(partial.failedAt.error.retryable ? 5 : 1);
|
|
561
610
|
}
|
|
@@ -710,6 +759,16 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
710
759
|
},
|
|
711
760
|
});
|
|
712
761
|
}
|
|
762
|
+
for (const row of outcome.held) {
|
|
763
|
+
const node = byKey.get(row.key);
|
|
764
|
+
heldRows.push({
|
|
765
|
+
tempId: row.key,
|
|
766
|
+
parentTempId: node?.parentKey,
|
|
767
|
+
action: row.reason === 'pending_approval' ? 'pending_approval' : 'waiting_on_approval',
|
|
768
|
+
title: node?.payload.title,
|
|
769
|
+
...(row.proposal ? { proposal: row.proposal } : {}),
|
|
770
|
+
});
|
|
771
|
+
}
|
|
713
772
|
const failure = outcome.failures.find((f) => !f.skipped) ?? outcome.failures[0];
|
|
714
773
|
if (failure) {
|
|
715
774
|
const node = byKey.get(failure.key);
|
|
@@ -773,6 +832,7 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
773
832
|
timing: { elapsedMs: Date.now() - startedAt, requests: rounds },
|
|
774
833
|
mapping,
|
|
775
834
|
results,
|
|
835
|
+
...(heldRows.length > 0 ? { held: heldRows } : {}),
|
|
776
836
|
...(verification ? { verification } : {}),
|
|
777
837
|
};
|
|
778
838
|
if (flags.json) {
|
|
@@ -788,6 +848,15 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
788
848
|
if (item.url)
|
|
789
849
|
this.log(` ${item.url}`);
|
|
790
850
|
}
|
|
851
|
+
if (heldRows.length > 0) {
|
|
852
|
+
this.log(`Held for approval by the Space write policy (${heldRows.length} node(s), nothing written for them):`);
|
|
853
|
+
for (const row of heldRows) {
|
|
854
|
+
const proposal = row.proposal;
|
|
855
|
+
this.log(`- ${row.tempId}: ${row.action === 'pending_approval'
|
|
856
|
+
? `held in approval bundle ${proposal?.id} (item ${proposal?.itemId})`
|
|
857
|
+
: 'waits on a held node; send it again once that node exists'}`);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
791
860
|
if (verification)
|
|
792
861
|
this.printSpecificationSummary(verification);
|
|
793
862
|
if (verification && !verification.ok)
|
|
@@ -799,18 +868,23 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
799
868
|
}
|
|
800
869
|
}
|
|
801
870
|
async readbackSpecifications(planned, mapping) {
|
|
802
|
-
|
|
871
|
+
// A node held for approval has no id yet; there is nothing to read back.
|
|
872
|
+
const inputs = planned
|
|
873
|
+
.filter((item) => mapping[item.key])
|
|
874
|
+
.map((item) => {
|
|
803
875
|
const expected = { ...item.payload };
|
|
804
876
|
if (item.parentKey)
|
|
805
877
|
expected.parentId = mapping[item.parentKey];
|
|
806
878
|
if (item.blockerKeys?.length)
|
|
807
|
-
expected.blockedByIds = [
|
|
879
|
+
expected.blockedByIds = [
|
|
880
|
+
...new Set([
|
|
808
881
|
...(expected.blockedByIds ?? []),
|
|
809
|
-
...item.blockerKeys.map(key => mapping[key]),
|
|
810
|
-
])
|
|
882
|
+
...item.blockerKeys.map((key) => mapping[key]),
|
|
883
|
+
]),
|
|
884
|
+
];
|
|
811
885
|
return { tempId: item.key, id: mapping[item.key], expected };
|
|
812
886
|
});
|
|
813
|
-
return (0, task_spec_verification_1.verifyTaskSpecifications)(inputs, id => data_provider_1.dataService.getTask(id, { enrich: false }));
|
|
887
|
+
return (0, task_spec_verification_1.verifyTaskSpecifications)(inputs, (id) => data_provider_1.dataService.getTask(id, { enrich: false }));
|
|
814
888
|
}
|
|
815
889
|
printSpecificationSummary(verification) {
|
|
816
890
|
const { summary } = verification;
|
|
@@ -863,12 +937,12 @@ class TasksCreateTree extends base_command_1.BaseCommand {
|
|
|
863
937
|
}
|
|
864
938
|
let verification;
|
|
865
939
|
if (flags['verify-spec']) {
|
|
866
|
-
const mapping = Object.fromEntries(existing.map(row => [String(row.tempId), String(row.id)]));
|
|
940
|
+
const mapping = Object.fromEntries(existing.map((row) => [String(row.tempId), String(row.id)]));
|
|
867
941
|
const checkable = [];
|
|
868
942
|
for (const item of planned) {
|
|
869
943
|
if (!mapping[item.key] || cannotCheck.has(item.key))
|
|
870
944
|
continue;
|
|
871
|
-
const unresolved = [item.parentKey, ...(item.blockerKeys ?? [])].filter(key => key && !mapping[key]);
|
|
945
|
+
const unresolved = [item.parentKey, ...(item.blockerKeys ?? [])].filter((key) => key && !mapping[key]);
|
|
872
946
|
if (unresolved.length) {
|
|
873
947
|
cannotCheck.set(item.key, `Cannot resolve related node(s): ${unresolved.join(', ')}`);
|
|
874
948
|
continue;
|
|
@@ -116,7 +116,9 @@ function taskMatchesCreateIdentity(task, payload) {
|
|
|
116
116
|
if (!Array.isArray(payload[field]))
|
|
117
117
|
continue;
|
|
118
118
|
const requested = [...new Set(payload[field].map(String))].sort();
|
|
119
|
-
const actual = [
|
|
119
|
+
const actual = [
|
|
120
|
+
...new Set(Array.isArray(task[field]) ? task[field].map(String) : []),
|
|
121
|
+
].sort();
|
|
120
122
|
if (JSON.stringify(actual) !== JSON.stringify(requested))
|
|
121
123
|
return false;
|
|
122
124
|
}
|
|
@@ -426,6 +428,9 @@ class TasksCreate extends base_command_1.BaseCommand {
|
|
|
426
428
|
catch (err) {
|
|
427
429
|
this.failTaskCreate(err, payload, flags.goal !== undefined);
|
|
428
430
|
}
|
|
431
|
+
// Held for approval by the Space write policy: nothing was instantiated.
|
|
432
|
+
if (this.reportHeldSpaceWrite(instantiated, { json: flags.json }))
|
|
433
|
+
return;
|
|
429
434
|
const root = instantiated.rootTask ||
|
|
430
435
|
(instantiated.rootTasks || [])[0];
|
|
431
436
|
const url = root ? (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, root) : undefined;
|
|
@@ -603,6 +608,9 @@ class TasksCreate extends base_command_1.BaseCommand {
|
|
|
603
608
|
this.failTaskCreate(retryErr, payload, flags.goal !== undefined);
|
|
604
609
|
}
|
|
605
610
|
}
|
|
611
|
+
// Held for approval by the Space write policy: nothing was created.
|
|
612
|
+
if (this.reportHeldSpaceWrite(created, { json: flags.json }))
|
|
613
|
+
return;
|
|
606
614
|
const url = (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, created);
|
|
607
615
|
// Before either output path, and via `warn` so it reaches stderr — `--json`
|
|
608
616
|
// stdout stays a parseable task row.
|
|
@@ -268,16 +268,13 @@ class TasksDeliverableAdd extends base_command_1.BaseCommand {
|
|
|
268
268
|
expectationIds: opts.expectationIds,
|
|
269
269
|
},
|
|
270
270
|
});
|
|
271
|
+
assertArchivedDeliverableReceipt(asset);
|
|
271
272
|
}
|
|
272
273
|
catch (err) {
|
|
273
274
|
this.handleApiError(err);
|
|
274
275
|
return false;
|
|
275
276
|
}
|
|
276
277
|
const { resourceReceipt, ...archived } = asset;
|
|
277
|
-
if (!resourceReceipt?.link.id) {
|
|
278
|
-
this.warn('The file was archived, but this server did not return its Deliverable link. ' +
|
|
279
|
-
`Run skrr tasks deliverable list ${opts.taskId} --json to find the exact version before submitting a Result.`);
|
|
280
|
-
}
|
|
281
278
|
if (opts.json) {
|
|
282
279
|
// `--status` is overridden for an archived copy, and --json used to say nothing of it: the
|
|
283
280
|
// receipt's observation read `available` and the requested status appeared nowhere (OSK-15437).
|
|
@@ -288,15 +285,13 @@ class TasksDeliverableAdd extends base_command_1.BaseCommand {
|
|
|
288
285
|
identity: opts.identity,
|
|
289
286
|
...(notes ? { requestedStatus: opts.requestedStatus, notes: [notes] } : {}),
|
|
290
287
|
}, {
|
|
291
|
-
resource: { kind: 'task_resource_link', id: resourceReceipt
|
|
292
|
-
task: { id: resourceReceipt
|
|
288
|
+
resource: { kind: 'task_resource_link', id: resourceReceipt.link.id },
|
|
289
|
+
task: { id: resourceReceipt.link.taskId },
|
|
293
290
|
});
|
|
294
291
|
return true;
|
|
295
292
|
}
|
|
296
|
-
const recorded = resourceReceipt
|
|
297
|
-
|
|
298
|
-
: `Archived ${opts.identity}`;
|
|
299
|
-
const version = resourceReceipt?.version.id ? `version ${resourceReceipt.version.id}; ` : '';
|
|
293
|
+
const recorded = `Recorded Deliverable ${resourceReceipt.link.id}: ${opts.identity}`;
|
|
294
|
+
const version = `version ${resourceReceipt.version.id}; `;
|
|
300
295
|
this.log(`${recorded} — archived copy ${asset.id} ` +
|
|
301
296
|
`(${version}sha256 pinned; observed available; self reported).`);
|
|
302
297
|
const notApplied = statusNotApplied(opts.requestedStatus);
|
|
@@ -309,6 +304,21 @@ class TasksDeliverableAdd extends base_command_1.BaseCommand {
|
|
|
309
304
|
}
|
|
310
305
|
}
|
|
311
306
|
exports.default = TasksDeliverableAdd;
|
|
307
|
+
/** Availability and a named Resource version require the server's complete archive receipt. */
|
|
308
|
+
function assertArchivedDeliverableReceipt(asset) {
|
|
309
|
+
const receipt = asset?.resourceReceipt;
|
|
310
|
+
const ids = [asset?.id, receipt?.resource?.id, receipt?.version?.id, receipt?.link?.id,
|
|
311
|
+
receipt?.observation?.id];
|
|
312
|
+
const stored = asset?.digest;
|
|
313
|
+
const versionDigest = receipt?.version?.contentDigest;
|
|
314
|
+
if (asset?.status !== 'ready' || ids.some((id) => typeof id !== 'string' || !id.trim()) ||
|
|
315
|
+
receipt?.observation?.status !== 'available' || typeof stored !== 'string' ||
|
|
316
|
+
!/^[a-f0-9]{64}$/i.test(stored) || typeof versionDigest !== 'string' ||
|
|
317
|
+
versionDigest.toLowerCase() !== `sha256:${stored.toLowerCase()}`) {
|
|
318
|
+
throw new Error('The server did not confirm a ready archived Deliverable with its exact Resource receipt. ' +
|
|
319
|
+
'Re-read the Task attachments and Deliverables before retrying.');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
312
322
|
/** The sentence for a `--status` an archived copy overrides, or null when nothing was overridden. */
|
|
313
323
|
function statusNotApplied(requestedStatus) {
|
|
314
324
|
return requestedStatus && requestedStatus !== 'available'
|
|
@@ -131,6 +131,10 @@ class TasksMove extends base_command_1.BaseCommand {
|
|
|
131
131
|
force: flags.force === true ? true : undefined,
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
|
+
// Held for approval by the Space write policy: nothing moved, and the
|
|
135
|
+
// project change below is not sent on top of a held move.
|
|
136
|
+
if (this.reportHeldSpaceWrite(updated, { json: flags.json }))
|
|
137
|
+
return;
|
|
134
138
|
}
|
|
135
139
|
if (projectId !== undefined) {
|
|
136
140
|
// Project membership is an ordinary task field — PATCH /tasks/:id.
|
|
@@ -139,6 +143,8 @@ class TasksMove extends base_command_1.BaseCommand {
|
|
|
139
143
|
taskId: taskRef,
|
|
140
144
|
data: { projectId },
|
|
141
145
|
});
|
|
146
|
+
if (this.reportHeldSpaceWrite(updated, { json: flags.json }))
|
|
147
|
+
return;
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
150
|
catch (err) {
|
|
@@ -155,7 +161,8 @@ class TasksMove extends base_command_1.BaseCommand {
|
|
|
155
161
|
}
|
|
156
162
|
if (flags.json) {
|
|
157
163
|
this.printJsonOperation((0, web_url_1.withTaskUrl)(this.cliConfig.baseURL, updated), {
|
|
158
|
-
resource: { kind: 'task', id: updated?.id },
|
|
164
|
+
resource: { kind: 'task', id: updated?.id },
|
|
165
|
+
task: { id: updated?.id },
|
|
159
166
|
});
|
|
160
167
|
return;
|
|
161
168
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/** Inspect one durable Task Operation without replaying it or changing execution. */
|
|
3
|
+
export default class TasksOperationsShow extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static args: {
|
|
7
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
task: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'operation-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
'request-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
};
|
|
15
|
+
run(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
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_resolver_1 = require("../../../lib/task-resolver");
|
|
7
|
+
/** Inspect one durable Task Operation without replaying it or changing execution. */
|
|
8
|
+
class TasksOperationsShow extends base_command_1.BaseCommand {
|
|
9
|
+
static description = 'Inspect one server-authoritative Task operation by its operation ID or original request ID. Read-only; never replays work.';
|
|
10
|
+
static examples = [
|
|
11
|
+
'<%= config.bin %> tasks operations show <task-id> --operation-id opr_…',
|
|
12
|
+
'<%= config.bin %> tasks operations show <task-id> --request-id task-retry:deploy-42',
|
|
13
|
+
'<%= config.bin %> tasks operations show <task-id> --request-id task-start:deploy-42 --json',
|
|
14
|
+
];
|
|
15
|
+
static args = {
|
|
16
|
+
id: core_1.Args.string({
|
|
17
|
+
description: 'Task ID; defaults to OVERSKY_SESSION_TASK_ID in task runtimes',
|
|
18
|
+
required: false,
|
|
19
|
+
ignoreStdin: true,
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
static flags = {
|
|
23
|
+
task: core_1.Flags.string({ description: 'Task ID; overrides daemon runtime context' }),
|
|
24
|
+
'operation-id': core_1.Flags.string({ description: 'Opaque operation ID returned by the server' }),
|
|
25
|
+
'request-id': core_1.Flags.string({
|
|
26
|
+
description: 'Original start/retry request ID, when the operation response was lost',
|
|
27
|
+
}),
|
|
28
|
+
json: core_1.Flags.boolean({ description: 'Output the full operation projection as JSON' }),
|
|
29
|
+
};
|
|
30
|
+
async run() {
|
|
31
|
+
this.requireAuth();
|
|
32
|
+
const { args, flags } = await this.parse(TasksOperationsShow);
|
|
33
|
+
let taskIdentity;
|
|
34
|
+
try {
|
|
35
|
+
taskIdentity = (0, task_resolver_1.resolveTaskIdentity)({ positionalId: args.id, flagTask: flags.task });
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const failure = (0, task_resolver_1.taskResolutionFailure)(err);
|
|
39
|
+
this.failWithCliError({
|
|
40
|
+
message: failure.message,
|
|
41
|
+
code: failure.code,
|
|
42
|
+
exit: 2,
|
|
43
|
+
retryable: false,
|
|
44
|
+
details: { suggestion: failure.suggestion, context: failure.details },
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const operationId = flags['operation-id'];
|
|
48
|
+
const requestId = flags['request-id'];
|
|
49
|
+
if ((operationId && requestId) || (!operationId && !requestId)) {
|
|
50
|
+
this.error('Provide exactly one of --operation-id or --request-id.', { exit: 2 });
|
|
51
|
+
}
|
|
52
|
+
// `resolveTaskIdentity` decides which INPUT wins; it does no lookup. This
|
|
53
|
+
// turns whatever it picked into something the API can resolve — a UUID and
|
|
54
|
+
// an OSK-2423 ref pass through untouched, a title is searched.
|
|
55
|
+
const taskId = await this.resolveTaskReference(taskIdentity.id);
|
|
56
|
+
// Published CLI builds can lag the data-provider declaration during an
|
|
57
|
+
// additive rollout. The methods are still runtime functions exported by
|
|
58
|
+
// this same package, so this narrow cast preserves compatibility.
|
|
59
|
+
const service = data_provider_1.dataService;
|
|
60
|
+
let operation;
|
|
61
|
+
try {
|
|
62
|
+
operation = operationId
|
|
63
|
+
? await service.getTaskOperation(taskId, operationId)
|
|
64
|
+
: await service.getTaskOperationByRequest(taskId, requestId);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
this.handleApiError(error, { subject: `Task ${taskId} operation` });
|
|
68
|
+
}
|
|
69
|
+
if (flags.json) {
|
|
70
|
+
this.printJsonResult(operation);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.log(`Operation ${operation.operationId}: ${operation.state}`);
|
|
74
|
+
this.log(`Intent: ${operation.intent}`);
|
|
75
|
+
this.log(`Phase: ${operation.phase}`);
|
|
76
|
+
if (operation.outcome)
|
|
77
|
+
this.log(`Outcome: ${operation.outcome}`);
|
|
78
|
+
this.log(`Task: ${operation.task.identifier || operation.task.id}`);
|
|
79
|
+
if (operation.task.state.workflowGeneration !== undefined) {
|
|
80
|
+
this.log(`Workflow generation: ${operation.task.state.workflowGeneration}`);
|
|
81
|
+
}
|
|
82
|
+
if (operation.receipt?.requestId)
|
|
83
|
+
this.log(`Request receipt: ${operation.receipt.requestId}`);
|
|
84
|
+
if (operation.executionReference?.runId)
|
|
85
|
+
this.log(`Execution Run: ${operation.executionReference.runId}`);
|
|
86
|
+
const attempt = operation.execution?.run.activeExecutorAttemptRef ||
|
|
87
|
+
operation.execution?.run.terminalExecutorAttemptRef;
|
|
88
|
+
if (attempt) {
|
|
89
|
+
this.log(`Executor attempt: ${attempt.kind}/${attempt.runId} #${attempt.attempt} generation ${attempt.generation}`);
|
|
90
|
+
}
|
|
91
|
+
if (operation.provenance.code)
|
|
92
|
+
this.log(`Observation: ${operation.provenance.code}`);
|
|
93
|
+
this.log(operation.recovery.disposition === 'do_not_resend'
|
|
94
|
+
? 'This operation is not confirmed. Do not resend it; inspect the same operation or execution state.'
|
|
95
|
+
: 'This is inspect-only. Use execution-state for current execution authority.');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
exports.default = TasksOperationsShow;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Wait on a Task Operation's server-owned projection. This is intentionally a
|
|
4
|
+
* read-only command: it never retries, redrives, changes Task workflow, or
|
|
5
|
+
* reconstructs an action from the operation's intent.
|
|
6
|
+
*/
|
|
7
|
+
export default class TasksOperationsWait extends BaseCommand {
|
|
8
|
+
static description: string;
|
|
9
|
+
static examples: string[];
|
|
10
|
+
static args: {
|
|
11
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
12
|
+
};
|
|
13
|
+
static flags: {
|
|
14
|
+
task: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
operation: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
interval: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
timeout: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
};
|
|
20
|
+
run(): Promise<void>;
|
|
21
|
+
private printCheckpoint;
|
|
22
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
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_resolver_1 = require("../../../lib/task-resolver");
|
|
7
|
+
const task_operation_watch_1 = require("../../../lib/task-operation-watch");
|
|
8
|
+
/**
|
|
9
|
+
* Wait on a Task Operation's server-owned projection. This is intentionally a
|
|
10
|
+
* read-only command: it never retries, redrives, changes Task workflow, or
|
|
11
|
+
* reconstructs an action from the operation's intent.
|
|
12
|
+
*/
|
|
13
|
+
class TasksOperationsWait extends base_command_1.BaseCommand {
|
|
14
|
+
static description = 'Wait read-only for one immutable Task Operation; never retries or dispatches another run';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> tasks operations wait <task-id> --operation task-retry:deploy-42',
|
|
17
|
+
'<%= config.bin %> tasks operations wait <task-id> --operation task-start:deploy-42 --timeout 10m --json',
|
|
18
|
+
];
|
|
19
|
+
static args = {
|
|
20
|
+
id: core_1.Args.string({
|
|
21
|
+
description: 'Task ID; defaults to OVERSKY_SESSION_TASK_ID in task runtimes',
|
|
22
|
+
required: false,
|
|
23
|
+
ignoreStdin: true,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
static flags = {
|
|
27
|
+
task: core_1.Flags.string({ description: 'Task ID; overrides daemon runtime context' }),
|
|
28
|
+
operation: core_1.Flags.string({ description: 'Immutable Task Operation ID to observe', required: true }),
|
|
29
|
+
interval: core_1.Flags.integer({ description: 'Polling interval in seconds', default: 5 }),
|
|
30
|
+
timeout: core_1.Flags.string({ description: 'Timeout such as 30s, 10m, 2h' }),
|
|
31
|
+
json: core_1.Flags.boolean({ description: 'Emit newline-delimited JSON operation checkpoints' }),
|
|
32
|
+
};
|
|
33
|
+
async run() {
|
|
34
|
+
this.requireAuth();
|
|
35
|
+
const { args, flags } = await this.parse(TasksOperationsWait);
|
|
36
|
+
let taskIdentity;
|
|
37
|
+
try {
|
|
38
|
+
taskIdentity = (0, task_resolver_1.resolveTaskIdentity)({ positionalId: args.id, flagTask: flags.task });
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const failure = (0, task_resolver_1.taskResolutionFailure)(error);
|
|
42
|
+
this.failWithCliError({
|
|
43
|
+
code: failure.code,
|
|
44
|
+
message: failure.message,
|
|
45
|
+
exit: 2,
|
|
46
|
+
retryable: false,
|
|
47
|
+
details: failure.suggestion ? { suggestion: failure.suggestion } : undefined,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const taskId = await this.resolveTaskReference(taskIdentity.id);
|
|
51
|
+
let timeoutMs;
|
|
52
|
+
try {
|
|
53
|
+
timeoutMs = (0, task_operation_watch_1.parseTaskOperationWatchDuration)(flags.timeout);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.error(error.message, { exit: 2 });
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const operationId = flags.operation.trim();
|
|
60
|
+
if (!operationId || operationId.length > 200) {
|
|
61
|
+
this.error('--operation must be a non-empty operation ID of at most 200 characters.', { exit: 2 });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const getTaskOperation = data_provider_1.dataService.getTaskOperation;
|
|
65
|
+
if (!getTaskOperation) {
|
|
66
|
+
this.failWithCliError({
|
|
67
|
+
code: 'TASK_OPERATION_READER_UNAVAILABLE',
|
|
68
|
+
message: 'This CLI build cannot read Task Operations. Update skrr before waiting on this operation.',
|
|
69
|
+
exit: 2,
|
|
70
|
+
retryable: false,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const result = await (0, task_operation_watch_1.watchTaskOperation)({
|
|
75
|
+
taskId,
|
|
76
|
+
operationId,
|
|
77
|
+
intervalMs: Math.max(1, flags.interval) * 1000,
|
|
78
|
+
timeoutMs,
|
|
79
|
+
read: getTaskOperation,
|
|
80
|
+
onCheckpoint: (checkpoint) => this.printCheckpoint(checkpoint, Boolean(flags.json)),
|
|
81
|
+
});
|
|
82
|
+
if (result.result === 'failed')
|
|
83
|
+
this.exit(1);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
const candidate = error;
|
|
87
|
+
if (candidate?.code === 'TASK_OPERATION_WAIT_TIMEOUT') {
|
|
88
|
+
this.exit(124);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (candidate?.code === 'TASK_OPERATION_TERMINAL_UNKNOWN') {
|
|
92
|
+
this.failWithCliError({
|
|
93
|
+
code: 'TASK_OPERATION_TERMINAL_UNKNOWN',
|
|
94
|
+
message: 'The Task Operation is terminal but does not report a recognized outcome. Inspect it; do not issue a fresh operation by guesswork.',
|
|
95
|
+
exit: 2,
|
|
96
|
+
retryable: false,
|
|
97
|
+
details: { taskId, operationId },
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.handleApiError(error, { subject: `Task operation ${operationId}` });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
printCheckpoint(checkpoint, json) {
|
|
105
|
+
if (json) {
|
|
106
|
+
this.log(JSON.stringify(checkpoint));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (checkpoint.changed || checkpoint.terminal || checkpoint.observation === 'timeout') {
|
|
110
|
+
this.log((0, task_operation_watch_1.taskOperationCheckpointLine)(checkpoint));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.default = TasksOperationsWait;
|
|
@@ -8,6 +8,7 @@ export default class TasksPreflight extends BaseCommand {
|
|
|
8
8
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
9
|
task: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
skill: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
capability: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
};
|
|
12
13
|
static examples: string[];
|
|
13
14
|
run(): Promise<void>;
|
|
@@ -14,6 +14,10 @@ class TasksPreflight extends base_command_1.BaseCommand {
|
|
|
14
14
|
json: core_1.Flags.boolean({ description: 'Output native observations, uncertainty, and CLI verification metadata as JSON' }),
|
|
15
15
|
task: core_1.Flags.string({ description: 'Task ID/ref; overrides current Task runtime context' }),
|
|
16
16
|
skill: core_1.Flags.string({ description: 'Skill ID for the existing server execution preview' }),
|
|
17
|
+
capability: core_1.Flags.string({
|
|
18
|
+
multiple: true,
|
|
19
|
+
description: 'Capability required of the execution target. Repeat for every requirement.',
|
|
20
|
+
}),
|
|
17
21
|
};
|
|
18
22
|
static examples = [
|
|
19
23
|
'<%= config.bin %> tasks preflight OSK-123',
|
|
@@ -56,7 +60,13 @@ class TasksPreflight extends base_command_1.BaseCommand {
|
|
|
56
60
|
}
|
|
57
61
|
const report = await (0, task_preflight_1.readTaskPreflight)(taskId, {
|
|
58
62
|
workflow: () => data_provider_1.dataService.getTaskActionability(taskId),
|
|
59
|
-
execution: () =>
|
|
63
|
+
execution: () => {
|
|
64
|
+
const options = {
|
|
65
|
+
...(flags.skill ? { skillId: flags.skill } : {}),
|
|
66
|
+
...(flags.capability?.length ? { requestedCapabilities: flags.capability } : {}),
|
|
67
|
+
};
|
|
68
|
+
return data_provider_1.dataService.previewTaskStart(taskId, Object.keys(options).length ? options : undefined);
|
|
69
|
+
},
|
|
60
70
|
});
|
|
61
71
|
// Only native diagnostic responses establish an identity for _cli; a
|
|
62
72
|
// requested ref is not itself a confirmed Task record.
|
|
@@ -56,6 +56,10 @@ class TasksRearmRecurrence extends base_command_1.BaseCommand {
|
|
|
56
56
|
}, null, 2));
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
|
+
if (result.pending === true) {
|
|
60
|
+
this.log(result.message);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
59
63
|
const finished = result.task;
|
|
60
64
|
const from = finished.identifier || finished.id || taskRef;
|
|
61
65
|
const next = result.successor.identifier || result.successor.id;
|