craftdriver 1.7.0 → 1.8.0

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 (175) hide show
  1. package/CHANGELOG.md +23 -11
  2. package/README.md +13 -4
  3. package/dist/cli/agentSession.d.ts +62 -0
  4. package/dist/cli/agentSession.d.ts.map +1 -0
  5. package/dist/cli/agentSession.js +100 -0
  6. package/dist/cli/agentSession.js.map +1 -0
  7. package/dist/cli/artifactPaths.d.ts +42 -0
  8. package/dist/cli/artifactPaths.d.ts.map +1 -0
  9. package/dist/cli/artifactPaths.js +144 -0
  10. package/dist/cli/artifactPaths.js.map +1 -0
  11. package/dist/cli/bounds.d.ts +88 -0
  12. package/dist/cli/bounds.d.ts.map +1 -0
  13. package/dist/cli/bounds.js +128 -0
  14. package/dist/cli/bounds.js.map +1 -0
  15. package/dist/cli/client.d.ts +3 -0
  16. package/dist/cli/client.d.ts.map +1 -1
  17. package/dist/cli/client.js +24 -8
  18. package/dist/cli/client.js.map +1 -1
  19. package/dist/cli/daemon.d.ts +3 -0
  20. package/dist/cli/daemon.d.ts.map +1 -1
  21. package/dist/cli/daemon.js +152 -39
  22. package/dist/cli/daemon.js.map +1 -1
  23. package/dist/cli/defaults.d.ts +23 -3
  24. package/dist/cli/defaults.d.ts.map +1 -1
  25. package/dist/cli/defaults.js +50 -5
  26. package/dist/cli/defaults.js.map +1 -1
  27. package/dist/cli/dispatcher.d.ts +54 -11
  28. package/dist/cli/dispatcher.d.ts.map +1 -1
  29. package/dist/cli/dispatcher.js +851 -54
  30. package/dist/cli/dispatcher.js.map +1 -1
  31. package/dist/cli/index.d.ts.map +1 -1
  32. package/dist/cli/index.js +305 -56
  33. package/dist/cli/index.js.map +1 -1
  34. package/dist/cli/init.d.ts +14 -14
  35. package/dist/cli/init.d.ts.map +1 -1
  36. package/dist/cli/init.js +328 -180
  37. package/dist/cli/init.js.map +1 -1
  38. package/dist/cli/journal.d.ts +153 -0
  39. package/dist/cli/journal.d.ts.map +1 -0
  40. package/dist/cli/journal.js +252 -0
  41. package/dist/cli/journal.js.map +1 -0
  42. package/dist/cli/lineReader.d.ts +33 -0
  43. package/dist/cli/lineReader.d.ts.map +1 -0
  44. package/dist/cli/lineReader.js +66 -0
  45. package/dist/cli/lineReader.js.map +1 -0
  46. package/dist/cli/locatorCandidates.d.ts +44 -0
  47. package/dist/cli/locatorCandidates.d.ts.map +1 -0
  48. package/dist/cli/locatorCandidates.js +190 -0
  49. package/dist/cli/locatorCandidates.js.map +1 -0
  50. package/dist/cli/mcp/artifacts.d.ts +39 -1
  51. package/dist/cli/mcp/artifacts.d.ts.map +1 -1
  52. package/dist/cli/mcp/artifacts.js +104 -9
  53. package/dist/cli/mcp/artifacts.js.map +1 -1
  54. package/dist/cli/mcp/bounds.d.ts +65 -0
  55. package/dist/cli/mcp/bounds.d.ts.map +1 -0
  56. package/dist/cli/mcp/bounds.js +124 -0
  57. package/dist/cli/mcp/bounds.js.map +1 -0
  58. package/dist/cli/mcp/params.d.ts +38 -0
  59. package/dist/cli/mcp/params.d.ts.map +1 -0
  60. package/dist/cli/mcp/params.js +174 -0
  61. package/dist/cli/mcp/params.js.map +1 -0
  62. package/dist/cli/mcp/server.d.ts +94 -16
  63. package/dist/cli/mcp/server.d.ts.map +1 -1
  64. package/dist/cli/mcp/server.js +304 -150
  65. package/dist/cli/mcp/server.js.map +1 -1
  66. package/dist/cli/mcp/tools.d.ts +62 -17
  67. package/dist/cli/mcp/tools.d.ts.map +1 -1
  68. package/dist/cli/mcp/tools.js +373 -158
  69. package/dist/cli/mcp/tools.js.map +1 -1
  70. package/dist/cli/pageSemantics.d.ts +42 -0
  71. package/dist/cli/pageSemantics.d.ts.map +1 -0
  72. package/dist/cli/pageSemantics.js +194 -0
  73. package/dist/cli/pageSemantics.js.map +1 -0
  74. package/dist/cli/parseArgs.d.ts +6 -18
  75. package/dist/cli/parseArgs.d.ts.map +1 -1
  76. package/dist/cli/parseArgs.js +689 -45
  77. package/dist/cli/parseArgs.js.map +1 -1
  78. package/dist/cli/protocol.d.ts +8 -0
  79. package/dist/cli/protocol.d.ts.map +1 -1
  80. package/dist/cli/sessionRegistry.d.ts +42 -0
  81. package/dist/cli/sessionRegistry.d.ts.map +1 -0
  82. package/dist/cli/sessionRegistry.js +99 -0
  83. package/dist/cli/sessionRegistry.js.map +1 -0
  84. package/dist/cli/snapshot.d.ts +100 -18
  85. package/dist/cli/snapshot.d.ts.map +1 -1
  86. package/dist/cli/snapshot.js +248 -102
  87. package/dist/cli/snapshot.js.map +1 -1
  88. package/dist/cli/stateStore.d.ts +50 -0
  89. package/dist/cli/stateStore.d.ts.map +1 -0
  90. package/dist/cli/stateStore.js +122 -0
  91. package/dist/cli/stateStore.js.map +1 -0
  92. package/dist/index.d.ts +1 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/lib/bidi/index.d.ts +1 -1
  96. package/dist/lib/bidi/index.d.ts.map +1 -1
  97. package/dist/lib/bidi/index.js +2 -2
  98. package/dist/lib/bidi/index.js.map +1 -1
  99. package/dist/lib/bidi/logs.d.ts +3 -0
  100. package/dist/lib/bidi/logs.d.ts.map +1 -1
  101. package/dist/lib/bidi/logs.js +7 -0
  102. package/dist/lib/bidi/logs.js.map +1 -1
  103. package/dist/lib/bidi/network.d.ts +14 -1
  104. package/dist/lib/bidi/network.d.ts.map +1 -1
  105. package/dist/lib/bidi/network.js +45 -7
  106. package/dist/lib/bidi/network.js.map +1 -1
  107. package/dist/lib/bidi/storage.d.ts +30 -6
  108. package/dist/lib/bidi/storage.d.ts.map +1 -1
  109. package/dist/lib/bidi/storage.js +190 -45
  110. package/dist/lib/bidi/storage.js.map +1 -1
  111. package/dist/lib/bidi/types.d.ts +7 -2
  112. package/dist/lib/bidi/types.d.ts.map +1 -1
  113. package/dist/lib/browser.d.ts +6 -3
  114. package/dist/lib/browser.d.ts.map +1 -1
  115. package/dist/lib/browser.js +140 -30
  116. package/dist/lib/browser.js.map +1 -1
  117. package/dist/lib/browserContext.d.ts +54 -18
  118. package/dist/lib/browserContext.d.ts.map +1 -1
  119. package/dist/lib/browserContext.js +295 -92
  120. package/dist/lib/browserContext.js.map +1 -1
  121. package/dist/lib/by.d.ts +3 -3
  122. package/dist/lib/by.d.ts.map +1 -1
  123. package/dist/lib/by.js +7 -3
  124. package/dist/lib/by.js.map +1 -1
  125. package/dist/lib/driver.d.ts +7 -0
  126. package/dist/lib/driver.d.ts.map +1 -1
  127. package/dist/lib/driver.js +12 -0
  128. package/dist/lib/driver.js.map +1 -1
  129. package/dist/lib/errors.d.ts +8 -0
  130. package/dist/lib/errors.d.ts.map +1 -1
  131. package/dist/lib/errors.js +8 -0
  132. package/dist/lib/errors.js.map +1 -1
  133. package/dist/lib/initScript.d.ts +9 -0
  134. package/dist/lib/initScript.d.ts.map +1 -0
  135. package/dist/lib/initScript.js +14 -0
  136. package/dist/lib/initScript.js.map +1 -0
  137. package/dist/lib/page.d.ts +22 -0
  138. package/dist/lib/page.d.ts.map +1 -1
  139. package/dist/lib/page.js +48 -0
  140. package/dist/lib/page.js.map +1 -1
  141. package/dist/lib/secureFile.d.ts +8 -0
  142. package/dist/lib/secureFile.d.ts.map +1 -0
  143. package/dist/lib/secureFile.js +67 -0
  144. package/dist/lib/secureFile.js.map +1 -0
  145. package/dist/lib/sessionStateValidation.d.ts +35 -0
  146. package/dist/lib/sessionStateValidation.d.ts.map +1 -0
  147. package/dist/lib/sessionStateValidation.js +223 -0
  148. package/dist/lib/sessionStateValidation.js.map +1 -0
  149. package/dist/lib/tracing.d.ts +2 -1
  150. package/dist/lib/tracing.d.ts.map +1 -1
  151. package/dist/lib/tracing.js +12 -1
  152. package/dist/lib/tracing.js.map +1 -1
  153. package/docs/agents.md +56 -61
  154. package/docs/api-reference.md +2 -1
  155. package/docs/browser-api.md +24 -4
  156. package/docs/browser-context.md +18 -12
  157. package/docs/cli.md +346 -26
  158. package/docs/error-codes.md +5 -4
  159. package/docs/getting-started.md +6 -1
  160. package/docs/index.md +1 -1
  161. package/docs/mcp.md +129 -62
  162. package/docs/public/examples/agent-actions.html +48 -0
  163. package/docs/public/examples/agent-debug.html +86 -0
  164. package/docs/public/examples/agent-late-mutation.html +18 -0
  165. package/docs/public/examples/agent-ref-shift.html +33 -0
  166. package/docs/recipes/login-once-reuse-session.md +32 -4
  167. package/docs/session-management.md +64 -3
  168. package/docs/why-craftdriver.md +1 -1
  169. package/package.json +3 -1
  170. package/skills/craftdriver/SKILL.md +59 -75
  171. package/skills/craftdriver/agents/openai.yaml +4 -0
  172. package/skills/craftdriver/cheatsheet.md +18 -4
  173. package/skills/craftdriver/cli.md +194 -68
  174. package/skills/craftdriver/patterns.md +14 -8
  175. package/skills/craftdriver/workflow.md +149 -0
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Transport-neutral output bounds for the agent surface.
3
+ *
4
+ * Bounded, token-efficient output is a product contract, not an MCP feature.
5
+ * It was only ever enforced on the MCP envelope, so the same `eval` that
6
+ * produced a 32 KB-capped MCP result produced a ~1 MB daemon response, read
7
+ * into an unbounded client buffer, printed in full. The bound belongs where
8
+ * the value is produced, so every transport inherits it.
9
+ *
10
+ * Truncation is always visible: a shortened value carries `truncated` and the
11
+ * byte counts, so an agent can tell a short answer from a shortened one.
12
+ * Cuts land on code-point boundaries — splitting a multi-byte sequence would
13
+ * emit a replacement character, or an unparseable frame.
14
+ */
15
+ /** Cap on a single command result. */
16
+ export const DEFAULT_MAX_RESULT_BYTES = 32 * 1024;
17
+ /** Cap on `--ephemeral` stdin, which is read whole into memory. */
18
+ export const MAX_STDIN_BYTES = 1024 * 1024;
19
+ /** Largest `--limit` a list-returning command will honour. */
20
+ export const MAX_LIST_LIMIT = 1000;
21
+ /**
22
+ * Largest `--limit` a *character*-limited command will honour.
23
+ *
24
+ * Separate from the list cap because they count different things: `text`
25
+ * takes a character budget whose default is already 2000, so clamping it to
26
+ * the row cap silently halved it. The result is still bounded by
27
+ * `resolveMaxResultBytes` regardless of what is asked for here.
28
+ */
29
+ export const MAX_TEXT_CHARS = 100_000;
30
+ export function resolveMaxResultBytes(env = process.env) {
31
+ const raw = env.CRAFTDRIVER_MAX_RESULT_BYTES;
32
+ if (!raw)
33
+ return DEFAULT_MAX_RESULT_BYTES;
34
+ const n = Number.parseInt(raw, 10);
35
+ // A cap below the smallest useful payload would make every result a
36
+ // truncation notice, so ignore nonsense rather than honouring it.
37
+ return Number.isFinite(n) && n >= 1024 ? n : DEFAULT_MAX_RESULT_BYTES;
38
+ }
39
+ export function utf8Bytes(text) {
40
+ return Buffer.byteLength(text, 'utf8');
41
+ }
42
+ /**
43
+ * Truncate to at most `maxBytes` of UTF-8, never splitting a character.
44
+ *
45
+ * Iterates code points (so a surrogate pair is kept whole) and stops before
46
+ * the budget is exceeded. A string already within budget is returned as-is.
47
+ */
48
+ export function truncateUtf8(text, maxBytes) {
49
+ if (maxBytes <= 0)
50
+ return '';
51
+ if (utf8Bytes(text) <= maxBytes)
52
+ return text;
53
+ let used = 0;
54
+ let out = '';
55
+ for (const char of text) {
56
+ const size = utf8Bytes(char);
57
+ if (used + size > maxBytes)
58
+ break;
59
+ out += char;
60
+ used += size;
61
+ }
62
+ return out;
63
+ }
64
+ /**
65
+ * Bound one command result value.
66
+ *
67
+ * A string is truncated in place, which keeps the common case (`eval`
68
+ * returning a long string, `text` on a large element) readable. Anything else
69
+ * is serialized and replaced by a bounded preview, because trimming an
70
+ * arbitrary object structurally would produce something that still looks like
71
+ * a complete answer.
72
+ */
73
+ export function boundValue(value, maxBytes = resolveMaxResultBytes()) {
74
+ if (value === null || value === undefined)
75
+ return value;
76
+ if (typeof value === 'string') {
77
+ const total = utf8Bytes(value);
78
+ if (total <= maxBytes)
79
+ return value;
80
+ const kept = truncateUtf8(value, maxBytes);
81
+ return { value: kept, truncated: true, totalBytes: total, retainedBytes: utf8Bytes(kept) };
82
+ }
83
+ if (typeof value !== 'object')
84
+ return value;
85
+ let serialized;
86
+ try {
87
+ serialized = JSON.stringify(value) ?? String(value);
88
+ }
89
+ catch {
90
+ serialized = String(value);
91
+ }
92
+ const total = utf8Bytes(serialized);
93
+ if (total <= maxBytes)
94
+ return value;
95
+ const preview = truncateUtf8(serialized, maxBytes);
96
+ return {
97
+ value: preview,
98
+ truncated: true,
99
+ totalBytes: total,
100
+ retainedBytes: utf8Bytes(preview),
101
+ };
102
+ }
103
+ /**
104
+ * Clamp a caller-supplied list limit.
105
+ *
106
+ * A negative limit silently returned nothing and a huge one defeated the
107
+ * paging that keeps list output bounded, so both are pulled into range rather
108
+ * than rejected — the agent asked for a list, and one it can read is a better
109
+ * answer than an error.
110
+ */
111
+ export function clampLimit(raw, fallback, max = MAX_LIST_LIMIT) {
112
+ if (!Number.isFinite(raw))
113
+ return fallback;
114
+ const n = Math.floor(raw);
115
+ if (n < 1)
116
+ return 1;
117
+ return Math.min(n, max);
118
+ }
119
+ export function boundString(raw, options = {}) {
120
+ if (raw === null)
121
+ return { value: null, truncated: false, total: 0 };
122
+ const charLimited = options.maxChars !== undefined && raw.length > options.maxChars
123
+ ? raw.slice(0, options.maxChars)
124
+ : raw;
125
+ const kept = truncateUtf8(charLimited, options.maxBytes ?? resolveMaxResultBytes());
126
+ return { value: kept, truncated: kept.length < raw.length, total: raw.length };
127
+ }
128
+ //# sourceMappingURL=bounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounds.js","sourceRoot":"","sources":["../../src/cli/bounds.ts"],"names":[],"mappings":"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"}
@@ -2,11 +2,14 @@ import type { Response } from './protocol.js';
2
2
  export interface ClientOptions {
3
3
  socketPath?: string;
4
4
  timeoutMs?: number;
5
+ /** Named daemon session to address. Omitted means the default session. */
6
+ session?: string;
5
7
  }
