claw-design 1.0.1

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +72 -0
  3. package/dist/cli/commands/start.d.ts +7 -0
  4. package/dist/cli/commands/start.d.ts.map +1 -0
  5. package/dist/cli/commands/start.js +176 -0
  6. package/dist/cli/commands/start.js.map +1 -0
  7. package/dist/cli/index.d.ts +3 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +20 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/utils/claude.d.ts +21 -0
  12. package/dist/cli/utils/claude.d.ts.map +1 -0
  13. package/dist/cli/utils/claude.js +42 -0
  14. package/dist/cli/utils/claude.js.map +1 -0
  15. package/dist/cli/utils/dev-server.d.ts +14 -0
  16. package/dist/cli/utils/dev-server.d.ts.map +1 -0
  17. package/dist/cli/utils/dev-server.js +57 -0
  18. package/dist/cli/utils/dev-server.js.map +1 -0
  19. package/dist/cli/utils/electron.d.ts +7 -0
  20. package/dist/cli/utils/electron.d.ts.map +1 -0
  21. package/dist/cli/utils/electron.js +36 -0
  22. package/dist/cli/utils/electron.js.map +1 -0
  23. package/dist/cli/utils/output.d.ts +6 -0
  24. package/dist/cli/utils/output.d.ts.map +1 -0
  25. package/dist/cli/utils/output.js +21 -0
  26. package/dist/cli/utils/output.js.map +1 -0
  27. package/dist/cli/utils/port-detect.d.ts +30 -0
  28. package/dist/cli/utils/port-detect.d.ts.map +1 -0
  29. package/dist/cli/utils/port-detect.js +95 -0
  30. package/dist/cli/utils/port-detect.js.map +1 -0
  31. package/dist/cli/utils/preflight.d.ts +20 -0
  32. package/dist/cli/utils/preflight.d.ts.map +1 -0
  33. package/dist/cli/utils/preflight.js +33 -0
  34. package/dist/cli/utils/preflight.js.map +1 -0
  35. package/dist/cli/utils/process.d.ts +23 -0
  36. package/dist/cli/utils/process.d.ts.map +1 -0
  37. package/dist/cli/utils/process.js +57 -0
  38. package/dist/cli/utils/process.js.map +1 -0
  39. package/out/main/index.js +1123 -0
  40. package/out/preload/overlay.cjs +56 -0
  41. package/out/preload/sidebar.cjs +29 -0
  42. package/out/renderer/assets/overlay-Bsx1u_qg.css +449 -0
  43. package/out/renderer/assets/overlay-DZl3I3jq.js +689 -0
  44. package/out/renderer/assets/sidebar-Bt34gvPU.js +563 -0
  45. package/out/renderer/assets/sidebar-BxEPS84k.css +515 -0
  46. package/out/renderer/assets/toast-CLlgwMU_.js +110 -0
  47. package/out/renderer/overlay.html +131 -0
  48. package/out/renderer/sidebar.html +64 -0
  49. package/package.json +67 -0
  50. package/resources/icon.icns +0 -0
  51. package/resources/icon.png +0 -0
  52. package/scripts/postinstall.cjs +56 -0
