@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
|
@@ -186,6 +186,14 @@ export const DAEMON_COMPUTER_EVENTS = {
|
|
|
186
186
|
};
|
|
187
187
|
export const COMPUTER_EVENT_NAMES = Object.values(COMPUTER_EVENTS);
|
|
188
188
|
export const DAEMON_COMPUTER_EVENT_NAMES = Object.values(DAEMON_COMPUTER_EVENTS);
|
|
189
|
+
/**
|
|
190
|
+
* API → daemon: an authorized person observes, configures, stops or recovers
|
|
191
|
+
* the machine's Computer Use provider. Answered with `daemon:computer:ack`. It
|
|
192
|
+
* is deliberately outside `DAEMON_COMPUTER_EVENTS`, which lists the events the
|
|
193
|
+
* attachment protocol itself speaks, so the registry parity over that table
|
|
194
|
+
* does not move.
|
|
195
|
+
*/
|
|
196
|
+
export const DAEMON_COMPUTER_USE_CONTROL_EVENT = 'daemon:computer:use-control';
|
|
189
197
|
/** The daemon → API events; every other `daemon:computer:*` event flows API → daemon. */
|
|
190
198
|
export const DAEMON_COMPUTER_REPORT_EVENT_KEYS = [
|
|
191
199
|
'ack',
|
|
@@ -432,6 +440,14 @@ export const COMPUTER_REFUSAL_CODES = [
|
|
|
432
440
|
'too_large',
|
|
433
441
|
/** The machine has as many declared services as it allows (`COMPUTER_DECLARED_SERVICES_MAX`). */
|
|
434
442
|
'service_limit',
|
|
443
|
+
/**
|
|
444
|
+
* The machine's owner paused NEW work on it (OSK-19107). Refuses an `open` only:
|
|
445
|
+
* watching, reading files and controlling a surface that already exists keep
|
|
446
|
+
* working, and nothing running is touched. The refusal carries the hold's facts
|
|
447
|
+
* (`maintenance`), and it is not `machine_unavailable`, which says the machine is
|
|
448
|
+
* down: a paused machine is up.
|
|
449
|
+
*/
|
|
450
|
+
'maintenance_hold',
|
|
435
451
|
];
|
|
436
452
|
/**
|
|
437
453
|
* The code when it is a computer refusal, else `null`. There is one spelling
|
|
@@ -1258,7 +1274,8 @@ export function normalizeBrowserActivityOriginPolicy(input) {
|
|
|
1258
1274
|
const origins = (items, required) => {
|
|
1259
1275
|
if (!Array.isArray(items) || items.length > 20 || (required && !items.length))
|
|
1260
1276
|
throw new Error('Choose from one to twenty allowed origins and up to twenty excluded origins');
|
|
1261
|
-
return [
|
|
1277
|
+
return [
|
|
1278
|
+
...new Set(items.map((item) => {
|
|
1262
1279
|
if (typeof item !== 'string' || item.length > 500)
|
|
1263
1280
|
throw new Error('Use an exact http or https origin without a path, credentials, query or fragment');
|
|
1264
1281
|
let url;
|
|
@@ -1268,19 +1285,29 @@ export function normalizeBrowserActivityOriginPolicy(input) {
|
|
|
1268
1285
|
catch {
|
|
1269
1286
|
throw new Error('Use an exact http or https origin');
|
|
1270
1287
|
}
|
|
1271
|
-
if (!['http:', 'https:'].includes(url.protocol) ||
|
|
1288
|
+
if (!['http:', 'https:'].includes(url.protocol) ||
|
|
1289
|
+
url.hostname.includes('*') ||
|
|
1290
|
+
url.username ||
|
|
1291
|
+
url.password ||
|
|
1292
|
+
item !== url.origin)
|
|
1272
1293
|
throw new Error('Use an exact http or https origin without a path, credentials, query or fragment');
|
|
1273
1294
|
return url.origin;
|
|
1274
|
-
}))
|
|
1295
|
+
})),
|
|
1296
|
+
].sort();
|
|
1297
|
+
};
|
|
1298
|
+
return {
|
|
1299
|
+
allowOrigins: origins(value.allowOrigins, true),
|
|
1300
|
+
excludeOrigins: origins(value.excludeOrigins, false),
|
|
1275
1301
|
};
|
|
1276
|
-
return { allowOrigins: origins(value.allowOrigins, true), excludeOrigins: origins(value.excludeOrigins, false) };
|
|
1277
1302
|
}
|
|
1278
1303
|
export function browserActivityOriginAllowed(policy, url) {
|
|
1279
1304
|
if (typeof url !== 'string')
|
|
1280
1305
|
return false;
|
|
1281
1306
|
try {
|
|
1282
1307
|
const origin = new URL(url).origin;
|
|
1283
|
-
return ['http:', 'https:'].includes(new URL(url).protocol) &&
|
|
1308
|
+
return (['http:', 'https:'].includes(new URL(url).protocol) &&
|
|
1309
|
+
policy.allowOrigins.includes(origin) &&
|
|
1310
|
+
!policy.excludeOrigins.includes(origin));
|
|
1284
1311
|
}
|
|
1285
1312
|
catch {
|
|
1286
1313
|
return false;
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
* heard is `firstPartyHarness.ts`'s and the API's `sessionProvider.js`'s
|
|
47
47
|
* decision, not this table's.
|
|
48
48
|
*/
|
|
49
|
-
import { COMPUTER_DESKTOP_CAPABILITY, COMPUTER_DESKTOP_CONTROL_CAPABILITY, DAEMON_COMPUTER_DESKTOP_EVENTS } from './desktopWire.js';
|
|
50
|
-
import { COMPUTER_CAPABILITIES, DAEMON_COMPUTER_EVENTS, DAEMON_COMPUTER_REPORT_EVENT_KEYS, } from './computerWire.js';
|
|
49
|
+
import { COMPUTER_DESKTOP_CAPABILITY, COMPUTER_DESKTOP_CONTROL_CAPABILITY, DAEMON_COMPUTER_DESKTOP_EVENTS, } from './desktopWire.js';
|
|
50
|
+
import { COMPUTER_CAPABILITIES, DAEMON_COMPUTER_EVENTS, DAEMON_COMPUTER_REPORT_EVENT_KEYS, DAEMON_COMPUTER_USE_CONTROL_EVENT, } from './computerWire.js';
|
|
51
51
|
// ---------------------------------------------------------------------------
|
|
52
52
|
// Vocabulary
|
|
53
53
|
// ---------------------------------------------------------------------------
|
|
@@ -283,34 +283,53 @@ const TOOLS = [
|
|
|
283
283
|
capability: TOOL_RESPONSE_OUTBOX,
|
|
284
284
|
}),
|
|
285
285
|
toDaemon('daemon:tool:cancel', 'Abandon a running tool call.'),
|
|
286
|
-
toDaemon(
|
|
287
|
-
stability: 'experimental',
|
|
286
|
+
toDaemon(DAEMON_COMPUTER_USE_CONTROL_EVENT, 'An authorized person observes, configures, stops or recovers the machine Computer Use provider.', {
|
|
287
|
+
stability: 'experimental',
|
|
288
|
+
capability: 'computer_use_mcp_v1',
|
|
289
|
+
delivery: 'acked',
|
|
290
|
+
answeredBy: DAEMON_COMPUTER_EVENTS.ack,
|
|
288
291
|
payload: { kind: 'zod', schema: 'daemonComputerUseControlSchema' },
|
|
289
292
|
}),
|
|
290
293
|
toDaemon('daemon:computer-use:rotate-credential', 'The approved hosted-desktop owner requests credential rotation for this exact active machine lease generation.', {
|
|
291
|
-
stability: 'experimental',
|
|
294
|
+
stability: 'experimental',
|
|
295
|
+
capability: 'computer_use_mcp_v1',
|
|
296
|
+
delivery: 'acked',
|
|
297
|
+
answeredBy: DAEMON_COMPUTER_EVENTS.ack,
|
|
292
298
|
payload: { kind: 'zod', schema: 'daemonComputerUseRotateCredentialSchema' },
|
|
293
299
|
}),
|
|
294
300
|
toDaemon('daemon:computer-use:revoke', 'Revoke cloud Computer Use bindings after owner machine authority was removed.', {
|
|
295
|
-
stability: 'experimental',
|
|
301
|
+
stability: 'experimental',
|
|
302
|
+
capability: 'computer_use_mcp_v1',
|
|
296
303
|
payload: { kind: 'zod', schema: 'daemonComputerUseRevokeSchema' },
|
|
297
304
|
}),
|
|
298
305
|
...['subscribe', 'protocol', 'unsubscribe'].map((operation) => toDaemon(DAEMON_COMPUTER_DESKTOP_EVENTS[operation], `Read-only desktop stream: ${operation}; bound to an authenticated attachment and generation.`, {
|
|
299
|
-
stability: 'experimental',
|
|
300
|
-
|
|
301
|
-
|
|
306
|
+
stability: 'experimental',
|
|
307
|
+
capability: COMPUTER_DESKTOP_CAPABILITY,
|
|
308
|
+
delivery: 'acked',
|
|
309
|
+
answeredBy: DAEMON_COMPUTER_EVENTS.ack,
|
|
310
|
+
payload: {
|
|
311
|
+
kind: 'zod',
|
|
312
|
+
schema: `daemonComputerDesktop${operation[0].toUpperCase()}${operation.slice(1)}Schema`,
|
|
313
|
+
},
|
|
302
314
|
})),
|
|
303
315
|
...['control', 'input'].map((operation) => toDaemon(DAEMON_COMPUTER_DESKTOP_EVENTS[operation], `Human-only typed desktop ${operation}; exact authenticated attachment, stream and generation.`, {
|
|
304
|
-
stability: 'experimental',
|
|
305
|
-
|
|
306
|
-
|
|
316
|
+
stability: 'experimental',
|
|
317
|
+
capability: COMPUTER_DESKTOP_CONTROL_CAPABILITY,
|
|
318
|
+
delivery: 'acked',
|
|
319
|
+
answeredBy: DAEMON_COMPUTER_EVENTS.ack,
|
|
320
|
+
payload: {
|
|
321
|
+
kind: 'zod',
|
|
322
|
+
schema: `daemonComputerDesktop${operation[0].toUpperCase()}${operation.slice(1)}Schema`,
|
|
323
|
+
},
|
|
307
324
|
})),
|
|
308
325
|
toServer(DAEMON_COMPUTER_DESKTOP_EVENTS.controlChanged, 'Private desktop holder and input revocation fact; never carries a control token.', {
|
|
309
|
-
stability: 'experimental',
|
|
326
|
+
stability: 'experimental',
|
|
327
|
+
capability: COMPUTER_DESKTOP_CONTROL_CAPABILITY,
|
|
310
328
|
payload: { kind: 'zod', schema: 'computerDesktopControlResultSchema' },
|
|
311
329
|
}),
|
|
312
330
|
toServer(DAEMON_COMPUTER_DESKTOP_EVENTS.data, 'Read-only desktop stream data or a terminal close fact for one attachment generation.', {
|
|
313
|
-
stability: 'experimental',
|
|
331
|
+
stability: 'experimental',
|
|
332
|
+
capability: COMPUTER_DESKTOP_CAPABILITY,
|
|
314
333
|
payload: { kind: 'zod', schema: 'computerDesktopDataSchema' },
|
|
315
334
|
}),
|
|
316
335
|
toServer('daemon:wire:chunk', 'One slice of a tool or session response above the single-message ceiling, sha256-checked and reassembled by the API before the reassembled event reaches its normal handler. Sent only to a server that announced `serverCaps.wireChunking`; the last slice is acked by that handler (OSK-16616).', {
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure core of a GUIDED update (OSK-19107, Space OSK-S-524, tasks M51 to M53):
|
|
3
|
+
* hold the machine, wait for it to be quiet, update, verify, and give the machine
|
|
4
|
+
* back. The Desktop app and a standalone `skrr` install both run it, so what they
|
|
5
|
+
* decide on, and the words they use for what is in the way, cannot drift apart.
|
|
6
|
+
*
|
|
7
|
+
* This file is DECISIONS ONLY. It performs no I/O, reads no clock and holds no
|
|
8
|
+
* state, so every rule below is a table test. The orchestration (a persisted flow
|
|
9
|
+
* record, polling, the installer, the supervisor) lives with each caller, because
|
|
10
|
+
* that is the part that differs between a Desktop that quits mid-flow and a CLI that
|
|
11
|
+
* runs in the foreground.
|
|
12
|
+
*
|
|
13
|
+
* ## Why these rules (each names the failure it prevents)
|
|
14
|
+
*
|
|
15
|
+
* - **`prepare` is a probe that briefly refuses admitted work.** While it runs the
|
|
16
|
+
* daemon refuses admitted tool calls with an infra-class error, and a tool-proxy Run
|
|
17
|
+
* that sees one drops its tools to the Hosted Machine for good. So a guided flow
|
|
18
|
+
* calls it ONLY when the server's reading says there is nothing admitted to refuse
|
|
19
|
+
* ({@link prepareBasis}), never to find out whether there is.
|
|
20
|
+
* - **`unknown` is an answer.** A source nobody could read is never zero and never
|
|
21
|
+
* ready. {@link noServerVeto} is deliberately strict: every server source must have
|
|
22
|
+
* been read, and none may list active or unproven work.
|
|
23
|
+
* - **A server source can only veto.** Only the daemon's own positively announced
|
|
24
|
+
* report grants `ready`; the owner's attestation and the daemon's own `prepare`
|
|
25
|
+
* (labelled `no_veto`, D38) are the two other bases, and each is labelled as what
|
|
26
|
+
* it is wherever it is shown.
|
|
27
|
+
* - **Blockers are shown in the words of whoever knows them.** The daemon's blocker
|
|
28
|
+
* `reason` and the server's holder `label` are the vocabulary; nothing here
|
|
29
|
+
* re-spells them. They are bounded and never a raw path, because a diagnostic can
|
|
30
|
+
* carry one.
|
|
31
|
+
* - **A new PID, an exit code or a cloud connection is not a verified update.**
|
|
32
|
+
* {@link verifyReplacement} requires the daemon's own `verified`, from a process
|
|
33
|
+
* other than the one that was replaced, for the build that was asked for, and the
|
|
34
|
+
* same machine identity afterwards. A different identity is the reinstall case: the
|
|
35
|
+
* hold is left in place and shown, never resumed.
|
|
36
|
+
*
|
|
37
|
+
* The shapes are STRUCTURAL SUBSETS of `DaemonMaintenanceView` in
|
|
38
|
+
* `@skrr-ai/data-provider` (`daemonMaintenance.ts`), which is the one vocabulary.
|
|
39
|
+
* This package cannot import it (it sits below it), so `guidedUpdate.test.ts` reads
|
|
40
|
+
* that file and fails when a list mirrored here drifts from it.
|
|
41
|
+
*/
|
|
42
|
+
export type GuidedHolderClass = 'active' | 'pending_delivery' | 'unproven' | 'forensic';
|
|
43
|
+
export interface GuidedHolder {
|
|
44
|
+
kind: string;
|
|
45
|
+
class: GuidedHolderClass | string;
|
|
46
|
+
ref?: string;
|
|
47
|
+
label?: string;
|
|
48
|
+
since?: string | null;
|
|
49
|
+
detail?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface GuidedSourceReading {
|
|
52
|
+
source: string;
|
|
53
|
+
read: 'ok' | 'unreadable' | 'not_announced' | string;
|
|
54
|
+
cause?: string;
|
|
55
|
+
readAt?: string;
|
|
56
|
+
total?: number;
|
|
57
|
+
holders?: GuidedHolder[];
|
|
58
|
+
truncated?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface GuidedViewLike {
|
|
61
|
+
runtimeKey?: string;
|
|
62
|
+
hold: {
|
|
63
|
+
generation: number;
|
|
64
|
+
lifecycle: 'held' | 'released' | string;
|
|
65
|
+
reason?: string;
|
|
66
|
+
requestedAt?: string;
|
|
67
|
+
heldBy?: {
|
|
68
|
+
kind?: string;
|
|
69
|
+
id?: string;
|
|
70
|
+
name?: string;
|
|
71
|
+
};
|
|
72
|
+
attestation?: {
|
|
73
|
+
at?: string;
|
|
74
|
+
by?: string;
|
|
75
|
+
} | null;
|
|
76
|
+
} | null;
|
|
77
|
+
reading: {
|
|
78
|
+
state: 'draining' | 'ready' | 'unknown' | string;
|
|
79
|
+
cause: string | null;
|
|
80
|
+
readAt?: string;
|
|
81
|
+
sources?: GuidedSourceReading[];
|
|
82
|
+
} | null;
|
|
83
|
+
journey: {
|
|
84
|
+
phase: string;
|
|
85
|
+
modifiers?: string[];
|
|
86
|
+
cause?: string | null;
|
|
87
|
+
controls?: string[];
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** The server sources that can only veto. `daemon_report` is the only one that grants. */
|
|
91
|
+
export declare const GUIDED_SERVER_SOURCES: readonly ["claims", "receipts", "sessions", "runs", "leases", "custody"];
|
|
92
|
+
/** The refusals the owner API names, mirrored from `DAEMON_MAINTENANCE_REFUSALS`. */
|
|
93
|
+
export declare const GUIDED_REFUSALS: readonly ["managed_machine", "no_stable_identity", "not_found", "ambiguous", "generation_conflict", "not_held", "already_held", "attestation_not_applicable", "not_owner", "held_by_other"];
|
|
94
|
+
export type GuidedRefusal = (typeof GUIDED_REFUSALS)[number];
|
|
95
|
+
export declare function isGuidedRefusal(value: unknown): value is GuidedRefusal;
|
|
96
|
+
/** The daemon handoff phases, mirrored from `daemon/src/update/handoff.ts`. */
|
|
97
|
+
export declare const GUIDED_HANDOFF_PHASES: readonly ["ready", "deferred", "reconnecting", "verified", "failed", "rolled-back"];
|
|
98
|
+
/**
|
|
99
|
+
* What a guided flow may do with the server's answer. The flow reads `reading` and
|
|
100
|
+
* the fence, never the Journey's phase alone: a Journey says `back_held` for any
|
|
101
|
+
* process that registered after the fence, and that masks the reading it would
|
|
102
|
+
* otherwise carry.
|
|
103
|
+
*/
|
|
104
|
+
export type Readiness =
|
|
105
|
+
/** No live hold on this machine (it was released, or never existed). */
|
|
106
|
+
{
|
|
107
|
+
kind: 'not_held';
|
|
108
|
+
}
|
|
109
|
+
/** A live hold, but not the generation this flow took. Never adopted. */
|
|
110
|
+
| {
|
|
111
|
+
kind: 'generation_changed';
|
|
112
|
+
currentGeneration: number;
|
|
113
|
+
}
|
|
114
|
+
/** The fence is not confirmed on every row, so no reading means anything yet. */
|
|
115
|
+
| {
|
|
116
|
+
kind: 'pausing';
|
|
117
|
+
}
|
|
118
|
+
/** Nothing admitted is running: the daemon's report said so, or the owner vouched. */
|
|
119
|
+
| {
|
|
120
|
+
kind: 'ready';
|
|
121
|
+
basis: 'evidence' | 'attested';
|
|
122
|
+
}
|
|
123
|
+
/** The daemon cannot report. No server source vetoes. Only the daemon's own check may decide. */
|
|
124
|
+
| {
|
|
125
|
+
kind: 'no_report';
|
|
126
|
+
} | {
|
|
127
|
+
kind: 'draining';
|
|
128
|
+
} | {
|
|
129
|
+
kind: 'unknown';
|
|
130
|
+
cause: string | null;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Whether the server holds a reading that nothing vetoes, for a daemon that cannot
|
|
134
|
+
* report (D38). Strict on purpose: a source that is absent from the list, unreadable,
|
|
135
|
+
* truncated, or that names active or unproven work, is a veto. `daemon_report` must
|
|
136
|
+
* be `not_announced`: any other answer means the reading is not the
|
|
137
|
+
* `no_inventory_capability` case this is for.
|
|
138
|
+
*/
|
|
139
|
+
export declare function noServerVeto(sources: readonly GuidedSourceReading[] | undefined): boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Read the owner API's view for a flow that took `generation`.
|
|
142
|
+
*
|
|
143
|
+
* Order matters and is the rule set (each is a test):
|
|
144
|
+
* 1. No live hold: `not_held`. A different live generation: `generation_changed`.
|
|
145
|
+
* 2. The fence is not confirmed (`pausing`): nothing below it means anything.
|
|
146
|
+
* 3. The reading is `ready` (the daemon's own report): `ready` by evidence.
|
|
147
|
+
* 4. `draining`: work is running. Evidence, never overridden.
|
|
148
|
+
* 5. `unknown`: ready by attestation if the Journey says the owner vouched for this
|
|
149
|
+
* cause; `no_report` if the daemon cannot report and no source vetoes; else
|
|
150
|
+
* `unknown`. No reading at all is `unknown (source_unreadable)`, never ready.
|
|
151
|
+
*/
|
|
152
|
+
export declare function evaluateReadiness(view: GuidedViewLike | null | undefined, expectedGeneration: number | null): Readiness;
|
|
153
|
+
/** How a `prepare` is justified. Labelled on every surface as exactly this. */
|
|
154
|
+
export type PrepareBasis = 'evidence' | 'attested' | 'no_veto';
|
|
155
|
+
/**
|
|
156
|
+
* Whether a guided flow may call the daemon's `prepare`, and on what basis. `null`
|
|
157
|
+
* means NO: `prepare` is never a way to find out. A legacy daemon never gets one:
|
|
158
|
+
* it has no endpoint, and its restart is the owner's attested decision, not a probe.
|
|
159
|
+
*/
|
|
160
|
+
export declare function prepareBasis(readiness: Readiness, opts: {
|
|
161
|
+
legacy: boolean;
|
|
162
|
+
}): PrepareBasis | null;
|
|
163
|
+
/**
|
|
164
|
+
* Whether a legacy daemon (no handoff endpoint) may be restarted by the supervisor.
|
|
165
|
+
* Only on the owner's attestation: the daemon cannot report what it is doing and a
|
|
166
|
+
* SIGTERM ends its wrappers, so nothing but the owner's word can vouch for it.
|
|
167
|
+
*/
|
|
168
|
+
export declare function legacyRestartAllowed(readiness: Readiness): boolean;
|
|
169
|
+
export interface DaemonBlockerLike {
|
|
170
|
+
kind: string;
|
|
171
|
+
id?: string;
|
|
172
|
+
reason?: string;
|
|
173
|
+
}
|
|
174
|
+
export interface DesktopWorkLike {
|
|
175
|
+
localSessions: number;
|
|
176
|
+
agentBrowserWindows: number;
|
|
177
|
+
}
|
|
178
|
+
export type OwnerBlockerSource = 'server' | 'daemon' | 'desktop';
|
|
179
|
+
export interface OwnerBlocker {
|
|
180
|
+
source: OwnerBlockerSource;
|
|
181
|
+
/** The holder or blocker kind as its owner spelled it, or a `desktop_*` id for the app's own work. */
|
|
182
|
+
kind: string;
|
|
183
|
+
/** The server's label, or the daemon's reason, verbatim after bounding. Absent when it was unsafe to show. */
|
|
184
|
+
text?: string;
|
|
185
|
+
/** A server label for a daemon blocker the server holds under the same ref. */
|
|
186
|
+
label?: string;
|
|
187
|
+
/** A bounded identifier (a session or request id), never a path. */
|
|
188
|
+
id?: string;
|
|
189
|
+
since?: string | null;
|
|
190
|
+
/** For the app's own work: how many. */
|
|
191
|
+
count?: number;
|
|
192
|
+
}
|
|
193
|
+
export declare const MAX_OWNER_BLOCKERS = 20;
|
|
194
|
+
/** A sentence safe to put in front of the owner, or `undefined` when it is not. */
|
|
195
|
+
export declare function sanitizeBlockerText(value: unknown, max?: number): string | undefined;
|
|
196
|
+
/**
|
|
197
|
+
* Everything in the way, from the three places that know: the server's holders
|
|
198
|
+
* (active and unproven work: `pending_delivery` and `forensic` never block), the
|
|
199
|
+
* daemon's own refusal from `prepare`, and the work the Desktop app itself hosts and
|
|
200
|
+
* ends when it quits (`LocalSessionService` processes and agent browser windows,
|
|
201
|
+
* which the daemon's inventory cannot see).
|
|
202
|
+
*
|
|
203
|
+
* A daemon blocker whose id equals a server holder's ref is the same work seen twice:
|
|
204
|
+
* it is listed once, with the daemon's reason and the server's label. Whether the two
|
|
205
|
+
* ids are in fact comparable was never established (review §6.2 item 2), so a match
|
|
206
|
+
* only MERGES the wording and never hides a blocker that has no match.
|
|
207
|
+
*/
|
|
208
|
+
export declare function describeBlockers(input: {
|
|
209
|
+
view?: GuidedViewLike | null;
|
|
210
|
+
daemon?: readonly DaemonBlockerLike[] | null;
|
|
211
|
+
desktop?: DesktopWorkLike | null;
|
|
212
|
+
}): OwnerBlocker[];
|
|
213
|
+
/**
|
|
214
|
+
* A string that changes whenever the set of things in the way changes. The "update
|
|
215
|
+
* now anyway" confirmation carries the one it was shown, and the action is refused
|
|
216
|
+
* when it no longer matches: a confirmation that names what WAS running is not a
|
|
217
|
+
* confirmation of what is.
|
|
218
|
+
*/
|
|
219
|
+
export declare function blockersFingerprint(blockers: readonly OwnerBlocker[]): string;
|
|
220
|
+
/**
|
|
221
|
+
* The labels the owner is shown, as the server records them in the outcome
|
|
222
|
+
* (`acknowledged`): each bounded to the server's 160-character limit.
|
|
223
|
+
*/
|
|
224
|
+
export declare function acknowledgedLabels(blockers: readonly OwnerBlocker[], max?: number): string[];
|
|
225
|
+
export interface HandoffBlocker {
|
|
226
|
+
kind: string;
|
|
227
|
+
id?: string;
|
|
228
|
+
reason: string;
|
|
229
|
+
}
|
|
230
|
+
export interface HandoffStatusLike {
|
|
231
|
+
protocolVersion: 1;
|
|
232
|
+
handoffId: string;
|
|
233
|
+
phase: 'ready' | 'deferred' | 'reconnecting' | 'verified' | 'failed' | 'rolled-back';
|
|
234
|
+
reason: string;
|
|
235
|
+
sourceProcessId: string;
|
|
236
|
+
sourceVersion: string;
|
|
237
|
+
target: {
|
|
238
|
+
path?: string;
|
|
239
|
+
mtimeMs?: number;
|
|
240
|
+
sha256: string;
|
|
241
|
+
};
|
|
242
|
+
blockers: HandoffBlocker[];
|
|
243
|
+
expectedSessions: unknown[];
|
|
244
|
+
adoptedSessionCount?: number;
|
|
245
|
+
verifiedBy?: {
|
|
246
|
+
processId: string;
|
|
247
|
+
version: string;
|
|
248
|
+
};
|
|
249
|
+
observer?: {
|
|
250
|
+
processId: string;
|
|
251
|
+
version: string;
|
|
252
|
+
buildMatches: boolean;
|
|
253
|
+
ready: boolean;
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* What a call to the daemon's loopback `/v1/update-handoff` came back as.
|
|
258
|
+
*
|
|
259
|
+
* - `absent`: a 404. The daemon answered and has no such endpoint: it predates the
|
|
260
|
+
* handoff (the installed 0.8.117 answers 404 to every path it does not serve). This
|
|
261
|
+
* is the ONLY reply that means "legacy". A refused connection is not.
|
|
262
|
+
* - `unauthorized`: the bootstrap secret was refused (it rotates when the daemon
|
|
263
|
+
* restarts). Re-read the bootstrap and try again.
|
|
264
|
+
* - `refused`: reachable, speaks the protocol, said no (409: no handoff owned, or the
|
|
265
|
+
* lease expired; 400; 413). A refusal is a value the caller shows.
|
|
266
|
+
* - `unreachable`: no bootstrap file, a connection error, a timeout, a malformed or
|
|
267
|
+
* unexpected body. Unknown: never `absent`, never `ready`.
|
|
268
|
+
*/
|
|
269
|
+
export type HandoffReply = {
|
|
270
|
+
kind: 'ok';
|
|
271
|
+
status: HandoffStatusLike;
|
|
272
|
+
} | {
|
|
273
|
+
kind: 'absent';
|
|
274
|
+
} | {
|
|
275
|
+
kind: 'unauthorized';
|
|
276
|
+
} | {
|
|
277
|
+
kind: 'refused';
|
|
278
|
+
code?: string;
|
|
279
|
+
} | {
|
|
280
|
+
kind: 'unreachable';
|
|
281
|
+
};
|
|
282
|
+
export declare function classifyHandoffReply(input: {
|
|
283
|
+
/** `null` when no HTTP response arrived at all. */
|
|
284
|
+
statusCode: number | null;
|
|
285
|
+
/** The parsed JSON body, or `undefined` when there was none or it did not parse. */
|
|
286
|
+
body?: unknown;
|
|
287
|
+
}): HandoffReply;
|
|
288
|
+
export interface ReplacementEvidence {
|
|
289
|
+
/** The daemon's own answer to `status` for the handoff, or null when it did not answer. */
|
|
290
|
+
handoff: Pick<HandoffStatusLike, 'phase' | 'verifiedBy' | 'target' | 'reason' | 'observer'> | null;
|
|
291
|
+
expect: {
|
|
292
|
+
sourceProcessId: string;
|
|
293
|
+
targetSha256: string;
|
|
294
|
+
/** The bundled daemon's version, or null when it could not be read (the hash binds it anyway). */
|
|
295
|
+
version: string | null;
|
|
296
|
+
};
|
|
297
|
+
identity: {
|
|
298
|
+
recordedDaemonId: string;
|
|
299
|
+
recordedRuntimeKey: string;
|
|
300
|
+
/** The daemon id of the process now holding the loopback bootstrap, or null when unreadable. */
|
|
301
|
+
bootstrapDaemonId: string | null;
|
|
302
|
+
/** The runtimeKey the machine payload lists for `recordedDaemonId` now, or null when it lists none or could not be read. */
|
|
303
|
+
runtimeKeyNow: string | null;
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
export type ReplacementVerdict =
|
|
307
|
+
/** (1) the daemon's `verified` for this build by another process, and (2) the same identity. */
|
|
308
|
+
{
|
|
309
|
+
kind: 'verified';
|
|
310
|
+
} | {
|
|
311
|
+
kind: 'not_yet';
|
|
312
|
+
missing: 'daemon_status' | 'verified' | 'identity_unreadable';
|
|
313
|
+
}
|
|
314
|
+
/** The daemon id or the machine's runtimeKey changed: a reinstall. The hold is left and shown. */
|
|
315
|
+
| {
|
|
316
|
+
kind: 'reinstall';
|
|
317
|
+
what: 'daemon_id' | 'runtime_key';
|
|
318
|
+
} | {
|
|
319
|
+
kind: 'failed';
|
|
320
|
+
phase: 'failed' | 'rolled-back';
|
|
321
|
+
reason: string;
|
|
322
|
+
sameProcess: boolean;
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* Decide whether a committed replacement is complete. All of (1) and (2) must hold
|
|
326
|
+
* before anything else is asked of the server (3, {@link serverSawNewProcess}), and
|
|
327
|
+
* nothing here resumes: the verdict only says what was seen.
|
|
328
|
+
*
|
|
329
|
+
* An identity that is merely UNREADABLE (the bootstrap is mid-rotation, the machine
|
|
330
|
+
* payload could not be fetched) is `not_yet`, never a reinstall and never verified.
|
|
331
|
+
*/
|
|
332
|
+
export declare function verifyReplacement(evidence: ReplacementEvidence): ReplacementVerdict;
|
|
333
|
+
export interface LegacyRestartEvidence {
|
|
334
|
+
before: {
|
|
335
|
+
startedAt: number | null;
|
|
336
|
+
processId: number | null;
|
|
337
|
+
};
|
|
338
|
+
after: {
|
|
339
|
+
daemonId: string | null;
|
|
340
|
+
version: string | null;
|
|
341
|
+
startedAt: number | null;
|
|
342
|
+
processId: number | null;
|
|
343
|
+
};
|
|
344
|
+
expect: {
|
|
345
|
+
daemonId: string;
|
|
346
|
+
version: string | null;
|
|
347
|
+
};
|
|
348
|
+
runtimeKeyNow: string | null;
|
|
349
|
+
recordedRuntimeKey: string;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* The legacy counterpart: a daemon with no handoff cannot say `verified`, so the copy
|
|
353
|
+
* claims only what was seen ("restarted on version X"), never "adopted N sessions".
|
|
354
|
+
* A new process (a different start time and, where known, a different PID), the same
|
|
355
|
+
* identity, and the version it announces equal to the bundled one.
|
|
356
|
+
*/
|
|
357
|
+
export declare function verifyLegacyRestart(evidence: LegacyRestartEvidence): ReplacementVerdict;
|
|
358
|
+
/**
|
|
359
|
+
* Whether the server independently saw a new process register under the held key
|
|
360
|
+
* (condition 3). The Journey says `back_held` for ANY process that registered since
|
|
361
|
+
* the fence, so it can only corroborate THIS replacement when it did not already say
|
|
362
|
+
* so before the commit. When it did, the answer is `not_independent`: the flow rests
|
|
363
|
+
* on (1) and (2) and says so.
|
|
364
|
+
*/
|
|
365
|
+
export declare function serverSawNewProcess(input: {
|
|
366
|
+
journeyPhase: string | null | undefined;
|
|
367
|
+
backHeldAtCommit: boolean;
|
|
368
|
+
}): 'seen' | 'not_yet' | 'not_independent';
|
|
369
|
+
/** Whether an observed hold is the one this flow took, and still live. */
|
|
370
|
+
export declare function isOurLiveHold(view: GuidedViewLike | null | undefined, generation: number | null): boolean;
|