6
8
  export declare class DaemonClient {
7
9
  private nextId;
8
10
  private readonly socketPath;
9
11
  private readonly timeoutMs;
12
+ private readonly session;
10
13
  constructor(opts?: ClientOptions);
11
14
  /** Returns true if a daemon socket is reachable. */
12
15
  static isRunning(socketPath?: string): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAW,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,IAAI,GAAE,aAAkB;IAKpC,oDAAoD;WACvC,SAAS,CAAC,UAAU,GAAE,MAA2B,GAAG,OAAO,CAAC,OAAO,CAAC;IAWjF,6EAA6E;IAC7E,MAAM,CAAC,MAAM,CAAC,OAAO,GAAE,MAAwB,GAAG,MAAM,GAAG,IAAI;IAYzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAsC/E"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAW,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGvD,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,IAAI,GAAE,aAAkB;IAMpC,oDAAoD;WACvC,SAAS,CAAC,UAAU,GAAE,MAA2B,GAAG,OAAO,CAAC,OAAO,CAAC;IAWjF,6EAA6E;IAC7E,MAAM,CAAC,MAAM,CAAC,OAAO,GAAE,MAAwB,GAAG,MAAM,GAAG,IAAI;IAYzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAoD/E"}
@@ -6,13 +6,16 @@
6
6
  import net from 'net';