@@ -0,0 +1,95 @@
1
+ import { createConnection } from 'node:net';
2
+ import { execFileSync } from 'node:child_process';
3
+ /**
4
+ * Ordered patterns for extracting port numbers from dev server stdout.
5
+ * Most specific first to avoid false positives (Pitfall 4 from research).
6
+ */
7
+ export const PORT_PATTERNS = [
8
+ // Full URL: http://localhost:3000, https://127.0.0.1:8080, http://0.0.0.0:4321, http://[::]:3000
9
+ /https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::\]):(\d+)/,
10
+ // "listening on port 3000", "running at port 8080", "started server on 0.0.0.0:3000"
11
+ /(?:listening|running|started\s+server)\s+(?:on|at)\s+(?:(?:\S+:)?(?:port\s+)?)?(\d+)/i,
12
+ // "port: 3000", "Port 3000", "PORT=3000"
13
+ /\b(?:port|Port|PORT)\s*[:=]?\s*(\d+)/,
14
+ // Fallback: any :NNNNN (4-5 digit port after colon) -- most generic, last resort
15
+ /:(\d{4,5})\b/,
16
+ ];
17
+ /**
18
+ * Lines containing these phrases are error messages about ports, not actual
19
+ * listening announcements. Filter them out to avoid false positives like
20
+ * "Port 3016 is already in use" being detected as the dev server port.
21
+ */
22
+ const PORT_ERROR_PHRASES = /(?:in use|EADDRINUSE|already|error|failed|unavailable)/i;
23
+ /**
24
+ * Extract a port number from dev server output text.
25
+ * Tests patterns from most specific (URL) to least specific (colon:digits).
26
+ * Filters out error lines to avoid false positives from port-in-use messages.
27
+ * Returns null if no valid port found.
28
+ */
29
+ export function extractPortFromOutput(output) {
30
+ // Filter out lines that mention port errors before matching
31
+ const cleanedOutput = output
32
+ .split('\n')
33
+ .filter(line => !PORT_ERROR_PHRASES.test(line))
34
+ .join('\n');
35
+ for (const pattern of PORT_PATTERNS) {
36
+ const match = cleanedOutput.match(pattern);
37
+ if (match) {
38
+ const port = parseInt(match[1], 10);
39
+ if (port > 0 && port <= 65535)
40
+ return port;
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Poll a TCP port until it accepts connections or timeout expires.
47
+ * Default timeout: 30s (per D-09). Default poll interval: 250ms.
48
+ */
49
+ export function waitForPort(port, opts) {
50
+ const timeout = opts?.timeout ?? 30_000;
51
+ const interval = opts?.interval ?? 250;
52
+ return new Promise((resolve, reject) => {
53
+ const startTime = Date.now();
54
+ function attempt() {
55
+ if (Date.now() - startTime > timeout) {
56
+ reject(new Error(`Timeout: port ${port} not ready after ${timeout / 1000}s`));
57
+ return;
58
+ }
59
+ const socket = createConnection({ port, host: '127.0.0.1' });
60
+ socket.once('connect', () => {
61
+ socket.destroy();
62
+ resolve();
63
+ });
64
+ socket.once('error', () => {
65
+ socket.destroy();
66
+ setTimeout(attempt, interval);
67
+ });
68
+ }
69
+ attempt();
70
+ });
71
+ }
72
+ /**
73
+ * Attempt to identify which process is listening on a given port.
74
+ * Best-effort -- returns null if lsof/ps unavailable or port is free.
75
+ * Used for D-14: port-in-use diagnostics.
76
+ */
77
+ export function getProcessOnPort(port) {
78
+ try {
79
+ const pidStr = execFileSync('lsof', ['-i', `:${port}`, '-t'], {
80
+ encoding: 'utf-8',
81
+ }).trim();
82
+ // lsof may return multiple PIDs (one per line); take the first
83
+ const pid = parseInt(pidStr.split('\n')[0], 10);
84
+ if (Number.isNaN(pid))
85
+ return null;
86
+ const name = execFileSync('ps', ['-p', String(pid), '-o', 'comm='], {
87
+ encoding: 'utf-8',
88
+ }).trim();
89
+ return { pid, name };
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ }
95
+ //# sourceMappingURL=port-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-detect.js","sourceRoot":"","sources":["../../../src/cli/utils/port-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Parse Node.js version string to major version number.
3
+ * Exported for testability.
4
+ */
5
+ export declare function parseNodeMajor(versionString: string): number;
6
+ /**
7
+ * Check if the running Node.js version meets the minimum requirement (>= 20).
8
+ * Per D-14: fast pre-flight check before any async work.
9
+ */
10
+ export declare function checkNodeVersion(): {
11
+ ok: boolean;
12
+ version: string;
13
+ };
14
+ /**
15
+ * Check if the Electron binary is installed and accessible.
16
+ * Uses the same resolution pattern as electron.ts:spawnElectron().
17
+ * Per D-14: catches missing electron after npm install failures.
18
+ */
19
+ export declare function checkElectronBinary(): boolean;
20
+ //# sourceMappingURL=preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/preflight.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C"}
@@ -0,0 +1,33 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ /**
4
+ * Parse Node.js version string to major version number.
5
+ * Exported for testability.
6
+ */
7
+ export function parseNodeMajor(versionString) {
8
+ return parseInt(versionString.split('.')[0], 10);
9
+ }
10
+ /**
11
+ * Check if the running Node.js version meets the minimum requirement (>= 20).
12
+ * Per D-14: fast pre-flight check before any async work.
13
+ */
14
+ export function checkNodeVersion() {
15
+ const major = parseNodeMajor(process.versions.node);
16
+ return { ok: major >= 20, version: process.versions.node };
17
+ }
18
+ /**
19
+ * Check if the Electron binary is installed and accessible.
20
+ * Uses the same resolution pattern as electron.ts:spawnElectron().
21
+ * Per D-14: catches missing electron after npm install failures.
22
+ */
23
+ export function checkElectronBinary() {
24
+ try {
25
+ const require = createRequire(import.meta.url);
26
+ const electronPath = require('electron');
27
+ return typeof electronPath === 'string' && existsSync(electronPath);
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ //# sourceMappingURL=preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../../src/cli/utils/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,aAAqB;IAClD,OAAO,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAsB,CAAC;QAC9D,OAAO,OAAO,YAAY,KAAK,QAAQ,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Processes managed by the shutdown coordinator.
3
+ * Each field is optional -- only populated when the process has been spawned.
4
+ */
5
+ export interface ManagedProcesses {
6
+ devServer?: {
7
+ pid: number;
8
+ };
9
+ electronProcess?: {
10
+ pid: number;
11
+ };
12
+ }
13
+ /**
14
+ * Register signal handlers for graceful shutdown of all managed processes.
15
+ * Coordinates ordered teardown: Claude session, Electron, dev server.
16
+ * Idempotent -- second shutdown call is a no-op.
17
+ */
18
+ export declare function registerShutdownHandlers(processes: ManagedProcesses): void;
19
+ /**
20
+ * Reset shutdown state for testing. Removes registered signal listeners.
21
+ */
22
+ export declare function resetShutdownState(): void;
23
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/process.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,eAAe,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACnC;AAKD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,CA+C1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC"}
@@ -0,0 +1,57 @@
1
+ import kill from 'tree-kill';
2
+ import pc from 'picocolors';
3
+ let shuttingDown = false;
4
+ const registeredListeners = [];
5
+ /**
6
+ * Register signal handlers for graceful shutdown of all managed processes.
7
+ * Coordinates ordered teardown: Claude session, Electron, dev server.
8
+ * Idempotent -- second shutdown call is a no-op.
9
+ */
10
+ export function registerShutdownHandlers(processes) {
11
+ function shutdown(signal) {
12
+ if (shuttingDown)
13
+ return;
14
+ shuttingDown = true;
15
+ console.log(pc.dim(`\n Shutting down (${signal})...`));
16
+ // Force exit after 5s if kills hang
17
+ setTimeout(() => process.exit(1), 5000).unref();
18
+ // Step 2: Kill process trees, wait for completion before exiting
19
+ let pending = 0;
20
+ function onKilled() {
21
+ pending--;
22
+ if (pending === 0)
23
+ process.exit(0);
24
+ }
25
+ if (processes.electronProcess?.pid) {
26
+ pending++;
27
+ kill(processes.electronProcess.pid, 'SIGTERM', onKilled);
28
+ }
29
+ if (processes.devServer?.pid) {
30
+ pending++;
31
+ kill(processes.devServer.pid, 'SIGTERM', onKilled);
32
+ }
33
+ if (pending === 0)
34
+ process.exit(0);
35
+ }
36
+ const sigintHandler = () => shutdown('SIGINT');
37
+ const sigtermHandler = () => shutdown('SIGTERM');
38
+ const uncaughtHandler = (err) => {
39
+ console.error('Uncaught exception:', err);
40
+ shutdown('uncaughtException');
41
+ };
42
+ process.on('SIGINT', sigintHandler);
43
+ process.on('SIGTERM', sigtermHandler);
44
+ process.on('uncaughtException', uncaughtHandler);
45
+ registeredListeners.push({ event: 'SIGINT', handler: sigintHandler }, { event: 'SIGTERM', handler: sigtermHandler }, { event: 'uncaughtException', handler: uncaughtHandler });
46
+ }
47
+ /**
48
+ * Reset shutdown state for testing. Removes registered signal listeners.
49
+ */
50
+ export function resetShutdownState() {
51
+ shuttingDown = false;
52
+ for (const { event, handler } of registeredListeners) {
53
+ process.removeListener(event, handler);
54
+ }
55
+ registeredListeners.length = 0;
56
+ }
57
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/cli/utils/process.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAW5B,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,MAAM,mBAAmB,GAAgE,EAAE,CAAC;AAE5F;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,SAA2B;IAClE,SAAS,QAAQ,CAAC,MAAc;QAC9B,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QAEpB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,sBAAsB,MAAM,MAAM,CAAC,CAAC,CAAC;QAExD,oCAAoC;QACpC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAEhD,iEAAiE;QACjE,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,SAAS,QAAQ;YACf,OAAO,EAAE,CAAC;YACV,IAAI,OAAO,KAAK,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,SAAS,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,SAAS,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,OAAO,KAAK,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,eAAe,GAAG,CAAC,GAAU,EAAE,EAAE;QACrC,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;QAC1C,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;IAEjD,mBAAmB,CAAC,IAAI,CACtB,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,EAC3C,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,EAC7C,EAAE,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE,eAAe,EAAE,CACzD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,YAAY,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,mBAAmB,EAAE,CAAC;QACrD,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IACD,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;AACjC,CAAC"}