@skrr-ai/cli 0.1.119 → 0.1.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/dist/base-command.d.ts +31 -0
  2. package/dist/base-command.js +117 -6
  3. package/dist/commands/agent/message/context.d.ts +1 -0
  4. package/dist/commands/agent/message/context.js +3 -2
  5. package/dist/commands/commands.js +11 -0
  6. package/dist/commands/commitments/action-proposal.d.ts +13 -0
  7. package/dist/commands/commitments/action-proposal.js +39 -0
  8. package/dist/commands/commitments/action-proposals/decide.js +8 -1
  9. package/dist/commands/commitments/action-proposals/execute.js +11 -1
  10. package/dist/commands/commitments/create.js +2 -2
  11. package/dist/commands/commitments/doctor.d.ts +8 -0
  12. package/dist/commands/commitments/doctor.js +22 -0
  13. package/dist/commands/commitments/execute-remediation.js +12 -1
  14. package/dist/commands/commitments/observations.js +2 -2
  15. package/dist/commands/commitments/pack/bind.d.ts +18 -1
  16. package/dist/commands/commitments/pack/bind.js +66 -8
  17. package/dist/commands/commitments/pack/plan.d.ts +4 -1
  18. package/dist/commands/commitments/pack/plan.js +30 -2
  19. package/dist/commands/commitments/update.js +8 -2
  20. package/dist/commands/completion/index.js +1 -1
  21. package/dist/commands/completion/values.js +1 -1
  22. package/dist/commands/computer-use/audio.d.ts +1 -0
  23. package/dist/commands/computer-use/audio.js +1 -0
  24. package/dist/commands/computer-use/browser.d.ts +1 -0
  25. package/dist/commands/computer-use/browser.js +1 -0
  26. package/dist/commands/computer-use/disable.d.ts +1 -0
  27. package/dist/commands/computer-use/disable.js +1 -0
  28. package/dist/commands/computer-use/enable.d.ts +1 -0
  29. package/dist/commands/computer-use/enable.js +1 -0
  30. package/dist/commands/computer-use/index.d.ts +1 -0
  31. package/dist/commands/computer-use/index.js +1 -0
  32. package/dist/commands/computer-use/install.d.ts +1 -0
  33. package/dist/commands/computer-use/install.js +1 -0
  34. package/dist/commands/computer-use/recover.d.ts +1 -0
  35. package/dist/commands/computer-use/recover.js +1 -0
  36. package/dist/commands/computer-use/status.d.ts +1 -0
  37. package/dist/commands/computer-use/status.js +1 -0
  38. package/dist/commands/computer-use/stop.d.ts +1 -0
  39. package/dist/commands/computer-use/stop.js +1 -0
  40. package/dist/commands/context.js +16 -11
  41. package/dist/commands/convos/recovery.js +1 -1
  42. package/dist/commands/daemon/diagnostics.d.ts +9 -0
  43. package/dist/commands/daemon/diagnostics.js +53 -0
  44. package/dist/commands/daemon/index.js +2 -0
  45. package/dist/commands/daemon/maintenance/attest.d.ts +15 -0
  46. package/dist/commands/daemon/maintenance/attest.js +52 -0
  47. package/dist/commands/daemon/maintenance/hold.d.ts +17 -0
  48. package/dist/commands/daemon/maintenance/hold.js +70 -0
  49. package/dist/commands/daemon/maintenance/index.d.ts +12 -0
  50. package/dist/commands/daemon/maintenance/index.js +30 -0
  51. package/dist/commands/daemon/maintenance/resume.d.ts +13 -0
  52. package/dist/commands/daemon/maintenance/resume.js +36 -0
  53. package/dist/commands/daemon/maintenance/status.d.ts +13 -0
  54. package/dist/commands/daemon/maintenance/status.js +36 -0
  55. package/dist/commands/doctor.d.ts +4 -1
  56. package/dist/commands/doctor.js +50 -6
  57. package/dist/commands/followups/plans/cancel-batch.js +6 -3
  58. package/dist/commands/followups/plans/capacity.js +7 -3
  59. package/dist/commands/followups/plans/observability.js +11 -3
  60. package/dist/commands/followups/plans/preferences/set.js +26 -8
  61. package/dist/commands/followups/plans/preferences.js +1 -1
  62. package/dist/commands/followups/plans/show.js +1 -1
  63. package/dist/commands/goals/key-results/assess.d.ts +36 -0
  64. package/dist/commands/goals/key-results/assess.js +110 -0
  65. package/dist/commands/goals/key-results/history.d.ts +30 -0
  66. package/dist/commands/goals/key-results/history.js +104 -0
  67. package/dist/commands/goals/key-results/list.d.ts +5 -4
  68. package/dist/commands/goals/key-results/list.js +12 -6
  69. package/dist/commands/goals/key-results/show.d.ts +4 -2
  70. package/dist/commands/goals/key-results/show.js +25 -4
  71. package/dist/commands/goals/key-results/update.d.ts +4 -0
  72. package/dist/commands/goals/key-results/update.js +18 -24
  73. package/dist/commands/goals/plan-now.js +12 -1
  74. package/dist/commands/goals/planner-compare.d.ts +30 -0
  75. package/dist/commands/goals/planner-compare.js +136 -0
  76. package/dist/commands/machines/dedicated/service/exec.d.ts +3 -0
  77. package/dist/commands/machines/dedicated/service/exec.js +70 -11
  78. package/dist/commands/machines/hosted/destroy.d.ts +1 -0
  79. package/dist/commands/machines/hosted/destroy.js +11 -1
  80. package/dist/commands/machines/hosted/exec.d.ts +1 -0
  81. package/dist/commands/machines/hosted/exec.js +12 -1
  82. package/dist/commands/machines/hosted/index.js +1 -0
  83. package/dist/commands/machines/hosted/operation.d.ts +14 -0
  84. package/dist/commands/machines/hosted/operation.js +51 -0
  85. package/dist/commands/machines/hosted/pull.js +1 -1
  86. package/dist/commands/machines/hosted/start.js +6 -2
  87. package/dist/commands/search/agents.js +5 -1
  88. package/dist/commands/search/all.js +74 -22
  89. package/dist/commands/search/skills.d.ts +1 -0
  90. package/dist/commands/search/skills.js +12 -1
  91. package/dist/commands/search/spaces.d.ts +8 -1
  92. package/dist/commands/search/spaces.js +50 -12
  93. package/dist/commands/search/tasks.d.ts +13 -2
  94. package/dist/commands/search/tasks.js +78 -14
  95. package/dist/commands/search/teams.js +5 -1
  96. package/dist/commands/search/workspace.d.ts +19 -0
  97. package/dist/commands/search/workspace.js +126 -0
  98. package/dist/commands/skills/browse.d.ts +1 -0
  99. package/dist/commands/skills/browse.js +8 -1
  100. package/dist/commands/skills/search.d.ts +1 -0
  101. package/dist/commands/skills/search.js +12 -1
  102. package/dist/commands/spaces/auto-executor/compare.d.ts +18 -0
  103. package/dist/commands/spaces/auto-executor/compare.js +139 -0
  104. package/dist/commands/spaces/auto-executor/runs.d.ts +3 -0
  105. package/dist/commands/spaces/auto-executor/runs.js +13 -1
  106. package/dist/commands/spaces/charter/create-from-description.d.ts +21 -0
  107. package/dist/commands/spaces/charter/create-from-description.js +77 -0
  108. package/dist/commands/spaces/charter/show.d.ts +22 -0
  109. package/dist/commands/spaces/charter/show.js +61 -0
  110. package/dist/commands/spaces/heartbeats/list.d.ts +1 -16
  111. package/dist/commands/spaces/heartbeats/list.js +13 -0
  112. package/dist/commands/spaces/install-template.js +3 -0
  113. package/dist/commands/spaces/list.d.ts +1 -0
  114. package/dist/commands/spaces/list.js +12 -3
  115. package/dist/commands/spaces/loops/migrate.d.ts +32 -0
  116. package/dist/commands/spaces/loops/migrate.js +103 -0
  117. package/dist/commands/spaces/loops/release.d.ts +14 -0
  118. package/dist/commands/spaces/loops/release.js +59 -0
  119. package/dist/commands/spaces/notebook.d.ts +25 -0
  120. package/dist/commands/spaces/notebook.js +75 -0
  121. package/dist/commands/spaces/proposals/discard.d.ts +17 -0
  122. package/dist/commands/spaces/proposals/discard.js +17 -0
  123. package/dist/commands/spaces/proposals/keep.d.ts +17 -0
  124. package/dist/commands/spaces/proposals/keep.js +17 -0
  125. package/dist/commands/spaces/proposals/list.d.ts +24 -0
  126. package/dist/commands/spaces/proposals/list.js +89 -0
  127. package/dist/commands/spaces/search.d.ts +1 -0
  128. package/dist/commands/spaces/search.js +9 -0
  129. package/dist/commands/spaces/skills/propose.d.ts +29 -0
  130. package/dist/commands/spaces/skills/propose.js +82 -0
  131. package/dist/commands/spaces/templates/fork.js +3 -0
  132. package/dist/commands/spaces/triggers/show.js +6 -0
  133. package/dist/commands/spaces/workflows/retry.d.ts +1 -0
  134. package/dist/commands/spaces/workflows/retry.js +8 -1
  135. package/dist/commands/spaces/workflows/triggers/create.js +3 -2
  136. package/dist/commands/spaces/workflows/triggers/fire.js +4 -0
  137. package/dist/commands/spaces/workflows/triggers/update.js +2 -1
  138. package/dist/commands/spaces/write-policy/set.d.ts +22 -0
  139. package/dist/commands/spaces/write-policy/set.js +82 -0
  140. package/dist/commands/spaces/write-policy/show.d.ts +19 -0
  141. package/dist/commands/spaces/write-policy/show.js +49 -0
  142. package/dist/commands/store/artifacts/receipt.d.ts +14 -0
  143. package/dist/commands/store/artifacts/receipt.js +34 -0
  144. package/dist/commands/store/artifacts/release.d.ts +2 -0
  145. package/dist/commands/store/artifacts/release.js +11 -0
  146. package/dist/commands/store/governance/publish-release.d.ts +2 -0
  147. package/dist/commands/store/governance/publish-release.js +30 -1
  148. package/dist/commands/store/governance/release-receipt.d.ts +12 -0
  149. package/dist/commands/store/governance/release-receipt.js +32 -0
  150. package/dist/commands/tasks/approvals/list.d.ts +11 -5
  151. package/dist/commands/tasks/approvals/list.js +13 -6
  152. package/dist/commands/tasks/attachments/facts.d.ts +12 -0
  153. package/dist/commands/tasks/attachments/facts.js +29 -0
  154. package/dist/commands/tasks/attachments/upload.d.ts +1 -0
  155. package/dist/commands/tasks/attachments/upload.js +16 -0
  156. package/dist/commands/tasks/bulk-update.js +35 -1
  157. package/dist/commands/tasks/context.d.ts +15 -0
  158. package/dist/commands/tasks/context.js +69 -0
  159. package/dist/commands/tasks/copy.d.ts +18 -0
  160. package/dist/commands/tasks/copy.js +85 -0
  161. package/dist/commands/tasks/create-tree.js +97 -23
  162. package/dist/commands/tasks/create.js +9 -1
  163. package/dist/commands/tasks/deliverable/add.js +20 -10
  164. package/dist/commands/tasks/move.js +8 -1
  165. package/dist/commands/tasks/operations/show.d.ts +16 -0
  166. package/dist/commands/tasks/operations/show.js +98 -0
  167. package/dist/commands/tasks/operations/wait.d.ts +22 -0
  168. package/dist/commands/tasks/operations/wait.js +114 -0
  169. package/dist/commands/tasks/preflight.d.ts +1 -0
  170. package/dist/commands/tasks/preflight.js +11 -1
  171. package/dist/commands/tasks/rearm-recurrence.js +4 -0
  172. package/dist/commands/tasks/result/show.js +22 -0
  173. package/dist/commands/tasks/result/submit.d.ts +1 -0
  174. package/dist/commands/tasks/result/submit.js +3 -0
  175. package/dist/commands/tasks/retry-receipt.d.ts +15 -0
  176. package/dist/commands/tasks/retry-receipt.js +89 -0
  177. package/dist/commands/tasks/retry-review.d.ts +16 -0
  178. package/dist/commands/tasks/retry-review.js +66 -0
  179. package/dist/commands/tasks/retry.d.ts +4 -8
  180. package/dist/commands/tasks/retry.js +34 -68
  181. package/dist/commands/tasks/runs.d.ts +21 -0
  182. package/dist/commands/tasks/runs.js +95 -0
  183. package/dist/commands/tasks/search.d.ts +1 -0
  184. package/dist/commands/tasks/search.js +9 -0
  185. package/dist/commands/tasks/show.d.ts +2 -0
  186. package/dist/commands/tasks/show.js +15 -1
  187. package/dist/commands/tasks/start-receipt.d.ts +15 -0
  188. package/dist/commands/tasks/start-receipt.js +95 -0
  189. package/dist/commands/tasks/start.d.ts +4 -0
  190. package/dist/commands/tasks/start.js +49 -3
  191. package/dist/commands/tasks/update.js +3 -0
  192. package/dist/commands/tasks/upsert.js +17 -3
  193. package/dist/commands/tasks/watch.d.ts +3 -0
  194. package/dist/commands/tasks/watch.js +85 -20
  195. package/dist/commands/wiki/history.d.ts +33 -0
  196. package/dist/commands/wiki/history.js +134 -0
  197. package/dist/commands/wiki/ls.d.ts +2 -0
  198. package/dist/commands/wiki/ls.js +8 -0
  199. package/dist/commands/wiki/update.d.ts +3 -1
  200. package/dist/commands/wiki/update.js +24 -2
  201. package/dist/commands/wiki/write.d.ts +22 -0
  202. package/dist/commands/wiki/write.js +144 -6
  203. package/dist/generated/agent-guides.json +81 -81
  204. package/dist/generated/managed-instruction-guides.json +1 -1
  205. package/dist/lib/agent-guides.d.ts +9 -0
  206. package/dist/lib/agent-guides.js +23 -1
  207. package/dist/lib/agentic-stream.d.ts +5 -0
  208. package/dist/lib/agentic-stream.js +122 -3
  209. package/dist/lib/api-error-reason.d.ts +2 -0
  210. package/dist/lib/api-error-reason.js +14 -0
  211. package/dist/lib/api-fetch.js +3 -0
  212. package/dist/lib/auth-diagnostics.d.ts +39 -0
  213. package/dist/lib/auth-diagnostics.js +71 -0
  214. package/dist/lib/cli-client-identity.d.ts +6 -0
  215. package/dist/lib/cli-client-identity.js +16 -0
  216. package/dist/lib/cli-installation-diagnostics.d.ts +52 -0
  217. package/dist/lib/cli-installation-diagnostics.js +254 -0
  218. package/dist/lib/command-hygiene.d.ts +45 -0
  219. package/dist/lib/command-hygiene.js +413 -0
  220. package/dist/lib/commitments.d.ts +64 -3
  221. package/dist/lib/commitments.js +34 -6
  222. package/dist/lib/completion-index.d.ts +16 -4
  223. package/dist/lib/completion-index.js +50 -14
  224. package/dist/lib/config.js +7 -1
  225. package/dist/lib/daemon-maintenance-command.d.ts +22 -0
  226. package/dist/lib/daemon-maintenance-command.js +39 -0
  227. package/dist/lib/daemon-maintenance.d.ts +275 -0
  228. package/dist/lib/daemon-maintenance.js +1035 -0
  229. package/dist/lib/dedicated-service.d.ts +3 -2
  230. package/dist/lib/dedicated-service.js +11 -3
  231. package/dist/lib/governed-store.d.ts +8 -0
  232. package/dist/lib/governed-store.js +5 -0
  233. package/dist/lib/hosted-machines.d.ts +33 -2
  234. package/dist/lib/hosted-machines.js +19 -1
  235. package/dist/lib/json-output.d.ts +1 -1
  236. package/dist/lib/machines.d.ts +9 -1
  237. package/dist/lib/machines.js +15 -1
  238. package/dist/lib/node-adapter.js +13 -0
  239. package/dist/lib/record-output.d.ts +22 -0
  240. package/dist/lib/record-output.js +78 -0
  241. package/dist/lib/roles.d.ts +3 -3
  242. package/dist/lib/scoped-memory-command.d.ts +18 -0
  243. package/dist/lib/scoped-memory-command.js +53 -2
  244. package/dist/lib/search-display.d.ts +7 -0
  245. package/dist/lib/search-display.js +31 -0
  246. package/dist/lib/skill-store-pagination.d.ts +8 -0
  247. package/dist/lib/skill-store-pagination.js +35 -0
  248. package/dist/lib/space-charter.d.ts +49 -0
  249. package/dist/lib/space-charter.js +78 -0
  250. package/dist/lib/space-loop-migration.d.ts +18 -0
  251. package/dist/lib/space-loop-migration.js +128 -0
  252. package/dist/lib/space-notebook.d.ts +22 -0
  253. package/dist/lib/space-notebook.js +140 -0
  254. package/dist/lib/space-proposal-decision-command.d.ts +36 -0
  255. package/dist/lib/space-proposal-decision-command.js +108 -0
  256. package/dist/lib/space-proposals.d.ts +44 -0
  257. package/dist/lib/space-proposals.js +186 -0
  258. package/dist/lib/space-templates.d.ts +8 -0
  259. package/dist/lib/space-templates.js +17 -0
  260. package/dist/lib/space-write-policy.d.ts +24 -0
  261. package/dist/lib/space-write-policy.js +103 -0
  262. package/dist/lib/task-agent-context-capabilities.d.ts +10 -0
  263. package/dist/lib/task-agent-context-capabilities.js +22 -0
  264. package/dist/lib/task-agent-context-compatibility.d.ts +9 -0
  265. package/dist/lib/task-agent-context-compatibility.js +30 -0
  266. package/dist/lib/task-asset-upload.d.ts +22 -0
  267. package/dist/lib/task-asset-upload.js +257 -29
  268. package/dist/lib/task-batch.d.ts +15 -1
  269. package/dist/lib/task-batch.js +35 -2
  270. package/dist/lib/task-operation-watch.d.ts +66 -0
  271. package/dist/lib/task-operation-watch.js +159 -0
  272. package/dist/lib/task-resolver.d.ts +1 -1
  273. package/dist/lib/task-resolver.js +4 -3
  274. package/dist/lib/task-work.d.ts +1 -1
  275. package/dist/lib/task-work.js +35 -1
  276. package/dist/lib/task-write-attribution.d.ts +14 -0
  277. package/dist/lib/task-write-attribution.js +35 -2
  278. package/dist/lib/triggers.d.ts +11 -0
  279. package/dist/lib/triggers.js +7 -0
  280. package/dist/lib/wiki-update.d.ts +1 -0
  281. package/dist/lib/wiki-update.js +10 -1
  282. package/dist/lib/wiki.js +4 -1
  283. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +9 -1
  284. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +31 -15
  285. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialEnvelopeBridge.d.ts +10 -0
  286. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialEnvelopeBridge.js +147 -0
  287. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonConsentProof.d.ts +20 -0
  288. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonConsentProof.js +72 -0
  289. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +1 -0
  290. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.js +13 -7
  291. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/desktopDaemonProof.d.ts +21 -0
  292. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/desktopDaemonProof.js +96 -0
  293. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.d.ts +2 -3
  294. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +102 -20
  295. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/guidedUpdate.d.ts +370 -0
  296. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/guidedUpdate.js +315 -0
  297. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineReservation.d.ts +27 -0
  298. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineReservation.js +161 -0
  299. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineScopes.d.ts +26 -0
  300. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/independentMachineScopes.js +41 -0
  301. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +2 -1
  302. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +15 -0
  303. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/macos.js +20 -4
  304. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/maintenanceReportWire.d.ts +178 -0
  305. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/maintenanceReportWire.js +262 -0
  306. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.d.ts +51 -0
  307. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.js +106 -0
  308. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +9 -1
  309. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +32 -5
  310. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialEnvelopeBridge.d.ts +10 -0
  311. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialEnvelopeBridge.js +172 -1
  312. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonConsentProof.d.ts +20 -0
  313. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonConsentProof.js +43 -0
  314. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +1 -0
  315. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.js +33 -14
  316. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/desktopDaemonProof.d.ts +21 -0
  317. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/desktopDaemonProof.js +62 -0
  318. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.d.ts +2 -3
  319. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +133 -25
  320. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/guidedUpdate.d.ts +370 -0
  321. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/guidedUpdate.js +404 -0
  322. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineReservation.d.ts +27 -0
  323. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineReservation.js +132 -0
  324. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineScopes.d.ts +26 -0
  325. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/independentMachineScopes.js +15 -0
  326. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +2 -1
  327. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +2 -1
  328. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/macos.js +28 -15
  329. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/maintenanceReportWire.d.ts +178 -0
  330. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/maintenanceReportWire.js +342 -0
  331. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.d.ts +51 -0
  332. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.js +138 -0
  333. package/dist/node_modules/@skrr-ai/auth-core/package.json +51 -1
  334. package/dist/node_modules/@skrr-ai/data-provider/index.js +27181 -20293
  335. package/oclif.manifest.json +5745 -1813
  336. package/package.json +20 -2
