@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
|
@@ -252,8 +252,9 @@ export interface DedicatedServiceSocketOptions {
|
|
|
252
252
|
export type ServiceVerb = 'list' | 'get' | 'create' | 'update' | 'action' | 'logs' | 'logs:stop' | 'approve' | 'secret' | 'exec';
|
|
253
253
|
/**
|
|
254
254
|
* One admitted socket for a run of service verbs. `call` emits
|
|
255
|
-
* `dedicated:service:<verb>` with a
|
|
256
|
-
*
|
|
255
|
+
* `dedicated:service:<verb>` with a requestId and resolves on the matching
|
|
256
|
+
* `dedicated:service:ack`; callers normally get a fresh id, while service
|
|
257
|
+
* exec may provide its durable idempotency key. Push events (`state`, `log`,
|
|
257
258
|
* `log:closed`, `proposed`) are exposed via `on` for the follow loop.
|
|
258
259
|
*/
|
|
259
260
|
export declare class DedicatedServiceChannel {
|
|
@@ -122,6 +122,7 @@ exports.DedicatedServiceError = DedicatedServiceError;
|
|
|
122
122
|
function isServiceUnsupportedCode(code) {
|
|
123
123
|
const c = (code || '').toLowerCase();
|
|
124
124
|
return (c === 'dedicated_runtime_services_unsupported' ||
|
|
125
|
+
c === 'dedicated_runtime_service_exec_receipts_unsupported' ||
|
|
125
126
|
c === 'dedicated_runtime_terminal_unsupported' ||
|
|
126
127
|
c === 'services_unsupported' ||
|
|
127
128
|
c === 'unsupported' ||
|
|
@@ -432,8 +433,9 @@ function socketOptions(token, wsOrigin) {
|
|
|
432
433
|
}
|
|
433
434
|
/**
|
|
434
435
|
* One admitted socket for a run of service verbs. `call` emits
|
|
435
|
-
* `dedicated:service:<verb>` with a
|
|
436
|
-
*
|
|
436
|
+
* `dedicated:service:<verb>` with a requestId and resolves on the matching
|
|
437
|
+
* `dedicated:service:ack`; callers normally get a fresh id, while service
|
|
438
|
+
* exec may provide its durable idempotency key. Push events (`state`, `log`,
|
|
437
439
|
* `log:closed`, `proposed`) are exposed via `on` for the follow loop.
|
|
438
440
|
*/
|
|
439
441
|
class DedicatedServiceChannel {
|
|
@@ -539,7 +541,13 @@ class DedicatedServiceChannel {
|
|
|
539
541
|
}
|
|
540
542
|
/** The shared request/ack round-trip. */
|
|
541
543
|
callEvent(event, ackEvent, payload, context, timeoutMs, describe = describeServiceRefusal) {
|
|
542
|
-
|
|
544
|
+
// `service exec` deliberately supplies its durable request id so a lost
|
|
545
|
+
// socket response can be inspected or replayed without a second effect.
|
|
546
|
+
// Other verbs retain their historical per-call id generation.
|
|
547
|
+
const supplied = payload.requestId;
|
|
548
|
+
const requestId = typeof supplied === 'string' && /^[A-Za-z0-9_.:-]{1,128}$/.test(supplied)
|
|
549
|
+
? supplied
|
|
550
|
+
: `svc-${(0, node_crypto_1.randomUUID)()}`;
|
|
543
551
|
return new Promise((resolve, reject) => {
|
|
544
552
|
if (this.dead) {
|
|
545
553
|
reject(new DedicatedServiceError('The connection to skrr is closed.', 'disconnected'));
|
|
@@ -65,6 +65,14 @@ export declare function resolveGovernedStoreInstallPlan(body: {
|
|
|
65
65
|
/** `POST /admin/releases` — publish one artifact release. Admin. */
|
|
66
66
|
export declare function publishGovernedStoreRelease(body: Record<string, unknown>): Promise<{
|
|
67
67
|
release: unknown;
|
|
68
|
+
releaseId?: string;
|
|
69
|
+
execution?: unknown;
|
|
70
|
+
}>;
|
|
71
|
+
/** Read the immutable governed-release receipt before retrying a lost response. */
|
|
72
|
+
export declare function getGovernedStoreReleaseReceipt(releaseId: string): Promise<{
|
|
73
|
+
release: unknown;
|
|
74
|
+
releaseId: string;
|
|
75
|
+
execution: unknown;
|
|
68
76
|
}>;
|
|
69
77
|
/** `POST /admin/licenses` — mint a bundle license against an acquisition. Admin. */
|
|
70
78
|
export declare function createGovernedStoreLicense(body: Record<string, unknown>): Promise<{
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.searchGovernedStoreArtifacts = searchGovernedStoreArtifacts;
|
|
4
4
|
exports.resolveGovernedStoreInstallPlan = resolveGovernedStoreInstallPlan;
|
|
5
5
|
exports.publishGovernedStoreRelease = publishGovernedStoreRelease;
|
|
6
|
+
exports.getGovernedStoreReleaseReceipt = getGovernedStoreReleaseReceipt;
|
|
6
7
|
exports.createGovernedStoreLicense = createGovernedStoreLicense;
|
|
7
8
|
exports.updateOwnLicensePolicy = updateOwnLicensePolicy;
|
|
8
9
|
exports.updateWorkspaceLicensePolicy = updateWorkspaceLicensePolicy;
|
|
@@ -46,6 +47,10 @@ async function publishGovernedStoreRelease(body) {
|
|
|
46
47
|
body,
|
|
47
48
|
});
|
|
48
49
|
}
|
|
50
|
+
/** Read the immutable governed-release receipt before retrying a lost response. */
|
|
51
|
+
async function getGovernedStoreReleaseReceipt(releaseId) {
|
|
52
|
+
return (0, api_fetch_1.apiFetch)(`/api/store/governance/admin/releases/${encodeURIComponent(releaseId)}/receipt`);
|
|
53
|
+
}
|
|
49
54
|
/** `POST /admin/licenses` — mint a bundle license against an acquisition. Admin. */
|
|
50
55
|
async function createGovernedStoreLicense(body) {
|
|
51
56
|
return (0, api_fetch_1.apiFetch)('/api/store/governance/admin/licenses', {
|
|
@@ -44,6 +44,26 @@ export interface HostedMachineSession {
|
|
|
44
44
|
}
|
|
45
45
|
export interface HostedMachineResponse {
|
|
46
46
|
session?: HostedMachineSession;
|
|
47
|
+
operation?: HostedMachineOperation;
|
|
48
|
+
replayed?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** A durable request receipt, deliberately separate from the machine state. */
|
|
51
|
+
export interface HostedMachineOperation {
|
|
52
|
+
id: string;
|
|
53
|
+
action: 'start' | 'execute' | 'destroy';
|
|
54
|
+
state: 'accepted' | 'started' | 'completed' | 'failed' | 'unknown';
|
|
55
|
+
acceptedAt?: string | null;
|
|
56
|
+
startedAt?: string | null;
|
|
57
|
+
completedAt?: string | null;
|
|
58
|
+
sessionId?: string;
|
|
59
|
+
result?: Record<string, unknown>;
|
|
60
|
+
error?: {
|
|
61
|
+
code?: string;
|
|
62
|
+
message?: string;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export interface HostedMachineOperationResponse {
|
|
66
|
+
operation: HostedMachineOperation;
|
|
47
67
|
}
|
|
48
68
|
export interface HostedMachineListResponse {
|
|
49
69
|
data?: HostedMachineSession[];
|
|
@@ -77,6 +97,8 @@ export interface HostedMachineExecResponse {
|
|
|
77
97
|
executionTime?: number;
|
|
78
98
|
previewUrl?: string | null;
|
|
79
99
|
session?: HostedMachineSession;
|
|
100
|
+
operation?: HostedMachineOperation;
|
|
101
|
+
replayed?: boolean;
|
|
80
102
|
}
|
|
81
103
|
/**
|
|
82
104
|
* The curated `machines hosted exec --json` shape (OSK-4870).
|
|
@@ -98,6 +120,9 @@ export interface HostedMachineExecJson {
|
|
|
98
120
|
id: string;
|
|
99
121
|
status: string;
|
|
100
122
|
};
|
|
123
|
+
/** Additive durable receipt metadata for safely recovering a lost response. */
|
|
124
|
+
operation?: HostedMachineOperation;
|
|
125
|
+
replayed?: boolean;
|
|
101
126
|
}
|
|
102
127
|
export declare function curateHostedMachineExecResult(response: HostedMachineExecResponse): HostedMachineExecJson;
|
|
103
128
|
export interface HostedMachineScope {
|
|
@@ -155,8 +180,14 @@ export declare function getHostedMachine(id: string, scope?: HostedMachineScope)
|
|
|
155
180
|
export declare function attachHostedMachineRepo(id: string, input: AttachHostedMachineRepoInput, scope?: HostedMachineScope): Promise<HostedMachineResponse>;
|
|
156
181
|
export declare function pauseHostedMachine(id: string, scope?: HostedMachineScope): Promise<HostedMachineResponse>;
|
|
157
182
|
export declare function resumeHostedMachine(id: string, scope?: HostedMachineScope): Promise<HostedMachineResponse>;
|
|
158
|
-
export declare function destroyHostedMachine(id: string, scope?: HostedMachineScope
|
|
159
|
-
|
|
183
|
+
export declare function destroyHostedMachine(id: string, scope?: HostedMachineScope & {
|
|
184
|
+
requestId?: string;
|
|
185
|
+
}): Promise<HostedMachineResponse>;
|
|
186
|
+
export declare function execHostedMachine(id: string, input: HostedMachineExecInput, scope?: HostedMachineScope & {
|
|
187
|
+
requestId?: string;
|
|
188
|
+
}): Promise<HostedMachineExecResponse>;
|
|
189
|
+
/** Read a durable operation receipt without touching the machine or provider. */
|
|
190
|
+
export declare function getHostedMachineOperation(operationId: string, scope?: HostedMachineScope): Promise<HostedMachineOperationResponse>;
|
|
160
191
|
/**
|
|
161
192
|
* The CLI gave up watching. The RUNTIME did not give up.
|
|
162
193
|
*
|
|
@@ -23,6 +23,7 @@ exports.pauseHostedMachine = pauseHostedMachine;
|
|
|
23
23
|
exports.resumeHostedMachine = resumeHostedMachine;
|
|
24
24
|
exports.destroyHostedMachine = destroyHostedMachine;
|
|
25
25
|
exports.execHostedMachine = execHostedMachine;
|
|
26
|
+
exports.getHostedMachineOperation = getHostedMachineOperation;
|
|
26
27
|
exports.waitForHostedMachineReady = waitForHostedMachineReady;
|
|
27
28
|
exports.offlineForLabel = offlineForLabel;
|
|
28
29
|
const api_fetch_1 = require("./api-fetch");
|
|
@@ -77,6 +78,10 @@ function curateHostedMachineExecResult(response) {
|
|
|
77
78
|
status: hostedMachineStatus(response.session),
|
|
78
79
|
};
|
|
79
80
|
}
|
|
81
|
+
if (response.operation)
|
|
82
|
+
out.operation = response.operation;
|
|
83
|
+
if (response.replayed)
|
|
84
|
+
out.replayed = true;
|
|
80
85
|
return out;
|
|
81
86
|
}
|
|
82
87
|
function hostedMachineId(session) {
|
|
@@ -201,6 +206,10 @@ async function startHostedMachine(input) {
|
|
|
201
206
|
return (0, api_fetch_1.apiFetch)('/api/agentic/sandbox-sessions', {
|
|
202
207
|
method: 'POST',
|
|
203
208
|
body: input,
|
|
209
|
+
// apiFetch normally creates a fresh key for each invocation. The key
|
|
210
|
+
// generated (or supplied) by `machines hosted start` instead names this
|
|
211
|
+
// exact operation across a process restart and a lost response.
|
|
212
|
+
headers: { 'Idempotency-Key': input.clientRequestId },
|
|
204
213
|
});
|
|
205
214
|
}
|
|
206
215
|
async function listHostedMachines(scope = {}) {
|
|
@@ -228,14 +237,23 @@ async function resumeHostedMachine(id, scope = {}) {
|
|
|
228
237
|
async function destroyHostedMachine(id, scope = {}) {
|
|
229
238
|
return (0, api_fetch_1.apiFetch)(hostedMachinePath(`/${encodeURIComponent(id)}`, scope), {
|
|
230
239
|
method: 'DELETE',
|
|
240
|
+
...(scope.requestId ? { headers: { 'Idempotency-Key': scope.requestId } } : {}),
|
|
231
241
|
});
|
|
232
242
|
}
|
|
233
243
|
async function execHostedMachine(id, input, scope = {}) {
|
|
234
244
|
return (0, api_fetch_1.apiFetch)(hostedMachinePath(`/${encodeURIComponent(id)}/execute`, scope), {
|
|
235
245
|
method: 'POST',
|
|
236
|
-
body:
|
|
246
|
+
body: {
|
|
247
|
+
...input,
|
|
248
|
+
...(scope.requestId ? { clientRequestId: scope.requestId } : {}),
|
|
249
|
+
},
|
|
250
|
+
...(scope.requestId ? { headers: { 'Idempotency-Key': scope.requestId } } : {}),
|
|
237
251
|
});
|
|
238
252
|
}
|
|
253
|
+
/** Read a durable operation receipt without touching the machine or provider. */
|
|
254
|
+
async function getHostedMachineOperation(operationId, scope = {}) {
|
|
255
|
+
return (0, api_fetch_1.apiFetch)(`/api/agentic/sandbox-sessions/operations/${encodeURIComponent(operationId)}${scope.workspaceId ? `?workspaceId=${encodeURIComponent(scope.workspaceId)}` : ''}`);
|
|
256
|
+
}
|
|
239
257
|
/**
|
|
240
258
|
* The CLI gave up watching. The RUNTIME did not give up.
|
|
241
259
|
*
|
|
@@ -53,7 +53,7 @@ export declare function stripStorageFieldsFromText(text: string): string;
|
|
|
53
53
|
export declare function withOk<T>(value: T, ok?: boolean): T | ({
|
|
54
54
|
ok: boolean;
|
|
55
55
|
} & Record<string, unknown>);
|
|
56
|
-
export type CliOperationMode = 'execute' | 'dry_run' | 'verify';
|
|
56
|
+
export type CliOperationMode = 'execute' | 'dry_run' | 'read' | 'verify';
|
|
57
57
|
export type CliWriteState = 'confirmed' | 'not_attempted' | 'unknown';
|
|
58
58
|
export type CliResourceIdentity = {
|
|
59
59
|
kind: string;
|
package/dist/lib/machines.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DaemonContactState } from '@skrr-ai/data-provider';
|
|
1
|
+
import type { DaemonContactState, DaemonMaintenanceSummary } from '@skrr-ai/data-provider';
|
|
2
2
|
/**
|
|
3
3
|
* machines.ts — request client for `/api/machines`.
|
|
4
4
|
*
|
|
@@ -220,6 +220,14 @@ export interface MachineDaemonSummary {
|
|
|
220
220
|
supersededCount: number;
|
|
221
221
|
/** The profile this CLI is running as. */
|
|
222
222
|
activeProfile: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* The key a maintenance hold addresses this daemon by (`skrr daemon maintenance`),
|
|
225
|
+
* read from the server's own `daemons` list (D25). Absent on a server older than that
|
|
226
|
+
* list, on a managed machine, and on a daemon with no stable identity.
|
|
227
|
+
*/
|
|
228
|
+
runtimeKey?: string;
|
|
229
|
+
/** Present only while this daemon is held. See `DaemonMaintenanceSummary`. */
|
|
230
|
+
maintenance?: DaemonMaintenanceSummary;
|
|
223
231
|
}
|
|
224
232
|
export declare function parseDaemonId(daemonId: string): {
|
|
225
233
|
source: string;
|
package/dist/lib/machines.js
CHANGED
|
@@ -207,10 +207,24 @@ function machineListView(machine, options) {
|
|
|
207
207
|
? daemons
|
|
208
208
|
: daemons.filter((daemon) => daemon.harnessCount > daemon.supersededCount);
|
|
209
209
|
const hidden = rows.length - visibleRows.length;
|
|
210
|
+
// The server's own `daemons` (one per runtimeKey, D25) carries the key a hold is
|
|
211
|
+
// addressed by, and this view REPLACES that list with one per daemon id, so it
|
|
212
|
+
// would drop the key. Carried over by daemon id, and only when the server sent one.
|
|
213
|
+
const serverDaemons = machine.daemons ?? [];
|
|
214
|
+
const keyedDaemons = visibleDaemons.map((daemon) => {
|
|
215
|
+
const named = serverDaemons.find((candidate) => candidate.daemonId === daemon.daemonId);
|
|
216
|
+
if (!named?.runtimeKey)
|
|
217
|
+
return daemon;
|
|
218
|
+
return {
|
|
219
|
+
...daemon,
|
|
220
|
+
runtimeKey: named.runtimeKey,
|
|
221
|
+
...(named.maintenance ? { maintenance: named.maintenance } : {}),
|
|
222
|
+
};
|
|
223
|
+
});
|
|
210
224
|
return {
|
|
211
225
|
...machine,
|
|
212
226
|
thisComputer: isThisComputer(machine, options.hardwareMachineUuid),
|
|
213
|
-
daemons:
|
|
227
|
+
daemons: keyedDaemons,
|
|
214
228
|
harnesses: visibleRows,
|
|
215
229
|
...(hidden > 0 ? { hiddenHarnessCount: hidden } : {}),
|
|
216
230
|
};
|
package/dist/lib/node-adapter.js
CHANGED
|
@@ -98,10 +98,23 @@ function createNodeAdapter(opts = {}) {
|
|
|
98
98
|
// the exact attempt session before stamping Commitment provenance.
|
|
99
99
|
const autonomousRunId = process.env.OVERSKY_AUTONOMOUS_RUN_ID?.trim();
|
|
100
100
|
const sessionId = process.env.OVERSKY_SESSION_ID?.trim();
|
|
101
|
+
// The same pair for a Task run the AgentWorker executes (OSK-18132). It has
|
|
102
|
+
// no AutonomousRun, so the server names its TaskExecutionRun instead, and
|
|
103
|
+
// the wiki verifies that Run against this session before crediting the
|
|
104
|
+
// agent. A separate header pair, and only when there is no autonomous one:
|
|
105
|
+
// routes that read the session header above treat it as the
|
|
106
|
+
// AutonomousRun's attempt session and refuse it without a Run id beside
|
|
107
|
+
// it. Brand-free like the rest of the public contract (OSK-18267); the
|
|
108
|
+
// server names the pair once, in TaskExecutionRun/sessionRunBinding.js.
|
|
109
|
+
const taskRunId = process.env.OVERSKY_SESSION_TASK_RUN_ID?.trim();
|
|
101
110
|
if (autonomousRunId && sessionId) {
|
|
102
111
|
headers['X-Oversky-Autonomous-Run-Id'] = autonomousRunId;
|
|
103
112
|
headers['X-Oversky-Session-Id'] = sessionId;
|
|
104
113
|
}
|
|
114
|
+
else if (taskRunId && sessionId) {
|
|
115
|
+
headers['X-Task-Run-Id'] = taskRunId;
|
|
116
|
+
headers['X-Task-Run-Session-Id'] = sessionId;
|
|
117
|
+
}
|
|
105
118
|
// Which agent this process is running AS, for attribution only — it is
|
|
106
119
|
// what lets a task record `createdByAgentId` instead of overloading the
|
|
107
120
|
// assignee list to remember that an agent filed it. Same contract as the
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const COMPACT_RECORD_FIELDS: {
|
|
2
|
+
readonly task: readonly ["id", "identifier", "ref", "title", "status", "statusType", "priority", "parentId", "spaceId", "projectId", "goalId", "assigneeAgentIds", "assigneeUserIds", "dri", "executionMode", "actionability", "execution", "completion", "currentResultId", "createdAt", "updatedAt", "completedAt", "url"];
|
|
3
|
+
};
|
|
4
|
+
export type RecordResource = keyof typeof COMPACT_RECORD_FIELDS;
|
|
5
|
+
/** JSON-only projection flags for detail reads. */
|
|
6
|
+
export declare const recordOutputFlags: {
|
|
7
|
+
fields: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
compact: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
export type RecordOutputFlags = {
|
|
11
|
+
fields?: string;
|
|
12
|
+
compact?: boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Shape an already-normalized record. `--fields` is an explicit caller
|
|
16
|
+
* selection and therefore wins over `--compact`; no envelope is introduced.
|
|
17
|
+
*/
|
|
18
|
+
export declare function shapeRecordResponse(response: unknown, { resource, fields, compact }: RecordOutputFlags & {
|
|
19
|
+
resource: RecordResource;
|
|
20
|
+
}): unknown;
|
|
21
|
+
/** Explain that projection flags are intentionally JSON-only on a detail read. */
|
|
22
|
+
export declare function textModeRecordProjectionNotes(flags: RecordOutputFlags): string[];
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.recordOutputFlags = exports.COMPACT_RECORD_FIELDS = void 0;
|
|
4
|
+
exports.shapeRecordResponse = shapeRecordResponse;
|
|
5
|
+
exports.textModeRecordProjectionNotes = textModeRecordProjectionNotes;
|
|
6
|
+
/**
|
|
7
|
+
* JSON projection for one record, deliberately separate from list output.
|
|
8
|
+
*
|
|
9
|
+
* A list has paging and an envelope; a detail read is one canonical document.
|
|
10
|
+
* Sharing the field selector is useful, but wrapping a detail in `{data:[...]}`
|
|
11
|
+
* merely to reuse list mechanics would give callers two incompatible meanings
|
|
12
|
+
* for the same command. This module owns the record-shaped contract instead.
|
|
13
|
+
*/
|
|
14
|
+
const core_1 = require("@oclif/core");
|
|
15
|
+
const list_output_1 = require("./list-output");
|
|
16
|
+
exports.COMPACT_RECORD_FIELDS = {
|
|
17
|
+
task: [
|
|
18
|
+
'id',
|
|
19
|
+
'identifier',
|
|
20
|
+
'ref',
|
|
21
|
+
'title',
|
|
22
|
+
'status',
|
|
23
|
+
'statusType',
|
|
24
|
+
'priority',
|
|
25
|
+
'parentId',
|
|
26
|
+
'spaceId',
|
|
27
|
+
'projectId',
|
|
28
|
+
'goalId',
|
|
29
|
+
'assigneeAgentIds',
|
|
30
|
+
'assigneeUserIds',
|
|
31
|
+
'dri',
|
|
32
|
+
'executionMode',
|
|
33
|
+
'actionability',
|
|
34
|
+
'execution',
|
|
35
|
+
'completion',
|
|
36
|
+
'currentResultId',
|
|
37
|
+
'createdAt',
|
|
38
|
+
'updatedAt',
|
|
39
|
+
'completedAt',
|
|
40
|
+
'url',
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
/** JSON-only projection flags for detail reads. */
|
|
44
|
+
exports.recordOutputFlags = {
|
|
45
|
+
fields: core_1.Flags.string({
|
|
46
|
+
description: 'JSON only: comma-separated fields to keep on this record (dotted paths allowed, e.g. id,title,actionability.reason). Wins over --compact.',
|
|
47
|
+
}),
|
|
48
|
+
compact: core_1.Flags.boolean({
|
|
49
|
+
description: 'JSON only: keep the task detail navigation and state fields, omitting description, activity, lifecycle, and other bulk. See docs/cli/SKRR_TASKS.md (Task detail output for agents).',
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Shape an already-normalized record. `--fields` is an explicit caller
|
|
54
|
+
* selection and therefore wins over `--compact`; no envelope is introduced.
|
|
55
|
+
*/
|
|
56
|
+
function shapeRecordResponse(response, { resource, fields, compact }) {
|
|
57
|
+
if (!response || typeof response !== 'object' || Array.isArray(response))
|
|
58
|
+
return response;
|
|
59
|
+
const record = response;
|
|
60
|
+
const selected = (0, list_output_1.parseFields)(fields);
|
|
61
|
+
if (selected)
|
|
62
|
+
return (0, list_output_1.projectRow)(record, selected);
|
|
63
|
+
if (!compact)
|
|
64
|
+
return record;
|
|
65
|
+
const compacted = (0, list_output_1.projectRow)(record, exports.COMPACT_RECORD_FIELDS[resource]);
|
|
66
|
+
// Do not turn a future/unknown detail response into an empty object: preserving
|
|
67
|
+
// it is safer than hiding the only information a caller received.
|
|
68
|
+
return Object.keys(compacted).length > 0 ? compacted : record;
|
|
69
|
+
}
|
|
70
|
+
/** Explain that projection flags are intentionally JSON-only on a detail read. */
|
|
71
|
+
function textModeRecordProjectionNotes(flags) {
|
|
72
|
+
const given = [flags.fields ? '--fields' : null, flags.compact ? '--compact' : null].filter(Boolean);
|
|
73
|
+
if (given.length === 0)
|
|
74
|
+
return [];
|
|
75
|
+
return [
|
|
76
|
+
`Note: ${given.join(' and ')} ${given.length > 1 ? 'shape' : 'shapes'} JSON output only; the detail view is unchanged. Add --json to apply ${given.length > 1 ? 'them' : 'it'}.`,
|
|
77
|
+
];
|
|
78
|
+
}
|
package/dist/lib/roles.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export declare const roleApi: {
|
|
|
53
53
|
config?: Record<string, unknown> | undefined;
|
|
54
54
|
}[];
|
|
55
55
|
sources: {
|
|
56
|
-
source: "space" | "tasks" | "memory" | "
|
|
56
|
+
source: "space" | "tasks" | "memory" | "daemon" | "email" | "goal" | "files" | "local" | "browser" | "conversations" | "slack" | "github" | "messages" | "calendar" | "agent_run" | "docs" | "metrics" | "agent_initiatives" | "documents" | "product_metrics" | "business_metrics" | "state_monitor" | "monitor";
|
|
57
57
|
enabled: boolean;
|
|
58
58
|
config?: Record<string, unknown> | undefined;
|
|
59
59
|
}[];
|
|
@@ -135,7 +135,7 @@ export declare const roleApi: {
|
|
|
135
135
|
text: string;
|
|
136
136
|
effect: "append";
|
|
137
137
|
id: string;
|
|
138
|
-
status: "active" | "
|
|
138
|
+
status: "active" | "retired" | "proposed";
|
|
139
139
|
reason?: string | undefined;
|
|
140
140
|
source?: {
|
|
141
141
|
kind: "owner" | "role_spec" | "correction";
|
|
@@ -151,7 +151,7 @@ export declare const roleApi: {
|
|
|
151
151
|
phrases: string[];
|
|
152
152
|
effect: "refuse" | "require_approval";
|
|
153
153
|
id: string;
|
|
154
|
-
status: "active" | "
|
|
154
|
+
status: "active" | "retired" | "proposed";
|
|
155
155
|
reason?: string | undefined;
|
|
156
156
|
source?: {
|
|
157
157
|
kind: "owner" | "role_spec" | "correction";
|
|
@@ -12,6 +12,24 @@ export type MemoryStoreResolution = {
|
|
|
12
12
|
};
|
|
13
13
|
export declare function parseMemoryStoreResolutions(value: unknown): MemoryStoreResolution[] | undefined;
|
|
14
14
|
export declare function memoryStoreResolutionLines(resolutions?: MemoryStoreResolution[]): string[];
|
|
15
|
+
/**
|
|
16
|
+
* A Space on a command is context for the request; it is not evidence that
|
|
17
|
+
* this session mounted the Space's Memory Store. Keeping that distinction in
|
|
18
|
+
* one diagnostic prevents every Memory verb from inventing a different (and
|
|
19
|
+
* often unsafe) recovery path.
|
|
20
|
+
*
|
|
21
|
+
* `stores` has already passed the server's mount visibility check. We expose
|
|
22
|
+
* only those scopes, never a guessed Store or an inaccessible Space.
|
|
23
|
+
*/
|
|
24
|
+
export declare function memoryNotMountedDiagnostic({ requestedScope, agentId, spaceId, stores, }: {
|
|
25
|
+
requestedScope: string;
|
|
26
|
+
agentId: string;
|
|
27
|
+
spaceId?: string;
|
|
28
|
+
stores: MemoryStore[];
|
|
29
|
+
}): {
|
|
30
|
+
message: string;
|
|
31
|
+
details: Record<string, unknown>;
|
|
32
|
+
};
|
|
15
33
|
export declare function parseMemoryMount(value: unknown): MemoryMount;
|
|
16
34
|
export declare function parseMountedMemoryStore(value: unknown): MemoryStore;
|
|
17
35
|
export declare const scopedMemoryFlags: {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ScopedMemoryCommand = exports.versionedMutationFlags = exports.mutationFlags = exports.scopedMemoryFlags = void 0;
|
|
4
4
|
exports.parseMemoryStoreResolutions = parseMemoryStoreResolutions;
|
|
5
5
|
exports.memoryStoreResolutionLines = memoryStoreResolutionLines;
|
|
6
|
+
exports.memoryNotMountedDiagnostic = memoryNotMountedDiagnostic;
|
|
6
7
|
exports.parseMemoryMount = parseMemoryMount;
|
|
7
8
|
exports.parseMountedMemoryStore = parseMountedMemoryStore;
|
|
8
9
|
exports.parseMemoryApiError = parseMemoryApiError;
|
|
@@ -45,6 +46,43 @@ function memoryStoreResolutionLines(resolutions) {
|
|
|
45
46
|
};
|
|
46
47
|
return resolutions.map((resolution) => `${labels[resolution.outcome]}: ${resolution.storeId}`);
|
|
47
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* A Space on a command is context for the request; it is not evidence that
|
|
51
|
+
* this session mounted the Space's Memory Store. Keeping that distinction in
|
|
52
|
+
* one diagnostic prevents every Memory verb from inventing a different (and
|
|
53
|
+
* often unsafe) recovery path.
|
|
54
|
+
*
|
|
55
|
+
* `stores` has already passed the server's mount visibility check. We expose
|
|
56
|
+
* only those scopes, never a guessed Store or an inaccessible Space.
|
|
57
|
+
*/
|
|
58
|
+
function memoryNotMountedDiagnostic({ requestedScope, agentId, spaceId, stores, }) {
|
|
59
|
+
const availableScopes = [...new Set(stores.map((store) => `${store.owner.kind}:${store.owner.id}`))].sort();
|
|
60
|
+
const agentScope = `agent:${agentId}`;
|
|
61
|
+
const writableAgentStore = stores.some((store) => store.owner.kind === 'agent' &&
|
|
62
|
+
store.owner.id === agentId &&
|
|
63
|
+
store.mount.access === 'read_write');
|
|
64
|
+
const requestedSpaceId = requestedScope.startsWith('space:')
|
|
65
|
+
? requestedScope.slice('space:'.length)
|
|
66
|
+
: undefined;
|
|
67
|
+
const resolve = `skrr memory mounts resolve --agent ${agentId}${spaceId ? ` --space ${spaceId}` : requestedSpaceId ? ` --space ${requestedSpaceId}` : ''} --json`;
|
|
68
|
+
const remedy = [
|
|
69
|
+
`Run \`${resolve}\` and select a writable mounted Store.`,
|
|
70
|
+
writableAgentStore
|
|
71
|
+
? `To file Agent-owned Memory, retry with \`--scope ${agentScope}\`; Task or Space placement does not change that ownership.`
|
|
72
|
+
: 'A Space Store can be selected only after the session has mounted it; do not infer a mount from `--space` alone.',
|
|
73
|
+
].join(' ');
|
|
74
|
+
return {
|
|
75
|
+
message: `MEMORY_NOT_MOUNTED: ${requestedScope} is not mounted for this session. ` +
|
|
76
|
+
'`--space` selects request context; it does not mount Space Memory. ' +
|
|
77
|
+
`→ ${remedy}`,
|
|
78
|
+
details: {
|
|
79
|
+
requestedScope,
|
|
80
|
+
...(spaceId ? { spaceContext: spaceId } : {}),
|
|
81
|
+
availableScopes,
|
|
82
|
+
remedy,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
48
86
|
// The public CLI must not load the private data-schemas package at runtime.
|
|
49
87
|
// The API validates the full wire contract; check the fields used by CLI commands
|
|
50
88
|
// before treating a response as a mounted Store or mount.
|
|
@@ -236,8 +274,21 @@ class ScopedMemoryCommand extends base_command_1.BaseCommand {
|
|
|
236
274
|
const response = await this.memoryApi(flags.agent, `/stores${this.query(flags)}`);
|
|
237
275
|
const stores = response.stores.map(parseMountedMemoryStore);
|
|
238
276
|
const store = stores.find((candidate) => candidate.owner.kind === kind && candidate.owner.id === id);
|
|
239
|
-
if (!store)
|
|
240
|
-
|
|
277
|
+
if (!store) {
|
|
278
|
+
const diagnostic = memoryNotMountedDiagnostic({
|
|
279
|
+
requestedScope: flags.scope,
|
|
280
|
+
agentId: flags.agent,
|
|
281
|
+
spaceId: flags.space,
|
|
282
|
+
stores,
|
|
283
|
+
});
|
|
284
|
+
this.failWithCliError({
|
|
285
|
+
message: diagnostic.message,
|
|
286
|
+
code: 'MEMORY_NOT_MOUNTED',
|
|
287
|
+
exit: 5,
|
|
288
|
+
retryable: false,
|
|
289
|
+
details: diagnostic.details,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
241
292
|
if (write && store.mount?.access !== 'read_write') {
|
|
242
293
|
this.error('MEMORY_STORE_READ_ONLY: selected Store is read-only', { exit: 5 });
|
|
243
294
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for `skrr spaces charter …` and the wiki commands that can
|
|
3
|
+
* meet the one-charter rule (OSK-17985).
|
|
4
|
+
*
|
|
5
|
+
* A Space's charter is its one live `kind: 'charter'` wiki page. Its LEAD
|
|
6
|
+
* SECTION — everything before the first `##` heading — is what every agent
|
|
7
|
+
* turn in the Space receives; the rest is read on demand. The server computes
|
|
8
|
+
* the lead (`leadSection` on the charter read) with the same function the
|
|
9
|
+
* Space context builder uses, so these helpers print it rather than
|
|
10
|
+
* re-deriving it.
|
|
11
|
+
*/
|
|
12
|
+
import type { WikiCharterPage } from '@skrr-ai/data-provider';
|
|
13
|
+
export type CharterConflictHint = {
|
|
14
|
+
message: string;
|
|
15
|
+
details: {
|
|
16
|
+
pageId?: string;
|
|
17
|
+
path?: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A `409 WIKI_CHARTER_EXISTS` turned into a message that names the charter
|
|
22
|
+
* already there and the command that frees the slot. `undefined` for anything
|
|
23
|
+
* else, so the caller falls through to its ordinary error handling.
|
|
24
|
+
*/
|
|
25
|
+
export declare function charterConflictHint(err: unknown, { binName, spaceId }: {
|
|
26
|
+
binName: string;
|
|
27
|
+
spaceId: string;
|
|
28
|
+
}): CharterConflictHint | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* The lines `charter show` prints: where the charter is, then its lead section
|
|
31
|
+
* marked as what every agent reads, then either the whole page (`full`) or the
|
|
32
|
+
* command that reads it.
|
|
33
|
+
*
|
|
34
|
+
* An EMPTY lead is said in words, because it is the one charter state that
|
|
35
|
+
* changes what agents see without anything looking wrong: a page that opens
|
|
36
|
+
* with a `##` heading gives them no charter lead at all.
|
|
37
|
+
*/
|
|
38
|
+
export declare function charterLines(charter: WikiCharterPage & {
|
|
39
|
+
url?: string | null;
|
|
40
|
+
}, { binName, spaceId, full }: {
|
|
41
|
+
binName: string;
|
|
42
|
+
spaceId: string;
|
|
43
|
+
full?: boolean;
|
|
44
|
+
}): string[];
|
|
45
|
+
/** What `charter show` prints for a Space that has no charter page yet. */
|
|
46
|
+
export declare function noCharterLines({ binName, spaceId, }: {
|
|
47
|
+
binName: string;
|
|
48
|
+
spaceId: string;
|
|
49
|
+
}): string[];
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.charterConflictHint = charterConflictHint;
|
|
4
|
+
exports.charterLines = charterLines;
|
|
5
|
+
exports.noCharterLines = noCharterLines;
|
|
6
|
+
const http_error_1 = require("./http-error");
|
|
7
|
+
/**
|
|
8
|
+
* A `409 WIKI_CHARTER_EXISTS` turned into a message that names the charter
|
|
9
|
+
* already there and the command that frees the slot. `undefined` for anything
|
|
10
|
+
* else, so the caller falls through to its ordinary error handling.
|
|
11
|
+
*/
|
|
12
|
+
function charterConflictHint(err, { binName, spaceId }) {
|
|
13
|
+
if (!(0, http_error_1.hasHttpStatus)(err, 409))
|
|
14
|
+
return undefined;
|
|
15
|
+
const body = (0, http_error_1.httpBodyOf)(err);
|
|
16
|
+
if (body?.code !== 'WIKI_CHARTER_EXISTS')
|
|
17
|
+
return undefined;
|
|
18
|
+
const pageId = typeof body.pageId === 'string' && body.pageId ? body.pageId : undefined;
|
|
19
|
+
const path = typeof body.path === 'string' && body.path ? body.path : undefined;
|
|
20
|
+
let where = 'another page';
|
|
21
|
+
if (path)
|
|
22
|
+
where = `'${path}'`;
|
|
23
|
+
else if (pageId)
|
|
24
|
+
where = `page ${pageId}`;
|
|
25
|
+
return {
|
|
26
|
+
message: `This Space already has a charter page: ${where}. A Space holds at most one live charter. ` +
|
|
27
|
+
`Change that page to another kind first (\`${binName} wiki update ${spaceId} ${path ?? '<path>'} ` +
|
|
28
|
+
`--kind doc\`) or archive it, then try again. Show it with \`${binName} spaces charter show ${spaceId}\`.`,
|
|
29
|
+
details: { ...(pageId ? { pageId } : {}), ...(path ? { path } : {}) },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The lines `charter show` prints: where the charter is, then its lead section
|
|
34
|
+
* marked as what every agent reads, then either the whole page (`full`) or the
|
|
35
|
+
* command that reads it.
|
|
36
|
+
*
|
|
37
|
+
* An EMPTY lead is said in words, because it is the one charter state that
|
|
38
|
+
* changes what agents see without anything looking wrong: a page that opens
|
|
39
|
+
* with a `##` heading gives them no charter lead at all.
|
|
40
|
+
*/
|
|
41
|
+
function charterLines(charter, { binName, spaceId, full = false }) {
|
|
42
|
+
const path = charter.path ?? charter.slug;
|
|
43
|
+
const lines = [`Charter: ${path} (${charter.pageId})`];
|
|
44
|
+
if (charter.title && charter.title !== path)
|
|
45
|
+
lines.push(`Title: ${charter.title}`);
|
|
46
|
+
if (charter.url)
|
|
47
|
+
lines.push(`URL: ${charter.url}`);
|
|
48
|
+
lines.push('');
|
|
49
|
+
lines.push('Lead section (everything before the first ## heading; read by every agent in this Space):');
|
|
50
|
+
const lead = typeof charter.leadSection === 'string' ? charter.leadSection : '';
|
|
51
|
+
if (lead) {
|
|
52
|
+
for (const line of lead.split('\n'))
|
|
53
|
+
lines.push(` ${line}`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
lines.push(' (empty: the page opens with a ## heading, so agents receive no charter lead. ' +
|
|
57
|
+
'Put the essentials before the first ## heading.)');
|
|
58
|
+
}
|
|
59
|
+
lines.push('');
|
|
60
|
+
if (full) {
|
|
61
|
+
lines.push('Full page:');
|
|
62
|
+
for (const line of String(charter.content ?? '').split('\n'))
|
|
63
|
+
lines.push(` ${line}`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
lines.push(`The rest of the page is read on demand: \`${binName} spaces charter show ${spaceId} --full\` ` +
|
|
67
|
+
`or \`${binName} wiki cat ${spaceId} ${path}\`.`);
|
|
68
|
+
}
|
|
69
|
+
return lines;
|
|
70
|
+
}
|
|
71
|
+
/** What `charter show` prints for a Space that has no charter page yet. */
|
|
72
|
+
function noCharterLines({ binName, spaceId, }) {
|
|
73
|
+
return [
|
|
74
|
+
'This Space has no charter page yet.',
|
|
75
|
+
`Create one from the Space description: \`${binName} spaces charter create-from-description ${spaceId}\``,
|
|
76
|
+
`Or make an existing page the charter: \`${binName} wiki update ${spaceId} <path> --kind charter\``,
|
|
77
|
+
];
|
|
78
|
+
}
|