@skrr-ai/cli 0.1.109 → 0.1.111
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/bin/run.js +15 -1
- package/dist/base-command.d.ts +44 -1
- package/dist/base-command.js +194 -33
- package/dist/commands/actions/list.js +2 -1
- package/dist/commands/agenda/trigger/create.js +1 -1
- package/dist/commands/agenda/trigger/list.js +2 -1
- package/dist/commands/agent-groups/list.js +2 -1
- package/dist/commands/agents/actions/list.js +2 -1
- package/dist/commands/agents/always-on/status.js +5 -0
- package/dist/commands/agents/chat.js +4 -1
- package/dist/commands/agents/duplicate.js +4 -0
- package/dist/commands/agents/eval/list.js +2 -1
- package/dist/commands/agents/files/list.js +2 -1
- package/dist/commands/agents/folders/list.js +2 -1
- package/dist/commands/agents/goals/list.js +2 -1
- package/dist/commands/agents/intuitions/list.js +8 -5
- package/dist/commands/agents/list.d.ts +12 -0
- package/dist/commands/agents/list.js +45 -8
- package/dist/commands/agents/releases/known-issues/list.js +2 -1
- package/dist/commands/agents/releases/list.js +5 -1
- package/dist/commands/agents/releases/trusted-publishers/list.js +2 -1
- package/dist/commands/agents/roles/list.js +2 -1
- package/dist/commands/agents/skills/list.js +2 -1
- package/dist/commands/agents/todos/list.js +2 -1
- package/dist/commands/agents/triggers/create.js +1 -1
- package/dist/commands/agents/triggers/list.js +2 -1
- package/dist/commands/agents/triggers/update.js +1 -1
- package/dist/commands/agents/update.d.ts +11 -0
- package/dist/commands/agents/update.js +58 -2
- package/dist/commands/api-keys/list.js +2 -1
- package/dist/commands/apps/channel.d.ts +20 -0
- package/dist/commands/apps/channel.js +64 -0
- package/dist/commands/apps/check-draft.d.ts +12 -0
- package/dist/commands/apps/check-draft.js +41 -0
- package/dist/commands/apps/check.d.ts +42 -0
- package/dist/commands/apps/check.js +91 -0
- package/dist/commands/apps/create.d.ts +15 -0
- package/dist/commands/apps/create.js +59 -0
- package/dist/commands/apps/data/put.d.ts +18 -0
- package/dist/commands/apps/data/put.js +72 -0
- package/dist/commands/apps/data/query.d.ts +20 -0
- package/dist/commands/apps/data/query.js +88 -0
- package/dist/commands/apps/disclosure.d.ts +16 -0
- package/dist/commands/apps/disclosure.js +71 -0
- package/dist/commands/apps/file/cat.d.ts +15 -0
- package/dist/commands/apps/file/cat.js +50 -0
- package/dist/commands/apps/file/ls.d.ts +13 -0
- package/dist/commands/apps/file/ls.js +47 -0
- package/dist/commands/apps/file/mv.d.ts +15 -0
- package/dist/commands/apps/file/mv.js +49 -0
- package/dist/commands/apps/file/rm.d.ts +15 -0
- package/dist/commands/apps/file/rm.js +53 -0
- package/dist/commands/apps/file/write.d.ts +17 -0
- package/dist/commands/apps/file/write.js +81 -0
- package/dist/commands/apps/install.d.ts +19 -0
- package/dist/commands/apps/install.js +136 -0
- package/dist/commands/apps/installations/list.d.ts +11 -0
- package/dist/commands/apps/installations/list.js +49 -0
- package/dist/commands/apps/installations/show.d.ts +12 -0
- package/dist/commands/apps/installations/show.js +61 -0
- package/dist/commands/apps/layout/set.d.ts +11 -0
- package/dist/commands/apps/layout/set.js +125 -0
- package/dist/commands/apps/layout/show.d.ts +9 -0
- package/dist/commands/apps/layout/show.js +33 -0
- package/dist/commands/apps/list.d.ts +10 -0
- package/dist/commands/apps/list.js +45 -0
- package/dist/commands/apps/logs.d.ts +13 -0
- package/dist/commands/apps/logs.js +55 -0
- package/dist/commands/apps/preview.d.ts +12 -0
- package/dist/commands/apps/preview.js +39 -0
- package/dist/commands/apps/publish/propose.d.ts +14 -0
- package/dist/commands/apps/publish/propose.js +45 -0
- package/dist/commands/apps/pull.d.ts +14 -0
- package/dist/commands/apps/pull.js +56 -0
- package/dist/commands/apps/push.d.ts +15 -0
- package/dist/commands/apps/push.js +75 -0
- package/dist/commands/apps/reconsent.d.ts +13 -0
- package/dist/commands/apps/reconsent.js +67 -0
- package/dist/commands/apps/report.d.ts +20 -0
- package/dist/commands/apps/report.js +63 -0
- package/dist/commands/apps/resume.d.ts +12 -0
- package/dist/commands/apps/resume.js +36 -0
- package/dist/commands/apps/settings/set.d.ts +13 -0
- package/dist/commands/apps/settings/set.js +54 -0
- package/dist/commands/apps/settings/show.d.ts +11 -0
- package/dist/commands/apps/settings/show.js +31 -0
- package/dist/commands/apps/show.d.ts +12 -0
- package/dist/commands/apps/show.js +49 -0
- package/dist/commands/apps/suspend.d.ts +12 -0
- package/dist/commands/apps/suspend.js +35 -0
- package/dist/commands/apps/uninstall.d.ts +13 -0
- package/dist/commands/apps/uninstall.js +43 -0
- package/dist/commands/apps/upgrade.d.ts +14 -0
- package/dist/commands/apps/upgrade.js +49 -0
- package/dist/commands/apps/version/create.d.ts +14 -0
- package/dist/commands/apps/version/create.js +53 -0
- package/dist/commands/apps/version/show.d.ts +12 -0
- package/dist/commands/apps/version/show.js +39 -0
- package/dist/commands/apps/versions.d.ts +12 -0
- package/dist/commands/apps/versions.js +40 -0
- package/dist/commands/apps/webhooks/list.d.ts +12 -0
- package/dist/commands/apps/webhooks/list.js +47 -0
- package/dist/commands/characters/list.js +2 -1
- package/dist/commands/chats/files/list.js +2 -1
- package/dist/commands/chats/folders/list.js +2 -1
- package/dist/commands/chats/list.js +2 -1
- package/dist/commands/chats/spaces/list.js +2 -1
- package/dist/commands/chats/widgets/list.js +2 -1
- package/dist/commands/code/jobs/list.js +4 -1
- package/dist/commands/commerce/incidents/list.js +2 -1
- package/dist/commands/commitments/accounting.js +3 -0
- package/dist/commands/commitments/action-proposals.d.ts +8 -0
- package/dist/commands/commitments/action-proposals.js +17 -2
- package/dist/commands/commitments/cost.d.ts +11 -0
- package/dist/commands/commitments/cost.js +25 -0
- package/dist/commands/commitments/create.js +6 -1
- package/dist/commands/commitments/endpoints/list.js +2 -1
- package/dist/commands/commitments/links/list.js +2 -1
- package/dist/commands/commitments/list.js +2 -1
- package/dist/commands/commitments/liveness.d.ts +30 -0
- package/dist/commands/commitments/liveness.js +22 -5
- package/dist/commands/commitments/pack/list.js +2 -1
- package/dist/commands/commitments/preflight.js +6 -2
- package/dist/commands/commitments/update.js +10 -1
- package/dist/commands/compass/list.js +2 -1
- package/dist/commands/context.js +7 -1
- package/dist/commands/convos/list.js +3 -2
- package/dist/commands/daemon/install.js +17 -1
- package/dist/commands/daemon/login.js +14 -0
- package/dist/commands/dm/list.js +2 -1
- package/dist/commands/dm/work.d.ts +19 -0
- package/dist/commands/dm/work.js +54 -0
- package/dist/commands/feeds/list.js +2 -1
- package/dist/commands/followups/list.js +2 -1
- package/dist/commands/followups/plans/cancel.d.ts +13 -0
- package/dist/commands/followups/plans/cancel.js +26 -0
- package/dist/commands/followups/plans/create.d.ts +11 -0
- package/dist/commands/followups/plans/create.js +35 -0
- package/dist/commands/followups/plans/list.d.ts +13 -0
- package/dist/commands/followups/plans/list.js +50 -0
- package/dist/commands/followups/plans/observability.d.ts +11 -0
- package/dist/commands/followups/plans/observability.js +46 -0
- package/dist/commands/followups/plans/revise.d.ts +13 -0
- package/dist/commands/followups/plans/revise.js +35 -0
- package/dist/commands/followups/plans/show.d.ts +11 -0
- package/dist/commands/followups/plans/show.js +32 -0
- package/dist/commands/goals/key-results/list.js +2 -1
- package/dist/commands/goals/labels/list.js +3 -2
- package/dist/commands/goals/list.js +3 -2
- package/dist/commands/grants/list.js +2 -1
- package/dist/commands/harnesses/grants/list.js +2 -1
- package/dist/commands/harnesses/leases/list.js +2 -1
- package/dist/commands/harnesses/list.js +10 -1
- package/dist/commands/harnesses/prune.d.ts +26 -0
- package/dist/commands/harnesses/prune.js +172 -0
- package/dist/commands/ingress/list.js +2 -1
- package/dist/commands/initiatives/list.js +2 -1
- package/dist/commands/instruction-blocks/list.js +2 -1
- package/dist/commands/instructions/list.js +2 -1
- package/dist/commands/integrations/connections/list.js +2 -1
- package/dist/commands/integrations/tools/list.js +2 -1
- package/dist/commands/labels/list.js +3 -2
- package/dist/commands/learning/adapters.d.ts +16 -0
- package/dist/commands/learning/adapters.js +44 -0
- package/dist/commands/login.js +11 -0
- package/dist/commands/machines/dedicated/list.js +2 -1
- package/dist/commands/machines/hosted/list.js +2 -1
- package/dist/commands/machines/list.js +2 -1
- package/dist/commands/machines/show.js +5 -2
- package/dist/commands/measures/list.js +2 -1
- package/dist/commands/memory/list.js +2 -1
- package/dist/commands/memory/proposals/list.js +2 -1
- package/dist/commands/memory/stores/list.js +2 -1
- package/dist/commands/memory/topics/list.js +2 -1
- package/dist/commands/memory/versions/list.js +2 -1
- package/dist/commands/messages/list.js +2 -1
- package/dist/commands/northstars/intents/list.js +2 -1
- package/dist/commands/northstars/list.js +2 -1
- package/dist/commands/northstars/recommendations/list.js +2 -1
- package/dist/commands/outbox/list.js +2 -1
- package/dist/commands/profiles/list.js +2 -1
- package/dist/commands/projects/docs/list.js +8 -1
- package/dist/commands/projects/updates/list.js +2 -1
- package/dist/commands/proposals/list.js +2 -1
- package/dist/commands/requests/comments/list.js +2 -1
- package/dist/commands/requests/list.js +2 -1
- package/dist/commands/shares/list.js +2 -1
- package/dist/commands/shortcuts/list.js +2 -1
- package/dist/commands/signals/monitors/list.js +2 -1
- package/dist/commands/signals/schemas/list.js +2 -1
- package/dist/commands/signals/sources/list.js +2 -1
- package/dist/commands/space-directory-views/list.js +2 -1
- package/dist/commands/spaces/actions/list.js +4 -3
- package/dist/commands/spaces/briefs/list.js +2 -1
- package/dist/commands/spaces/cycles/list.js +2 -1
- package/dist/commands/spaces/files/folders/list.js +2 -1
- package/dist/commands/spaces/files/list.js +3 -2
- package/dist/commands/spaces/heartbeats/list.js +3 -2
- package/dist/commands/spaces/labels/list.js +3 -2
- package/dist/commands/spaces/list.d.ts +3 -18
- package/dist/commands/spaces/list.js +28 -35
- package/dist/commands/spaces/live/cards/list.js +2 -1
- package/dist/commands/spaces/members/list.d.ts +1 -0
- package/dist/commands/spaces/members/list.js +4 -1
- package/dist/commands/spaces/show.js +2 -2
- package/dist/commands/spaces/skills/list.js +6 -2
- package/dist/commands/spaces/states/list.js +2 -1
- package/dist/commands/spaces/views/list.js +2 -1
- package/dist/commands/spaces/widgets/list.js +3 -2
- package/dist/commands/spaces/workflow-templates/list.js +2 -1
- package/dist/commands/spaces/workflows/fixtures/list.js +2 -1
- package/dist/commands/spaces/workflows/list.js +3 -2
- package/dist/commands/spaces/workflows/proposals/list.js +2 -1
- package/dist/commands/spaces/workflows/start.js +3 -1
- package/dist/commands/spaces/workflows/triggers/list.js +2 -1
- package/dist/commands/spaces/workflows/validate.js +12 -2
- package/dist/commands/store/acquisitions/list.js +2 -1
- package/dist/commands/store/admissions/list.js +17 -1
- package/dist/commands/store/advisories/list.js +2 -1
- package/dist/commands/store/follows/list.js +2 -1
- package/dist/commands/store/publishers/domains/list.js +2 -1
- package/dist/commands/store/reports/list.js +2 -1
- package/dist/commands/subscriptions/list.js +2 -1
- package/dist/commands/tasks/actionability.js +7 -30
- package/dist/commands/tasks/activity.js +14 -8
- package/dist/commands/tasks/approvals/list.js +2 -1
- package/dist/commands/tasks/assign.d.ts +1 -0
- package/dist/commands/tasks/assign.js +43 -7
- package/dist/commands/tasks/attachments/list.js +2 -1
- package/dist/commands/tasks/chat/send.js +34 -0
- package/dist/commands/tasks/comments/add.js +6 -1
- package/dist/commands/tasks/comments/list.js +2 -1
- package/dist/commands/tasks/complete.js +26 -2
- package/dist/commands/tasks/continue.d.ts +18 -0
- package/dist/commands/tasks/continue.js +54 -0
- package/dist/commands/tasks/create-tree.d.ts +5 -0
- package/dist/commands/tasks/create-tree.js +399 -219
- package/dist/commands/tasks/create.d.ts +1 -0
- package/dist/commands/tasks/create.js +63 -11
- package/dist/commands/tasks/deliverable/add.js +10 -3
- package/dist/commands/tasks/deliverable/list.js +2 -1
- package/dist/commands/tasks/events/list.js +2 -1
- package/dist/commands/tasks/execution-state.d.ts +12 -0
- package/dist/commands/tasks/execution-state.js +28 -0
- package/dist/commands/tasks/expectations/assess.js +40 -5
- package/dist/commands/tasks/guide.d.ts +10 -0
- package/dist/commands/tasks/guide.js +20 -0
- package/dist/commands/tasks/labels/list.js +2 -1
- package/dist/commands/tasks/list.d.ts +19 -0
- package/dist/commands/tasks/list.js +103 -6
- package/dist/commands/tasks/move.js +10 -2
- package/dist/commands/tasks/preflight.d.ts +14 -0
- package/dist/commands/tasks/preflight.js +77 -0
- package/dist/commands/tasks/rearm-recurrence.js +22 -3
- package/dist/commands/tasks/resource/list.js +2 -1
- package/dist/commands/tasks/result/submit.js +10 -1
- package/dist/commands/tasks/review.js +6 -1
- package/dist/commands/tasks/revisions.d.ts +2 -0
- package/dist/commands/tasks/revisions.js +8 -1
- package/dist/commands/tasks/show.d.ts +8 -0
- package/dist/commands/tasks/show.js +81 -43
- package/dist/commands/tasks/start.d.ts +1 -0
- package/dist/commands/tasks/start.js +35 -0
- package/dist/commands/tasks/templates/list.js +2 -1
- package/dist/commands/tasks/timeline.d.ts +5 -0
- package/dist/commands/tasks/timeline.js +9 -1
- package/dist/commands/tasks/unschedule.js +5 -1
- package/dist/commands/tasks/update.d.ts +1 -0
- package/dist/commands/tasks/update.js +36 -3
- package/dist/commands/tasks/updates/add.js +6 -1
- package/dist/commands/tasks/updates/list.js +2 -1
- package/dist/commands/tasks/upsert.d.ts +1 -0
- package/dist/commands/tasks/upsert.js +8 -1
- package/dist/commands/token/list.js +2 -1
- package/dist/commands/tokens/list.js +2 -1
- package/dist/commands/tones/list.js +4 -2
- package/dist/commands/triggers/audit.js +12 -3
- package/dist/commands/triggers/create.js +1 -1
- package/dist/commands/triggers/fire-detail.d.ts +7 -0
- package/dist/commands/triggers/fire-detail.js +30 -12
- package/dist/commands/triggers/fire.js +13 -3
- package/dist/commands/triggers/list.js +2 -1
- package/dist/commands/triggers/parse-intent.js +1 -1
- package/dist/commands/triggers/update.js +1 -1
- package/dist/commands/views/list.js +2 -1
- package/dist/commands/webhooks/list.js +2 -1
- package/dist/commands/whoami.js +1 -1
- package/dist/commands/widgets/list.js +2 -1
- package/dist/commands/widgets/save-as-app.d.ts +13 -0
- package/dist/commands/widgets/save-as-app.js +65 -0
- package/dist/commands/work-views/list.js +2 -1
- package/dist/commands/worklog/list.js +2 -1
- package/dist/commands/workspaces/grants.js +1 -4
- package/dist/commands/workspaces/list.js +3 -2
- package/dist/commands/workspaces/members.d.ts +1 -0
- package/dist/commands/workspaces/members.js +10 -7
- package/dist/generated/managed-instruction-guides.json +2 -2
- package/dist/help.js +7 -0
- package/dist/lib/agent-proactive-baseline.d.ts +9 -0
- package/dist/lib/agent-proactive-baseline.js +44 -0
- package/dist/lib/agentic-stream.d.ts +4 -1
- package/dist/lib/agentic-stream.js +29 -4
- package/dist/lib/appData.d.ts +75 -0
- package/dist/lib/appData.js +274 -0
- package/dist/lib/appInstallations.d.ts +117 -0
- package/dist/lib/appInstallations.js +960 -0
- package/dist/lib/appSettings.d.ts +3 -0
- package/dist/lib/appSettings.js +71 -0
- package/dist/lib/appWebhooks.d.ts +7 -0
- package/dist/lib/appWebhooks.js +59 -0
- package/dist/lib/apps-command.d.ts +44 -0
- package/dist/lib/apps-command.js +164 -0
- package/dist/lib/apps.d.ts +45 -0
- package/dist/lib/apps.js +148 -0
- package/dist/lib/appsCheck.d.ts +12 -0
- package/dist/lib/appsCheck.js +173 -0
- package/dist/lib/appsFs.d.ts +58 -0
- package/dist/lib/appsFs.js +384 -0
- package/dist/lib/auth-failure.d.ts +20 -0
- package/dist/lib/auth-failure.js +40 -3
- package/dist/lib/cli-installers.d.ts +9 -2
- package/dist/lib/command-miss.js +107 -0
- package/dist/lib/commitment-loop-status.js +25 -3
- package/dist/lib/commitment-product.js +5 -2
- package/dist/lib/commitments.d.ts +45 -3
- package/dist/lib/commitments.js +139 -41
- package/dist/lib/compasses.d.ts +4 -0
- package/dist/lib/compasses.js +11 -0
- package/dist/lib/daemon-machine-identity-copy.d.ts +14 -0
- package/dist/lib/daemon-machine-identity-copy.js +27 -0
- package/dist/lib/daemon-machine-identity.d.ts +27 -0
- package/dist/lib/daemon-machine-identity.js +61 -0
- package/dist/lib/daemon-setup.js +7 -7
- package/dist/lib/daemonHandoff.d.ts +19 -1
- package/dist/lib/daemonHandoff.js +62 -2
- package/dist/lib/dedicated-ssh.d.ts +2 -0
- package/dist/lib/dedicated-ssh.js +98 -28
- package/dist/lib/harnesses.d.ts +71 -0
- package/dist/lib/harnesses.js +70 -0
- package/dist/lib/json-output.d.ts +33 -0
- package/dist/lib/json-output.js +37 -0
- package/dist/lib/list-output.d.ts +9 -4
- package/dist/lib/list-output.js +38 -9
- package/dist/lib/lookbackPlans.d.ts +13 -0
- package/dist/lib/lookbackPlans.js +68 -0
- package/dist/lib/machines.d.ts +27 -6
- package/dist/lib/machines.js +25 -14
- package/dist/lib/member-output.d.ts +20 -0
- package/dist/lib/member-output.js +57 -0
- package/dist/lib/preflight-copy.d.ts +7 -0
- package/dist/lib/preflight-copy.js +31 -0
- package/dist/lib/profile-machine-identity-guard.js +11 -1
- package/dist/lib/roles.d.ts +2 -2
- package/dist/lib/task-admission.d.ts +9 -0
- package/dist/lib/task-admission.js +35 -0
- package/dist/lib/task-batch.d.ts +4 -0
- package/dist/lib/task-batch.js +2 -0
- package/dist/lib/task-economics.d.ts +10 -0
- package/dist/lib/task-economics.js +24 -2
- package/dist/lib/task-operations.d.ts +25 -0
- package/dist/lib/task-operations.js +123 -0
- package/dist/lib/task-preflight.d.ts +35 -0
- package/dist/lib/task-preflight.js +121 -0
- package/dist/lib/task-resource-references.d.ts +23 -0
- package/dist/lib/task-resource-references.js +119 -0
- package/dist/lib/task-spec-verification.d.ts +42 -0
- package/dist/lib/task-spec-verification.js +101 -0
- package/dist/lib/task-work.d.ts +11 -0
- package/dist/lib/task-work.js +41 -0
- package/dist/lib/task-write-attribution.d.ts +26 -0
- package/dist/lib/task-write-attribution.js +47 -0
- package/dist/lib/tasks.d.ts +13 -0
- package/dist/lib/tasks.js +61 -8
- package/dist/lib/triggers.d.ts +18 -0
- package/dist/lib/triggers.js +97 -5
- package/dist/lib/usage-discovery.d.ts +4 -0
- package/dist/lib/usage-discovery.js +14 -4
- package/dist/lib/widgetApps.d.ts +10 -0
- package/dist/lib/widgetApps.js +47 -0
- package/dist/lib/widgetStaticScan.js +25 -1
- package/dist/lib/workflow-run-view.d.ts +4 -0
- package/dist/lib/workflow-run-view.js +5 -0
- package/dist/lib/workspaces.d.ts +33 -9
- package/dist/lib/workspaces.js +19 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +14 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.d.ts +49 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +26 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.d.ts +118 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.js +614 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +5 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.d.ts +60 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.js +130 -6
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.js +15 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refreshClassification.d.ts +5 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refreshClassification.js +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionRevocation.d.ts +177 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionRevocation.js +484 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/telemetryRedaction.d.ts +11 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/telemetryRedaction.js +46 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.d.ts +232 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.js +372 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/types.d.ts +17 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/types.js +12 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +14 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +45 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.d.ts +49 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +24 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.d.ts +118 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.js +608 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.d.ts +60 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.js +128 -6
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.js +15 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refreshClassification.d.ts +5 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refreshClassification.js +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionRevocation.d.ts +177 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionRevocation.js +472 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/telemetryRedaction.d.ts +11 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/telemetryRedaction.js +44 -6
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.d.ts +232 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.js +360 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/types.d.ts +17 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/types.js +12 -1
- package/dist/node_modules/@skrr-ai/auth-core/package.json +31 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +25255 -18711
- package/docs/v1/operations.md +52 -0
- package/docs/v1/space-search.md +19 -0
- package/oclif.manifest.json +4843 -513
- package/package.json +32 -2
package/dist/lib/compasses.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ export interface CompassInvariantTarget {
|
|
|
8
8
|
maintainedState?: string[];
|
|
9
9
|
successMetrics?: string[];
|
|
10
10
|
boundaries?: string[];
|
|
11
|
+
learnedTactics?: Array<{
|
|
12
|
+
id?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
}>;
|
|
11
15
|
freshness?: Record<string, unknown>;
|
|
12
16
|
cadence?: Record<string, unknown>;
|
|
13
17
|
escalation?: Record<string, unknown>;
|
package/dist/lib/compasses.js
CHANGED
|
@@ -44,6 +44,12 @@ exports.compassApi = {
|
|
|
44
44
|
appendTactic: (id, body) => data_provider_2.request.post(`${base(id)}/tactics`, body),
|
|
45
45
|
commitments: (id, query) => data_provider_2.request.get((0, triggers_1.withQuery)(`${base(id)}/commitments`, query)),
|
|
46
46
|
};
|
|
47
|
+
const OVERFLOW_FIELD_LABEL = {
|
|
48
|
+
maintainedState: 'keeps-true entries',
|
|
49
|
+
successMetrics: 'success metrics',
|
|
50
|
+
boundaries: 'boundaries',
|
|
51
|
+
learnedTactics: 'learned tactics',
|
|
52
|
+
};
|
|
47
53
|
function shortDate(value) {
|
|
48
54
|
if (!value)
|
|
49
55
|
return '—';
|
|
@@ -120,6 +126,11 @@ function renderCompass(compass, log) {
|
|
|
120
126
|
if (target.successMetrics?.length) {
|
|
121
127
|
log(` measured by: ${target.successMetrics.join('; ')}`);
|
|
122
128
|
}
|
|
129
|
+
// The agent's prompt carries a bounded number of each list. Say which
|
|
130
|
+
// were cut, so the list above is not read as what the agent sees.
|
|
131
|
+
for (const overflow of (0, data_provider_1.describeCompassOverflow)(target)) {
|
|
132
|
+
log(` ! shown to the agent: ${overflow.rendered} of ${overflow.authored} ${OVERFLOW_FIELD_LABEL[overflow.field]} (${overflow.omitted} not shown)`);
|
|
133
|
+
}
|
|
123
134
|
}
|
|
124
135
|
}
|
|
125
136
|
const tactics = compass.learnedTactics ?? [];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DaemonMachineIdentitySkew } from './daemon-machine-identity';
|
|
2
|
+
/**
|
|
3
|
+
* What to tell someone whose installed background service would register their
|
|
4
|
+
* profile on the default profile's machine row (OSK-S-440).
|
|
5
|
+
*
|
|
6
|
+
* The consequence is stated before the remedy because the remedy costs something
|
|
7
|
+
* (updating a service) and the consequence is what justifies it: a second
|
|
8
|
+
* profile on the default's row replaces its Daemon and its device-key pin, and
|
|
9
|
+
* the default profile's next refresh is refused until it signs in again.
|
|
10
|
+
*
|
|
11
|
+
* Lives here, apart from the comparison, because this is copy and reads
|
|
12
|
+
* `BRAND.displayName`; the comparison is pure and imports nothing from it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function describeDaemonMachineIdentitySkew(skew: DaemonMachineIdentitySkew): string[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.describeDaemonMachineIdentitySkew = describeDaemonMachineIdentitySkew;
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
/**
|
|
6
|
+
* What to tell someone whose installed background service would register their
|
|
7
|
+
* profile on the default profile's machine row (OSK-S-440).
|
|
8
|
+
*
|
|
9
|
+
* The consequence is stated before the remedy because the remedy costs something
|
|
10
|
+
* (updating a service) and the consequence is what justifies it: a second
|
|
11
|
+
* profile on the default's row replaces its Daemon and its device-key pin, and
|
|
12
|
+
* the default profile's next refresh is refused until it signs in again.
|
|
13
|
+
*
|
|
14
|
+
* Lives here, apart from the comparison, because this is copy and reads
|
|
15
|
+
* `BRAND.displayName`; the comparison is pure and imports nothing from it.
|
|
16
|
+
*/
|
|
17
|
+
function describeDaemonMachineIdentitySkew(skew) {
|
|
18
|
+
const product = data_provider_1.BRAND.displayName;
|
|
19
|
+
const said = skew.reported
|
|
20
|
+
? `it reports machine identity ${skew.reported}, where profile '${skew.profile}' has ${skew.expected}`
|
|
21
|
+
: `it does not report a machine identity at all, so ${product} cannot tell which one it would use`;
|
|
22
|
+
return [
|
|
23
|
+
`The ${product} background service at ${skew.binary} does not support a separate machine identity per profile: ${said}.`,
|
|
24
|
+
`Using it for '${skew.profile}' would register that profile on the default profile's machine and could replace the default profile's device-key pin. Nothing was changed.`,
|
|
25
|
+
`Update the background service (skrr daemon update), or put a current skrrd first on your PATH, then run: skrr login --profile ${skew.profile}`,
|
|
26
|
+
];
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface DaemonMachineIdentitySkew {
|
|
2
|
+
/** The profile being signed in. */
|
|
3
|
+
profile: string;
|
|
4
|
+
/** The machine identity this profile has, as decided by the profile's own record. */
|
|
5
|
+
expected: string;
|
|
6
|
+
/** What the daemon binary says it will send; null when it said nothing. */
|
|
7
|
+
reported: string | null;
|
|
8
|
+
/** The `skrrd` that was asked. */
|
|
9
|
+
binary: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Null when the daemon will register this profile under the identity it has;
|
|
13
|
+
* otherwise what disagrees.
|
|
14
|
+
*
|
|
15
|
+
* Not applicable to the default profile (its identity is the hardware value in
|
|
16
|
+
* every version), to a hosted runtime (the control plane issues it), or when no
|
|
17
|
+
* profile is named.
|
|
18
|
+
*
|
|
19
|
+
* A daemon that reports NOTHING is a skew, not a pass: this check exists because
|
|
20
|
+
* an older binary cannot say, and "could not confirm" must not read as "fine" on
|
|
21
|
+
* the step that binds a credential to a machine row.
|
|
22
|
+
*/
|
|
23
|
+
export declare function daemonMachineIdentitySkew(opts: {
|
|
24
|
+
profile: string | null | undefined;
|
|
25
|
+
binary: string;
|
|
26
|
+
reported: string | null | undefined;
|
|
27
|
+
}): DaemonMachineIdentitySkew | null;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.daemonMachineIdentitySkew = daemonMachineIdentitySkew;
|
|
4
|
+
/**
|
|
5
|
+
* daemon-machine-identity.ts — does the installed daemon give this profile the
|
|
6
|
+
* machine identity the CLI decided it has?
|
|
7
|
+
*
|
|
8
|
+
* Two programs compute one identity: the CLI (and the profile's persisted
|
|
9
|
+
* `machine-identity.json`) say a profile that started new has its own machine
|
|
10
|
+
* row, and the DAEMON is what registers. A daemon that predates per-profile
|
|
11
|
+
* identities (OSK-13845) does not read that file; it sends the hardware value
|
|
12
|
+
* whatever the profile is. Nothing noticed. The CLI minted the daemon's credential
|
|
13
|
+
* for what the daemon REPORTED (`accept-handoff --print-id`), so the credential
|
|
14
|
+
* was bound to the default machine's row, the service registered there, and the
|
|
15
|
+
* failure OSK-13845 exists to prevent happened anyway: two profiles on one Daemon
|
|
16
|
+
* row and one device-key pin, the second profile's interactive login re-pinning
|
|
17
|
+
* the first one's key (OSK-S-440, profile `aapexp`).
|
|
18
|
+
*
|
|
19
|
+
* Measured, not inferred: the same new profile, in an empty home, answered by
|
|
20
|
+
* two `skrrd` binaries. The current one reports `<hardware>:p-<hash>` and writes
|
|
21
|
+
* `machine-identity.json` and `daemon-identity.json`; the build that was first on
|
|
22
|
+
* the dogfooder's PATH (a checkout `dist` from before OSK-13845, whose version
|
|
23
|
+
* string still reads the checkout's package.json) reports the bare hardware value
|
|
24
|
+
* and writes neither. The profile it left behind had a `machine-identity.json`
|
|
25
|
+
* (the CLI's) and no `daemon-identity.json` after four daemon starts.
|
|
26
|
+
*
|
|
27
|
+
* The fix is to compare, not to guess a version: ask the binary what it will
|
|
28
|
+
* send, compare with what this profile's decided identity is, and refuse BEFORE
|
|
29
|
+
* anything is minted or installed when they differ. Comparing the value is the
|
|
30
|
+
* only test that cannot be wrong about a build that is older than its own
|
|
31
|
+
* version string says.
|
|
32
|
+
*
|
|
33
|
+
* Pure: the I/O (spawning the binary) is in `daemonHandoff.ts`, the copy in
|
|
34
|
+
* `daemon-machine-identity-copy.ts`.
|
|
35
|
+
*/
|
|
36
|
+
const machine_uuid_1 = require("@skrr-ai/auth-core/machine-uuid");
|
|
37
|
+
const keychain_1 = require("./keychain");
|
|
38
|
+
/**
|
|
39
|
+
* Null when the daemon will register this profile under the identity it has;
|
|
40
|
+
* otherwise what disagrees.
|
|
41
|
+
*
|
|
42
|
+
* Not applicable to the default profile (its identity is the hardware value in
|
|
43
|
+
* every version), to a hosted runtime (the control plane issues it), or when no
|
|
44
|
+
* profile is named.
|
|
45
|
+
*
|
|
46
|
+
* A daemon that reports NOTHING is a skew, not a pass: this check exists because
|
|
47
|
+
* an older binary cannot say, and "could not confirm" must not read as "fine" on
|
|
48
|
+
* the step that binds a credential to a machine row.
|
|
49
|
+
*/
|
|
50
|
+
function daemonMachineIdentitySkew(opts) {
|
|
51
|
+
const profile = opts.profile?.trim();
|
|
52
|
+
if (!profile || profile === keychain_1.DEFAULT_PROFILE)
|
|
53
|
+
return null;
|
|
54
|
+
if ((0, machine_uuid_1.hostedRuntimeIdOverride)('OVERSKY_MACHINE_UUID'))
|
|
55
|
+
return null;
|
|
56
|
+
const expected = (0, machine_uuid_1.getMachineUuidForProfile)(profile);
|
|
57
|
+
const reported = opts.reported?.trim() || null;
|
|
58
|
+
if (reported === expected)
|
|
59
|
+
return null;
|
|
60
|
+
return { profile, expected, reported, binary: opts.binary };
|
|
61
|
+
}
|
package/dist/lib/daemon-setup.js
CHANGED
|
@@ -98,13 +98,13 @@ async function offerDaemonSetup(opts = {}) {
|
|
|
98
98
|
log('');
|
|
99
99
|
log(` This computer has no ${data_provider_1.BRAND.displayName} background service. It is what lets your agents work here —`);
|
|
100
100
|
log(' running commands, editing files, and driving a browser on this machine.');
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
log(
|
|
107
|
-
log(`
|
|
101
|
+
// Disclose both the safe new-profile default and upgrade compatibility at
|
|
102
|
+
// the point where the person consents to a persistent local service.
|
|
103
|
+
log(' New local profiles require approval for file reads, edits and shell commands.');
|
|
104
|
+
log(' Cloud-started Claude Code sessions are refused until explicitly enabled.');
|
|
105
|
+
log(' Existing profiles keep their permission settings, which may allow tools without asking.');
|
|
106
|
+
log(` Require approvals for this profile: \`${(0, daemon_command_hint_1.daemonCommandHint)('config', { extraArgs: '--require-approvals' })}\``);
|
|
107
|
+
log(` Allow only a chosen category without asking: \`${(0, daemon_command_hint_1.daemonCommandHint)('config', { extraArgs: '--mode read=auto' })}\``);
|
|
108
108
|
// This creates a persistent service with broad local capabilities, so a
|
|
109
109
|
// bare Enter must visibly and behaviorally decline it. `confirm` names its
|
|
110
110
|
// second argument `defaultNo`; passing false showed `[Y/n]` and accepted an
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DaemonMachineIdentitySkew } from './daemon-machine-identity';
|
|
1
2
|
/**
|
|
2
3
|
* Hand the local daemon a credential of its own, right after `skrr login`.
|
|
3
4
|
*
|
|
@@ -40,8 +41,25 @@ export interface DaemonHandoffOutcome {
|
|
|
40
41
|
* The two absent cases are separated because they need different work — one
|
|
41
42
|
* needs a binary fetched, the other only needs the service registered.
|
|
42
43
|
*/
|
|
43
|
-
reason?: 'opted-out' | 'brokered' | 'no-binary' | 'legacy-binary' | 'unsupported-daemon' | 'no-service' | 'foreign-root' | 'mint-refused' | 'platform-managed';
|
|
44
|
+
reason?: 'opted-out' | 'brokered' | 'no-binary' | 'legacy-binary' | 'unsupported-daemon' | 'no-service' | 'foreign-root' | 'mint-refused' | 'platform-managed' | 'machine-identity-skew';
|
|
45
|
+
/** Set with `reason: 'machine-identity-skew'`; the caller words it. */
|
|
46
|
+
skew?: DaemonMachineIdentitySkew;
|
|
44
47
|
}
|
|
45
48
|
export declare function handOffToLocalDaemon(env?: NodeJS.ProcessEnv, opts?: {
|
|
46
49
|
loginFlow?: string;
|
|
47
50
|
}): Promise<DaemonHandoffOutcome>;
|
|
51
|
+
/**
|
|
52
|
+
* Ask the installed daemon which machine identity it will register `profile`
|
|
53
|
+
* under, and say what disagrees with the profile's own (OSK-S-440).
|
|
54
|
+
*
|
|
55
|
+
* For the commands that install or sign in a daemon WITHOUT going through the
|
|
56
|
+
* credential hand-off (`skrr daemon install`, `skrr daemon login`): the same
|
|
57
|
+
* question, asked of the binary they are about to run. Null when the daemon
|
|
58
|
+
* agrees, when the profile is the default one, or when there is no binary to ask
|
|
59
|
+
* (the caller has its own answer for that).
|
|
60
|
+
*
|
|
61
|
+
* A binary that cannot be asked at all - too old to have `accept-handoff`, or
|
|
62
|
+
* one that fails the probe - is reported as a skew with no identity, because the
|
|
63
|
+
* point of asking is not to bind a profile to a machine row on a guess.
|
|
64
|
+
*/
|
|
65
|
+
export declare function checkLocalDaemonMachineIdentity(profile: string | null | undefined, binary?: string | null): Promise<DaemonMachineIdentitySkew | null>;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handOffToLocalDaemon = handOffToLocalDaemon;
|
|
4
|
+
exports.checkLocalDaemonMachineIdentity = checkLocalDaemonMachineIdentity;
|
|
4
5
|
const node_child_process_1 = require("node:child_process");
|
|
5
6
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
7
|
const config_1 = require("./config");
|
|
7
8
|
const daemon_handoff_opt_out_1 = require("./daemon-handoff-opt-out");
|
|
9
|
+
const daemon_machine_identity_1 = require("./daemon-machine-identity");
|
|
8
10
|
const dedicated_service_1 = require("./dedicated-service");
|
|
9
11
|
const exec_runtime_binary_1 = require("./exec-runtime-binary");
|
|
10
12
|
const keychain_1 = require("./keychain");
|
|
@@ -146,8 +148,9 @@ function describeDelivery(opts) {
|
|
|
146
148
|
/**
|
|
147
149
|
* Compare deployments, not spellings.
|
|
148
150
|
*
|
|
149
|
-
*
|
|
150
|
-
* and the first is still what every daemon installed before the cutover
|
|
151
|
+
* The pre-cutover production host and `https://skrr.ai` are one deployment under
|
|
152
|
+
* two names, and the first is still what every daemon installed before the cutover
|
|
153
|
+
* carries.
|
|
151
154
|
* Trimming and lowercasing alone would report a move on every login from every
|
|
152
155
|
* one of those machines — a warning that is wrong for the largest group of users
|
|
153
156
|
* who would see it, which is how a signal becomes noise. `canonicalizeKnownBaseURL`
|
|
@@ -275,6 +278,26 @@ async function handOffToLocalDaemon(env = process.env, opts = {}) {
|
|
|
275
278
|
};
|
|
276
279
|
}
|
|
277
280
|
const { idSource, machineUuid, daemonServer } = parseIdProvenance(printed.stderr);
|
|
281
|
+
// Before anything is minted or installed: does THIS binary register the profile
|
|
282
|
+
// under the machine identity the profile has? The mint below binds the
|
|
283
|
+
// credential to the machine uuid the daemon just REPORTED, so a binary that
|
|
284
|
+
// reports the hardware value for a profile that has its own would put it on the
|
|
285
|
+
// default profile's row - and the install that follows would run that same
|
|
286
|
+
// binary as a service. Nothing about the id or the provenance would look wrong.
|
|
287
|
+
const skew = (0, daemon_machine_identity_1.daemonMachineIdentitySkew)({
|
|
288
|
+
profile: (0, keychain_1.getActiveProfile)(),
|
|
289
|
+
binary,
|
|
290
|
+
reported: machineUuid,
|
|
291
|
+
});
|
|
292
|
+
if (skew) {
|
|
293
|
+
return {
|
|
294
|
+
status: 'failed',
|
|
295
|
+
reason: 'machine-identity-skew',
|
|
296
|
+
skew,
|
|
297
|
+
detail: `the installed daemon reports machine identity ${skew.reported ?? '(none)'} ` +
|
|
298
|
+
`where profile '${skew.profile}' has ${skew.expected}`,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
278
301
|
// A well-formed id is not the same as a real daemon. With no service installed
|
|
279
302
|
// the daemon derives one from whatever directory this process is in, so the id
|
|
280
303
|
// above names a daemon that does not exist and will not exist under that id if
|
|
@@ -354,3 +377,40 @@ async function handOffToLocalDaemon(env = process.env, opts = {}) {
|
|
|
354
377
|
}),
|
|
355
378
|
};
|
|
356
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* Ask the installed daemon which machine identity it will register `profile`
|
|
382
|
+
* under, and say what disagrees with the profile's own (OSK-S-440).
|
|
383
|
+
*
|
|
384
|
+
* For the commands that install or sign in a daemon WITHOUT going through the
|
|
385
|
+
* credential hand-off (`skrr daemon install`, `skrr daemon login`): the same
|
|
386
|
+
* question, asked of the binary they are about to run. Null when the daemon
|
|
387
|
+
* agrees, when the profile is the default one, or when there is no binary to ask
|
|
388
|
+
* (the caller has its own answer for that).
|
|
389
|
+
*
|
|
390
|
+
* A binary that cannot be asked at all - too old to have `accept-handoff`, or
|
|
391
|
+
* one that fails the probe - is reported as a skew with no identity, because the
|
|
392
|
+
* point of asking is not to bind a profile to a machine row on a guess.
|
|
393
|
+
*/
|
|
394
|
+
async function checkLocalDaemonMachineIdentity(profile, binary = (0, exec_runtime_binary_1.findRuntimeBinary)()) {
|
|
395
|
+
if (!profile || profile === keychain_1.DEFAULT_PROFILE || !binary)
|
|
396
|
+
return null;
|
|
397
|
+
const printed = await runOversky(binary, ['accept-handoff', '--print-id', '--profile', profile], {
|
|
398
|
+
timeoutMs: PROBE_TIMEOUT_MS,
|
|
399
|
+
});
|
|
400
|
+
if (!printed.ok) {
|
|
401
|
+
// A daemon too old to have `accept-handoff` answers "unknown command": it is
|
|
402
|
+
// older than per-profile identities too, which is the skew itself.
|
|
403
|
+
if (/unknown command/i.test(printed.stderr)) {
|
|
404
|
+
return (0, daemon_machine_identity_1.daemonMachineIdentitySkew)({ profile, binary, reported: null });
|
|
405
|
+
}
|
|
406
|
+
// Any other failed probe says nothing about the daemon's identity, and
|
|
407
|
+
// refusing a sign-in on a flaky probe would be a worse failure than the one
|
|
408
|
+
// this guards: let the command run and meet whatever the daemon itself says.
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
return (0, daemon_machine_identity_1.daemonMachineIdentitySkew)({
|
|
412
|
+
profile,
|
|
413
|
+
binary,
|
|
414
|
+
reported: parseIdProvenance(printed.stderr).machineUuid,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
@@ -132,6 +132,8 @@ export interface SshProxyOptions {
|
|
|
132
132
|
ttlSeconds?: number;
|
|
133
133
|
getToken?: () => Promise<string>;
|
|
134
134
|
recoveryMs?: number;
|
|
135
|
+
/** Process lifecycle; injectable so tests never signal the test runner. */
|
|
136
|
+
signalSource?: Pick<NodeJS.Process, 'on' | 'off'>;
|
|
135
137
|
/** Injected for tests. */
|
|
136
138
|
connect?: (url: string, opts: Parameters<typeof io>[1]) => Socket;
|
|
137
139
|
/** Injected for tests. */
|
|
@@ -301,8 +301,11 @@ function runSshProxy(options) {
|
|
|
301
301
|
let closing = false;
|
|
302
302
|
let lastKeepaliveAt = 0;
|
|
303
303
|
let pendingInput = null;
|
|
304
|
-
const identityAuth = () => ({
|
|
305
|
-
|
|
304
|
+
const identityAuth = () => ({
|
|
305
|
+
...(0, data_provider_1.getClientIdentityAuth)(),
|
|
306
|
+
clientPlatform: 'cli',
|
|
307
|
+
clientOs: process.platform === 'darwin' ? 'macos' : process.platform,
|
|
308
|
+
});
|
|
306
309
|
const wsOrigin = (0, agentic_stream_1.toWebSocketOrigin)(options.baseURL);
|
|
307
310
|
const handshakeAuth = (token, callback) => {
|
|
308
311
|
// Resolve a fresh proof after token renewal on every reconnect. Never
|
|
@@ -315,20 +318,30 @@ function runSshProxy(options) {
|
|
|
315
318
|
};
|
|
316
319
|
const socket = connect(wsOrigin, {
|
|
317
320
|
path: '/ws/agentic',
|
|
318
|
-
auth: options.getToken
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
321
|
+
auth: options.getToken
|
|
322
|
+
? (callback) => {
|
|
323
|
+
void options.getToken().then((token) => handshakeAuth(token, callback), () => {
|
|
324
|
+
finish(1, 'Could not renew SSH authentication. Restore skrr login and connect again.');
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
: (0, dpop_auth_1.socketAuthWithDpop)({ token: options.token, ...identityAuth() }, wsOrigin),
|
|
328
|
+
transports: ['websocket'],
|
|
329
|
+
reconnection: true,
|
|
330
|
+
reconnectionDelay: 1000,
|
|
331
|
+
reconnectionDelayMax: 2000,
|
|
325
332
|
});
|
|
326
333
|
const startTimer = setTimeout(() => finish(1, 'The machine did not answer the SSH channel in time. Its daemon may be busy or offline.'), exports.SSH_START_TIMEOUT_MS);
|
|
327
334
|
function sendPendingInput() {
|
|
328
335
|
if (closing || !online || !attached || !pendingInput || finished)
|
|
329
336
|
return;
|
|
330
|
-
socket.emit('dedicated:ssh:data', {
|
|
331
|
-
|
|
337
|
+
socket.emit('dedicated:ssh:data', {
|
|
338
|
+
channelId,
|
|
339
|
+
data: pendingInput.bytes.toString('base64'),
|
|
340
|
+
resumeV2: true,
|
|
341
|
+
epoch,
|
|
342
|
+
generation,
|
|
343
|
+
offset: pendingInput.offset,
|
|
344
|
+
});
|
|
332
345
|
}
|
|
333
346
|
function pumpInput() {
|
|
334
347
|
if (closing || !started || !resumable || !online || !attached || pendingInput || finished)
|
|
@@ -351,11 +364,23 @@ function runSshProxy(options) {
|
|
|
351
364
|
};
|
|
352
365
|
function sendResume() {
|
|
353
366
|
if (online && started && resumable && !attached && !finished) {
|
|
354
|
-
socket.emit('dedicated:ssh:resume', {
|
|
367
|
+
socket.emit('dedicated:ssh:resume', {
|
|
368
|
+
leaseId: options.leaseId,
|
|
369
|
+
channelId,
|
|
370
|
+
resumeProof,
|
|
371
|
+
epoch,
|
|
372
|
+
generation,
|
|
373
|
+
attachmentSeq,
|
|
374
|
+
});
|
|
355
375
|
}
|
|
356
376
|
}
|
|
357
377
|
function keepalive() {
|
|
358
|
-
if (started &&
|
|
378
|
+
if (started &&
|
|
379
|
+
resumable &&
|
|
380
|
+
attached &&
|
|
381
|
+
online &&
|
|
382
|
+
!finished &&
|
|
383
|
+
Date.now() - lastKeepaliveAt >= 10_000) {
|
|
359
384
|
lastKeepaliveAt = Date.now();
|
|
360
385
|
socket.emit('dedicated:ssh:keepalive', { channelId, epoch });
|
|
361
386
|
}
|
|
@@ -376,6 +401,10 @@ function runSshProxy(options) {
|
|
|
376
401
|
keepalive();
|
|
377
402
|
}, 2000);
|
|
378
403
|
ticker.unref?.();
|
|
404
|
+
const signals = options.signalSource ?? process;
|
|
405
|
+
const onTermination = () => finish(0);
|
|
406
|
+
signals.on('SIGHUP', onTermination);
|
|
407
|
+
signals.on('SIGTERM', onTermination);
|
|
379
408
|
const onInputEnded = () => finish(0);
|
|
380
409
|
const onOutputError = () => finish(1);
|
|
381
410
|
input.once('end', onInputEnded);
|
|
@@ -397,10 +426,24 @@ function runSshProxy(options) {
|
|
|
397
426
|
if (notice)
|
|
398
427
|
errorOutput.write(`${notice}\n`);
|
|
399
428
|
// Never queue an offline stop that might arrive after another attachment.
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
429
|
+
const disconnected = () => {
|
|
430
|
+
signals.off('SIGHUP', onTermination);
|
|
431
|
+
signals.off('SIGTERM', onTermination);
|
|
432
|
+
socket.disconnect();
|
|
433
|
+
resolve(code);
|
|
434
|
+
};
|
|
435
|
+
if (started && online) {
|
|
436
|
+
// OpenSSH may SIGHUP its ProxyCommand before stdio reaches EOF. Keep
|
|
437
|
+
// the transport alive until the API has forwarded stop. A bounded
|
|
438
|
+
// fallback also supports older servers without this receipt.
|
|
439
|
+
const closeTimer = setTimeout(disconnected, 1000);
|
|
440
|
+
socket.emit('dedicated:ssh:stop', { channelId, ...(resumable ? { epoch } : {}) }, () => {
|
|
441
|
+
clearTimeout(closeTimer);
|
|
442
|
+
disconnected();
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
else
|
|
446
|
+
disconnected();
|
|
404
447
|
}
|
|
405
448
|
socket.on('connect_error', (error) => {
|
|
406
449
|
if (finished || (started && resumable))
|
|
@@ -420,9 +463,16 @@ function runSshProxy(options) {
|
|
|
420
463
|
return;
|
|
421
464
|
}
|
|
422
465
|
startSent = true;
|
|
423
|
-
socket.emit('dedicated:ssh:start', {
|
|
424
|
-
|
|
425
|
-
|
|
466
|
+
socket.emit('dedicated:ssh:start', {
|
|
467
|
+
leaseId: options.leaseId,
|
|
468
|
+
channelId,
|
|
469
|
+
keyType: identity.keyType,
|
|
470
|
+
keyBlob: identity.keyBlob,
|
|
471
|
+
receiverAckV1: true,
|
|
472
|
+
resumeV2: true,
|
|
473
|
+
resumeProof,
|
|
474
|
+
epoch,
|
|
475
|
+
});
|
|
426
476
|
});
|
|
427
477
|
socket.on('dedicated:ssh:start:ack', (ack) => {
|
|
428
478
|
if (!ack || ack.channelId !== channelId || started || finished)
|
|
@@ -432,7 +482,9 @@ function runSshProxy(options) {
|
|
|
432
482
|
return;
|
|
433
483
|
}
|
|
434
484
|
if (ack.resumeV2 === true) {
|
|
435
|
-
if (ack.epoch !== epoch ||
|
|
485
|
+
if (ack.epoch !== epoch ||
|
|
486
|
+
!Number.isSafeInteger(ack.generation) ||
|
|
487
|
+
Number(ack.generation) < 1 ||
|
|
436
488
|
(generation !== null && generation !== ack.generation)) {
|
|
437
489
|
finish(1, 'Invalid SSH stream admission.');
|
|
438
490
|
return;
|
|
@@ -458,7 +510,13 @@ function runSshProxy(options) {
|
|
|
458
510
|
}
|
|
459
511
|
});
|
|
460
512
|
socket.on('dedicated:ssh:resume:ack', (ack) => {
|
|
461
|
-
if (!ack ||
|
|
513
|
+
if (!ack ||
|
|
514
|
+
ack.channelId !== channelId ||
|
|
515
|
+
ack.epoch !== epoch ||
|
|
516
|
+
!started ||
|
|
517
|
+
!resumable ||
|
|
518
|
+
finished ||
|
|
519
|
+
attached)
|
|
462
520
|
return;
|
|
463
521
|
if (!ack.ok) {
|
|
464
522
|
if (ack.retryable === true)
|
|
@@ -483,8 +541,14 @@ function runSshProxy(options) {
|
|
|
483
541
|
pumpInput();
|
|
484
542
|
});
|
|
485
543
|
socket.on('dedicated:ssh:input:ack', (ack) => {
|
|
486
|
-
if (finished ||
|
|
487
|
-
|
|
544
|
+
if (finished ||
|
|
545
|
+
!resumable ||
|
|
546
|
+
!pendingInput ||
|
|
547
|
+
!attached ||
|
|
548
|
+
ack?.channelId !== channelId ||
|
|
549
|
+
ack.epoch !== epoch ||
|
|
550
|
+
ack.generation !== generation ||
|
|
551
|
+
ack.offset !== pendingInput.offset)
|
|
488
552
|
return;
|
|
489
553
|
if (!ack.ok) {
|
|
490
554
|
finish(1, ack.error || 'The SSH input stream was refused.');
|
|
@@ -499,19 +563,25 @@ function runSshProxy(options) {
|
|
|
499
563
|
pumpInput();
|
|
500
564
|
});
|
|
501
565
|
socket.on('dedicated:ssh:data', async (frame, receipt) => {
|
|
502
|
-
if (!frame ||
|
|
566
|
+
if (!frame ||
|
|
567
|
+
frame.channelId !== channelId ||
|
|
568
|
+
finished ||
|
|
569
|
+
typeof frame.data !== 'string' ||
|
|
570
|
+
!frame.data.length)
|
|
503
571
|
return;
|
|
504
572
|
try {
|
|
505
573
|
const bytes = Buffer.from(frame.data, 'base64');
|
|
506
574
|
if (frame.resumeV2 === true) {
|
|
507
575
|
if (frame.epoch !== epoch)
|
|
508
576
|
return;
|
|
509
|
-
if (!Number.isSafeInteger(frame.generation) ||
|
|
510
|
-
(
|
|
577
|
+
if (!Number.isSafeInteger(frame.generation) ||
|
|
578
|
+
Number(frame.generation) < 1 ||
|
|
579
|
+
(generation !== null && frame.generation !== generation) ||
|
|
580
|
+
bytes.toString('base64') !== frame.data) {
|
|
511
581
|
throw new Error('invalid SSH output frame');
|
|
512
582
|
}
|
|
513
583
|
generation ??= frame.generation;
|
|
514
|
-
const nextOffset = await receiver.receive(frame.offset, bytes, (value) => new Promise((done, reject) => output.write(value, (error) => error ? reject(error) : done())));
|
|
584
|
+
const nextOffset = await receiver.receive(frame.offset, bytes, (value) => new Promise((done, reject) => output.write(value, (error) => (error ? reject(error) : done()))));
|
|
515
585
|
receipt?.({ channelId, ok: !finished, epoch: frame.epoch, nextOffset });
|
|
516
586
|
}
|
|
517
587
|
else {
|
package/dist/lib/harnesses.d.ts
CHANGED
|
@@ -238,6 +238,77 @@ export declare function updateHarness(id: string, patch: Record<string, unknown>
|
|
|
238
238
|
harness?: Harness;
|
|
239
239
|
}>;
|
|
240
240
|
export declare function forgetHarness(id: string): Promise<unknown>;
|
|
241
|
+
/**
|
|
242
|
+
* Why a superseded-looking row is KEPT by `harnesses prune`. Declared by the
|
|
243
|
+
* server (`pruneSupersededHarnesses.js`, `REASONS`) and worded once, in
|
|
244
|
+
* `harnessPruneReasonSentence`, so the table and `--json` never disagree.
|
|
245
|
+
*/
|
|
246
|
+
export type HarnessPruneReason = 'recent' | 'latest_registration' | 'no_live_sibling' | 'pinned' | 'granted' | 'default' | 'aliased' | 'changed_since_plan';
|
|
247
|
+
export interface HarnessPruneRow {
|
|
248
|
+
id: string;
|
|
249
|
+
daemonId: string | null;
|
|
250
|
+
provider: string | null;
|
|
251
|
+
name: string | null;
|
|
252
|
+
lastSeenAt: string | null;
|
|
253
|
+
machineUuid: string | null;
|
|
254
|
+
/** The live sibling that replaced a row this call removes (or would). */
|
|
255
|
+
supersededBy?: {
|
|
256
|
+
id: string;
|
|
257
|
+
daemonId: string | null;
|
|
258
|
+
lastSeenAt: string | null;
|
|
259
|
+
};
|
|
260
|
+
/** Set on kept rows. */
|
|
261
|
+
reason?: HarnessPruneReason;
|
|
262
|
+
/** For `pinned`: who holds the pin. Other people's agents are a count, never named. */
|
|
263
|
+
detail?: {
|
|
264
|
+
agents?: Array<{
|
|
265
|
+
id: string;
|
|
266
|
+
name: string | null;
|
|
267
|
+
}>;
|
|
268
|
+
moreAgents?: number;
|
|
269
|
+
otherAuthors?: number;
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
export interface HarnessPruneResult {
|
|
273
|
+
dryRun: boolean;
|
|
274
|
+
limit: number;
|
|
275
|
+
minUnseenMs: number;
|
|
276
|
+
scan: {
|
|
277
|
+
rows: number;
|
|
278
|
+
complete: boolean;
|
|
279
|
+
};
|
|
280
|
+
/** Rows this call removes (dry run: would remove). */
|
|
281
|
+
remove: HarnessPruneRow[];
|
|
282
|
+
/** Rows this call actually removed; 0 on a dry run. */
|
|
283
|
+
removedCount: number;
|
|
284
|
+
/** Removable rows beyond `limit`; the next call takes them. */
|
|
285
|
+
remaining: number;
|
|
286
|
+
kept: HarnessPruneRow[];
|
|
287
|
+
keptTruncated: boolean;
|
|
288
|
+
counts: Record<string, number>;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Remove the caller's superseded harness rows - or, by default, say which would go.
|
|
292
|
+
*
|
|
293
|
+
* ONE route for both: the server makes the decision once and this only asks for it
|
|
294
|
+
* to be shown (`dryRun: true`, also its own default) or carried out. The caller
|
|
295
|
+
* never lists rows and picks, so there is no client-side rule to drift from the
|
|
296
|
+
* server's. A write, so `apiFetch` gives it an idempotency key and a retried
|
|
297
|
+
* request replays the recorded answer instead of running again.
|
|
298
|
+
*/
|
|
299
|
+
export declare function pruneHarnesses(options?: {
|
|
300
|
+
dryRun: boolean;
|
|
301
|
+
limit?: number;
|
|
302
|
+
minUnseenMs?: number;
|
|
303
|
+
}): Promise<HarnessPruneResult>;
|
|
304
|
+
/**
|
|
305
|
+
* `--older-than` takes a whole number with a unit: `90m`, `36h`, `7d`. A bare
|
|
306
|
+
* number is hours. Returns milliseconds. The server never goes below its offline
|
|
307
|
+
* window whatever this says.
|
|
308
|
+
*/
|
|
309
|
+
export declare function parseHarnessPruneAge(value: string): number;
|
|
310
|
+
/** One sentence per reason a row was kept. The only place they are worded. */
|
|
311
|
+
export declare function harnessPruneReasonSentence(row: HarnessPruneRow): string;
|
|
241
312
|
/**
|
|
242
313
|
* A per-USER display name. Distinct from `updateHarness({name})`, which renames
|
|
243
314
|
* the harness for everyone it is shared with — this only changes what YOU see,
|