@@ -40,7 +40,7 @@
40
40
  * when not active. CLI leaves it unset; legacy `OVERSKY_KEK_REQUIRED=1`
41
41
  * env var is still honored as a back-compat trigger.
42
42
  */
43
- import { createHash } from 'node:crypto';
43
+ import { createHash, randomBytes } from 'node:crypto';
44
44
  import fs from 'node:fs';
45
45
  import path from 'node:path';
46
46
  import lockfile from 'proper-lockfile';
@@ -429,6 +429,172 @@ function retiredDekFiles(profile) {
429
429
  return [];
430
430
  }
431
431
  }
432
+ /** Open only the existing wrapped DEK. Recovery must never enroll a new key,
433
+ * consolidate profile paths or replace an unreadable envelope. A caller gets
434
+ * an error if the existing file or the platform's read-only unwrap is unsafe
435
+ * or unavailable. This intentionally does not load retired keys; credentials
436
+ * that require one remain unavailable rather than triggering a migration. */
437
+ export async function initExistingCredEnvelope(profile) {
438
+ if (_state.kind === 'active' && _state.profile === profile)
439
+ return;
440
+ if (_state.kind !== 'uninit' || typeof profile !== 'string' || !profile) {
441
+ throw new Error('Existing credential envelope is unavailable');
442
+ }
443
+ let fd;
444
+ let candidate;
445
+ try {
446
+ const target = wrappedDekFilePath(profile);
447
+ fd = fs.openSync(target, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
448
+ const before = fs.fstatSync(fd);
449
+ const safe = (stat) => stat.isFile() && stat.nlink === 1 && stat.size > 0 && stat.size <= 65_536 &&
450
+ (stat.mode & 0o077) === 0 && (typeof process.getuid !== 'function' || stat.uid === process.getuid());
451
+ if (!safe(before))
452
+ throw new Error('unsafe envelope');
453
+ const readBounded = () => {
454
+ const bytes = Buffer.alloc(before.size);
455
+ let offset = 0;
456
+ while (offset < bytes.length) {
457
+ const count = fs.readSync(fd, bytes, offset, bytes.length - offset, offset);
458
+ if (count <= 0)
459
+ throw new Error('changed envelope');
460
+ offset += count;
461
+ }
462
+ return bytes;
463
+ };
464
+ const wrapped = readBounded();
465
+ const kek = getKekStrategy();
466
+ if (!kek.unwrapExisting || !(await kek.available()))
467
+ throw new Error('read-only KEK unavailable');
468
+ candidate = await kek.unwrapExisting(wrapped, buildCredentialAad(profile));
469
+ if (!Buffer.isBuffer(candidate) || candidate.length !== 32)
470
+ throw new Error('invalid envelope');
471
+ // The unwrap can wait for Keychain. A different file, a replaced path or
472
+ // a second initializer must not make this process adopt a stale key.
473
+ if (!readBounded().equals(wrapped))
474
+ throw new Error('changed envelope');
475
+ const after = fs.fstatSync(fd);
476
+ const current = fs.lstatSync(target);
477
+ if (!safe(after) || !safe(current) || before.dev !== after.dev || before.ino !== after.ino ||
478
+ before.dev !== current.dev || before.ino !== current.ino || before.size !== after.size ||
479
+ before.size !== current.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs ||
480
+ before.mtimeMs !== current.mtimeMs || before.ctimeMs !== current.ctimeMs ||
481
+ wrappedDekFilePath(profile) !== target || _state.kind !== 'uninit') {
482
+ throw new Error('changed envelope');
483
+ }
484
+ for (const old of _retiredDeks)
485
+ old.fill(0);
486
+ _retiredDeks = [];
487
+ _state = { kind: 'active', dek: candidate, kekId: kek.id,
488
+ kekKind: typeof kek.kind === 'string' || kek.kind === null ? (kek.kind ?? null) : null, profile };
489
+ candidate = undefined;
490
+ }
491
+ catch {
492
+ if (Buffer.isBuffer(candidate))
493
+ candidate.fill(0);
494
+ throw new Error('Existing credential envelope is unavailable');
495
+ }
496
+ finally {
497
+ if (fd !== undefined)
498
+ fs.closeSync(fd);
499
+ }
500
+ }
501
+ /** First enrollment for a reserved desktop background profile. Existing or
502
+ * ambiguous state is opened read-only or refused; it is never re-enrolled.
503
+ * The caller must validate the reservation before calling this function. */
504
+ export async function initNewIndependentCredEnvelope(profile) {
505
+ if (!/^desktop-bg-[a-f0-9]{32}$/.test(profile))
506
+ throw new Error('Background credential enrollment is unavailable');
507
+ if (_state.kind === 'active' && _state.profile === profile)
508
+ return;
509
+ if (_state.kind !== 'uninit')
510
+ throw new Error('Background credential enrollment is unavailable');
511
+ const resolved = resolveProfileStateFile(profile, ACCOUNT_CRED_DEK_WRAPPED);
512
+ const paths = [resolved.canonicalPath, ...(resolved.legacyPath ? [resolved.legacyPath] : [])];
513
+ const present = (file) => {
514
+ try {
515
+ fs.lstatSync(file);
516
+ return true;
517
+ }
518
+ catch (err) {
519
+ if (err.code === 'ENOENT')
520
+ return false;
521
+ throw err;
522
+ }
523
+ };
524
+ if (paths.some(present))
525
+ return initExistingCredEnvelope(profile);
526
+ // A missing DEK alongside a previously written identity or credential is
527
+ // recovery, not first enrollment, even if a retried caller says otherwise.
528
+ const dir = resolved.canonicalDir;
529
+ const stat = fs.lstatSync(dir);
530
+ if (!stat.isDirectory() || stat.isSymbolicLink() || (stat.mode & 0o077) !== 0 ||
531
+ (typeof process.getuid === 'function' && stat.uid !== process.getuid())) {
532
+ throw new Error('Background credential enrollment is unavailable');
533
+ }
534
+ const artifacts = ['device-private-key', 'device-public-key.jwk', 'auth-binding.json', 'auth.json'];
535
+ const artifactDirs = [dir, ...(resolved.legacyDir ? [resolved.legacyDir] : [])];
536
+ const assertEmpty = () => {
537
+ if (paths.some(present) || artifactDirs.some((root) => artifacts.some((name) => present(path.join(root, name)))) ||
538
+ wrappedDekFilePath(profile) !== resolved.canonicalPath) {
539
+ throw new Error('Background credential enrollment needs recovery');
540
+ }
541
+ };
542
+ assertEmpty();
543
+ const kek = getKekStrategy();
544
+ if (!kek.unwrapExisting || !(await kek.available()))
545
+ throw new Error('Background credential enrollment is unavailable');
546
+ assertEmpty();
547
+ const dek = generateDek();
548
+ let temp;
549
+ try {
550
+ const wrapped = await kek.wrap(dek, buildCredentialAad(profile));
551
+ // Another enrollment may have won while the platform store was busy.
552
+ // Its file is opened read-only; this process never overwrites it.
553
+ if (paths.some(present))
554
+ return await initExistingCredEnvelope(profile);
555
+ assertEmpty();
556
+ const temporaryPath = path.join(dir, `.cred-dek-enrollment.${randomBytes(12).toString('hex')}.tmp`);
557
+ const fd = fs.openSync(temporaryPath, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL |
558
+ (fs.constants.O_NOFOLLOW ?? 0), 0o600);
559
+ temp = temporaryPath;
560
+ try {
561
+ fs.writeFileSync(fd, wrapped);
562
+ fs.fsyncSync(fd);
563
+ }
564
+ finally {
565
+ fs.closeSync(fd);
566
+ }
567
+ assertEmpty();
568
+ try {
569
+ fs.linkSync(temp, resolved.canonicalPath);
570
+ }
571
+ catch (err) {
572
+ if (err.code !== 'EEXIST')
573
+ throw err;
574
+ }
575
+ const dirFd = fs.openSync(dir, 'r');
576
+ try {
577
+ fs.fsyncSync(dirFd);
578
+ }
579
+ finally {
580
+ fs.closeSync(dirFd);
581
+ }
582
+ }
583
+ finally {
584
+ dek.fill(0);
585
+ if (temp) {
586
+ fs.unlinkSync(temp);
587
+ const dirFd = fs.openSync(dir, 'r');
588
+ try {
589
+ fs.fsyncSync(dirFd);
590
+ }
591
+ finally {
592
+ fs.closeSync(dirFd);
593
+ }
594
+ }
595
+ }
596
+ await initExistingCredEnvelope(profile);
597
+ }
432
598
  /**
433
599
  * Initialize the envelope path. Idempotent — second call when state is
434
600
  * non-uninit returns immediately.
@@ -440,6 +606,11 @@ function retiredDekFiles(profile) {
440
606
  * 4. Any throw → disabled+init_failed; transforms stay passthrough.
441
607
  */
442
608
  export async function initCredEnvelope(profile) {
609
+ // A reserved background profile has an independent owner and device key.
610
+ // Generic status, startup and CLI paths may read it, but cannot replace a
611
+ // missing or unreadable key. Only validated first enrollment can create one.
612
+ if (/^desktop-bg-[a-f0-9]{32}$/i.test(profile))
613
+ return initExistingCredEnvelope(profile);
443
614
  if (_state.kind !== 'uninit')
444
615
  return;
445
616
  if (typeof profile !== 'string' || profile.length === 0) {
@@ -0,0 +1,20 @@
1
+ export interface DaemonConsentPayload {
2
+ consentVersion: number;
3
+ consentSource: string;
4
+ isLegacy: boolean;
5
+ isReConsent: boolean;
6
+ scopes: string[];
7
+ scopeDescriptions: Record<string, string>;
8
+ }
9
+ /** A single canonical, bounded representation on both sides of the log. */
10
+ export declare function normalizeDaemonConsent(input: unknown): DaemonConsentPayload | null;
11
+ export interface DaemonConsentIdentity {
12
+ pid: number;
13
+ daemonId: string;
14
+ userId: string;
15
+ origin: string;
16
+ }
17
+ /** The bootstrap secret is never logged. This MAC binds the exact consent,
18
+ * live process, daemon and cloud owner; an old log entry is not authority. */
19
+ export declare function daemonConsentProof(secret: string, identity: DaemonConsentIdentity, payload: DaemonConsentPayload): string;
20
+ export declare function verifyDaemonConsentProof(secret: string, identity: DaemonConsentIdentity, payload: DaemonConsentPayload, proof: string): boolean;
@@ -0,0 +1,43 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ /** A single canonical, bounded representation on both sides of the log. */
3
+ export function normalizeDaemonConsent(input) {
4
+ if (!input || typeof input !== 'object' || Array.isArray(input))
5
+ return null;
6
+ const value = input;
7
+ if (!Number.isSafeInteger(value.consentVersion) || value.consentVersion < 0 ||
8
+ typeof value.consentSource !== 'string' || value.consentSource.length > 64 ||
9
+ typeof value.isLegacy !== 'boolean' || typeof value.isReConsent !== 'boolean' ||
10
+ !Array.isArray(value.scopes) || value.scopes.length > 128 ||
11
+ !value.scopes.every((scope) => typeof scope === 'string' && scope.length <= 256) ||
12
+ !value.scopeDescriptions || typeof value.scopeDescriptions !== 'object' || Array.isArray(value.scopeDescriptions))
13
+ return null;
14
+ const entries = Object.entries(value.scopeDescriptions)
15
+ .sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
16
+ if (entries.length > 128 || entries.some(([key, text]) => key.length > 256 || typeof text !== 'string' || text.length > 1024))
17
+ return null;
18
+ return { consentVersion: value.consentVersion, consentSource: value.consentSource,
19
+ isLegacy: value.isLegacy, isReConsent: value.isReConsent, scopes: value.scopes,
20
+ scopeDescriptions: Object.fromEntries(entries) };
21
+ }
22
+ /** The bootstrap secret is never logged. This MAC binds the exact consent,
23
+ * live process, daemon and cloud owner; an old log entry is not authority. */
24
+ export function daemonConsentProof(secret, identity, payload) {
25
+ const key = Buffer.from(secret, 'base64');
26
+ if (key.length !== 32 || !Number.isSafeInteger(identity.pid) || identity.pid <= 0 ||
27
+ !identity.daemonId || !identity.userId)
28
+ throw new Error('Invalid daemon consent identity');
29
+ const origin = new URL(identity.origin).origin;
30
+ return createHmac('sha256', key).update('skrr-daemon-consent:v1\0').update(JSON.stringify([
31
+ identity.pid, identity.daemonId, identity.userId.toLowerCase(), origin, payload,
32
+ ])).digest('hex');
33
+ }
34
+ export function verifyDaemonConsentProof(secret, identity, payload, proof) {
35
+ if (!/^[a-f0-9]{64}$/.test(proof))
36
+ return false;
37
+ try {
38
+ return timingSafeEqual(Buffer.from(proof, 'hex'), Buffer.from(daemonConsentProof(secret, identity, payload), 'hex'));
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
@@ -67,6 +67,7 @@ export function categoryForDaemonTool(toolName) {
67
67
  case 'filelist':
68
68
  case 'filestat':
69
69
  case 'filereadtagged':
70
+ case 'personaldata':
70
71
  return 'read';
71
72
  case 'write':
72
73
  case 'edit':
@@ -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('daemon:computer:use-control', 'An authorized person observes, configures, stops or recovers the machine Computer Use provider.', {
287
- stability: 'experimental', capability: 'computer_use_mcp_v1', delivery: 'acked', answeredBy: 'daemon:computer:ack',
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', capability: 'computer_use_mcp_v1', delivery: 'acked', answeredBy: 'daemon:computer:ack',
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', capability: 'computer_use_mcp_v1',
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', capability: COMPUTER_DESKTOP_CAPABILITY,
300
- delivery: 'acked', answeredBy: 'daemon:computer:ack',
301
- payload: { kind: 'zod', schema: `daemonComputerDesktop${operation[0].toUpperCase()}${operation.slice(1)}Schema` },
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', capability: COMPUTER_DESKTOP_CONTROL_CAPABILITY,
305
- delivery: 'acked', answeredBy: 'daemon:computer:ack',
306
- payload: { kind: 'zod', schema: `daemonComputerDesktop${operation[0].toUpperCase()}${operation.slice(1)}Schema` },
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', capability: COMPUTER_DESKTOP_CONTROL_CAPABILITY,
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', capability: COMPUTER_DESKTOP_CAPABILITY,
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,21 @@
1
+ export declare const DESKTOP_DAEMON_PROOF_NAMESPACE = "/desktop-proof-v1";
2
+ export declare const DESKTOP_DAEMON_RENEWAL_NAMESPACE = "/desktop-renewal-v1";
3
+ export interface DesktopDaemonOwner {
4
+ userId: string;
5
+ serverUrl: string;
6
+ }
7
+ export interface DesktopDaemonChallenge {
8
+ owner: DesktopDaemonOwner;
9
+ port: number;
10
+ clientNonce: string;
11
+ serverNonce: string;
12
+ }
13
+ /** The same canonical owner is used by the daemon's owner boundary and MAC. */
14
+ export declare function normalizeDesktopDaemonOwner(input: unknown): DesktopDaemonOwner | null;
15
+ /** Role separation prevents reflecting the daemon's proof as client proof. */
16
+ export declare function desktopDaemonProof(secret: string, role: 'daemon' | 'desktop', challenge: DesktopDaemonChallenge): string;
17
+ /** Renewal uses a distinct domain so a proof for this narrow channel cannot
18
+ * be reflected or replayed as a normal desktop attachment. */
19
+ export declare function desktopRenewalProof(secret: string, role: 'daemon' | 'desktop', challenge: DesktopDaemonChallenge): string;
20
+ export declare function verifyDesktopDaemonProof(secret: string, role: 'daemon' | 'desktop', challenge: DesktopDaemonChallenge, proof: unknown): boolean;
21
+ export declare function verifyDesktopRenewalProof(secret: string, role: 'daemon' | 'desktop', challenge: DesktopDaemonChallenge, proof: unknown): boolean;
@@ -0,0 +1,62 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ export const DESKTOP_DAEMON_PROOF_NAMESPACE = '/desktop-proof-v1';
3
+ export const DESKTOP_DAEMON_RENEWAL_NAMESPACE = '/desktop-renewal-v1';
4
+ /** The same canonical owner is used by the daemon's owner boundary and MAC. */
5
+ export function normalizeDesktopDaemonOwner(input) {
6
+ if (!input || typeof input !== 'object' || Array.isArray(input))
7
+ return null;
8
+ const value = input;
9
+ if (typeof value.userId !== 'string' || !value.userId || value.userId.length > 128 ||
10
+ typeof value.serverUrl !== 'string' || value.serverUrl.length > 2048)
11
+ return null;
12
+ try {
13
+ const url = new URL(value.serverUrl);
14
+ if (url.protocol !== 'https:' && url.protocol !== 'http:')
15
+ return null;
16
+ return { userId: value.userId, serverUrl: url.origin };
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ /** Role separation prevents reflecting the daemon's proof as client proof. */
23
+ export function desktopDaemonProof(secret, role, challenge) {
24
+ return proofForPurpose(secret, role, challenge, 'skrr-desktop-daemon-proof:v1\0');
25
+ }
26
+ /** Renewal uses a distinct domain so a proof for this narrow channel cannot
27
+ * be reflected or replayed as a normal desktop attachment. */
28
+ export function desktopRenewalProof(secret, role, challenge) {
29
+ return proofForPurpose(secret, role, challenge, 'skrr-desktop-renewal-proof:v1\0');
30
+ }
31
+ function proofForPurpose(secret, role, challenge, domain) {
32
+ const key = Buffer.from(secret, 'base64');
33
+ const owner = normalizeDesktopDaemonOwner(challenge.owner);
34
+ if (key.length !== 32 || key.toString('base64') !== secret || !owner ||
35
+ !Number.isInteger(challenge.port) || challenge.port < 1 || challenge.port > 65535 ||
36
+ !/^[a-f0-9]{64}$/.test(challenge.clientNonce) || !/^[a-f0-9]{64}$/.test(challenge.serverNonce)) {
37
+ throw new Error('Invalid desktop daemon challenge');
38
+ }
39
+ return createHmac('sha256', key).update(domain).update(JSON.stringify([
40
+ role, challenge.port, owner.userId, owner.serverUrl, challenge.clientNonce, challenge.serverNonce,
41
+ ])).digest('hex');
42
+ }
43
+ export function verifyDesktopDaemonProof(secret, role, challenge, proof) {
44
+ if (typeof proof !== 'string' || !/^[a-f0-9]{64}$/.test(proof))
45
+ return false;
46
+ try {
47
+ return timingSafeEqual(Buffer.from(proof, 'hex'), Buffer.from(desktopDaemonProof(secret, role, challenge), 'hex'));
48
+ }
49
+ catch {
50
+ return false;
51
+ }
52
+ }
53
+ export function verifyDesktopRenewalProof(secret, role, challenge, proof) {
54
+ if (typeof proof !== 'string' || !/^[a-f0-9]{64}$/.test(proof))
55
+ return false;
56
+ try {
57
+ return timingSafeEqual(Buffer.from(proof, 'hex'), Buffer.from(desktopRenewalProof(secret, role, challenge), 'hex'));
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ }
@@ -51,9 +51,8 @@ export declare function describeDeviceKeySplit(profile: string): {
51
51
  * `createIfMissing: false` stops before step 2 (disabled+no_stored_key) and
52
52
  * never replaces anything: for a short-lived process that must only READ the
53
53
  * daemon's key while the daemon itself may be creating it (OSK-15990's
54
- * `skrrd device-proof`). The persist below is not an exclusive create, so a
55
- * second creator racing the daemon could leave the daemon holding one key in
56
- * memory and the disk another.
54
+ * `skrrd device-proof`). Readers and writers both take the profile lock so
55
+ * they cannot observe an incomplete write from another updated process.
57
56
  */
58
57
  export declare function initDeviceIdentity(profile: string, options?: {
59
58
  recoverUnreadable?: boolean;