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.
- package/CHANGELOG.md +23 -11
- package/README.md +13 -4
- package/dist/cli/agentSession.d.ts +62 -0
- package/dist/cli/agentSession.d.ts.map +1 -0
- package/dist/cli/agentSession.js +100 -0
- package/dist/cli/agentSession.js.map +1 -0
- package/dist/cli/artifactPaths.d.ts +42 -0
- package/dist/cli/artifactPaths.d.ts.map +1 -0
- package/dist/cli/artifactPaths.js +144 -0
- package/dist/cli/artifactPaths.js.map +1 -0
- package/dist/cli/bounds.d.ts +88 -0
- package/dist/cli/bounds.d.ts.map +1 -0
- package/dist/cli/bounds.js +128 -0
- package/dist/cli/bounds.js.map +1 -0
- package/dist/cli/client.d.ts +3 -0
- package/dist/cli/client.d.ts.map +1 -1
- package/dist/cli/client.js +24 -8
- package/dist/cli/client.js.map +1 -1
- package/dist/cli/daemon.d.ts +3 -0
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +152 -39
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/defaults.d.ts +23 -3
- package/dist/cli/defaults.d.ts.map +1 -1
- package/dist/cli/defaults.js +50 -5
- package/dist/cli/defaults.js.map +1 -1
- package/dist/cli/dispatcher.d.ts +54 -11
- package/dist/cli/dispatcher.d.ts.map +1 -1
- package/dist/cli/dispatcher.js +851 -54
- package/dist/cli/dispatcher.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +305 -56
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +14 -14
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +328 -180
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/journal.d.ts +153 -0
- package/dist/cli/journal.d.ts.map +1 -0
- package/dist/cli/journal.js +252 -0
- package/dist/cli/journal.js.map +1 -0
- package/dist/cli/lineReader.d.ts +33 -0
- package/dist/cli/lineReader.d.ts.map +1 -0
- package/dist/cli/lineReader.js +66 -0
- package/dist/cli/lineReader.js.map +1 -0
- package/dist/cli/locatorCandidates.d.ts +44 -0
- package/dist/cli/locatorCandidates.d.ts.map +1 -0
- package/dist/cli/locatorCandidates.js +190 -0
- package/dist/cli/locatorCandidates.js.map +1 -0
- package/dist/cli/mcp/artifacts.d.ts +39 -1
- package/dist/cli/mcp/artifacts.d.ts.map +1 -1
- package/dist/cli/mcp/artifacts.js +104 -9
- package/dist/cli/mcp/artifacts.js.map +1 -1
- package/dist/cli/mcp/bounds.d.ts +65 -0
- package/dist/cli/mcp/bounds.d.ts.map +1 -0
- package/dist/cli/mcp/bounds.js +124 -0
- package/dist/cli/mcp/bounds.js.map +1 -0
- package/dist/cli/mcp/params.d.ts +38 -0
- package/dist/cli/mcp/params.d.ts.map +1 -0
- package/dist/cli/mcp/params.js +174 -0
- package/dist/cli/mcp/params.js.map +1 -0
- package/dist/cli/mcp/server.d.ts +94 -16
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/server.js +304 -150
- package/dist/cli/mcp/server.js.map +1 -1
- package/dist/cli/mcp/tools.d.ts +62 -17
- package/dist/cli/mcp/tools.d.ts.map +1 -1
- package/dist/cli/mcp/tools.js +373 -158
- package/dist/cli/mcp/tools.js.map +1 -1
- package/dist/cli/pageSemantics.d.ts +42 -0
- package/dist/cli/pageSemantics.d.ts.map +1 -0
- package/dist/cli/pageSemantics.js +194 -0
- package/dist/cli/pageSemantics.js.map +1 -0
- package/dist/cli/parseArgs.d.ts +6 -18
- package/dist/cli/parseArgs.d.ts.map +1 -1
- package/dist/cli/parseArgs.js +689 -45
- package/dist/cli/parseArgs.js.map +1 -1
- package/dist/cli/protocol.d.ts +8 -0
- package/dist/cli/protocol.d.ts.map +1 -1
- package/dist/cli/sessionRegistry.d.ts +42 -0
- package/dist/cli/sessionRegistry.d.ts.map +1 -0
- package/dist/cli/sessionRegistry.js +99 -0
- package/dist/cli/sessionRegistry.js.map +1 -0
- package/dist/cli/snapshot.d.ts +100 -18
- package/dist/cli/snapshot.d.ts.map +1 -1
- package/dist/cli/snapshot.js +248 -102
- package/dist/cli/snapshot.js.map +1 -1
- package/dist/cli/stateStore.d.ts +50 -0
- package/dist/cli/stateStore.d.ts.map +1 -0
- package/dist/cli/stateStore.js +122 -0
- package/dist/cli/stateStore.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/bidi/index.d.ts +1 -1
- package/dist/lib/bidi/index.d.ts.map +1 -1
- package/dist/lib/bidi/index.js +2 -2
- package/dist/lib/bidi/index.js.map +1 -1
- package/dist/lib/bidi/logs.d.ts +3 -0
- package/dist/lib/bidi/logs.d.ts.map +1 -1
- package/dist/lib/bidi/logs.js +7 -0
- package/dist/lib/bidi/logs.js.map +1 -1
- package/dist/lib/bidi/network.d.ts +14 -1
- package/dist/lib/bidi/network.d.ts.map +1 -1
- package/dist/lib/bidi/network.js +45 -7
- package/dist/lib/bidi/network.js.map +1 -1
- package/dist/lib/bidi/storage.d.ts +30 -6
- package/dist/lib/bidi/storage.d.ts.map +1 -1
- package/dist/lib/bidi/storage.js +190 -45
- package/dist/lib/bidi/storage.js.map +1 -1
- package/dist/lib/bidi/types.d.ts +7 -2
- package/dist/lib/bidi/types.d.ts.map +1 -1
- package/dist/lib/browser.d.ts +6 -3
- package/dist/lib/browser.d.ts.map +1 -1
- package/dist/lib/browser.js +140 -30
- package/dist/lib/browser.js.map +1 -1
- package/dist/lib/browserContext.d.ts +54 -18
- package/dist/lib/browserContext.d.ts.map +1 -1
- package/dist/lib/browserContext.js +295 -92
- package/dist/lib/browserContext.js.map +1 -1
- package/dist/lib/by.d.ts +3 -3
- package/dist/lib/by.d.ts.map +1 -1
- package/dist/lib/by.js +7 -3
- package/dist/lib/by.js.map +1 -1
- package/dist/lib/driver.d.ts +7 -0
- package/dist/lib/driver.d.ts.map +1 -1
- package/dist/lib/driver.js +12 -0
- package/dist/lib/driver.js.map +1 -1
- package/dist/lib/errors.d.ts +8 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +8 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/initScript.d.ts +9 -0
- package/dist/lib/initScript.d.ts.map +1 -0
- package/dist/lib/initScript.js +14 -0
- package/dist/lib/initScript.js.map +1 -0
- package/dist/lib/page.d.ts +22 -0
- package/dist/lib/page.d.ts.map +1 -1
- package/dist/lib/page.js +48 -0
- package/dist/lib/page.js.map +1 -1
- package/dist/lib/secureFile.d.ts +8 -0
- package/dist/lib/secureFile.d.ts.map +1 -0
- package/dist/lib/secureFile.js +67 -0
- package/dist/lib/secureFile.js.map +1 -0
- package/dist/lib/sessionStateValidation.d.ts +35 -0
- package/dist/lib/sessionStateValidation.d.ts.map +1 -0
- package/dist/lib/sessionStateValidation.js +223 -0
- package/dist/lib/sessionStateValidation.js.map +1 -0
- package/dist/lib/tracing.d.ts +2 -1
- package/dist/lib/tracing.d.ts.map +1 -1
- package/dist/lib/tracing.js +12 -1
- package/dist/lib/tracing.js.map +1 -1
- package/docs/agents.md +56 -61
- package/docs/api-reference.md +2 -1
- package/docs/browser-api.md +24 -4
- package/docs/browser-context.md +18 -12
- package/docs/cli.md +346 -26
- package/docs/error-codes.md +5 -4
- package/docs/getting-started.md +6 -1
- package/docs/index.md +1 -1
- package/docs/mcp.md +129 -62
- package/docs/public/examples/agent-actions.html +48 -0
- package/docs/public/examples/agent-debug.html +86 -0
- package/docs/public/examples/agent-late-mutation.html +18 -0
- package/docs/public/examples/agent-ref-shift.html +33 -0
- package/docs/recipes/login-once-reuse-session.md +32 -4
- package/docs/session-management.md +64 -3
- package/docs/why-craftdriver.md +1 -1
- package/package.json +3 -1
- package/skills/craftdriver/SKILL.md +59 -75
- package/skills/craftdriver/agents/openai.yaml +4 -0
- package/skills/craftdriver/cheatsheet.md +18 -4
- package/skills/craftdriver/cli.md +194 -68
- package/skills/craftdriver/patterns.md +14 -8
- 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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"}
|
package/dist/cli/client.d.ts
CHANGED
|
@@ -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>;
|
package/dist/cli/client.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/cli/client.js
CHANGED
|
@@ -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 = {
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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 (!
|
|
96
|
+
if (!answered) {
|
|
81
97
|
clearTimeout(timer);
|
|
82
98
|
reject(new Error('daemon closed connection without sending a response'));
|
|
83
99
|
}
|
package/dist/cli/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/daemon.d.ts
CHANGED
|
@@ -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;
|
package/dist/cli/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/cli/daemon.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Daemon process: long-lived browser exposed over a Unix domain socket.
|
|
3
3
|
*
|
|
4
|
-
* -
|
|
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
|
|
9
|
-
*
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
61
|
-
|
|
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
|
-
|
|
120
|
+
fs.unlinkSync(pidPath);
|
|
101
121
|
}
|
|
102
122
|
catch { /* ignore */ }
|
|
103
|
-
await handle.close();
|
|
104
123
|
try {
|
|
105
|
-
|
|
124
|
+
server.close();
|
|
106
125
|
}
|
|
107
126
|
catch { /* ignore */ }
|
|
127
|
+
await registry.closeAll();
|
|
108
128
|
try {
|
|
109
|
-
await fs.promises.unlink(
|
|
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
|
-
|
|
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 {
|
|
252
|
+
return {
|
|
253
|
+
code: ErrorCode.DRIVER_ERROR,
|
|
254
|
+
message: boundErrorText(err.message, MAX_ERROR_MESSAGE_BYTES),
|
|
255
|
+
};
|
|
146
256
|
}
|
|
147
|
-
return {
|
|
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
|
package/dist/cli/daemon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/defaults.d.ts
CHANGED
|
@@ -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
|
|
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":"
|
|
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"}
|