7
7
  import fs from 'fs';
8
8
  import { DAEMON_SOCKET_PATH, DAEMON_PID_PATH } from './defaults.js';
9
+ import { BoundedLineReader, MAX_FRAME_BYTES } from './lineReader.js';
9
10
  export class DaemonClient {
10
11
  nextId = 1;
11
12
  socketPath;
12
13
  timeoutMs;
14
+ session;
13
15
  constructor(opts = {}) {
14
16
  this.socketPath = opts.socketPath ?? DAEMON_SOCKET_PATH;
15
17
  this.timeoutMs = opts.timeoutMs ?? 60_000;
18
+ this.session = opts.session;
16
19
  }
17
20
  /** Returns true if a daemon socket is reachable. */
18
21
  static async isRunning(socketPath = DAEMON_SOCKET_PATH) {
@@ -46,10 +49,19 @@ export class DaemonClient {
46
49
  }
47
50
  }
48
51
  async send(cmd, args = {}) {
49
- const req = { id: this.nextId++, cmd, args };
52
+ const req = {
53
+ id: this.nextId++,
54
+ cmd,
55
+ args,
56
+ ...(this.session ? { session: this.session } : {}),
57
+ };
50
58
  return new Promise((resolve, reject) => {
51
59
  const sock = net.createConnection(this.socketPath);
52
- let buf = '';
60
+ // Bounded like the daemon's own reader. Accumulating without a cap meant
61
+ // a daemon that never wrote a newline could grow this buffer until the
62
+ // CLI process died, with nothing to report for it.
63
+ const reader = new BoundedLineReader();
64
+ let answered = false;
53
65
  const timer = setTimeout(() => {
54
66
  sock.destroy();
55
67
  reject(new Error(`daemon call timed out after ${this.timeoutMs}ms`));
@@ -62,14 +74,18 @@ export class DaemonClient {
62
74
  sock.write(JSON.stringify(req) + '\n');
63
75
  });
64
76
  sock.on('data', (chunk) => {
65
- buf += chunk.toString('utf8');
66
- const idx = buf.indexOf('\n');
67
- if (idx >= 0) {
77
+ for (const event of reader.push(chunk)) {
78
+ if (answered)
79
+ return;
80
+ answered = true;
68
81
  clearTimeout(timer);
69
- const line = buf.slice(0, idx);
70
82
  sock.end();
83
+ if (event.kind === 'oversized') {
84
+ reject(new Error(`daemon response exceeded ${MAX_FRAME_BYTES} bytes and was discarded`));
85
+ return;
86
+ }
71
87
  try {
72
- resolve(JSON.parse(line));
88
+ resolve(JSON.parse(event.line));
73
89
  }
74
90
  catch (e) {
75
91
  reject(new Error('invalid response from daemon: ' + e.message));
@@ -77,7 +93,7 @@ export class DaemonClient {
77
93
  }
78
94
  });
79
95
  sock.on('end', () => {
80
- if (!buf.includes('\n')) {
96
+ if (!answered) {
81
97
  clearTimeout(timer);
82
98
  reject(new Error('daemon closed connection without sending a response'));
83
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASrE,MAAM,OAAO,YAAY;IACf,MAAM,GAAG,CAAC,CAAC;IACF,UAAU,CAAS;IACnB,SAAS,CAAS;IAClB,OAAO,CAAqB;IAE7C,YAAY,OAAsB,EAAE;QAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,kBAAkB,CAAC;QACxD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC9B,CAAC;IAED,oDAAoD;IACpD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,aAAqB,kBAAkB;QAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7C,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;YACtC,MAAM,IAAI,GAAG,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,IAAI,GAAG,CAAC,CAAU,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,MAAM,CAAC,MAAM,CAAC,UAAkB,eAAe;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YACpD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YACnD,IAAI,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;YACpD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,OAAgC,EAAE;QACxD,MAAM,GAAG,GAAY;YACnB,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE;YACjB,GAAG;YACH,IAAI;YACJ,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD,CAAC;QACF,OAAO,IAAI,OAAO,CAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACnD,yEAAyE;YACzE,uEAAuE;YACvE,mDAAmD;YACnD,MAAM,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;YACvC,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;YACvE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACnB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;gBACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBACxB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBACvC,IAAI,QAAQ;wBAAE,OAAO;oBACrB,QAAQ,GAAG,IAAI,CAAC;oBAChB,YAAY,CAAC,KAAK,CAAC,CAAC;oBACpB,IAAI,CAAC,GAAG,EAAE,CAAC;oBACX,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;wBAC/B,MAAM,CAAC,IAAI,KAAK,CACd,4BAA4B,eAAe,0BAA0B,CACtE,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBACD,IAAI,CAAC;wBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAa,CAAC,CAAC;oBAC9C,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,GAAI,CAAW,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC7E,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,YAAY,CAAC,KAAK,CAAC,CAAC;oBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -1,10 +1,13 @@
1
1
  import type { LaunchOptions } from '../lib/browser.js';
2
+ import { type SessionRegistry } from './sessionRegistry.js';
3
+ import type { Request, Response } from './protocol.js';
2
4
  interface DaemonOptions {
3
5
  socketPath?: string;
4
6
  pidPath?: string;
5
7
  launch: LaunchOptions;
6
8
  }
7
9
  export declare function runDaemon(opts: DaemonOptions): Promise<void>;
10
+ export declare function handleDaemonRequest(registry: SessionRegistry, req: Request, onStop?: () => void): Promise<Response>;
8
11
  export declare function toWireError(err: unknown): {
9
12
  code: string;
10
13
  message: string;
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAOvD,UAAU,aAAa;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGlE;AAUD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAc5H"}
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKvD,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvD,UAAU,aAAa;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8GlE;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,eAAe,EACzB,GAAG,EAAE,OAAO,EACZ,MAAM,CAAC,EAAE,MAAM,IAAI,GAClB,OAAO,CAAC,QAAQ,CAAC,CAuCnB;AA4DD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAoB5H"}
@@ -1,12 +1,16 @@
1
1
  /**
2
2
  * Daemon process: long-lived browser exposed over a Unix domain socket.
3
3
  *
4
- * - Listens on `~/.craftdriver/sock` (override with `$CRAFTDRIVER_SOCKET`).
4
+ * - One daemon per project: it listens on a socket under
5
+ * `~/.craftdriver/projects/<project>-<hash>/` keyed by the project root
6
+ * (override with `$CRAFTDRIVER_SOCKET`). A user-global socket meant a
7
+ * daemon started in one project answered commands from another, sharing
8
+ * its browser, cookies and refs.
5
9
  * - Line-delimited JSON request/response, one connection per CLI call.
6
10
  * - Lazy browser launch: the first request that needs a browser starts
7
11
  * one. Subsequent requests reuse it.
8
- * - Writes its PID to `~/.craftdriver/pid` so `daemon status/stop` can
9
- * find it. PID file is cleaned up on graceful exit.
12
+ * - Writes its PID beside the socket so `daemon status/stop` can find it.
13
+ * PID file is cleaned up on graceful exit.
10
14
  *
11
15
  * Run as a child process via `craftdriver daemon start`.
12
16
  */
@@ -17,7 +21,10 @@ import { Browser } from '../lib/browser.js';
17
21
  import { assertLocalOnlyLaunch } from '../lib/launchTarget.js';
18
22
  import { CraftdriverError, ErrorCode } from '../lib/errors.js';
19
23
  import { DAEMON_SOCKET_PATH, DAEMON_PID_PATH } from './defaults.js';
20
- import { createBrowserHandle, dispatch } from './dispatcher.js';
24
+ import { AgentSession } from './agentSession.js';
25
+ import { createSessionRegistry, validateSessionName, MAX_SESSIONS, } from './sessionRegistry.js';
26
+ import { BoundedLineReader, MAX_FRAME_BYTES } from './lineReader.js';
27
+ import { truncateUtf8, utf8Bytes } from './bounds.js';
21
28
  export async function runDaemon(opts) {
22
29
  // The daemon is a local dev tool only — never reachable against a
23
30
  // Grid/cloud. Fail fast at startup, not on first browser use.
@@ -31,15 +38,36 @@ export async function runDaemon(opts) {
31
38
  await fs.promises.unlink(socketPath);
32
39
  }
33
40
  catch { /* ignore */ }
34
- const handle = createBrowserHandle(() => Browser.launch(opts.launch));
41
+ // One browser per named session, created on first use. As with the
42
+ // ephemeral CLI: the wire response carries only the command result, so an
43
+ // automatic post-action snapshot would be pure cost.
44
+ const registry = createSessionRegistry({
45
+ create: (name) => new AgentSession({
46
+ launchOptions: opts.launch,
47
+ launch: () => Browser.launch(opts.launch),
48
+ autoSnapshot: false,
49
+ artifactName: name,
50
+ }),
51
+ });
35
52
  const server = net.createServer((sock) => {
36
- let buf = '';
53
+ // Bounded like the MCP transport: this process is long-lived, so a peer
54
+ // that writes without a newline would grow the buffer until the daemon
55
+ // dies, with no process exit to reclaim it.
56
+ const reader = new BoundedLineReader();
37
57
  sock.on('data', async (chunk) => {
38
- buf += chunk.toString('utf8');
39
- let idx;
40
- while ((idx = buf.indexOf('\n')) >= 0) {
41
- const line = buf.slice(0, idx);
42
- buf = buf.slice(idx + 1);
58
+ for (const event of reader.push(chunk)) {
59
+ if (event.kind === 'oversized') {
60
+ writeResp(sock, {
61
+ id: -1,
62
+ ok: false,
63
+ error: {
64
+ code: ErrorCode.INVALID_ARGUMENT,
65
+ message: `request frame exceeds ${MAX_FRAME_BYTES}-byte limit`,
66
+ },
67
+ });
68
+ continue;
69
+ }
70
+ const line = event.line;
43
71
  if (!line.trim())
44
72
  continue;
45
73
  let req;
@@ -57,24 +85,8 @@ export async function runDaemon(opts) {
57
85
  });
58
86
  continue;
59
87
  }
60
- try {
61
- // Built-in daemon control commands handled here.
62
- if (req.cmd === 'daemon:ping') {
63
- writeResp(sock, { id: req.id, ok: true, result: { pong: true, pid: process.pid } });
64
- continue;
65
- }
66
- if (req.cmd === 'daemon:stop') {
67
- writeResp(sock, { id: req.id, ok: true, result: { stopping: true, pid: process.pid } });
68
- // Defer shutdown so the response flushes.
69
- setImmediate(() => void shutdown(0));
70
- continue;
71
- }
72
- const result = await dispatch({ handle, launchOptions: opts.launch }, req.cmd, req.args ?? {});
73
- writeResp(sock, { id: req.id, ok: true, result });
74
- }
75
- catch (err) {
76
- writeResp(sock, { id: req.id, ok: false, error: toWireError(err) });
77
- }
88
+ const response = await handleDaemonRequest(registry, req, () => void shutdown(0));
89
+ writeResp(sock, response);
78
90
  }
79
91
  });
80
92
  sock.on('error', () => { });
@@ -96,17 +108,25 @@ export async function runDaemon(opts) {
96
108
  if (shuttingDown)
97
109
  return;
98
110
  shuttingDown = true;
111
+ // Remove both files before anything that can block or yield.
112
+ //
113
+ // `daemon stop` reports success once the socket stops answering, and Node
114
+ // unlinks a Unix socket path during `server.close()`. Cleaning up after
115
+ // `registry.closeAll()` — which waits for every browser to quit — left a
116
+ // window, seconds wide, where stop had already returned "daemon stopped"
117
+ // and the PID file was still on disk. A later `daemon status` then
118
+ // reported a PID owning nothing.
99
119
  try {
100
- server.close();
120
+ fs.unlinkSync(pidPath);
101
121
  }
102
122
  catch { /* ignore */ }
103
- await handle.close();
104
123
  try {
105
- await fs.promises.unlink(socketPath);
124
+ server.close();
106
125
  }
107
126
  catch { /* ignore */ }
127
+ await registry.closeAll();
108
128
  try {
109
- await fs.promises.unlink(pidPath);
129
+ await fs.promises.unlink(socketPath);
110
130
  }
111
131
  catch { /* ignore */ }
112
132
  process.exit(code);
@@ -121,29 +141,122 @@ export async function runDaemon(opts) {
121
141
  // `daemon:stop`, both of which call `process.exit()` directly.
122
142
  await new Promise(() => { });
123
143
  }
144
+ export async function handleDaemonRequest(registry, req, onStop) {
145
+ // Daemon- and registry-level commands answer without touching a session.
146
+ // `session:close` in particular must not be routed *through* the session it
147
+ // is about, which would queue the close behind that session's own work.
148
+ if (req.cmd === 'daemon:ping') {
149
+ return { id: req.id, ok: true, result: { pong: true, pid: process.pid } };
150
+ }
151
+ if (req.cmd === 'daemon:stop') {
152
+ if (onStop)
153
+ setImmediate(onStop);
154
+ return { id: req.id, ok: true, result: { stopping: true, pid: process.pid } };
155
+ }
156
+ if (req.cmd === 'session:list') {
157
+ const sessions = registry.list();
158
+ return {
159
+ id: req.id,
160
+ ok: true,
161
+ result: { sessions, count: sessions.length, limit: MAX_SESSIONS },
162
+ };
163
+ }
164
+ try {
165
+ if (req.cmd === 'session:close') {
166
+ // `target` when named explicitly, otherwise whichever session the
167
+ // caller addressed — `craftdriver session close --session checkout`.
168
+ const name = validateSessionName(req.args?.target ?? req.session);
169
+ const closed = await registry.close(name);
170
+ return { id: req.id, ok: true, result: { closed, name } };
171
+ }
172
+ // Untrusted: the CLI validates before opening a socket, but a socket peer
173
+ // is not necessarily the CLI. Validation precedes session creation.
174
+ const session = registry.get(validateSessionName(req.session));
175
+ const result = await session.run({ cmd: req.cmd, args: req.args ?? {} });
176
+ return { id: req.id, ok: true, result };
177
+ }
178
+ catch (err) {
179
+ return { id: req.id, ok: false, error: toWireError(err) };
180
+ }
181
+ }
124
182
  function writeResp(sock, resp) {
125
183
  try {
126
- sock.write(JSON.stringify(resp) + '\n');
184
+ const frame = JSON.stringify(resp);
185
+ // Results are bounded where they are produced, so an oversized frame here
186
+ // means a bug rather than a large-but-legitimate answer. Reporting it
187
+ // beats writing a megabyte into a reader that has to buffer the whole
188
+ // line before it can parse anything.
189
+ if (Buffer.byteLength(frame, 'utf8') > MAX_FRAME_BYTES) {
190
+ const replacement = {
191
+ id: resp.id,
192
+ ok: false,
193
+ error: {
194
+ code: ErrorCode.INVALID_ARGUMENT,
195
+ message: `daemon: response exceeded ${MAX_FRAME_BYTES} bytes and was dropped`,
196
+ hint: 'narrow the command (a selector, a smaller --limit) and retry',
197
+ },
198
+ };
199
+ sock.write(JSON.stringify(replacement) + '\n');
200
+ return;
201
+ }
202
+ sock.write(frame + '\n');
127
203
  }
128
204
  catch {
129
205
  /* socket may have closed; ignore */
130
206
  }
131
207
  }
208
+ const MAX_ERROR_MESSAGE_BYTES = 16 * 1024;
209
+ const MAX_ERROR_HINT_BYTES = 4 * 1024;
210
+ const MAX_ERROR_DETAIL_BYTES = 8 * 1024;
211
+ function boundErrorText(text, maxBytes) {
212
+ if (utf8Bytes(text) <= maxBytes)
213
+ return text;
214
+ const marker = '…';
215
+ return truncateUtf8(text, maxBytes - utf8Bytes(marker)) + marker;
216
+ }
217
+ function boundErrorDetail(detail) {
218
+ let serialized;
219
+ try {
220
+ serialized = JSON.stringify(detail);
221
+ }
222
+ catch {
223
+ return { truncated: true, preview: '[unserializable error detail]' };
224
+ }
225
+ if (utf8Bytes(serialized) <= MAX_ERROR_DETAIL_BYTES) {
226
+ const parsed = JSON.parse(serialized);
227
+ return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)
228
+ ? parsed
229
+ : { value: parsed };
230
+ }
231
+ const preview = truncateUtf8(serialized, MAX_ERROR_DETAIL_BYTES);
232
+ return {
233
+ truncated: true,
234
+ totalBytes: utf8Bytes(serialized),
235
+ retainedBytes: utf8Bytes(preview),
236
+ preview,
237
+ };
238
+ }
132
239
  export function toWireError(err) {
133
240
  if (err instanceof CraftdriverError) {
134
241
  const out = {
135
242
  code: err.code,
136
- message: err.message,
243
+ message: boundErrorText(err.message, MAX_ERROR_MESSAGE_BYTES),
137
244
  };
138
245
  if (err.hint)
139
- out.hint = err.hint;
246
+ out.hint = boundErrorText(err.hint, MAX_ERROR_HINT_BYTES);
140
247
  if (err.detail)
141
- out.detail = err.detail;
248
+ out.detail = boundErrorDetail(err.detail);
142
249
  return out;
143
250
  }
144
251
  if (err instanceof Error) {
145
- return { code: ErrorCode.DRIVER_ERROR, message: err.message };
252
+ return {
253
+ code: ErrorCode.DRIVER_ERROR,
254
+ message: boundErrorText(err.message, MAX_ERROR_MESSAGE_BYTES),
255
+ };
146
256
  }
147
- return { code: ErrorCode.DRIVER_ERROR, message: String(err) };
257
+ return {
258
+ code: ErrorCode.DRIVER_ERROR,
259
+ message: boundErrorText(String(err), MAX_ERROR_MESSAGE_BYTES),
260
+ };
148
261
  }
149
262
  //# sourceMappingURL=daemon.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAsB,MAAM,iBAAiB,CAAC;AASpF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAmB;IACjD,kEAAkE;IAClE,8DAA8D;IAC9D,qBAAqB,CAAC,IAAI,CAAC,MAA4C,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,kBAAkB,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC;IAEhD,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,sEAAsE;IACtE,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAkB,mBAAmB,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAErF,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QACvC,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YAC9B,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,GAAW,CAAC;YAChB,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC/B,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBAAE,SAAS;gBAC3B,IAAI,GAAY,CAAC;gBACjB,IAAI,CAAC;oBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;gBACpC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,SAAS,CAAC,IAAI,EAAE;wBACd,EAAE,EAAE,CAAC,CAAC;wBACN,EAAE,EAAE,KAAK;wBACT,KAAK,EAAE;4BACL,IAAI,EAAE,SAAS,CAAC,gBAAgB;4BAChC,OAAO,EAAE,wBAAwB,GAAI,CAAW,CAAC,OAAO;yBACzD;qBACF,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,IAAI,CAAC;oBACH,iDAAiD;oBACjD,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;wBAC9B,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;wBACpF,SAAS;oBACX,CAAC;oBACD,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;wBAC9B,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;wBACxF,0CAA0C;wBAC1C,YAAY,CAAC,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;wBACrC,SAAS;oBACX,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAC3B,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,MAAM,EAAE,EACtC,GAAG,CAAC,GAAG,EACP,GAAG,CAAC,IAAI,IAAI,EAAE,CACf,CAAC;oBACF,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACpD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAmC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,IAAI,CAAC;gBAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;YAClE,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAElE,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,KAAK,UAAU,QAAQ,CAAC,IAAY;QAClC,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC;YAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACpE,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,GAAG,CAAE,CAAW,EAAE,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/F,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,gEAAgE;IAChE,+DAA+D;IAC/D,MAAM,IAAI,OAAO,CAAO,GAAG,EAAE,GAAwB,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,SAAS,CAAC,IAAgB,EAAE,IAAc;IACjD,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;QACpC,MAAM,GAAG,GAAuF;YAC9F,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC;QACF,IAAI,GAAG,CAAC,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAClC,IAAI,GAAG,CAAC,MAAM;YAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QACxC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,GAEb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAStD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAmB;IACjD,kEAAkE;IAClE,8DAA8D;IAC9D,qBAAqB,CAAC,IAAI,CAAC,MAA4C,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,kBAAkB,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC;IAEhD,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,sEAAsE;IACtE,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAEpE,mEAAmE;IACnE,0EAA0E;IAC1E,qDAAqD;IACrD,MAAM,QAAQ,GAAG,qBAAqB,CAAC;QACrC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC;YACjC,aAAa,EAAE,IAAI,CAAC,MAAM;YAC1B,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACzC,YAAY,EAAE,KAAK;YACnB,YAAY,EAAE,IAAI;SACnB,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QACvC,wEAAwE;QACxE,uEAAuE;QACvE,4CAA4C;QAC5C,MAAM,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBAC/B,SAAS,CAAC,IAAI,EAAE;wBACd,EAAE,EAAE,CAAC,CAAC;wBACN,EAAE,EAAE,KAAK;wBACT,KAAK,EAAE;4BACL,IAAI,EAAE,SAAS,CAAC,gBAAgB;4BAChC,OAAO,EAAE,yBAAyB,eAAe,aAAa;yBAC/D;qBACF,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;gBACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBAAE,SAAS;gBAC3B,IAAI,GAAY,CAAC;gBACjB,IAAI,CAAC;oBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;gBACpC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,SAAS,CAAC,IAAI,EAAE;wBACd,EAAE,EAAE,CAAC,CAAC;wBACN,EAAE,EAAE,KAAK;wBACT,KAAK,EAAE;4BACL,IAAI,EAAE,SAAS,CAAC,gBAAgB;4BAChC,OAAO,EAAE,wBAAwB,GAAI,CAAW,CAAC,OAAO;yBACzD;qBACF,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CACxC,QAAQ,EACR,GAAG,EACH,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CACvB,CAAC;gBACF,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAmC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,IAAI,CAAC;gBAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;YAClE,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAElE,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,KAAK,UAAU,QAAQ,CAAC,IAAY;QAClC,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QACpB,6DAA6D;QAC7D,EAAE;QACF,0EAA0E;QAC1E,wEAAwE;QACxE,yEAAyE;QACzE,yEAAyE;QACzE,mEAAmE;QACnE,iCAAiC;QACjC,IAAI,CAAC;YAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC;YAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,GAAG,CAAE,CAAW,EAAE,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/F,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,gEAAgE;IAChE,+DAA+D;IAC/D,MAAM,IAAI,OAAO,CAAO,GAAG,EAAE,GAAwB,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAyB,EACzB,GAAY,EACZ,MAAmB;IAEnB,yEAAyE;IACzE,4EAA4E;IAC5E,wEAAwE;IACxE,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;QAC9B,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;QAC9B,IAAI,MAAM;YAAE,YAAY,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;IAChF,CAAC;IACD,IAAI,GAAG,CAAC,GAAG,KAAK,cAAc,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE;SAClE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,GAAG,KAAK,eAAe,EAAE,CAAC;YAChC,kEAAkE;YAClE,qEAAqE;YACrE,MAAM,IAAI,GAAG,mBAAmB,CAC7B,GAAG,CAAC,IAAI,EAAE,MAAkB,IAAI,GAAG,CAAC,OAAO,CAC7C,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1C,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QAC5D,CAAC;QAED,0EAA0E;QAC1E,oEAAoE;QACpE,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QACzE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAgB,EAAE,IAAc;IACjD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,0EAA0E;QAC1E,sEAAsE;QACtE,sEAAsE;QACtE,qCAAqC;QACrC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,eAAe,EAAE,CAAC;YACvD,MAAM,WAAW,GAAa;gBAC5B,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,SAAS,CAAC,gBAAgB;oBAChC,OAAO,EAAE,6BAA6B,eAAe,wBAAwB;oBAC7E,IAAI,EAAE,8DAA8D;iBACrE;aACF,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;YAC/C,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC1C,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAI,CAAC;AACtC,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,CAAC;AAExC,SAAS,cAAc,CAAC,IAAY,EAAE,QAAgB;IACpD,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC;IACnB,OAAO,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC;AACnE,CAAC;AAED,SAAS,gBAAgB,CAAC,MAA+B;IACvD,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;IACvE,CAAC;IACD,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,sBAAsB,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAY,CAAC;QACjD,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5E,CAAC,CAAC,MAAiC;YACnC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;IACjE,OAAO;QACL,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC;QACjC,aAAa,EAAE,SAAS,CAAC,OAAO,CAAC;QACjC,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;QACpC,MAAM,GAAG,GAAuF;YAC9F,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,uBAAuB,CAAC;SAC9D,CAAC;QACF,IAAI,GAAG,CAAC,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;QACxE,IAAI,GAAG,CAAC,MAAM;YAAE,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1D,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO;YACL,IAAI,EAAE,SAAS,CAAC,YAAY;YAC5B,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,uBAAuB,CAAC;SAC9D,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,YAAY;QAC5B,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,uBAAuB,CAAC;KAC9D,CAAC;AACJ,CAAC"}
@@ -1,10 +1,30 @@
1
+ /**
2
+ * Root of the project the CLI is being run against: the nearest ancestor
3
+ * holding a `package.json` or `.git`, falling back to the working directory.
4
+ *
5
+ * Resolved through `realpath` so `/tmp` and `/private/tmp` — or any other
6
+ * symlinked path — do not key two daemons for the same project.
7
+ */
8
+ export declare function projectRoot(cwd?: string): string;
9
+ /**
10
+ * Per-project daemon directory.
11
+ *
12
+ * The socket used to be user-global, so a daemon started in project A served
13
+ * project B: same browser, same cookies, same refs, and artifacts written
14
+ * into whichever project happened to start it first. Keying the socket by
15
+ * project root fixes that at the transport, and — unlike a session namespace
16
+ * inside one shared daemon — it also stops project A's installed craftdriver
17
+ * version from serving project B.
18
+ *
19
+ * The directory name carries the project's basename purely so `lsof` and
20
+ * `ls ~/.craftdriver/projects` are readable; the hash is what disambiguates.
21
+ */
22
+ export declare function daemonDir(root?: string): string;
1
23
  export declare const AGENT_DEFAULT_TIMEOUT_MS: number;
2
24
  /** Default `--limit` for list-returning commands. */
3
25
  export declare const AGENT_DEFAULT_LIMIT = 20;
4
- /** Path to the daemon's Unix socket. */
26
+ /** Path to this project's daemon socket. */
5
27
  export declare const DAEMON_SOCKET_PATH: string;
6
28
  /** PID file written by the daemon so `daemon status/stop` can find it. */
7
29
  export declare const DAEMON_PID_PATH: string;
8
- /** Idle browser shutdown delay (ms) when daemon receives no requests. */
9
- export declare const DAEMON_IDLE_SHUTDOWN_MS = 0;
10
30
  //# sourceMappingURL=defaults.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/cli/defaults.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,wBAAwB,QAKjC,CAAC;AAEL,qDAAqD;AACrD,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,wCAAwC;AACxC,eAAO,MAAM,kBAAkB,QAI3B,CAAC;AAEL,0EAA0E;AAC1E,eAAO,MAAM,eAAe,QAIxB,CAAC;AAEL,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,IAAI,CAAC"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/cli/defaults.ts"],"names":[],"mappings":"AAmBA;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAmB/D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAsB,GAAG,MAAM,CAI9D;AAED,eAAO,MAAM,wBAAwB,QAKjC,CAAC;AAEL,qDAAqD;AACrD,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,QAI3B,CAAC;AAEL,0EAA0E;AAC1E,eAAO,MAAM,eAAe,QAIxB,CAAC"}