@ai-codebot/daemon 0.1.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/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/broker/handoff.d.ts +57 -0
- package/dist/broker/handoff.js +87 -0
- package/dist/broker/handoff.js.map +1 -0
- package/dist/broker/server.d.ts +34 -0
- package/dist/broker/server.js +204 -0
- package/dist/broker/server.js.map +1 -0
- package/dist/broker/token.d.ts +36 -0
- package/dist/broker/token.js +48 -0
- package/dist/broker/token.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.js +120 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.js +132 -0
- package/dist/config.js.map +1 -0
- package/dist/frames.d.ts +311 -0
- package/dist/frames.js +137 -0
- package/dist/frames.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/launch.d.ts +40 -0
- package/dist/launch.js +163 -0
- package/dist/launch.js.map +1 -0
- package/dist/logging.d.ts +27 -0
- package/dist/logging.js +91 -0
- package/dist/logging.js.map +1 -0
- package/dist/spawn/cli-runner.d.ts +91 -0
- package/dist/spawn/cli-runner.js +180 -0
- package/dist/spawn/cli-runner.js.map +1 -0
- package/dist/spawn/detect.d.ts +18 -0
- package/dist/spawn/detect.js +46 -0
- package/dist/spawn/detect.js.map +1 -0
- package/dist/spawn/disallowed-tools.d.ts +15 -0
- package/dist/spawn/disallowed-tools.js +30 -0
- package/dist/spawn/disallowed-tools.js.map +1 -0
- package/dist/spawn/git.d.ts +19 -0
- package/dist/spawn/git.js +56 -0
- package/dist/spawn/git.js.map +1 -0
- package/dist/spawn/llm-client.d.ts +52 -0
- package/dist/spawn/llm-client.js +61 -0
- package/dist/spawn/llm-client.js.map +1 -0
- package/dist/spawn/n2-runner.d.ts +33 -0
- package/dist/spawn/n2-runner.js +176 -0
- package/dist/spawn/n2-runner.js.map +1 -0
- package/dist/spawn/n2-tools.d.ts +44 -0
- package/dist/spawn/n2-tools.js +374 -0
- package/dist/spawn/n2-tools.js.map +1 -0
- package/dist/spawn/result-map.d.ts +40 -0
- package/dist/spawn/result-map.js +68 -0
- package/dist/spawn/result-map.js.map +1 -0
- package/dist/tunnel.d.ts +61 -0
- package/dist/tunnel.js +205 -0
- package/dist/tunnel.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Outcome → `Result` frame mapping (design §4 — DR-6, OQ-6).
|
|
3
|
+
*
|
|
4
|
+
* Maps the internal executor outcome (CLI exit code / N2 loop status) to the closed
|
|
5
|
+
* `Result.status` set `succeeded | failed | timed_out`, mirroring the Python
|
|
6
|
+
* `agentic_backend` contract (`success` → `succeeded`).
|
|
7
|
+
*
|
|
8
|
+
* - CLI exit 0 / N2 `success` → succeeded (text=summary, diff, files)
|
|
9
|
+
* - N2 `no_changes` → succeeded (diff null)
|
|
10
|
+
* - N2 `needs_clarification` → succeeded (text=question)
|
|
11
|
+
* - CLI nonzero / N2 `error`/crash → failed (error, NO secrets)
|
|
12
|
+
* - deadline → timed_out
|
|
13
|
+
*
|
|
14
|
+
* `cost_usd` is ALWAYS `null` (the tenant runs their own model — cost is unknown,
|
|
15
|
+
* NOT 0; OQ-6).
|
|
16
|
+
*/
|
|
17
|
+
/** Trailing chars of stderr kept on a failure result (no full dump). */
|
|
18
|
+
export const ERROR_TAIL_CHARS = 4000;
|
|
19
|
+
/** Map an internal outcome to the wire `Result` frame for a launch. */
|
|
20
|
+
export function toResult(launchId, outcome) {
|
|
21
|
+
const base = {
|
|
22
|
+
type: "result",
|
|
23
|
+
launch_id: launchId,
|
|
24
|
+
// cost_usd is the tenant's own model — unknown, NOT 0 (OQ-6).
|
|
25
|
+
cost_usd: null,
|
|
26
|
+
};
|
|
27
|
+
switch (outcome.kind) {
|
|
28
|
+
case "success":
|
|
29
|
+
return {
|
|
30
|
+
...base,
|
|
31
|
+
status: "succeeded",
|
|
32
|
+
text: outcome.text,
|
|
33
|
+
diff: outcome.diff,
|
|
34
|
+
files: outcome.files,
|
|
35
|
+
};
|
|
36
|
+
case "no_changes":
|
|
37
|
+
return {
|
|
38
|
+
...base,
|
|
39
|
+
status: "succeeded",
|
|
40
|
+
text: outcome.text,
|
|
41
|
+
diff: null,
|
|
42
|
+
files: [],
|
|
43
|
+
};
|
|
44
|
+
case "needs_clarification":
|
|
45
|
+
return {
|
|
46
|
+
...base,
|
|
47
|
+
status: "succeeded",
|
|
48
|
+
text: outcome.question,
|
|
49
|
+
diff: null,
|
|
50
|
+
files: [],
|
|
51
|
+
};
|
|
52
|
+
case "failed":
|
|
53
|
+
return {
|
|
54
|
+
...base,
|
|
55
|
+
status: "failed",
|
|
56
|
+
error: outcome.error.slice(-ERROR_TAIL_CHARS),
|
|
57
|
+
};
|
|
58
|
+
case "timed_out":
|
|
59
|
+
return {
|
|
60
|
+
...base,
|
|
61
|
+
status: "timed_out",
|
|
62
|
+
error: outcome.error
|
|
63
|
+
? outcome.error.slice(-ERROR_TAIL_CHARS)
|
|
64
|
+
: "deadline exceeded",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=result-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-map.js","sourceRoot":"","sources":["../../src/spawn/result-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAiBH,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC,uEAAuE;AACvE,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,OAAoB;IAC7D,MAAM,IAAI,GAAG;QACX,IAAI,EAAE,QAAiB;QACvB,SAAS,EAAE,QAAQ;QACnB,8DAA8D;QAC9D,QAAQ,EAAE,IAAI;KACf,CAAC;IAEF,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO;gBACL,GAAG,IAAI;gBACP,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC;QACJ,KAAK,YAAY;YACf,OAAO;gBACL,GAAG,IAAI;gBACP,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,IAAI;gBACV,KAAK,EAAE,EAAE;aACV,CAAC;QACJ,KAAK,qBAAqB;YACxB,OAAO;gBACL,GAAG,IAAI;gBACP,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,OAAO,CAAC,QAAQ;gBACtB,IAAI,EAAE,IAAI;gBACV,KAAK,EAAE,EAAE;aACV,CAAC;QACJ,KAAK,QAAQ;YACX,OAAO;gBACL,GAAG,IAAI;gBACP,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC;aAC9C,CAAC;QACJ,KAAK,WAAW;YACd,OAAO;gBACL,GAAG,IAAI;gBACP,MAAM,EAAE,WAAW;gBACnB,KAAK,EAAE,OAAO,CAAC,KAAK;oBAClB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC;oBACxC,CAAC,CAAC,mBAAmB;aACxB,CAAC;IACN,CAAC;AACH,CAAC"}
|
package/dist/tunnel.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket tunnel to the cloud relay (`/daemon/connect`, design §3).
|
|
3
|
+
*
|
|
4
|
+
* - Bearer in the `Authorization` HEADER (never query — the server rejects query
|
|
5
|
+
* keys and proxies log query strings).
|
|
6
|
+
* - `maxPayload = MAX_FRAME_BYTES` (256 KiB) — the wire-level frame ceiling.
|
|
7
|
+
* - Handshake: send `Hello` on open → recv `HelloAck` (resets backoff) → loop:
|
|
8
|
+
* `Ping`→reply `Pong`, `Launch`→run a launch, `error`→handle.
|
|
9
|
+
* - Inbound frames are zod-validated at the boundary; a malformed frame is logged
|
|
10
|
+
* and ignored — never crashes the loop.
|
|
11
|
+
* - Close codes: 4401 unauth → NO reconnect (exit non-zero); 4409 superseded → NO
|
|
12
|
+
* reconnect (exit clean); 4408 / 1006 / network → reconnect with exp backoff +
|
|
13
|
+
* FULL JITTER (base 1s, cap 30s), unbounded for transient only.
|
|
14
|
+
*/
|
|
15
|
+
import WebSocket from "ws";
|
|
16
|
+
import { type Launch, type OutboundFrame } from "./frames.js";
|
|
17
|
+
export declare const CLOSE_UNAUTH = 4401;
|
|
18
|
+
export declare const CLOSE_HEARTBEAT = 4408;
|
|
19
|
+
export declare const CLOSE_SUPERSEDED = 4409;
|
|
20
|
+
export declare const BACKOFF_BASE_MS = 1000;
|
|
21
|
+
export declare const BACKOFF_CAP_MS = 30000;
|
|
22
|
+
/** Full-jitter backoff for retry `attempt` (0-based). PUBLIC for unit testing. */
|
|
23
|
+
export declare function backoffDelayMs(attempt: number, random?: () => number): number;
|
|
24
|
+
/**
|
|
25
|
+
* Decide the outbound HTTPS proxy for `serverUrl` from the env (DR-1). Returns the
|
|
26
|
+
* proxy URL string when `HTTPS_PROXY`/`https_proxy` is set AND the host is NOT
|
|
27
|
+
* excluded by `NO_PROXY`/`no_proxy`; otherwise `null` (direct dial). Pure + unit
|
|
28
|
+
* tested — no I/O, env injected for tests.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveProxyUrl(serverUrl: string, env?: NodeJS.ProcessEnv): string | null;
|
|
31
|
+
export interface TunnelOptions {
|
|
32
|
+
readonly serverUrl: string;
|
|
33
|
+
readonly apiKey: string;
|
|
34
|
+
readonly daemonVersion: string;
|
|
35
|
+
readonly advertisedTools: string[];
|
|
36
|
+
/** Handle one Launch → resolve with the outbound frames to send (Progress*, Result). */
|
|
37
|
+
readonly onLaunch: (launch: Launch, send: (frame: OutboundFrame) => void) => Promise<void>;
|
|
38
|
+
/** Stop after the first handled launch (`--once`, for CI). */
|
|
39
|
+
readonly once: boolean;
|
|
40
|
+
/** Injected for tests; defaults to the real `ws`. */
|
|
41
|
+
readonly wsFactory?: (url: string, opts: {
|
|
42
|
+
headers: Record<string, string>;
|
|
43
|
+
maxPayload: number;
|
|
44
|
+
}) => WebSocket;
|
|
45
|
+
readonly random?: () => number;
|
|
46
|
+
/** Sleep hook (injected for tests). */
|
|
47
|
+
readonly sleep?: (ms: number) => Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
/** Why the connection loop terminated (drives exit code). */
|
|
50
|
+
export type TunnelExit = {
|
|
51
|
+
kind: "unauth";
|
|
52
|
+
} | {
|
|
53
|
+
kind: "superseded";
|
|
54
|
+
} | {
|
|
55
|
+
kind: "once_done";
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Run the tunnel until a terminal condition (4401 / 4409 / `--once`). Transient
|
|
59
|
+
* disconnects reconnect with backoff. Resolves with the terminal exit reason.
|
|
60
|
+
*/
|
|
61
|
+
export declare function runTunnel(opts: TunnelOptions): Promise<TunnelExit>;
|
package/dist/tunnel.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket tunnel to the cloud relay (`/daemon/connect`, design §3).
|
|
3
|
+
*
|
|
4
|
+
* - Bearer in the `Authorization` HEADER (never query — the server rejects query
|
|
5
|
+
* keys and proxies log query strings).
|
|
6
|
+
* - `maxPayload = MAX_FRAME_BYTES` (256 KiB) — the wire-level frame ceiling.
|
|
7
|
+
* - Handshake: send `Hello` on open → recv `HelloAck` (resets backoff) → loop:
|
|
8
|
+
* `Ping`→reply `Pong`, `Launch`→run a launch, `error`→handle.
|
|
9
|
+
* - Inbound frames are zod-validated at the boundary; a malformed frame is logged
|
|
10
|
+
* and ignored — never crashes the loop.
|
|
11
|
+
* - Close codes: 4401 unauth → NO reconnect (exit non-zero); 4409 superseded → NO
|
|
12
|
+
* reconnect (exit clean); 4408 / 1006 / network → reconnect with exp backoff +
|
|
13
|
+
* FULL JITTER (base 1s, cap 30s), unbounded for transient only.
|
|
14
|
+
*/
|
|
15
|
+
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
16
|
+
import WebSocket from "ws";
|
|
17
|
+
import { MAX_FRAME_BYTES, makeHello, makePong, parseInbound, } from "./frames.js";
|
|
18
|
+
import { log } from "./logging.js";
|
|
19
|
+
// Close codes (mirror daemon_connect.py §8.6).
|
|
20
|
+
export const CLOSE_UNAUTH = 4401;
|
|
21
|
+
export const CLOSE_HEARTBEAT = 4408;
|
|
22
|
+
export const CLOSE_SUPERSEDED = 4409;
|
|
23
|
+
// Backoff (design §3): exp base 1s, cap 30s, full jitter.
|
|
24
|
+
export const BACKOFF_BASE_MS = 1000;
|
|
25
|
+
export const BACKOFF_CAP_MS = 30_000;
|
|
26
|
+
/** Full-jitter backoff for retry `attempt` (0-based). PUBLIC for unit testing. */
|
|
27
|
+
export function backoffDelayMs(attempt, random = Math.random) {
|
|
28
|
+
const exp = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** attempt);
|
|
29
|
+
return Math.floor(random() * exp);
|
|
30
|
+
}
|
|
31
|
+
/** True if `host` matches any NO_PROXY entry (DR-1). `*` / empty entry = match-all. */
|
|
32
|
+
function hostMatchesNoProxy(host, noProxy) {
|
|
33
|
+
const lowerHost = host.toLowerCase();
|
|
34
|
+
for (const rawEntry of noProxy.split(",")) {
|
|
35
|
+
const entry = rawEntry.trim().toLowerCase();
|
|
36
|
+
if (entry === "")
|
|
37
|
+
continue;
|
|
38
|
+
if (entry === "*")
|
|
39
|
+
return true;
|
|
40
|
+
// Leading-dot / suffix match: ".example.com" or "example.com" matches sub.example.com.
|
|
41
|
+
const suffix = entry.startsWith(".") ? entry : `.${entry}`;
|
|
42
|
+
if (lowerHost === entry || lowerHost.endsWith(suffix))
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Decide the outbound HTTPS proxy for `serverUrl` from the env (DR-1). Returns the
|
|
49
|
+
* proxy URL string when `HTTPS_PROXY`/`https_proxy` is set AND the host is NOT
|
|
50
|
+
* excluded by `NO_PROXY`/`no_proxy`; otherwise `null` (direct dial). Pure + unit
|
|
51
|
+
* tested — no I/O, env injected for tests.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveProxyUrl(serverUrl, env = process.env) {
|
|
54
|
+
const proxy = env["HTTPS_PROXY"] ?? env["https_proxy"] ?? null;
|
|
55
|
+
if (!proxy)
|
|
56
|
+
return null;
|
|
57
|
+
let host;
|
|
58
|
+
try {
|
|
59
|
+
host = new URL(serverUrl).hostname;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const noProxy = env["NO_PROXY"] ?? env["no_proxy"] ?? "";
|
|
65
|
+
if (noProxy && hostMatchesNoProxy(host, noProxy))
|
|
66
|
+
return null;
|
|
67
|
+
return proxy;
|
|
68
|
+
}
|
|
69
|
+
const defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
70
|
+
function defaultWsFactory(url, opts) {
|
|
71
|
+
// DR-1: dial through HTTPS_PROXY when set and the host isn't NO_PROXY-excluded,
|
|
72
|
+
// else direct. Corporate-proxy environments need this to reach the relay at all.
|
|
73
|
+
const proxyUrl = resolveProxyUrl(url);
|
|
74
|
+
const agent = proxyUrl !== null ? new HttpsProxyAgent(proxyUrl) : undefined;
|
|
75
|
+
if (proxyUrl !== null)
|
|
76
|
+
log.info("tunnel.proxy", { proxied: true });
|
|
77
|
+
return new WebSocket(url, {
|
|
78
|
+
headers: opts.headers,
|
|
79
|
+
maxPayload: opts.maxPayload,
|
|
80
|
+
agent,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Run the tunnel until a terminal condition (4401 / 4409 / `--once`). Transient
|
|
85
|
+
* disconnects reconnect with backoff. Resolves with the terminal exit reason.
|
|
86
|
+
*/
|
|
87
|
+
export async function runTunnel(opts) {
|
|
88
|
+
const wsFactory = opts.wsFactory ?? defaultWsFactory;
|
|
89
|
+
const random = opts.random ?? Math.random;
|
|
90
|
+
const sleep = opts.sleep ?? defaultSleep;
|
|
91
|
+
let attempt = 0;
|
|
92
|
+
for (;;) {
|
|
93
|
+
const result = await connectOnce(opts, wsFactory);
|
|
94
|
+
if (result.kind === "unauth")
|
|
95
|
+
return { kind: "unauth" };
|
|
96
|
+
if (result.kind === "superseded")
|
|
97
|
+
return { kind: "superseded" };
|
|
98
|
+
if (result.kind === "once_done")
|
|
99
|
+
return { kind: "once_done" };
|
|
100
|
+
// Transient (handshakeOk resets backoff): reconnect with full jitter.
|
|
101
|
+
if (result.handshakeOk)
|
|
102
|
+
attempt = 0;
|
|
103
|
+
const delay = backoffDelayMs(attempt, random);
|
|
104
|
+
attempt += 1;
|
|
105
|
+
log.info("tunnel.reconnect", { attempt, delay_ms: delay });
|
|
106
|
+
await sleep(delay);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function connectOnce(opts, wsFactory) {
|
|
110
|
+
return new Promise((resolvePromise) => {
|
|
111
|
+
let handshakeOk = false;
|
|
112
|
+
let settled = false;
|
|
113
|
+
const settle = (r) => {
|
|
114
|
+
if (settled)
|
|
115
|
+
return;
|
|
116
|
+
settled = true;
|
|
117
|
+
resolvePromise({ ...r, handshakeOk });
|
|
118
|
+
};
|
|
119
|
+
const ws = wsFactory(opts.serverUrl, {
|
|
120
|
+
// Bearer in the HEADER, never the query string.
|
|
121
|
+
headers: { authorization: `Bearer ${opts.apiKey}` },
|
|
122
|
+
maxPayload: MAX_FRAME_BYTES,
|
|
123
|
+
});
|
|
124
|
+
const send = (frame) => {
|
|
125
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
126
|
+
ws.send(JSON.stringify(frame));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
ws.on("open", () => {
|
|
130
|
+
log.info("tunnel.open", {});
|
|
131
|
+
send(makeHello(opts.daemonVersion, opts.advertisedTools));
|
|
132
|
+
});
|
|
133
|
+
ws.on("message", (data) => {
|
|
134
|
+
void handleMessage(data, ws, opts, send, () => {
|
|
135
|
+
handshakeOk = true;
|
|
136
|
+
}, () => settle({ kind: "once_done", handshakeOk: true }));
|
|
137
|
+
});
|
|
138
|
+
ws.on("close", (code) => {
|
|
139
|
+
log.info("tunnel.close", { code });
|
|
140
|
+
if (code === CLOSE_UNAUTH) {
|
|
141
|
+
settle({ kind: "unauth", handshakeOk });
|
|
142
|
+
}
|
|
143
|
+
else if (code === CLOSE_SUPERSEDED) {
|
|
144
|
+
settle({ kind: "superseded", handshakeOk });
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// 4408 / 1006 / normal / network → reconnect.
|
|
148
|
+
settle({ kind: "transient", handshakeOk });
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
ws.on("error", (err) => {
|
|
152
|
+
// Don't double-settle; the close event (1006 on a failed handshake) drives the
|
|
153
|
+
// reconnect. Log only — never crash the loop.
|
|
154
|
+
log.warn("tunnel.error", { error: err.message });
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async function handleMessage(data, ws, opts, send, onHandshake, onOnceDone) {
|
|
159
|
+
let raw;
|
|
160
|
+
try {
|
|
161
|
+
raw = JSON.parse(data.toString());
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
log.warn("tunnel.bad_json", {});
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
let frame;
|
|
168
|
+
try {
|
|
169
|
+
frame = parseInbound(raw);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Unknown/malformed server frame → log + ignore, never crash the loop.
|
|
173
|
+
log.warn("tunnel.bad_frame", {});
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
switch (frame.type) {
|
|
177
|
+
case "hello_ack":
|
|
178
|
+
onHandshake();
|
|
179
|
+
log.info("tunnel.hello_ack", { machine_id: frame.machine_id });
|
|
180
|
+
return;
|
|
181
|
+
case "ping":
|
|
182
|
+
send(makePong(frame.nonce));
|
|
183
|
+
return;
|
|
184
|
+
case "error":
|
|
185
|
+
log.warn("tunnel.server_error", {
|
|
186
|
+
code: frame.code,
|
|
187
|
+
launch_id: frame.launch_id ?? null,
|
|
188
|
+
});
|
|
189
|
+
return;
|
|
190
|
+
case "launch":
|
|
191
|
+
await opts.onLaunch(frame, send);
|
|
192
|
+
if (opts.once) {
|
|
193
|
+
// One launch handled — close cleanly and signal exit.
|
|
194
|
+
try {
|
|
195
|
+
ws.close(1000);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
/* ignore */
|
|
199
|
+
}
|
|
200
|
+
onOnceDone();
|
|
201
|
+
}
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,EACL,eAAe,EACf,SAAS,EACT,QAAQ,EACR,YAAY,GAIb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AAErC,kFAAkF;AAClF,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,SAAuB,IAAI,CAAC,MAAM;IAElC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,eAAe,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,uFAAuF;AACvF,SAAS,kBAAkB,CAAC,IAAY,EAAE,OAAe;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5C,IAAI,KAAK,KAAK,EAAE;YAAE,SAAS;QAC3B,IAAI,KAAK,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAC/B,uFAAuF;QACvF,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;QAC3D,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC;IAC/D,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,OAAO,IAAI,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9D,OAAO,KAAK,CAAC;AACf,CAAC;AA8BD,MAAM,YAAY,GAAG,CAAC,EAAU,EAAiB,EAAE,CACjD,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAExC,SAAS,gBAAgB,CACvB,GAAW,EACX,IAA6D;IAE7D,gFAAgF;IAChF,iFAAiF;IACjF,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,IAAI,QAAQ,KAAK,IAAI;QAAE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,OAAO,IAAI,SAAS,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAmB;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,gBAAgB,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC;IAEzC,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,SAAS,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAElD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QACxD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAChE,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;YAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAE9D,sEAAsE;QACtE,IAAI,MAAM,CAAC,WAAW;YAAE,OAAO,GAAG,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAQD,SAAS,WAAW,CAClB,IAAmB,EACnB,SAAkD;IAElD,OAAO,IAAI,OAAO,CAAgB,CAAC,cAAc,EAAE,EAAE;QACnD,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,CAAgB,EAAQ,EAAE;YACxC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,cAAc,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;QACxC,CAAC,CAAC;QAEF,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE;YACnC,gDAAgD;YAChD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE;YACnD,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,CAAC,KAAoB,EAAQ,EAAE;YAC1C,IAAI,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;gBACrC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACjB,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YAC5B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAuB,EAAE,EAAE;YAC3C,KAAK,aAAa,CAChB,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,IAAI,EACJ,GAAG,EAAE;gBACH,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC,EACD,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CACvD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE;YAC9B,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YACnC,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1B,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;YAC1C,CAAC;iBAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACrC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,8CAA8C;gBAC9C,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAC5B,+EAA+E;YAC/E,8CAA8C;YAC9C,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,IAAuB,EACvB,EAAa,EACb,IAAmB,EACnB,IAAoC,EACpC,WAAuB,EACvB,UAAsB;IAEtB,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IAED,IAAI,KAAmB,CAAC;IACxB,IAAI,CAAC;QACH,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;QACvE,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW;YACd,WAAW,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YAC/D,OAAO;QACT,KAAK,MAAM;YACT,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5B,OAAO;QACT,KAAK,OAAO;YACV,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE;gBAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;aACnC,CAAC,CAAC;YACH,OAAO;QACT,KAAK,QAAQ;YACX,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACjC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,sDAAsD;gBACtD,IAAI,CAAC;oBACH,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjB,CAAC;gBAAC,MAAM,CAAC;oBACP,YAAY;gBACd,CAAC;gBACD,UAAU,EAAE,CAAC;YACf,CAAC;YACD,OAAO;IACX,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ai-codebot/daemon",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "slock local-runner daemon — dials the cloud relay over outbound WSS and brokers a local coding-agent CLI through a 127.0.0.1 capability proxy.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "ai-codebot",
|
|
7
|
+
"homepage": "https://github.com/lufeng0715/ai-codebot/tree/main/packages/local-daemon#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/lufeng0715/ai-codebot.git",
|
|
11
|
+
"directory": "packages/local-daemon"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/lufeng0715/ai-codebot/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ai-codebot",
|
|
18
|
+
"local-runner",
|
|
19
|
+
"daemon",
|
|
20
|
+
"coding-agent",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"private": false,
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"bin": {
|
|
29
|
+
"codebot-daemon": "dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc -p tsconfig.json",
|
|
41
|
+
"lint": "eslint . --ext .ts",
|
|
42
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
43
|
+
"test": "tsx --test test/*.test.ts",
|
|
44
|
+
"prepack": "tsc -p tsconfig.json"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"https-proxy-agent": "^7.0.6",
|
|
48
|
+
"ws": "^8.18.0",
|
|
49
|
+
"zod": "^3.23.8"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^22.7.5",
|
|
53
|
+
"@types/ws": "^8.5.12",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
55
|
+
"@typescript-eslint/parser": "^7.18.0",
|
|
56
|
+
"eslint": "^8.57.0",
|
|
57
|
+
"tsx": "^4.19.1",
|
|
58
|
+
"typescript": "^5.6.2"
|
|
59
|
+
}
|
|
60
|
+
}
|