@mseep/clawdcursor 1.5.5

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 (354) hide show
  1. package/CHANGELOG.md +2264 -0
  2. package/LICENSE +21 -0
  3. package/README.md +385 -0
  4. package/SECURITY.md +44 -0
  5. package/SKILL.md +503 -0
  6. package/dist/core/agent-loop/agent.d.ts +42 -0
  7. package/dist/core/agent-loop/agent.js +1023 -0
  8. package/dist/core/agent-loop/agent.js.map +1 -0
  9. package/dist/core/agent-loop/batch-tool.d.ts +25 -0
  10. package/dist/core/agent-loop/batch-tool.js +218 -0
  11. package/dist/core/agent-loop/batch-tool.js.map +1 -0
  12. package/dist/core/agent-loop/coord-scale.d.ts +72 -0
  13. package/dist/core/agent-loop/coord-scale.js +89 -0
  14. package/dist/core/agent-loop/coord-scale.js.map +1 -0
  15. package/dist/core/agent-loop/focus-guard.d.ts +24 -0
  16. package/dist/core/agent-loop/focus-guard.js +29 -0
  17. package/dist/core/agent-loop/focus-guard.js.map +1 -0
  18. package/dist/core/agent-loop/project-mcp.d.ts +97 -0
  19. package/dist/core/agent-loop/project-mcp.js +253 -0
  20. package/dist/core/agent-loop/project-mcp.js.map +1 -0
  21. package/dist/core/agent-loop/prompt.d.ts +45 -0
  22. package/dist/core/agent-loop/prompt.js +426 -0
  23. package/dist/core/agent-loop/prompt.js.map +1 -0
  24. package/dist/core/agent-loop/tool-meta.d.ts +93 -0
  25. package/dist/core/agent-loop/tool-meta.js +651 -0
  26. package/dist/core/agent-loop/tool-meta.js.map +1 -0
  27. package/dist/core/agent-loop/tools.d.ts +38 -0
  28. package/dist/core/agent-loop/tools.js +2134 -0
  29. package/dist/core/agent-loop/tools.js.map +1 -0
  30. package/dist/core/agent-loop/types.d.ts +170 -0
  31. package/dist/core/agent-loop/types.js +12 -0
  32. package/dist/core/agent-loop/types.js.map +1 -0
  33. package/dist/core/agent.d.ts +51 -0
  34. package/dist/core/agent.js +245 -0
  35. package/dist/core/agent.js.map +1 -0
  36. package/dist/core/app-categories.d.ts +67 -0
  37. package/dist/core/app-categories.js +108 -0
  38. package/dist/core/app-categories.js.map +1 -0
  39. package/dist/core/banner.d.ts +70 -0
  40. package/dist/core/banner.js +245 -0
  41. package/dist/core/banner.js.map +1 -0
  42. package/dist/core/classify/capability.d.ts +45 -0
  43. package/dist/core/classify/capability.js +78 -0
  44. package/dist/core/classify/capability.js.map +1 -0
  45. package/dist/core/decompose/llm-decomposer.d.ts +35 -0
  46. package/dist/core/decompose/llm-decomposer.js +156 -0
  47. package/dist/core/decompose/llm-decomposer.js.map +1 -0
  48. package/dist/core/decompose/parser.d.ts +27 -0
  49. package/dist/core/decompose/parser.js +101 -0
  50. package/dist/core/decompose/parser.js.map +1 -0
  51. package/dist/core/observability/correlation.d.ts +19 -0
  52. package/dist/core/observability/correlation.js +36 -0
  53. package/dist/core/observability/correlation.js.map +1 -0
  54. package/dist/core/observability/cost-meter.d.ts +51 -0
  55. package/dist/core/observability/cost-meter.js +134 -0
  56. package/dist/core/observability/cost-meter.js.map +1 -0
  57. package/dist/core/observability/logger.d.ts +61 -0
  58. package/dist/core/observability/logger.js +550 -0
  59. package/dist/core/observability/logger.js.map +1 -0
  60. package/dist/core/router/aliases.d.ts +50 -0
  61. package/dist/core/router/aliases.js +104 -0
  62. package/dist/core/router/aliases.js.map +1 -0
  63. package/dist/core/router/normalize.d.ts +41 -0
  64. package/dist/core/router/normalize.js +80 -0
  65. package/dist/core/router/normalize.js.map +1 -0
  66. package/dist/core/safety.d.ts +126 -0
  67. package/dist/core/safety.js +568 -0
  68. package/dist/core/safety.js.map +1 -0
  69. package/dist/core/sense/a11y-resolver.d.ts +73 -0
  70. package/dist/core/sense/a11y-resolver.js +76 -0
  71. package/dist/core/sense/a11y-resolver.js.map +1 -0
  72. package/dist/core/sense/fingerprint.d.ts +41 -0
  73. package/dist/core/sense/fingerprint.js +123 -0
  74. package/dist/core/sense/fingerprint.js.map +1 -0
  75. package/dist/core/sense/rank.d.ts +70 -0
  76. package/dist/core/sense/rank.js +192 -0
  77. package/dist/core/sense/rank.js.map +1 -0
  78. package/dist/core/sense/reactive-check.d.ts +40 -0
  79. package/dist/core/sense/reactive-check.js +48 -0
  80. package/dist/core/sense/reactive-check.js.map +1 -0
  81. package/dist/core/sense/snapshot.d.ts +19 -0
  82. package/dist/core/sense/snapshot.js +100 -0
  83. package/dist/core/sense/snapshot.js.map +1 -0
  84. package/dist/core/sense/types.d.ts +66 -0
  85. package/dist/core/sense/types.js +9 -0
  86. package/dist/core/sense/types.js.map +1 -0
  87. package/dist/core/sense/ui-map-anchors.d.ts +7 -0
  88. package/dist/core/sense/ui-map-anchors.js +24 -0
  89. package/dist/core/sense/ui-map-anchors.js.map +1 -0
  90. package/dist/core/sense/ui-map-elements.d.ts +5 -0
  91. package/dist/core/sense/ui-map-elements.js +33 -0
  92. package/dist/core/sense/ui-map-elements.js.map +1 -0
  93. package/dist/core/sense/ui-map-find.d.ts +56 -0
  94. package/dist/core/sense/ui-map-find.js +153 -0
  95. package/dist/core/sense/ui-map-find.js.map +1 -0
  96. package/dist/core/sense/ui-map-fuse.d.ts +4 -0
  97. package/dist/core/sense/ui-map-fuse.js +44 -0
  98. package/dist/core/sense/ui-map-fuse.js.map +1 -0
  99. package/dist/core/sense/ui-map-geom.d.ts +3 -0
  100. package/dist/core/sense/ui-map-geom.js +16 -0
  101. package/dist/core/sense/ui-map-geom.js.map +1 -0
  102. package/dist/core/sense/ui-map-holder.d.ts +58 -0
  103. package/dist/core/sense/ui-map-holder.js +87 -0
  104. package/dist/core/sense/ui-map-holder.js.map +1 -0
  105. package/dist/core/sense/ui-map-normalize.d.ts +19 -0
  106. package/dist/core/sense/ui-map-normalize.js +65 -0
  107. package/dist/core/sense/ui-map-normalize.js.map +1 -0
  108. package/dist/core/sense/ui-map-render.d.ts +4 -0
  109. package/dist/core/sense/ui-map-render.js +34 -0
  110. package/dist/core/sense/ui-map-render.js.map +1 -0
  111. package/dist/core/sense/ui-map-resolve.d.ts +41 -0
  112. package/dist/core/sense/ui-map-resolve.js +59 -0
  113. package/dist/core/sense/ui-map-resolve.js.map +1 -0
  114. package/dist/core/sense/ui-map-types.d.ts +66 -0
  115. package/dist/core/sense/ui-map-types.js +11 -0
  116. package/dist/core/sense/ui-map-types.js.map +1 -0
  117. package/dist/core/sense/ui-map.d.ts +29 -0
  118. package/dist/core/sense/ui-map.js +113 -0
  119. package/dist/core/sense/ui-map.js.map +1 -0
  120. package/dist/core/verify/assertions.d.ts +132 -0
  121. package/dist/core/verify/assertions.js +284 -0
  122. package/dist/core/verify/assertions.js.map +1 -0
  123. package/dist/index.d.ts +21 -0
  124. package/dist/index.js +24 -0
  125. package/dist/index.js.map +1 -0
  126. package/dist/llm/browser-config.d.ts +36 -0
  127. package/dist/llm/browser-config.js +83 -0
  128. package/dist/llm/browser-config.js.map +1 -0
  129. package/dist/llm/client.d.ts +268 -0
  130. package/dist/llm/client.js +1094 -0
  131. package/dist/llm/client.js.map +1 -0
  132. package/dist/llm/config.d.ts +79 -0
  133. package/dist/llm/config.js +375 -0
  134. package/dist/llm/config.js.map +1 -0
  135. package/dist/llm/credentials.d.ts +35 -0
  136. package/dist/llm/credentials.js +491 -0
  137. package/dist/llm/credentials.js.map +1 -0
  138. package/dist/llm/external-creds.d.ts +42 -0
  139. package/dist/llm/external-creds.js +169 -0
  140. package/dist/llm/external-creds.js.map +1 -0
  141. package/dist/llm/providers.d.ts +123 -0
  142. package/dist/llm/providers.js +717 -0
  143. package/dist/llm/providers.js.map +1 -0
  144. package/dist/paths.d.ts +31 -0
  145. package/dist/paths.js +147 -0
  146. package/dist/paths.js.map +1 -0
  147. package/dist/platform/accessibility.d.ts +139 -0
  148. package/dist/platform/accessibility.js +670 -0
  149. package/dist/platform/accessibility.js.map +1 -0
  150. package/dist/platform/cdp-driver.d.ts +318 -0
  151. package/dist/platform/cdp-driver.js +1179 -0
  152. package/dist/platform/cdp-driver.js.map +1 -0
  153. package/dist/platform/index.d.ts +11 -0
  154. package/dist/platform/index.js +69 -0
  155. package/dist/platform/index.js.map +1 -0
  156. package/dist/platform/keys.d.ts +17 -0
  157. package/dist/platform/keys.js +129 -0
  158. package/dist/platform/keys.js.map +1 -0
  159. package/dist/platform/launch-poll.d.ts +101 -0
  160. package/dist/platform/launch-poll.js +177 -0
  161. package/dist/platform/launch-poll.js.map +1 -0
  162. package/dist/platform/linux.d.ts +173 -0
  163. package/dist/platform/linux.js +1253 -0
  164. package/dist/platform/linux.js.map +1 -0
  165. package/dist/platform/macos.d.ts +136 -0
  166. package/dist/platform/macos.js +976 -0
  167. package/dist/platform/macos.js.map +1 -0
  168. package/dist/platform/native-desktop.d.ts +145 -0
  169. package/dist/platform/native-desktop.js +936 -0
  170. package/dist/platform/native-desktop.js.map +1 -0
  171. package/dist/platform/native-helper.d.ts +130 -0
  172. package/dist/platform/native-helper.js +592 -0
  173. package/dist/platform/native-helper.js.map +1 -0
  174. package/dist/platform/ocr-engine.d.ts +78 -0
  175. package/dist/platform/ocr-engine.js +363 -0
  176. package/dist/platform/ocr-engine.js.map +1 -0
  177. package/dist/platform/ps-runner.d.ts +28 -0
  178. package/dist/platform/ps-runner.js +228 -0
  179. package/dist/platform/ps-runner.js.map +1 -0
  180. package/dist/platform/types.d.ts +397 -0
  181. package/dist/platform/types.js +15 -0
  182. package/dist/platform/types.js.map +1 -0
  183. package/dist/platform/uri-handler.d.ts +75 -0
  184. package/dist/platform/uri-handler.js +273 -0
  185. package/dist/platform/uri-handler.js.map +1 -0
  186. package/dist/platform/wayland-backend.d.ts +53 -0
  187. package/dist/platform/wayland-backend.js +348 -0
  188. package/dist/platform/wayland-backend.js.map +1 -0
  189. package/dist/platform/windows.d.ts +232 -0
  190. package/dist/platform/windows.js +1210 -0
  191. package/dist/platform/windows.js.map +1 -0
  192. package/dist/postbuild.d.ts +10 -0
  193. package/dist/postbuild.js +98 -0
  194. package/dist/postbuild.js.map +1 -0
  195. package/dist/schema/snapshot.d.ts +33 -0
  196. package/dist/schema/snapshot.js +90 -0
  197. package/dist/schema/snapshot.js.map +1 -0
  198. package/dist/shortcuts.d.ts +30 -0
  199. package/dist/shortcuts.js +261 -0
  200. package/dist/shortcuts.js.map +1 -0
  201. package/dist/surface/cli.d.ts +7 -0
  202. package/dist/surface/cli.js +1556 -0
  203. package/dist/surface/cli.js.map +1 -0
  204. package/dist/surface/dashboard.d.ts +8 -0
  205. package/dist/surface/dashboard.js +1193 -0
  206. package/dist/surface/dashboard.js.map +1 -0
  207. package/dist/surface/doctor.d.ts +29 -0
  208. package/dist/surface/doctor.js +1514 -0
  209. package/dist/surface/doctor.js.map +1 -0
  210. package/dist/surface/format.d.ts +10 -0
  211. package/dist/surface/format.js +37 -0
  212. package/dist/surface/format.js.map +1 -0
  213. package/dist/surface/http-utility.d.ts +65 -0
  214. package/dist/surface/http-utility.js +336 -0
  215. package/dist/surface/http-utility.js.map +1 -0
  216. package/dist/surface/mcp-server.d.ts +91 -0
  217. package/dist/surface/mcp-server.js +280 -0
  218. package/dist/surface/mcp-server.js.map +1 -0
  219. package/dist/surface/onboarding.d.ts +15 -0
  220. package/dist/surface/onboarding.js +184 -0
  221. package/dist/surface/onboarding.js.map +1 -0
  222. package/dist/surface/pidfile.d.ts +79 -0
  223. package/dist/surface/pidfile.js +263 -0
  224. package/dist/surface/pidfile.js.map +1 -0
  225. package/dist/surface/readiness.d.ts +45 -0
  226. package/dist/surface/readiness.js +230 -0
  227. package/dist/surface/readiness.js.map +1 -0
  228. package/dist/surface/report.d.ts +68 -0
  229. package/dist/surface/report.js +341 -0
  230. package/dist/surface/report.js.map +1 -0
  231. package/dist/surface/skill-register.d.ts +14 -0
  232. package/dist/surface/skill-register.js +150 -0
  233. package/dist/surface/skill-register.js.map +1 -0
  234. package/dist/surface/version.d.ts +6 -0
  235. package/dist/surface/version.js +27 -0
  236. package/dist/surface/version.js.map +1 -0
  237. package/dist/tools/a11y.d.ts +8 -0
  238. package/dist/tools/a11y.js +545 -0
  239. package/dist/tools/a11y.js.map +1 -0
  240. package/dist/tools/a11y_depth.d.ts +19 -0
  241. package/dist/tools/a11y_depth.js +455 -0
  242. package/dist/tools/a11y_depth.js.map +1 -0
  243. package/dist/tools/agent.d.ts +15 -0
  244. package/dist/tools/agent.js +248 -0
  245. package/dist/tools/agent.js.map +1 -0
  246. package/dist/tools/batch.d.ts +46 -0
  247. package/dist/tools/batch.js +230 -0
  248. package/dist/tools/batch.js.map +1 -0
  249. package/dist/tools/cdp.d.ts +8 -0
  250. package/dist/tools/cdp.js +233 -0
  251. package/dist/tools/cdp.js.map +1 -0
  252. package/dist/tools/compact.d.ts +63 -0
  253. package/dist/tools/compact.js +418 -0
  254. package/dist/tools/compact.js.map +1 -0
  255. package/dist/tools/cost-class.d.ts +38 -0
  256. package/dist/tools/cost-class.js +117 -0
  257. package/dist/tools/cost-class.js.map +1 -0
  258. package/dist/tools/desktop.d.ts +9 -0
  259. package/dist/tools/desktop.js +346 -0
  260. package/dist/tools/desktop.js.map +1 -0
  261. package/dist/tools/electron_bridge.d.ts +41 -0
  262. package/dist/tools/electron_bridge.js +261 -0
  263. package/dist/tools/electron_bridge.js.map +1 -0
  264. package/dist/tools/extras.d.ts +22 -0
  265. package/dist/tools/extras.js +942 -0
  266. package/dist/tools/extras.js.map +1 -0
  267. package/dist/tools/favorites.d.ts +13 -0
  268. package/dist/tools/favorites.js +137 -0
  269. package/dist/tools/favorites.js.map +1 -0
  270. package/dist/tools/introspection.d.ts +13 -0
  271. package/dist/tools/introspection.js +55 -0
  272. package/dist/tools/introspection.js.map +1 -0
  273. package/dist/tools/ocr.d.ts +8 -0
  274. package/dist/tools/ocr.js +66 -0
  275. package/dist/tools/ocr.js.map +1 -0
  276. package/dist/tools/orchestration.d.ts +7 -0
  277. package/dist/tools/orchestration.js +377 -0
  278. package/dist/tools/orchestration.js.map +1 -0
  279. package/dist/tools/playbooks/extract-compose.d.ts +22 -0
  280. package/dist/tools/playbooks/extract-compose.js +85 -0
  281. package/dist/tools/playbooks/extract-compose.js.map +1 -0
  282. package/dist/tools/playbooks/find-replace.d.ts +11 -0
  283. package/dist/tools/playbooks/find-replace.js +56 -0
  284. package/dist/tools/playbooks/find-replace.js.map +1 -0
  285. package/dist/tools/playbooks/index.d.ts +63 -0
  286. package/dist/tools/playbooks/index.js +70 -0
  287. package/dist/tools/playbooks/index.js.map +1 -0
  288. package/dist/tools/playbooks/keys-blocklist.d.ts +24 -0
  289. package/dist/tools/playbooks/keys-blocklist.js +89 -0
  290. package/dist/tools/playbooks/keys-blocklist.js.map +1 -0
  291. package/dist/tools/registry.d.ts +40 -0
  292. package/dist/tools/registry.js +560 -0
  293. package/dist/tools/registry.js.map +1 -0
  294. package/dist/tools/safety-gate.d.ts +16 -0
  295. package/dist/tools/safety-gate.js +70 -0
  296. package/dist/tools/safety-gate.js.map +1 -0
  297. package/dist/tools/scheduler.d.ts +76 -0
  298. package/dist/tools/scheduler.js +413 -0
  299. package/dist/tools/scheduler.js.map +1 -0
  300. package/dist/tools/shortcuts.d.ts +13 -0
  301. package/dist/tools/shortcuts.js +205 -0
  302. package/dist/tools/shortcuts.js.map +1 -0
  303. package/dist/tools/smart.d.ts +15 -0
  304. package/dist/tools/smart.js +785 -0
  305. package/dist/tools/smart.js.map +1 -0
  306. package/dist/tools/types.d.ts +174 -0
  307. package/dist/tools/types.js +67 -0
  308. package/dist/tools/types.js.map +1 -0
  309. package/dist/tools/window-text.d.ts +15 -0
  310. package/dist/tools/window-text.js +39 -0
  311. package/dist/tools/window-text.js.map +1 -0
  312. package/dist/types.d.ts +122 -0
  313. package/dist/types.js +41 -0
  314. package/dist/types.js.map +1 -0
  315. package/native/Package.swift +38 -0
  316. package/native/README.md +113 -0
  317. package/native/Sources/ClawdCursorHelper/main.swift +602 -0
  318. package/native/Sources/ClawdCursorHost/main.swift +182 -0
  319. package/native/Sources/PermissionCheck/main.swift +53 -0
  320. package/native/Sources/ScreenshotHelper/main.swift +219 -0
  321. package/native/build.sh +139 -0
  322. package/native/entitlements.plist +12 -0
  323. package/package.json +115 -0
  324. package/scripts/banner.ps1 +112 -0
  325. package/scripts/coord-accuracy.ps1 +140 -0
  326. package/scripts/coord-uwp.ps1 +80 -0
  327. package/scripts/edge-glow.ps1 +180 -0
  328. package/scripts/find-element.ps1 +198 -0
  329. package/scripts/get-foreground-window.ps1 +71 -0
  330. package/scripts/get-screen-context.ps1 +183 -0
  331. package/scripts/get-windows.ps1 +66 -0
  332. package/scripts/install-panic-hotkey.ps1 +46 -0
  333. package/scripts/interact-element.ps1 +431 -0
  334. package/scripts/invoke-element.ps1 +314 -0
  335. package/scripts/linux/atspi-bridge.py +356 -0
  336. package/scripts/linux/ocr-recognize.py +154 -0
  337. package/scripts/mac/_window-picker.jxa +163 -0
  338. package/scripts/mac/find-element.jxa +0 -0
  339. package/scripts/mac/find-element.sh +161 -0
  340. package/scripts/mac/focus-window.jxa +284 -0
  341. package/scripts/mac/get-focused-element.jxa +102 -0
  342. package/scripts/mac/get-foreground-window.jxa +173 -0
  343. package/scripts/mac/get-screen-context.jxa +197 -0
  344. package/scripts/mac/get-ui-tree.sh +141 -0
  345. package/scripts/mac/get-windows.jxa +117 -0
  346. package/scripts/mac/interact-element.sh +235 -0
  347. package/scripts/mac/invoke-element.jxa +408 -0
  348. package/scripts/mac/ocr-recognize.swift +124 -0
  349. package/scripts/ocr-recognize.ps1 +102 -0
  350. package/scripts/postinstall-native.js +48 -0
  351. package/scripts/ps-bridge.ps1 +830 -0
  352. package/scripts/smoke-mcp.ps1 +119 -0
  353. package/scripts/sync-version.ts +178 -0
  354. package/scripts/verify-install.js +81 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Single-instance lockfile for `start` / `mcp` / `serve` modes.
