@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.
- package/CHANGELOG.md +2264 -0
- package/LICENSE +21 -0
- package/README.md +385 -0
- package/SECURITY.md +44 -0
- package/SKILL.md +503 -0
- package/dist/core/agent-loop/agent.d.ts +42 -0
- package/dist/core/agent-loop/agent.js +1023 -0
- package/dist/core/agent-loop/agent.js.map +1 -0
- package/dist/core/agent-loop/batch-tool.d.ts +25 -0
- package/dist/core/agent-loop/batch-tool.js +218 -0
- package/dist/core/agent-loop/batch-tool.js.map +1 -0
- package/dist/core/agent-loop/coord-scale.d.ts +72 -0
- package/dist/core/agent-loop/coord-scale.js +89 -0
- package/dist/core/agent-loop/coord-scale.js.map +1 -0
- package/dist/core/agent-loop/focus-guard.d.ts +24 -0
- package/dist/core/agent-loop/focus-guard.js +29 -0
- package/dist/core/agent-loop/focus-guard.js.map +1 -0
- package/dist/core/agent-loop/project-mcp.d.ts +97 -0
- package/dist/core/agent-loop/project-mcp.js +253 -0
- package/dist/core/agent-loop/project-mcp.js.map +1 -0
- package/dist/core/agent-loop/prompt.d.ts +45 -0
- package/dist/core/agent-loop/prompt.js +426 -0
- package/dist/core/agent-loop/prompt.js.map +1 -0
- package/dist/core/agent-loop/tool-meta.d.ts +93 -0
- package/dist/core/agent-loop/tool-meta.js +651 -0
- package/dist/core/agent-loop/tool-meta.js.map +1 -0
- package/dist/core/agent-loop/tools.d.ts +38 -0
- package/dist/core/agent-loop/tools.js +2134 -0
- package/dist/core/agent-loop/tools.js.map +1 -0
- package/dist/core/agent-loop/types.d.ts +170 -0
- package/dist/core/agent-loop/types.js +12 -0
- package/dist/core/agent-loop/types.js.map +1 -0
- package/dist/core/agent.d.ts +51 -0
- package/dist/core/agent.js +245 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/app-categories.d.ts +67 -0
- package/dist/core/app-categories.js +108 -0
- package/dist/core/app-categories.js.map +1 -0
- package/dist/core/banner.d.ts +70 -0
- package/dist/core/banner.js +245 -0
- package/dist/core/banner.js.map +1 -0
- package/dist/core/classify/capability.d.ts +45 -0
- package/dist/core/classify/capability.js +78 -0
- package/dist/core/classify/capability.js.map +1 -0
- package/dist/core/decompose/llm-decomposer.d.ts +35 -0
- package/dist/core/decompose/llm-decomposer.js +156 -0
- package/dist/core/decompose/llm-decomposer.js.map +1 -0
- package/dist/core/decompose/parser.d.ts +27 -0
- package/dist/core/decompose/parser.js +101 -0
- package/dist/core/decompose/parser.js.map +1 -0
- package/dist/core/observability/correlation.d.ts +19 -0
- package/dist/core/observability/correlation.js +36 -0
- package/dist/core/observability/correlation.js.map +1 -0
- package/dist/core/observability/cost-meter.d.ts +51 -0
- package/dist/core/observability/cost-meter.js +134 -0
- package/dist/core/observability/cost-meter.js.map +1 -0
- package/dist/core/observability/logger.d.ts +61 -0
- package/dist/core/observability/logger.js +550 -0
- package/dist/core/observability/logger.js.map +1 -0
- package/dist/core/router/aliases.d.ts +50 -0
- package/dist/core/router/aliases.js +104 -0
- package/dist/core/router/aliases.js.map +1 -0
- package/dist/core/router/normalize.d.ts +41 -0
- package/dist/core/router/normalize.js +80 -0
- package/dist/core/router/normalize.js.map +1 -0
- package/dist/core/safety.d.ts +126 -0
- package/dist/core/safety.js +568 -0
- package/dist/core/safety.js.map +1 -0
- package/dist/core/sense/a11y-resolver.d.ts +73 -0
- package/dist/core/sense/a11y-resolver.js +76 -0
- package/dist/core/sense/a11y-resolver.js.map +1 -0
- package/dist/core/sense/fingerprint.d.ts +41 -0
- package/dist/core/sense/fingerprint.js +123 -0
- package/dist/core/sense/fingerprint.js.map +1 -0
- package/dist/core/sense/rank.d.ts +70 -0
- package/dist/core/sense/rank.js +192 -0
- package/dist/core/sense/rank.js.map +1 -0
- package/dist/core/sense/reactive-check.d.ts +40 -0
- package/dist/core/sense/reactive-check.js +48 -0
- package/dist/core/sense/reactive-check.js.map +1 -0
- package/dist/core/sense/snapshot.d.ts +19 -0
- package/dist/core/sense/snapshot.js +100 -0
- package/dist/core/sense/snapshot.js.map +1 -0
- package/dist/core/sense/types.d.ts +66 -0
- package/dist/core/sense/types.js +9 -0
- package/dist/core/sense/types.js.map +1 -0
- package/dist/core/sense/ui-map-anchors.d.ts +7 -0
- package/dist/core/sense/ui-map-anchors.js +24 -0
- package/dist/core/sense/ui-map-anchors.js.map +1 -0
- package/dist/core/sense/ui-map-elements.d.ts +5 -0
- package/dist/core/sense/ui-map-elements.js +33 -0
- package/dist/core/sense/ui-map-elements.js.map +1 -0
- package/dist/core/sense/ui-map-find.d.ts +56 -0
- package/dist/core/sense/ui-map-find.js +153 -0
- package/dist/core/sense/ui-map-find.js.map +1 -0
- package/dist/core/sense/ui-map-fuse.d.ts +4 -0
- package/dist/core/sense/ui-map-fuse.js +44 -0
- package/dist/core/sense/ui-map-fuse.js.map +1 -0
- package/dist/core/sense/ui-map-geom.d.ts +3 -0
- package/dist/core/sense/ui-map-geom.js +16 -0
- package/dist/core/sense/ui-map-geom.js.map +1 -0
- package/dist/core/sense/ui-map-holder.d.ts +58 -0
- package/dist/core/sense/ui-map-holder.js +87 -0
- package/dist/core/sense/ui-map-holder.js.map +1 -0
- package/dist/core/sense/ui-map-normalize.d.ts +19 -0
- package/dist/core/sense/ui-map-normalize.js +65 -0
- package/dist/core/sense/ui-map-normalize.js.map +1 -0
- package/dist/core/sense/ui-map-render.d.ts +4 -0
- package/dist/core/sense/ui-map-render.js +34 -0
- package/dist/core/sense/ui-map-render.js.map +1 -0
- package/dist/core/sense/ui-map-resolve.d.ts +41 -0
- package/dist/core/sense/ui-map-resolve.js +59 -0
- package/dist/core/sense/ui-map-resolve.js.map +1 -0
- package/dist/core/sense/ui-map-types.d.ts +66 -0
- package/dist/core/sense/ui-map-types.js +11 -0
- package/dist/core/sense/ui-map-types.js.map +1 -0
- package/dist/core/sense/ui-map.d.ts +29 -0
- package/dist/core/sense/ui-map.js +113 -0
- package/dist/core/sense/ui-map.js.map +1 -0
- package/dist/core/verify/assertions.d.ts +132 -0
- package/dist/core/verify/assertions.js +284 -0
- package/dist/core/verify/assertions.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/browser-config.d.ts +36 -0
- package/dist/llm/browser-config.js +83 -0
- package/dist/llm/browser-config.js.map +1 -0
- package/dist/llm/client.d.ts +268 -0
- package/dist/llm/client.js +1094 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/config.d.ts +79 -0
- package/dist/llm/config.js +375 -0
- package/dist/llm/config.js.map +1 -0
- package/dist/llm/credentials.d.ts +35 -0
- package/dist/llm/credentials.js +491 -0
- package/dist/llm/credentials.js.map +1 -0
- package/dist/llm/external-creds.d.ts +42 -0
- package/dist/llm/external-creds.js +169 -0
- package/dist/llm/external-creds.js.map +1 -0
- package/dist/llm/providers.d.ts +123 -0
- package/dist/llm/providers.js +717 -0
- package/dist/llm/providers.js.map +1 -0
- package/dist/paths.d.ts +31 -0
- package/dist/paths.js +147 -0
- package/dist/paths.js.map +1 -0
- package/dist/platform/accessibility.d.ts +139 -0
- package/dist/platform/accessibility.js +670 -0
- package/dist/platform/accessibility.js.map +1 -0
- package/dist/platform/cdp-driver.d.ts +318 -0
- package/dist/platform/cdp-driver.js +1179 -0
- package/dist/platform/cdp-driver.js.map +1 -0
- package/dist/platform/index.d.ts +11 -0
- package/dist/platform/index.js +69 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/keys.d.ts +17 -0
- package/dist/platform/keys.js +129 -0
- package/dist/platform/keys.js.map +1 -0
- package/dist/platform/launch-poll.d.ts +101 -0
- package/dist/platform/launch-poll.js +177 -0
- package/dist/platform/launch-poll.js.map +1 -0
- package/dist/platform/linux.d.ts +173 -0
- package/dist/platform/linux.js +1253 -0
- package/dist/platform/linux.js.map +1 -0
- package/dist/platform/macos.d.ts +136 -0
- package/dist/platform/macos.js +976 -0
- package/dist/platform/macos.js.map +1 -0
- package/dist/platform/native-desktop.d.ts +145 -0
- package/dist/platform/native-desktop.js +936 -0
- package/dist/platform/native-desktop.js.map +1 -0
- package/dist/platform/native-helper.d.ts +130 -0
- package/dist/platform/native-helper.js +592 -0
- package/dist/platform/native-helper.js.map +1 -0
- package/dist/platform/ocr-engine.d.ts +78 -0
- package/dist/platform/ocr-engine.js +363 -0
- package/dist/platform/ocr-engine.js.map +1 -0
- package/dist/platform/ps-runner.d.ts +28 -0
- package/dist/platform/ps-runner.js +228 -0
- package/dist/platform/ps-runner.js.map +1 -0
- package/dist/platform/types.d.ts +397 -0
- package/dist/platform/types.js +15 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/platform/uri-handler.d.ts +75 -0
- package/dist/platform/uri-handler.js +273 -0
- package/dist/platform/uri-handler.js.map +1 -0
- package/dist/platform/wayland-backend.d.ts +53 -0
- package/dist/platform/wayland-backend.js +348 -0
- package/dist/platform/wayland-backend.js.map +1 -0
- package/dist/platform/windows.d.ts +232 -0
- package/dist/platform/windows.js +1210 -0
- package/dist/platform/windows.js.map +1 -0
- package/dist/postbuild.d.ts +10 -0
- package/dist/postbuild.js +98 -0
- package/dist/postbuild.js.map +1 -0
- package/dist/schema/snapshot.d.ts +33 -0
- package/dist/schema/snapshot.js +90 -0
- package/dist/schema/snapshot.js.map +1 -0
- package/dist/shortcuts.d.ts +30 -0
- package/dist/shortcuts.js +261 -0
- package/dist/shortcuts.js.map +1 -0
- package/dist/surface/cli.d.ts +7 -0
- package/dist/surface/cli.js +1556 -0
- package/dist/surface/cli.js.map +1 -0
- package/dist/surface/dashboard.d.ts +8 -0
- package/dist/surface/dashboard.js +1193 -0
- package/dist/surface/dashboard.js.map +1 -0
- package/dist/surface/doctor.d.ts +29 -0
- package/dist/surface/doctor.js +1514 -0
- package/dist/surface/doctor.js.map +1 -0
- package/dist/surface/format.d.ts +10 -0
- package/dist/surface/format.js +37 -0
- package/dist/surface/format.js.map +1 -0
- package/dist/surface/http-utility.d.ts +65 -0
- package/dist/surface/http-utility.js +336 -0
- package/dist/surface/http-utility.js.map +1 -0
- package/dist/surface/mcp-server.d.ts +91 -0
- package/dist/surface/mcp-server.js +280 -0
- package/dist/surface/mcp-server.js.map +1 -0
- package/dist/surface/onboarding.d.ts +15 -0
- package/dist/surface/onboarding.js +184 -0
- package/dist/surface/onboarding.js.map +1 -0
- package/dist/surface/pidfile.d.ts +79 -0
- package/dist/surface/pidfile.js +263 -0
- package/dist/surface/pidfile.js.map +1 -0
- package/dist/surface/readiness.d.ts +45 -0
- package/dist/surface/readiness.js +230 -0
- package/dist/surface/readiness.js.map +1 -0
- package/dist/surface/report.d.ts +68 -0
- package/dist/surface/report.js +341 -0
- package/dist/surface/report.js.map +1 -0
- package/dist/surface/skill-register.d.ts +14 -0
- package/dist/surface/skill-register.js +150 -0
- package/dist/surface/skill-register.js.map +1 -0
- package/dist/surface/version.d.ts +6 -0
- package/dist/surface/version.js +27 -0
- package/dist/surface/version.js.map +1 -0
- package/dist/tools/a11y.d.ts +8 -0
- package/dist/tools/a11y.js +545 -0
- package/dist/tools/a11y.js.map +1 -0
- package/dist/tools/a11y_depth.d.ts +19 -0
- package/dist/tools/a11y_depth.js +455 -0
- package/dist/tools/a11y_depth.js.map +1 -0
- package/dist/tools/agent.d.ts +15 -0
- package/dist/tools/agent.js +248 -0
- package/dist/tools/agent.js.map +1 -0
- package/dist/tools/batch.d.ts +46 -0
- package/dist/tools/batch.js +230 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cdp.d.ts +8 -0
- package/dist/tools/cdp.js +233 -0
- package/dist/tools/cdp.js.map +1 -0
- package/dist/tools/compact.d.ts +63 -0
- package/dist/tools/compact.js +418 -0
- package/dist/tools/compact.js.map +1 -0
- package/dist/tools/cost-class.d.ts +38 -0
- package/dist/tools/cost-class.js +117 -0
- package/dist/tools/cost-class.js.map +1 -0
- package/dist/tools/desktop.d.ts +9 -0
- package/dist/tools/desktop.js +346 -0
- package/dist/tools/desktop.js.map +1 -0
- package/dist/tools/electron_bridge.d.ts +41 -0
- package/dist/tools/electron_bridge.js +261 -0
- package/dist/tools/electron_bridge.js.map +1 -0
- package/dist/tools/extras.d.ts +22 -0
- package/dist/tools/extras.js +942 -0
- package/dist/tools/extras.js.map +1 -0
- package/dist/tools/favorites.d.ts +13 -0
- package/dist/tools/favorites.js +137 -0
- package/dist/tools/favorites.js.map +1 -0
- package/dist/tools/introspection.d.ts +13 -0
- package/dist/tools/introspection.js +55 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/tools/ocr.d.ts +8 -0
- package/dist/tools/ocr.js +66 -0
- package/dist/tools/ocr.js.map +1 -0
- package/dist/tools/orchestration.d.ts +7 -0
- package/dist/tools/orchestration.js +377 -0
- package/dist/tools/orchestration.js.map +1 -0
- package/dist/tools/playbooks/extract-compose.d.ts +22 -0
- package/dist/tools/playbooks/extract-compose.js +85 -0
- package/dist/tools/playbooks/extract-compose.js.map +1 -0
- package/dist/tools/playbooks/find-replace.d.ts +11 -0
- package/dist/tools/playbooks/find-replace.js +56 -0
- package/dist/tools/playbooks/find-replace.js.map +1 -0
- package/dist/tools/playbooks/index.d.ts +63 -0
- package/dist/tools/playbooks/index.js +70 -0
- package/dist/tools/playbooks/index.js.map +1 -0
- package/dist/tools/playbooks/keys-blocklist.d.ts +24 -0
- package/dist/tools/playbooks/keys-blocklist.js +89 -0
- package/dist/tools/playbooks/keys-blocklist.js.map +1 -0
- package/dist/tools/registry.d.ts +40 -0
- package/dist/tools/registry.js +560 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/safety-gate.d.ts +16 -0
- package/dist/tools/safety-gate.js +70 -0
- package/dist/tools/safety-gate.js.map +1 -0
- package/dist/tools/scheduler.d.ts +76 -0
- package/dist/tools/scheduler.js +413 -0
- package/dist/tools/scheduler.js.map +1 -0
- package/dist/tools/shortcuts.d.ts +13 -0
- package/dist/tools/shortcuts.js +205 -0
- package/dist/tools/shortcuts.js.map +1 -0
- package/dist/tools/smart.d.ts +15 -0
- package/dist/tools/smart.js +785 -0
- package/dist/tools/smart.js.map +1 -0
- package/dist/tools/types.d.ts +174 -0
- package/dist/tools/types.js +67 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/window-text.d.ts +15 -0
- package/dist/tools/window-text.js +39 -0
- package/dist/tools/window-text.js.map +1 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.js +41 -0
- package/dist/types.js.map +1 -0
- package/native/Package.swift +38 -0
- package/native/README.md +113 -0
- package/native/Sources/ClawdCursorHelper/main.swift +602 -0
- package/native/Sources/ClawdCursorHost/main.swift +182 -0
- package/native/Sources/PermissionCheck/main.swift +53 -0
- package/native/Sources/ScreenshotHelper/main.swift +219 -0
- package/native/build.sh +139 -0
- package/native/entitlements.plist +12 -0
- package/package.json +115 -0
- package/scripts/banner.ps1 +112 -0
- package/scripts/coord-accuracy.ps1 +140 -0
- package/scripts/coord-uwp.ps1 +80 -0
- package/scripts/edge-glow.ps1 +180 -0
- package/scripts/find-element.ps1 +198 -0
- package/scripts/get-foreground-window.ps1 +71 -0
- package/scripts/get-screen-context.ps1 +183 -0
- package/scripts/get-windows.ps1 +66 -0
- package/scripts/install-panic-hotkey.ps1 +46 -0
- package/scripts/interact-element.ps1 +431 -0
- package/scripts/invoke-element.ps1 +314 -0
- package/scripts/linux/atspi-bridge.py +356 -0
- package/scripts/linux/ocr-recognize.py +154 -0
- package/scripts/mac/_window-picker.jxa +163 -0
- package/scripts/mac/find-element.jxa +0 -0
- package/scripts/mac/find-element.sh +161 -0
- package/scripts/mac/focus-window.jxa +284 -0
- package/scripts/mac/get-focused-element.jxa +102 -0
- package/scripts/mac/get-foreground-window.jxa +173 -0
- package/scripts/mac/get-screen-context.jxa +197 -0
- package/scripts/mac/get-ui-tree.sh +141 -0
- package/scripts/mac/get-windows.jxa +117 -0
- package/scripts/mac/interact-element.sh +235 -0
- package/scripts/mac/invoke-element.jxa +408 -0
- package/scripts/mac/ocr-recognize.swift +124 -0
- package/scripts/ocr-recognize.ps1 +102 -0
- package/scripts/postinstall-native.js +48 -0
- package/scripts/ps-bridge.ps1 +830 -0
- package/scripts/smoke-mcp.ps1 +119 -0
- package/scripts/sync-version.ts +178 -0
- 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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"}
|