@skrr-ai/cli 0.1.119 → 0.1.121
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 +117 -6
- package/dist/commands/agent/message/context.d.ts +1 -0
- package/dist/commands/agent/message/context.js +3 -2
- 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/search/agents.js +5 -1
- package/dist/commands/search/all.js +74 -22
- package/dist/commands/search/skills.d.ts +1 -0
- package/dist/commands/search/skills.js +12 -1
- package/dist/commands/search/spaces.d.ts +8 -1
- package/dist/commands/search/spaces.js +50 -12
- package/dist/commands/search/tasks.d.ts +13 -2
- package/dist/commands/search/tasks.js +78 -14
- package/dist/commands/search/teams.js +5 -1
- package/dist/commands/search/workspace.d.ts +19 -0
- package/dist/commands/search/workspace.js +126 -0
- package/dist/commands/skills/browse.d.ts +1 -0
- package/dist/commands/skills/browse.js +8 -1
- package/dist/commands/skills/search.d.ts +1 -0
- package/dist/commands/skills/search.js +12 -1
- 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/list.d.ts +1 -0
- package/dist/commands/spaces/list.js +12 -3
- 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/search.d.ts +1 -0
- package/dist/commands/spaces/search.js +9 -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/search.d.ts +1 -0
- package/dist/commands/tasks/search.js +9 -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/api-error-reason.d.ts +2 -0
- package/dist/lib/api-error-reason.js +14 -0
- package/dist/lib/api-fetch.js +3 -0
- 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/search-display.d.ts +7 -0
- package/dist/lib/search-display.js +31 -0
- package/dist/lib/skill-store-pagination.d.ts +8 -0
- package/dist/lib/skill-store-pagination.js +35 -0
- 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/credentialEnvelopeBridge.d.ts +10 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialEnvelopeBridge.js +147 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonConsentProof.d.ts +20 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonConsentProof.js +72 -0
- 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/desktopDaemonProof.d.ts +21 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/desktopDaemonProof.js +96 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.d.ts +2 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +102 -20
- 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/independentMachineReservation.d.ts +27 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineReservation.js +161 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineScopes.d.ts +26 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineScopes.js +41 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +2 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +15 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/macos.js +20 -4
- 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/credentialEnvelopeBridge.d.ts +10 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialEnvelopeBridge.js +172 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonConsentProof.d.ts +20 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonConsentProof.js +43 -0
- 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/desktopDaemonProof.d.ts +21 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/desktopDaemonProof.js +62 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.d.ts +2 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +133 -25
- 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/independentMachineReservation.d.ts +27 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineReservation.js +132 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineScopes.d.ts +26 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineScopes.js +15 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +2 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +2 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/macos.js +28 -15
- 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 +51 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +27181 -20293
- package/oclif.manifest.json +5745 -1813
- package/package.json +20 -2
|
@@ -67,10 +67,15 @@ function refusalsOf(run) {
|
|
|
67
67
|
for (const entry of raw) {
|
|
68
68
|
if (!entry || typeof entry !== 'object')
|
|
69
69
|
continue;
|
|
70
|
-
const { tool, input } = entry;
|
|
71
|
-
|
|
70
|
+
const { tool, input, inputRecorded } = entry;
|
|
71
|
+
const text = typeof input === 'string' && input.trim() ? input.trim() : null;
|
|
72
|
+
if (text === null && inputRecorded !== true)
|
|
72
73
|
continue;
|
|
73
|
-
out.push({
|
|
74
|
+
out.push({
|
|
75
|
+
tool: typeof tool === 'string' && tool ? tool : null,
|
|
76
|
+
input: text,
|
|
77
|
+
inputRecorded: true,
|
|
78
|
+
});
|
|
74
79
|
}
|
|
75
80
|
return out;
|
|
76
81
|
}
|
|
@@ -117,7 +122,7 @@ function blockedRunSummary(run, bin = 'skrr', taskRef = '<task-id>') {
|
|
|
117
122
|
],
|
|
118
123
|
};
|
|
119
124
|
}
|
|
120
|
-
const SHELL_TOOL = /^(bash|shell|local_shell|exec_command|commandexecution|command_execution)$/i;
|
|
125
|
+
const SHELL_TOOL = /^(bash|shell|shell_command|local_shell|exec_command|commandexecution|command_execution)$/i;
|
|
121
126
|
function toolLabel(tool) {
|
|
122
127
|
if (!tool)
|
|
123
128
|
return '';
|
|
@@ -135,8 +140,10 @@ function permissionBlockLines(run, bin = 'skrr', taskRef = '<task-id>') {
|
|
|
135
140
|
// The sentence already quotes a lone refused input (shortened); list an
|
|
136
141
|
// input only when the sentence does not already show it.
|
|
137
142
|
const refusedLines = summary.refused
|
|
138
|
-
.filter((refusal) => !reason.includes(refusal.input.slice(0, 60)))
|
|
139
|
-
.map((refusal) =>
|
|
143
|
+
.filter((refusal) => refusal.input === null || !reason.includes(refusal.input.slice(0, 60)))
|
|
144
|
+
.map((refusal) => refusal.input === null
|
|
145
|
+
? ` Refused: a call${toolLabel(refusal.tool)}; its input is kept in the run transcript`
|
|
146
|
+
: ` Refused: ${refusal.input}${toolLabel(refusal.tool)}`);
|
|
140
147
|
const [chat, update, restart] = summary.remedies;
|
|
141
148
|
return [
|
|
142
149
|
`The latest run (${summary.runId}) is blocked on a permission, not on an approval request.`,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class TasksAttachmentsFacts extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
task: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
attachment: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const api_fetch_1 = require("../../../lib/api-fetch");
|
|
6
|
+
const session_task_write_1 = require("../../../lib/session-task-write");
|
|
7
|
+
class TasksAttachmentsFacts extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Read literal declarations from an exact JSON attachment; never follows referenced files';
|
|
9
|
+
static args = {
|
|
10
|
+
task: core_1.Args.string({ required: true, ignoreStdin: true }),
|
|
11
|
+
attachment: core_1.Args.string({ required: true, ignoreStdin: true }),
|
|
12
|
+
};
|
|
13
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output source facts JSON' }) };
|
|
14
|
+
async run() {
|
|
15
|
+
this.requireAuth();
|
|
16
|
+
const { args } = await this.parse(TasksAttachmentsFacts);
|
|
17
|
+
try {
|
|
18
|
+
const session = await (0, session_task_write_1.sessionTaskWrite)('attachment', args.task);
|
|
19
|
+
const task = session?.taskId || (await this.resolveEntityRef('task', args.task));
|
|
20
|
+
const prefix = session?.path || `/api/tasks/${encodeURIComponent(task)}/attachments`;
|
|
21
|
+
const facts = await (0, api_fetch_1.apiFetch)(`${prefix}/${encodeURIComponent(args.attachment)}/source-facts`, session ? { credential: session.credential } : undefined);
|
|
22
|
+
this.printJsonResult(facts);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
this.handleApiError(error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = TasksAttachmentsFacts;
|
|
@@ -8,6 +8,7 @@ export default class TasksAttachmentsUpload extends BaseCommand {
|
|
|
8
8
|
static flags: {
|
|
9
9
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
file: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'resume-attachment': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
role: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
};
|
|
13
14
|
run(): Promise<void>;
|
|
@@ -16,6 +16,9 @@ class TasksAttachmentsUpload extends base_command_1.BaseCommand {
|
|
|
16
16
|
static flags = {
|
|
17
17
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
18
18
|
file: core_1.Flags.string({ description: 'Path to the file to upload', required: true }),
|
|
19
|
+
'resume-attachment': core_1.Flags.string({
|
|
20
|
+
description: 'Resume this exact existing multipart attachment with the same file. Creates no replacement upload.',
|
|
21
|
+
}),
|
|
19
22
|
role: core_1.Flags.string({
|
|
20
23
|
description: 'Asset role: evidence (supports an Update/Result), deliverable (the media is the product), or input (forwarded into every future Run — only a person may add one; a person promotes an agent upload with `attachments set-role`). Defaults to evidence when an agent uploads, input when a person does.',
|
|
21
24
|
options: ['input', 'evidence', 'deliverable'],
|
|
@@ -34,9 +37,22 @@ class TasksAttachmentsUpload extends base_command_1.BaseCommand {
|
|
|
34
37
|
taskId: taskRef,
|
|
35
38
|
filePath: flags.file,
|
|
36
39
|
role: flags.role,
|
|
40
|
+
...(flags['resume-attachment'] !== undefined ? { resumeAttachmentId: flags['resume-attachment'] } : {}),
|
|
37
41
|
});
|
|
38
42
|
}
|
|
39
43
|
catch (err) {
|
|
44
|
+
const recovery = (0, task_asset_upload_1.taskAssetUploadRecovery)(err);
|
|
45
|
+
if (recovery) {
|
|
46
|
+
const failure = err;
|
|
47
|
+
this.failWithCliError({
|
|
48
|
+
message: failure.message,
|
|
49
|
+
code: failure.code || 'TASK_ASSET_UPLOAD_INCOMPLETE',
|
|
50
|
+
status: failure.status,
|
|
51
|
+
retryable: false,
|
|
52
|
+
exit: 1,
|
|
53
|
+
details: { upload: recovery, suggestion: 'Resume this attachment with --resume-attachment and the same --file after resolving the reported failure.' },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
40
56
|
this.handleApiError(err);
|
|
41
57
|
}
|
|
42
58
|
if (flags.json) {
|
|
@@ -7,6 +7,7 @@ const web_url_1 = require("../../lib/web-url");
|
|
|
7
7
|
const prompt_1 = require("../../lib/prompt");
|
|
8
8
|
const dry_run_plans_1 = require("../../lib/dry-run-plans");
|
|
9
9
|
const task_batch_1 = require("../../lib/task-batch");
|
|
10
|
+
const space_write_policy_1 = require("../../lib/space-write-policy");
|
|
10
11
|
const write_target_1 = require("../../lib/write-target");
|
|
11
12
|
const tasks_1 = require("../../lib/tasks");
|
|
12
13
|
class TasksBulkUpdate extends base_command_1.BaseCommand {
|
|
@@ -117,6 +118,17 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
|
|
|
117
118
|
let task = null;
|
|
118
119
|
if (Object.keys(row.patch).length > 0) {
|
|
119
120
|
const batched = batchByRow.get(index);
|
|
121
|
+
// Held for approval by the Space write policy (OSK-17988): this row
|
|
122
|
+
// changed nothing yet, and its status move is not sent on top of it.
|
|
123
|
+
if (usedBatch && batched?.status === 'pending_approval') {
|
|
124
|
+
results.push({
|
|
125
|
+
id: row.id,
|
|
126
|
+
ok: true,
|
|
127
|
+
status: 'pending_approval',
|
|
128
|
+
proposal: batched.proposal,
|
|
129
|
+
});
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
120
132
|
if (usedBatch && batched) {
|
|
121
133
|
if (!batched.ok) {
|
|
122
134
|
throw Object.assign(new Error(batched.error?.message ?? 'Update failed'), {
|
|
@@ -138,6 +150,15 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
|
|
|
138
150
|
taskId: row.id,
|
|
139
151
|
data: row.patch,
|
|
140
152
|
});
|
|
153
|
+
if ((0, space_write_policy_1.isSpaceWritePendingResponse)(task)) {
|
|
154
|
+
results.push({
|
|
155
|
+
id: row.id,
|
|
156
|
+
ok: true,
|
|
157
|
+
status: 'pending_approval',
|
|
158
|
+
proposal: task.proposal,
|
|
159
|
+
});
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
141
162
|
}
|
|
142
163
|
}
|
|
143
164
|
if (row.status !== undefined) {
|
|
@@ -151,6 +172,15 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
|
|
|
151
172
|
taskId: row.id,
|
|
152
173
|
status: row.status,
|
|
153
174
|
});
|
|
175
|
+
if ((0, space_write_policy_1.isSpaceWritePendingResponse)(task)) {
|
|
176
|
+
results.push({
|
|
177
|
+
id: row.id,
|
|
178
|
+
ok: true,
|
|
179
|
+
status: 'pending_approval',
|
|
180
|
+
proposal: task.proposal,
|
|
181
|
+
});
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
154
184
|
}
|
|
155
185
|
if (!task) {
|
|
156
186
|
task = await data_provider_1.dataService.getTask(row.id, { enrich: false });
|
|
@@ -202,7 +232,11 @@ class TasksBulkUpdate extends base_command_1.BaseCommand {
|
|
|
202
232
|
else {
|
|
203
233
|
this.log(`Bulk update complete: ${summary.succeeded}/${summary.requested} succeeded, ${summary.failed} failed.`);
|
|
204
234
|
for (const result of results) {
|
|
205
|
-
if (result.
|
|
235
|
+
if (result.status === 'pending_approval') {
|
|
236
|
+
const proposal = result.proposal;
|
|
237
|
+
this.log(`- held for approval ${result.id}: nothing changed yet (bundle ${proposal?.id}, item ${proposal?.itemId})`);
|
|
238
|
+
}
|
|
239
|
+
else if (result.ok) {
|
|
206
240
|
this.log(`- updated ${(0, tasks_1.formatTaskLabel)(result.task)}`);
|
|
207
241
|
}
|
|
208
242
|
else {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/** Print the server-authorized, read-only Agent Context for one Task. */
|
|
3
|
+
export default class TasksContext extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
task: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
static examples: string[];
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
protected wantsJsonOutput(): boolean;
|
|
15
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
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_agent_context_compatibility_1 = require("../../lib/task-agent-context-compatibility");
|
|
8
|
+
/** Print the server-authorized, read-only Agent Context for one Task. */
|
|
9
|
+
class TasksContext extends base_command_1.BaseCommand {
|
|
10
|
+
static description = 'Read the server-authorized, redacted Agent Context for a Task without starting execution';
|
|
11
|
+
static args = {
|
|
12
|
+
id: core_1.Args.string({ description: 'Task ID/ref; defaults to the current Task runtime', ignoreStdin: true }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
json: core_1.Flags.boolean({ description: 'Output the machine-readable Agent Context as JSON' }),
|
|
16
|
+
task: core_1.Flags.string({ description: 'Task ID/ref; overrides current Task runtime context' }),
|
|
17
|
+
};
|
|
18
|
+
static examples = [
|
|
19
|
+
'<%= config.bin %> tasks context OSK-123 --json',
|
|
20
|
+
'<%= config.bin %> tasks context --task OSK-123 --json',
|
|
21
|
+
];
|
|
22
|
+
async run() {
|
|
23
|
+
this.setJsonOperation({ command: 'tasks:context', mode: 'read', writeState: 'not_attempted' });
|
|
24
|
+
this.requireAuth();
|
|
25
|
+
const { args, flags } = await this.parse(TasksContext);
|
|
26
|
+
let identity;
|
|
27
|
+
try {
|
|
28
|
+
identity = (0, task_resolver_1.resolveTaskIdentity)({ positionalId: args.id, flagTask: flags.task });
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
const failure = (0, task_resolver_1.taskResolutionFailure)(error);
|
|
32
|
+
this.failWithCliError({
|
|
33
|
+
message: failure.message,
|
|
34
|
+
code: failure.code,
|
|
35
|
+
exit: 2,
|
|
36
|
+
retryable: false,
|
|
37
|
+
details: failure.suggestion ? { suggestion: failure.suggestion } : undefined,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
// `resolveTaskIdentity` decides which INPUT wins; it does no lookup. This
|
|
41
|
+
// turns whatever it picked into something the API can resolve — a UUID and
|
|
42
|
+
// an OSK-2423 ref pass through untouched, a title is searched.
|
|
43
|
+
const taskId = await this.resolveTaskReference(identity.id);
|
|
44
|
+
try {
|
|
45
|
+
const context = await data_provider_1.dataService.getTaskAgentContext(taskId, {
|
|
46
|
+
headers: (0, task_agent_context_compatibility_1.taskAgentContextRequestHeaders)(this.config.root),
|
|
47
|
+
});
|
|
48
|
+
if (!context?.task?.id) {
|
|
49
|
+
this.failWithCliError({
|
|
50
|
+
message: 'The server did not return a canonical Task identity for this Agent Context.',
|
|
51
|
+
code: 'TASK_AGENT_CONTEXT_IDENTITY_UNCONFIRMED',
|
|
52
|
+
exit: 2,
|
|
53
|
+
retryable: false,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
this.printJsonOperation(context, {
|
|
57
|
+
resource: { kind: 'task', id: context.task.id },
|
|
58
|
+
task: { id: context.task.id },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
this.handleApiError(error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
wantsJsonOutput() {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.default = TasksContext;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/** A deliberate cross-Space handoff; distinct from in-Space duplicate-pipeline. */
|
|
3
|
+
export default class TasksCopy extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static args: {
|
|
7
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
space: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
'idempotency-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
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 web_url_1 = require("../../lib/web-url");
|
|
7
|
+
/** A deliberate cross-Space handoff; distinct from in-Space duplicate-pipeline. */
|
|
8
|
+
class TasksCopy extends base_command_1.BaseCommand {
|
|
9
|
+
static description = 'Copy a task brief into another Space without source assignments, history, attachments, or media references';
|
|
10
|
+
static examples = [
|
|
11
|
+
'<%= config.bin %> tasks copy <task-id> --space <target-space> --dry-run',
|
|
12
|
+
'<%= config.bin %> tasks copy <task-id> --space <target-space> --idempotency-key handoff-2026-10-23',
|
|
13
|
+
'<%= config.bin %> tasks copy <task-id> --space <target-space> --title "Partner handoff" --json',
|
|
14
|
+
];
|
|
15
|
+
static args = {
|
|
16
|
+
id: core_1.Args.string({ description: 'Source task ID', required: true, ignoreStdin: true }),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
json: core_1.Flags.boolean({ description: 'Output the transfer plan or copied task as JSON' }),
|
|
20
|
+
space: core_1.Flags.string({
|
|
21
|
+
description: 'Destination Space ID (required; source and destination must differ)',
|
|
22
|
+
required: true,
|
|
23
|
+
}),
|
|
24
|
+
title: core_1.Flags.string({ description: 'Optional title override for the destination task' }),
|
|
25
|
+
description: core_1.Flags.string({
|
|
26
|
+
description: 'Optional description override. Task-asset and space-file references are always removed from a cross-Space copy.',
|
|
27
|
+
}),
|
|
28
|
+
'dry-run': core_1.Flags.boolean({
|
|
29
|
+
description: 'Validate source VIEW and target EDIT, then print the exact safe transfer plan without writing',
|
|
30
|
+
}),
|
|
31
|
+
'idempotency-key': core_1.Flags.string({
|
|
32
|
+
description: 'Required for a real handoff: a stable key for this exact copy. Reuse it after an ambiguous response to replay rather than creating another copy.',
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
async run() {
|
|
36
|
+
this.requireAuth();
|
|
37
|
+
const { args, flags } = await this.parse(TasksCopy);
|
|
38
|
+
if (!flags['dry-run'] && !flags['idempotency-key']) {
|
|
39
|
+
this.failWithCliError({
|
|
40
|
+
message: 'A real cross-Space copy requires --idempotency-key <stable-key> so an interrupted handoff can be retried without creating another task. Run --dry-run first to inspect the transfer plan.',
|
|
41
|
+
code: 'IDEMPOTENCY_KEY_REQUIRED',
|
|
42
|
+
exit: 2,
|
|
43
|
+
retryable: false,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const sourceTaskId = await this.resolveEntityRef('task', args.id);
|
|
47
|
+
const targetSpaceId = await this.resolveEntityRef('space', flags.space);
|
|
48
|
+
const idempotencyKey = flags['idempotency-key'];
|
|
49
|
+
let result;
|
|
50
|
+
try {
|
|
51
|
+
result = await data_provider_1.dataService.copyTask(sourceTaskId, {
|
|
52
|
+
spaceId: targetSpaceId,
|
|
53
|
+
...(flags.title ? { title: flags.title } : {}),
|
|
54
|
+
...(flags.description !== undefined ? { description: flags.description } : {}),
|
|
55
|
+
...(flags['dry-run'] ? { dryRun: true } : {}),
|
|
56
|
+
}, flags['dry-run'] ? undefined : { idempotencyKey });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
this.handleApiError(err);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const task = result.task;
|
|
63
|
+
const payload = {
|
|
64
|
+
...result,
|
|
65
|
+
...(flags['dry-run'] ? {} : { idempotencyKey }),
|
|
66
|
+
...(task ? { url: (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, task) } : {}),
|
|
67
|
+
};
|
|
68
|
+
if (flags.json) {
|
|
69
|
+
this.printJsonResult(payload);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (result.dryRun) {
|
|
73
|
+
this.log(`Copy plan is valid: ${sourceTaskId} → Space ${targetSpaceId}`);
|
|
74
|
+
this.log(`Will carry: ${result.copiedFields.join(', ')}`);
|
|
75
|
+
this.log(`Will omit: ${result.omittedFields.join(', ')}`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
this.log(`Copied task ${sourceTaskId} → ${task?.id ?? '-'} in Space ${targetSpaceId}`);
|
|
79
|
+
this.log(`Idempotency key: ${idempotencyKey}`);
|
|
80
|
+
const taskUrl = task ? (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, task) : null;
|
|
81
|
+
if (taskUrl)
|
|
82
|
+
this.log(taskUrl);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.default = TasksCopy;
|
|
@@ -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.
|