3
+ *
4
+ * Prior versions stored a bare integer PID. That format had two failure
5
+ * modes that surfaced as "Failed to reconnect to clawdcursor: -32000" on
6
+ * Windows hosts:
7
+ *
8
+ * 1. PID recycling. process.kill(pid, 0) returns true for *any* live
9
+ * process — including unrelated processes the OS later assigned the
10
+ * original clawdcursor's PID to. The lockfile then permanently looked
11
+ * "live" and refused all future spawns until manually removed.
12
+ *
13
+ * 2. Orphan accumulation. Editor hosts (Claude Code, Cursor, etc.) that
14
+ * crash without reaping their MCP child leave a live but unusable
15
+ * clawdcursor whose PID legitimately matches the lockfile. The host's
16
+ * next reconnect spawns a fresh child, which loses the single-instance
17
+ * race and exits.
18
+ *
19
+ * This module fixes (1) by recording process start time alongside the PID
20
+ * and verifying both before treating a lockfile as live. Recycled PIDs
21
+ * always have a later start time than the original, so the mismatch is
22
+ * unambiguous. Fix (2) lives at the call site — see the stdin-EOF handler
23
+ * in the `mcp` command in cli.ts, which releases the lock and exits when
24
+ * the host parent's stdio pipe closes.
25
+ *
26
+ * Backwards compat: a legacy bare-integer lockfile cannot be verified for
27
+ * identity (no recorded start time), so it is treated as stale and
28
+ * overwritten. First upgrade from a pre-fix version silently discards any
29
+ * old lock — correct behavior since the old format can't be trusted.
30
+ */
31
+ export type LockMode = 'start' | 'mcp' | 'serve';
32
+ interface LockData {
33
+ v: number;
34
+ pid: number;
35
+ startTime: number;
36
+ mode: LockMode;
37
+ }
38
+ export declare function pidFilePath(mode: LockMode): string;
39
+ export declare function isProcessAlive(pid: number): boolean;
40
+ /**
41
+ * Returns the start time of `pid` in ms since the Unix epoch, or null if
42
+ * the process is not running or its start time cannot be determined.
43
+ *
44
+ * Implementation is a one-shot shell-out per call. The lock check runs at
45
+ * most a handful of times across the whole lifetime of a clawdcursor
46
+ * process (startup + sweep), so per-call latency is not a hot path.
47
+ */
48
+ export declare function getProcessStartTime(pid: number): number | null;
49
+ /**
50
+ * Try to read and parse a lockfile. Returns null for any failure (missing,
51
+ * unreadable, unparseable, wrong schema, legacy bare-int format).
52
+ *
53
+ * Exported for tests; callers should use claimPidFile.
54
+ */
55
+ export declare function readLockFile(mode: LockMode): LockData | null;
56
+ /**
57
+ * Try to claim the lockfile for `mode`. Returns:
58
+ * - null if the claim succeeded (no live duplicate, or only a stale /
59
+ * recycled / legacy lockfile was present and has been overwritten).
60
+ * - the live duplicate's pid if a verified clawdcursor of `mode` is
61
+ * already running.
62
+ *
63
+ * Identity is verified by start-time match within START_TIME_TOLERANCE_MS.
64
+ * A bare PID liveness check would be fooled by PID recycling on Windows.
65
+ */
66
+ export declare function claimPidFile(mode: LockMode): number | null;
67
+ /**
68
+ * Release the lockfile for `mode`, but only if it still belongs to this
69
+ * process. Prevents a slow exit from accidentally releasing a successor
70
+ * process's lock.
71
+ */
72
+ export declare function releasePidFile(mode: LockMode): void;
73
+ /**
74
+ * Read just the PID from a lockfile, supporting both the new JSON format
75
+ * and the legacy bare-int format. Used by `clawdcursor stop` to enumerate
76
+ * running instances; callers do their own liveness check afterwards.
77
+ */
78
+ export declare function readPidLoose(mode: LockMode): number | null;
79
+ export {};
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ /**
3
+ * Single-instance lockfile for `start` / `mcp` / `serve` modes.
4
+ *
5
+ * Prior versions stored a bare integer PID. That format had two failure
6
+ * modes that surfaced as "Failed to reconnect to clawdcursor: -32000" on
7
+ * Windows hosts:
8
+ *
9
+ * 1. PID recycling. process.kill(pid, 0) returns true for *any* live
10
+ * process — including unrelated processes the OS later assigned the
11
+ * original clawdcursor's PID to. The lockfile then permanently looked
12
+ * "live" and refused all future spawns until manually removed.
13
+ *
14
+ * 2. Orphan accumulation. Editor hosts (Claude Code, Cursor, etc.) that
15
+ * crash without reaping their MCP child leave a live but unusable
16
+ * clawdcursor whose PID legitimately matches the lockfile. The host's
17
+ * next reconnect spawns a fresh child, which loses the single-instance
18
+ * race and exits.
19
+ *
20
+ * This module fixes (1) by recording process start time alongside the PID
21
+ * and verifying both before treating a lockfile as live. Recycled PIDs
22
+ * always have a later start time than the original, so the mismatch is
23
+ * unambiguous. Fix (2) lives at the call site — see the stdin-EOF handler
24
+ * in the `mcp` command in cli.ts, which releases the lock and exits when
25
+ * the host parent's stdio pipe closes.
26
+ *
27
+ * Backwards compat: a legacy bare-integer lockfile cannot be verified for
28
+ * identity (no recorded start time), so it is treated as stale and
29
+ * overwritten. First upgrade from a pre-fix version silently discards any
30
+ * old lock — correct behavior since the old format can't be trusted.
31
+ */
32
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
33
+ if (k2 === undefined) k2 = k;
34
+ var desc = Object.getOwnPropertyDescriptor(m, k);
35
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
36
+ desc = { enumerable: true, get: function() { return m[k]; } };
37
+ }
38
+ Object.defineProperty(o, k2, desc);
39
+ }) : (function(o, m, k, k2) {
40
+ if (k2 === undefined) k2 = k;
41
+ o[k2] = m[k];
42
+ }));
43
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
44
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
45
+ }) : function(o, v) {
46
+ o["default"] = v;
47
+ });
48
+ var __importStar = (this && this.__importStar) || (function () {
49
+ var ownKeys = function(o) {
50
+ ownKeys = Object.getOwnPropertyNames || function (o) {
51
+ var ar = [];
52
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
53
+ return ar;
54
+ };
55
+ return ownKeys(o);
56
+ };
57
+ return function (mod) {
58
+ if (mod && mod.__esModule) return mod;
59
+ var result = {};
60
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
61
+ __setModuleDefault(result, mod);
62
+ return result;
63
+ };
64
+ })();
65
+ Object.defineProperty(exports, "__esModule", { value: true });
66
+ exports.pidFilePath = pidFilePath;
67
+ exports.isProcessAlive = isProcessAlive;
68
+ exports.getProcessStartTime = getProcessStartTime;
69
+ exports.readLockFile = readLockFile;
70
+ exports.claimPidFile = claimPidFile;
71
+ exports.releasePidFile = releasePidFile;
72
+ exports.readPidLoose = readPidLoose;
73
+ const fs = __importStar(require("fs"));
74
+ const path = __importStar(require("path"));
75
+ const os = __importStar(require("os"));
76
+ const child_process_1 = require("child_process");
77
+ const PID_DIR = path.join(os.homedir(), '.clawdcursor');
78
+ const SCHEMA_VERSION = 1;
79
+ // OS process-start-time precision varies (Linux jiffies ~10ms, ps -o lstart=
80
+ // is second-precise on macOS, Windows CreationDate is ms-precise but coarse
81
+ // when the system clock changes). 5 s comfortably swallows reporting jitter
82
+ // without letting a recycled PID masquerade as the original — anything
83
+ // recycled within a 5 s window is already extraordinarily unlikely.
84
+ const START_TIME_TOLERANCE_MS = 5000;
85
+ function pidFilePath(mode) {
86
+ return path.join(PID_DIR, `${mode}.pid`);
87
+ }
88
+ function isProcessAlive(pid) {
89
+ try {
90
+ process.kill(pid, 0);
91
+ return true;
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ }
97
+ /**
98
+ * Returns the start time of `pid` in ms since the Unix epoch, or null if
99
+ * the process is not running or its start time cannot be determined.
100
+ *
101
+ * Implementation is a one-shot shell-out per call. The lock check runs at
102
+ * most a handful of times across the whole lifetime of a clawdcursor
103
+ * process (startup + sweep), so per-call latency is not a hot path.
104
+ */
105
+ function getProcessStartTime(pid) {
106
+ try {
107
+ if (process.platform === 'win32') {
108
+ // Windows CreationDate is a CIM datetime: yyyymmddHHMMSS.ffffff±UUU.
109
+ // ToFileTimeUtc returns 100-ns ticks since 1601-01-01 UTC; converting
110
+ // to ms-since-epoch is a fixed offset. Going through file time avoids
111
+ // having to parse a CIM-datetime string in JS.
112
+ const out = (0, child_process_1.execFileSync)('powershell', [
113
+ '-NoProfile',
114
+ '-NonInteractive',
115
+ '-ExecutionPolicy', 'Bypass',
116
+ '-Command',
117
+ `try { (Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}' -ErrorAction Stop).CreationDate.ToFileTimeUtc() } catch { '' }`,
118
+ ], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000 }).trim();
119
+ if (!out)
120
+ return null;
121
+ const fileTime = BigInt(out);
122
+ // FileTime epoch (1601-01-01) → Unix epoch (1970-01-01) = 11644473600 s
123
+ // = 116444736000000000 100-ns ticks. Each 10000 ticks is 1 ms.
124
+ const epochMs = Number((fileTime - 116444736000000000n) / 10000n);
125
+ return Number.isFinite(epochMs) && epochMs > 0 ? epochMs : null;
126
+ }
127
+ // POSIX: `ps -o lstart= -p <pid>` returns a single-line locale-formatted
128
+ // date like "Thu May 15 18:31:25 2026" with no trailing newline issues.
129
+ // Date.parse handles this format on every platform Node ships on.
130
+ const out = (0, child_process_1.execFileSync)('ps', ['-o', 'lstart=', '-p', String(pid)], {
131
+ encoding: 'utf-8',
132
+ stdio: ['ignore', 'pipe', 'ignore'],
133
+ timeout: 5000,
134
+ }).trim();
135
+ if (!out)
136
+ return null;
137
+ const t = Date.parse(out);
138
+ return Number.isFinite(t) ? t : null;
139
+ }
140
+ catch {
141
+ return null;
142
+ }
143
+ }
144
+ /**
145
+ * Try to read and parse a lockfile. Returns null for any failure (missing,
146
+ * unreadable, unparseable, wrong schema, legacy bare-int format).
147
+ *
148
+ * Exported for tests; callers should use claimPidFile.
149
+ */
150
+ function readLockFile(mode) {
151
+ try {
152
+ const raw = fs.readFileSync(pidFilePath(mode), 'utf-8').trim();
153
+ if (!raw)
154
+ return null;
155
+ // Legacy bare-int format from pre-fix versions. We can't verify identity
156
+ // from this alone, so callers treat it as stale and overwrite.
157
+ if (/^\d+$/.test(raw))
158
+ return null;
159
+ const parsed = JSON.parse(raw);
160
+ if (parsed &&
161
+ parsed.v === SCHEMA_VERSION &&
162
+ typeof parsed.pid === 'number' &&
163
+ typeof parsed.startTime === 'number' &&
164
+ (parsed.mode === 'start' || parsed.mode === 'mcp' || parsed.mode === 'serve')) {
165
+ return parsed;
166
+ }
167
+ return null;
168
+ }
169
+ catch {
170
+ return null;
171
+ }
172
+ }
173
+ /**
174
+ * Try to claim the lockfile for `mode`. Returns:
175
+ * - null if the claim succeeded (no live duplicate, or only a stale /
176
+ * recycled / legacy lockfile was present and has been overwritten).
177
+ * - the live duplicate's pid if a verified clawdcursor of `mode` is
178
+ * already running.
179
+ *
180
+ * Identity is verified by start-time match within START_TIME_TOLERANCE_MS.
181
+ * A bare PID liveness check would be fooled by PID recycling on Windows.
182
+ */
183
+ function claimPidFile(mode) {
184
+ try {
185
+ if (!fs.existsSync(PID_DIR))
186
+ fs.mkdirSync(PID_DIR, { recursive: true });
187
+ const existing = readLockFile(mode);
188
+ if (existing && existing.pid !== process.pid && isProcessAlive(existing.pid)) {
189
+ const actualStart = getProcessStartTime(existing.pid);
190
+ if (actualStart !== null &&
191
+ Math.abs(actualStart - existing.startTime) <= START_TIME_TOLERANCE_MS) {
192
+ // Same PID, same start time — this is a real live duplicate.
193
+ return existing.pid;
194
+ }
195
+ // PID is alive but doesn't match the recorded start time, OR the
196
+ // start time can't be determined — either way the lockfile no longer
197
+ // points to the original process. Fall through and overwrite.
198
+ }
199
+ const ourStart = Date.now() - Math.floor(process.uptime() * 1000);
200
+ const data = {
201
+ v: SCHEMA_VERSION,
202
+ pid: process.pid,
203
+ startTime: ourStart,
204
+ mode,
205
+ };
206
+ fs.writeFileSync(pidFilePath(mode), JSON.stringify(data), {
207
+ encoding: 'utf-8',
208
+ mode: 0o600,
209
+ });
210
+ return null;
211
+ }
212
+ catch {
213
+ // Lock is best-effort. A filesystem error here should not block the
214
+ // process from starting — the worst case (no single-instance guard)
215
+ // is what users had before this guard existed.
216
+ return null;
217
+ }
218
+ }
219
+ /**
220
+ * Release the lockfile for `mode`, but only if it still belongs to this
221
+ * process. Prevents a slow exit from accidentally releasing a successor
222
+ * process's lock.
223
+ */
224
+ function releasePidFile(mode) {
225
+ try {
226
+ const lock = readLockFile(mode);
227
+ if (lock && lock.pid === process.pid) {
228
+ fs.unlinkSync(pidFilePath(mode));
229
+ return;
230
+ }
231
+ // Legacy bare-int format also belongs to nobody we can verify — fall
232
+ // back to the old behavior of unlinking if the int matches our PID.
233
+ const raw = fs.readFileSync(pidFilePath(mode), 'utf-8').trim();
234
+ if (/^\d+$/.test(raw) && parseInt(raw, 10) === process.pid) {
235
+ fs.unlinkSync(pidFilePath(mode));
236
+ }
237
+ }
238
+ catch {
239
+ // Non-fatal. A leftover lockfile will be reclaimed by the next claim.
240
+ }
241
+ }
242
+ /**
243
+ * Read just the PID from a lockfile, supporting both the new JSON format
244
+ * and the legacy bare-int format. Used by `clawdcursor stop` to enumerate
245
+ * running instances; callers do their own liveness check afterwards.
246
+ */
247
+ function readPidLoose(mode) {
248
+ try {
249
+ const raw = fs.readFileSync(pidFilePath(mode), 'utf-8').trim();
250
+ if (!raw)
251
+ return null;
252
+ if (/^\d+$/.test(raw)) {
253
+ const n = parseInt(raw, 10);
254
+ return Number.isFinite(n) ? n : null;
255
+ }
256
+ const parsed = JSON.parse(raw);
257
+ return typeof parsed?.pid === 'number' ? parsed.pid : null;
258
+ }
259
+ catch {
260
+ return null;
261
+ }
262
+ }
263
+ //# sourceMappingURL=pidfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pidfile.js","sourceRoot":"","sources":["../../src/surface/pidfile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Readiness — single source of truth for Clawd Cursor operational status.
3
+ *
4
+ * Consolidates:
5
+ * - Consent status
6
+ * - macOS permissions (Accessibility, Screen Recording)
7
+ * - AI provider configuration
8
+ * - Overall readiness for desktop control
9
+ */
10
+ export interface ReadinessStatus {
11
+ consent: {
12
+ granted: boolean;
13
+ file: string;
14
+ };
15
+ macPermissions: {
16
+ accessibility: boolean;
17
+ screenRecording: boolean;
18
+ } | null;
19
+ aiConfig: {
20
+ configured: boolean;
21
+ configFile: string;
22
+ hasTextModel: boolean;
23
+ hasVisionModel: boolean;
24
+ };
25
+ ready: boolean;
26
+ readyForDesktopControl: boolean;
27
+ issues: string[];
28
+ nextSteps: string[];
29
+ }
30
+ /**
31
+ * Get full readiness status — the single source of truth.
32
+ */
33
+ export declare function getReadinessStatus(): Promise<ReadinessStatus>;
34
+ /**
35
+ * Print a formatted status report to console.
36
+ */
37
+ export declare function printStatusReport(): Promise<void>;
38
+ /**
39
+ * Quick check if basic requirements are met (for gating commands).
40
+ */
41
+ export declare function isReadyForDesktopControl(): Promise<boolean>;
42
+ /**
43
+ * Get a one-line summary suitable for doctor output.
44
+ */
45
+ export declare function getReadinessSummary(): Promise<string>;
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ /**
3
+ * Readiness — single source of truth for Clawd Cursor operational status.
4
+ *
5
+ * Consolidates:
6
+ * - Consent status
7
+ * - macOS permissions (Accessibility, Screen Recording)
8
+ * - AI provider configuration
9
+ * - Overall readiness for desktop control
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.getReadinessStatus = getReadinessStatus;
49
+ exports.printStatusReport = printStatusReport;
50
+ exports.isReadyForDesktopControl = isReadyForDesktopControl;
51
+ exports.getReadinessSummary = getReadinessSummary;
52
+ const fs = __importStar(require("fs"));
53
+ const path = __importStar(require("path"));
54
+ const os = __importStar(require("os"));
55
+ const picocolors_1 = __importDefault(require("picocolors"));
56
+ const onboarding_1 = require("./onboarding");
57
+ const native_helper_1 = require("../platform/native-helper");
58
+ const paths_1 = require("../paths");
59
+ const CONFIG_FILE = '.clawdcursor-config.json';
60
+ /**
61
+ * Check if AI config exists and has models configured
62
+ */
63
+ function getCandidateConfigPaths() {
64
+ const candidates = [
65
+ path.join(process.cwd(), CONFIG_FILE),
66
+ path.join(os.homedir(), 'clawdcursor', CONFIG_FILE),
67
+ path.join((0, paths_1.getPackageRoot)(), CONFIG_FILE),
68
+ ];
69
+ return Array.from(new Set(candidates));
70
+ }
71
+ function checkAiConfig() {
72
+ const configPath = getCandidateConfigPaths().find(p => fs.existsSync(p));
73
+ if (!configPath) {
74
+ return { configured: false, hasTextModel: false, hasVisionModel: false, configFile: getCandidateConfigPaths()[0] };
75
+ }
76
+ try {
77
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
78
+ const textLayer = config.pipeline?.textModel ?? config.pipeline?.layer2;
79
+ const visionLayer = config.pipeline?.visionModel ?? config.pipeline?.layer3;
80
+ const hasTextModel = !!(textLayer?.model || config.textModel || config.layer2?.model);
81
+ const hasVisionModel = !!(visionLayer?.model || config.visionModel || config.layer3?.model);
82
+ return { configured: true, hasTextModel, hasVisionModel, configFile: configPath };
83
+ }
84
+ catch {
85
+ return { configured: false, hasTextModel: false, hasVisionModel: false, configFile: configPath };
86
+ }
87
+ }
88
+ /**
89
+ * Get full readiness status — the single source of truth.
90
+ */
91
+ async function getReadinessStatus() {
92
+ const consentDir = path.join(os.homedir(), '.clawdcursor');
93
+ const consentFile = path.join(consentDir, 'consent');
94
+ const configFile = getCandidateConfigPaths()[0];
95
+ // Check consent
96
+ const consentGranted = (0, onboarding_1.hasConsent)();
97
+ // Check macOS permissions (only on macOS)
98
+ let macPermissions = null;
99
+ if ((0, native_helper_1.isMacOS)()) {
100
+ try {
101
+ const perms = await (0, native_helper_1.checkPermissionsQuick)();
102
+ macPermissions = {
103
+ accessibility: perms.accessibility,
104
+ screenRecording: perms.screenRecording,
105
+ };
106
+ }
107
+ catch {
108
+ // If native helper isn't built yet, assume unknown
109
+ macPermissions = {
110
+ accessibility: false,
111
+ screenRecording: false,
112
+ };
113
+ }
114
+ }
115
+ // Check AI config
116
+ const aiConfig = checkAiConfig();
117
+ // Determine issues and next steps
118
+ const issues = [];
119
+ const nextSteps = [];
120
+ if (!consentGranted) {
121
+ issues.push('Desktop control consent not granted');
122
+ nextSteps.push('Run: clawdcursor consent');
123
+ }
124
+ if ((0, native_helper_1.isMacOS)() && macPermissions) {
125
+ if (!macPermissions.accessibility) {
126
+ issues.push('macOS Accessibility permission not granted');
127
+ nextSteps.push('System Settings → Privacy & Security → Accessibility → Enable ClawdCursor');
128
+ }
129
+ if (!macPermissions.screenRecording) {
130
+ issues.push('macOS Screen Recording permission not granted');
131
+ nextSteps.push('System Settings → Privacy & Security → Screen & System Audio Recording → Enable ClawdCursor');
132
+ }
133
+ }
134
+ if (!aiConfig.configured) {
135
+ issues.push('AI provider not configured');
136
+ nextSteps.push('Run: clawdcursor doctor');
137
+ }
138
+ else if (!aiConfig.hasTextModel && !aiConfig.hasVisionModel) {
139
+ issues.push('No AI models configured');
140
+ nextSteps.push('Run: clawdcursor doctor');
141
+ }
142
+ // Determine overall readiness
143
+ const hasRequiredPermissions = !(0, native_helper_1.isMacOS)() || (macPermissions?.accessibility ?? false);
144
+ const readyForDesktopControl = consentGranted && hasRequiredPermissions;
145
+ const ready = readyForDesktopControl && aiConfig.configured;
146
+ return {
147
+ consent: {
148
+ granted: consentGranted,
149
+ file: consentFile,
150
+ },
151
+ macPermissions,
152
+ aiConfig: {
153
+ ...aiConfig,
154
+ configFile: aiConfig.configFile || configFile,
155
+ },
156
+ ready,
157
+ readyForDesktopControl,
158
+ issues,
159
+ nextSteps,
160
+ };
161
+ }
162
+ /**
163
+ * Print a formatted status report to console.
164
+ */
165
+ async function printStatusReport() {
166
+ const status = await getReadinessStatus();
167
+ const check = (ok) => ok ? picocolors_1.default.green('✓') : picocolors_1.default.red('✗');
168
+ const warn = (ok) => ok ? picocolors_1.default.green('✓') : picocolors_1.default.yellow('⚠');
169
+ console.log(`\n${picocolors_1.default.bold('🐾 Clawd Cursor Status')}\n`);
170
+ console.log(picocolors_1.default.gray('─'.repeat(50)));
171
+ // Consent
172
+ console.log(`${check(status.consent.granted)} Consent: ${status.consent.granted ? 'Granted' : 'Not granted'}`);
173
+ // macOS Permissions
174
+ if (status.macPermissions) {
175
+ console.log(`${check(status.macPermissions.accessibility)} Accessibility: ${status.macPermissions.accessibility ? 'Granted' : 'Not granted'}`);
176
+ console.log(`${warn(status.macPermissions.screenRecording)} Screen Recording: ${status.macPermissions.screenRecording ? 'Granted' : 'Not granted'} ${!status.macPermissions.screenRecording ? picocolors_1.default.gray('(optional)') : ''}`);
177
+ }
178
+ else if (process.platform !== 'darwin') {
179
+ console.log(`${picocolors_1.default.green('✓')} Platform: ${process.platform} ${picocolors_1.default.gray('(no special permissions needed)')}`);
180
+ }
181
+ // AI Config
182
+ console.log(`${check(status.aiConfig.configured)} AI Config: ${status.aiConfig.configured ? 'Found' : 'Not configured'}`);
183
+ if (status.aiConfig.configured) {
184
+ console.log(` ${check(status.aiConfig.hasTextModel)} Text model: ${status.aiConfig.hasTextModel ? 'Configured' : 'Not set'}`);
185
+ console.log(` ${warn(status.aiConfig.hasVisionModel)} Vision model: ${status.aiConfig.hasVisionModel ? 'Configured' : 'Not set'} ${!status.aiConfig.hasVisionModel ? picocolors_1.default.gray('(optional)') : ''}`);
186
+ }
187
+ console.log(picocolors_1.default.gray('─'.repeat(50)));
188
+ // Overall Status
189
+ if (status.ready) {
190
+ console.log(`\n${picocolors_1.default.green(picocolors_1.default.bold('✓ Ready for desktop control'))}\n`);
191
+ }
192
+ else if (status.readyForDesktopControl) {
193
+ console.log(`\n${picocolors_1.default.yellow(picocolors_1.default.bold('⚠ Desktop control ready, but AI not configured'))}`);
194
+ console.log(` Layer 1 (Action Router) will work without AI.\n`);
195
+ }
196
+ else {
197
+ console.log(`\n${picocolors_1.default.red(picocolors_1.default.bold('✗ Not ready for desktop control'))}\n`);
198
+ }
199
+ // Next Steps
200
+ if (status.nextSteps.length > 0) {
201
+ console.log(picocolors_1.default.bold('Next steps:'));
202
+ status.nextSteps.forEach((step, i) => {
203
+ console.log(` ${i + 1}. ${step}`);
204
+ });
205
+ console.log('');
206
+ }
207
+ }
208
+ /**
209
+ * Quick check if basic requirements are met (for gating commands).
210
+ */
211
+ async function isReadyForDesktopControl() {
212
+ const status = await getReadinessStatus();
213
+ return status.readyForDesktopControl;
214
+ }
215
+ /**
216
+ * Get a one-line summary suitable for doctor output.
217
+ */
218
+ async function getReadinessSummary() {
219
+ const status = await getReadinessStatus();
220
+ if (status.ready) {
221
+ return '✓ All systems ready';
222
+ }
223
+ else if (status.readyForDesktopControl) {
224
+ return '⚠ Desktop ready, AI not configured';
225
+ }
226
+ else {
227
+ return `✗ ${status.issues.length} issue(s): ${status.issues.slice(0, 2).join(', ')}`;
228
+ }
229
+ }
230
+ //# sourceMappingURL=readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../src/surface/readiness.ts"],"names":[],"mappings":"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"}