@redplanethq/corebrain 2.8.12 → 2.8.14
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/dist/commands/coding/list.js +1 -1
- package/dist/commands/coding/list.js.map +1 -1
- package/dist/commands/coding/setup.d.ts +2 -1
- package/dist/commands/coding/setup.d.ts.map +1 -1
- package/dist/commands/coding/setup.js +1 -24
- package/dist/commands/coding/setup.js.map +1 -1
- package/dist/commands/folder/add.d.ts +13 -0
- package/dist/commands/folder/add.d.ts.map +1 -0
- package/dist/commands/folder/add.js +71 -0
- package/dist/commands/folder/add.js.map +1 -0
- package/dist/commands/folder/index.d.ts +3 -0
- package/dist/commands/folder/index.d.ts.map +1 -0
- package/dist/commands/folder/index.js +5 -0
- package/dist/commands/folder/index.js.map +1 -0
- package/dist/commands/folder/list.d.ts +8 -0
- package/dist/commands/folder/list.d.ts.map +1 -0
- package/dist/commands/folder/list.js +39 -0
- package/dist/commands/folder/list.js.map +1 -0
- package/dist/commands/folder/remove.d.ts +10 -0
- package/dist/commands/folder/remove.d.ts.map +1 -0
- package/dist/commands/folder/remove.js +29 -0
- package/dist/commands/folder/remove.js.map +1 -0
- package/dist/commands/folder/scope.d.ts +13 -0
- package/dist/commands/folder/scope.d.ts.map +1 -0
- package/dist/commands/folder/scope.js +61 -0
- package/dist/commands/folder/scope.js.map +1 -0
- package/dist/commands/gateway/config.d.ts +1 -1
- package/dist/commands/gateway/config.d.ts.map +1 -1
- package/dist/commands/gateway/config.js +122 -116
- package/dist/commands/gateway/config.js.map +1 -1
- package/dist/commands/gateway/register.d.ts +37 -0
- package/dist/commands/gateway/register.d.ts.map +1 -0
- package/dist/commands/gateway/register.js +132 -0
- package/dist/commands/gateway/register.js.map +1 -0
- package/dist/commands/gateway/start.d.ts +2 -1
- package/dist/commands/gateway/start.d.ts.map +1 -1
- package/dist/commands/gateway/start.js +73 -6
- package/dist/commands/gateway/start.js.map +1 -1
- package/dist/commands/gateway/status.d.ts.map +1 -1
- package/dist/commands/gateway/status.js +10 -1
- package/dist/commands/gateway/status.js.map +1 -1
- package/dist/commands/gateway/stop.d.ts.map +1 -1
- package/dist/commands/gateway/stop.js +11 -0
- package/dist/commands/gateway/stop.js.map +1 -1
- package/dist/config/folders.d.ts +20 -0
- package/dist/config/folders.d.ts.map +1 -0
- package/dist/config/folders.js +114 -0
- package/dist/config/folders.js.map +1 -0
- package/dist/server/api/auth.d.ts +17 -0
- package/dist/server/api/auth.d.ts.map +1 -0
- package/dist/server/api/auth.js +45 -0
- package/dist/server/api/auth.js.map +1 -0
- package/dist/server/api/browser/cdp.d.ts +18 -0
- package/dist/server/api/browser/cdp.d.ts.map +1 -0
- package/dist/server/api/browser/cdp.js +137 -0
- package/dist/server/api/browser/cdp.js.map +1 -0
- package/dist/server/api/browser/index.d.ts +3 -0
- package/dist/server/api/browser/index.d.ts.map +1 -0
- package/dist/server/api/browser/index.js +10 -0
- package/dist/server/api/browser/index.js.map +1 -0
- package/dist/server/api/browser/launch.d.ts +17 -0
- package/dist/server/api/browser/launch.d.ts.map +1 -0
- package/dist/server/api/browser/launch.js +41 -0
- package/dist/server/api/browser/launch.js.map +1 -0
- package/dist/server/api/coding/coding_spawn.d.ts +22 -0
- package/dist/server/api/coding/coding_spawn.d.ts.map +1 -0
- package/dist/server/api/coding/coding_spawn.js +121 -0
- package/dist/server/api/coding/coding_spawn.js.map +1 -0
- package/dist/server/api/coding/coding_xterm_session.d.ts +3 -0
- package/dist/server/api/coding/coding_xterm_session.d.ts.map +1 -0
- package/dist/server/api/coding/coding_xterm_session.js +163 -0
- package/dist/server/api/coding/coding_xterm_session.js.map +1 -0
- package/dist/server/api/coding/index.d.ts +10 -0
- package/dist/server/api/coding/index.d.ts.map +1 -0
- package/dist/server/api/coding/index.js +17 -0
- package/dist/server/api/coding/index.js.map +1 -0
- package/dist/server/api/exec/index.d.ts +3 -0
- package/dist/server/api/exec/index.d.ts.map +1 -0
- package/dist/server/api/exec/index.js +6 -0
- package/dist/server/api/exec/index.js.map +1 -0
- package/dist/server/api/files/index.d.ts +3 -0
- package/dist/server/api/files/index.d.ts.map +1 -0
- package/dist/server/api/files/index.js +6 -0
- package/dist/server/api/files/index.js.map +1 -0
- package/dist/server/api/folders/index.d.ts +14 -0
- package/dist/server/api/folders/index.d.ts.map +1 -0
- package/dist/server/api/folders/index.js +161 -0
- package/dist/server/api/folders/index.js.map +1 -0
- package/dist/server/api/manifest-builder.d.ts +13 -0
- package/dist/server/api/manifest-builder.d.ts.map +1 -0
- package/dist/server/api/manifest-builder.js +155 -0
- package/dist/server/api/manifest-builder.js.map +1 -0
- package/dist/server/api/ops.d.ts +3 -0
- package/dist/server/api/ops.d.ts.map +1 -0
- package/dist/server/api/ops.js +32 -0
- package/dist/server/api/ops.js.map +1 -0
- package/dist/server/api/server.d.ts +9 -0
- package/dist/server/api/server.d.ts.map +1 -0
- package/dist/server/api/server.js +66 -0
- package/dist/server/api/server.js.map +1 -0
- package/dist/server/api/shell/index.d.ts +17 -0
- package/dist/server/api/shell/index.d.ts.map +1 -0
- package/dist/server/api/shell/index.js +61 -0
- package/dist/server/api/shell/index.js.map +1 -0
- package/dist/server/api/tool-group.d.ts +21 -0
- package/dist/server/api/tool-group.d.ts.map +1 -0
- package/dist/server/api/tool-group.js +23 -0
- package/dist/server/api/tool-group.js.map +1 -0
- package/dist/server/api/tunnels/ngrok.d.ts +10 -0
- package/dist/server/api/tunnels/ngrok.d.ts.map +1 -0
- package/dist/server/api/tunnels/ngrok.js +33 -0
- package/dist/server/api/tunnels/ngrok.js.map +1 -0
- package/dist/server/api/tunnels/tailscale.d.ts +12 -0
- package/dist/server/api/tunnels/tailscale.d.ts.map +1 -0
- package/dist/server/api/tunnels/tailscale.js +49 -0
- package/dist/server/api/tunnels/tailscale.js.map +1 -0
- package/dist/server/api/utils/index.d.ts +3 -0
- package/dist/server/api/utils/index.d.ts.map +1 -0
- package/dist/server/api/utils/index.js +6 -0
- package/dist/server/api/utils/index.js.map +1 -0
- package/dist/server/gateway-entry.d.ts +2 -2
- package/dist/server/gateway-entry.js +43 -106
- package/dist/server/gateway-entry.js.map +1 -1
- package/dist/server/gateway-log.d.ts +10 -0
- package/dist/server/gateway-log.d.ts.map +1 -0
- package/dist/server/gateway-log.js +33 -0
- package/dist/server/gateway-log.js.map +1 -0
- package/dist/server/pty/manager.d.ts +75 -0
- package/dist/server/pty/manager.d.ts.map +1 -0
- package/dist/server/pty/manager.js +280 -0
- package/dist/server/pty/manager.js.map +1 -0
- package/dist/server/tools/coding-tools.d.ts.map +1 -1
- package/dist/server/tools/coding-tools.js +83 -19
- package/dist/server/tools/coding-tools.js.map +1 -1
- package/dist/server/tools/exec-tools.d.ts.map +1 -1
- package/dist/server/tools/exec-tools.js +30 -3
- package/dist/server/tools/exec-tools.js.map +1 -1
- package/dist/server/tools/files-tools.d.ts +8 -0
- package/dist/server/tools/files-tools.d.ts.map +1 -0
- package/dist/server/tools/files-tools.js +523 -0
- package/dist/server/tools/files-tools.js.map +1 -0
- package/dist/server/tools/scope-error.d.ts +8 -0
- package/dist/server/tools/scope-error.d.ts.map +1 -0
- package/dist/server/tools/scope-error.js +11 -0
- package/dist/server/tools/scope-error.js.map +1 -0
- package/dist/types/config.d.ts +15 -3
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/agent-templates.d.ts +18 -0
- package/dist/utils/agent-templates.d.ts.map +1 -0
- package/dist/utils/agent-templates.js +59 -0
- package/dist/utils/agent-templates.js.map +1 -0
- package/dist/utils/browser-manager.d.ts +20 -0
- package/dist/utils/browser-manager.d.ts.map +1 -1
- package/dist/utils/browser-manager.js +76 -0
- package/dist/utils/browser-manager.js.map +1 -1
- package/dist/utils/coding-agents/claude-code.d.ts +1 -0
- package/dist/utils/coding-agents/claude-code.d.ts.map +1 -1
- package/dist/utils/coding-agents/claude-code.js +9 -0
- package/dist/utils/coding-agents/claude-code.js.map +1 -1
- package/dist/utils/coding-agents/codex.d.ts +6 -8
- package/dist/utils/coding-agents/codex.d.ts.map +1 -1
- package/dist/utils/coding-agents/codex.js +16 -19
- package/dist/utils/coding-agents/codex.js.map +1 -1
- package/dist/utils/coding-agents/index.d.ts +1 -0
- package/dist/utils/coding-agents/index.d.ts.map +1 -1
- package/dist/utils/coding-agents/index.js +3 -0
- package/dist/utils/coding-agents/index.js.map +1 -1
- package/dist/utils/coding-agents/types.d.ts +6 -0
- package/dist/utils/coding-agents/types.d.ts.map +1 -1
- package/dist/utils/coding-agents/types.js.map +1 -1
- package/dist/utils/coding-runner.d.ts +13 -9
- package/dist/utils/coding-runner.d.ts.map +1 -1
- package/dist/utils/coding-runner.js +45 -78
- package/dist/utils/coding-runner.js.map +1 -1
- package/dist/utils/env-bootstrap.d.ts +29 -0
- package/dist/utils/env-bootstrap.d.ts.map +1 -0
- package/dist/utils/env-bootstrap.js +204 -0
- package/dist/utils/env-bootstrap.js.map +1 -0
- package/package.json +8 -1
- package/dist/commands/coding/close.d.ts +0 -11
- package/dist/commands/coding/close.d.ts.map +0 -1
- package/dist/commands/coding/close.js +0 -76
- package/dist/commands/coding/close.js.map +0 -1
- package/dist/commands/coding/resume.d.ts +0 -12
- package/dist/commands/coding/resume.d.ts.map +0 -1
- package/dist/commands/coding/resume.js +0 -86
- package/dist/commands/coding/resume.js.map +0 -1
- package/dist/commands/coding/start.d.ts +0 -17
- package/dist/commands/coding/start.d.ts.map +0 -1
- package/dist/commands/coding/start.js +0 -135
- package/dist/commands/coding/start.js.map +0 -1
- package/dist/server/gateway-client.d.ts +0 -84
- package/dist/server/gateway-client.d.ts.map +0 -1
- package/dist/server/gateway-client.js +0 -340
- package/dist/server/gateway-client.js.map +0 -1
- package/dist/server/tools/imessage-tools.d.ts +0 -34
- package/dist/server/tools/imessage-tools.d.ts.map +0 -1
- package/dist/server/tools/imessage-tools.js +0 -262
- package/dist/server/tools/imessage-tools.js.map +0 -1
- package/dist/utils/app-bundle.d.ts +0 -25
- package/dist/utils/app-bundle.d.ts.map +0 -1
- package/dist/utils/app-bundle.js +0 -117
- package/dist/utils/app-bundle.js.map +0 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
import { getSessionCdpInfo } from '../../../utils/browser-manager.js';
|
|
3
|
+
import { gatewayLog } from '../../../server/gateway-log.js';
|
|
4
|
+
/**
|
|
5
|
+
* WebSocket proxy that pipes Chrome DevTools Protocol traffic between the
|
|
6
|
+
* webapp and a running Playwright-launched Chromium.
|
|
7
|
+
*
|
|
8
|
+
* GET /api/browser/cdp/:session
|
|
9
|
+
*
|
|
10
|
+
* Looks up the session's `--remote-debugging-port` endpoint (captured at
|
|
11
|
+
* launch time in `browser-manager.ts`), opens a client WS to the local
|
|
12
|
+
* Chromium, and pipes frames in both directions. The exposed endpoint is
|
|
13
|
+
* the *browser-level* CDP — the webapp viewer issues `Target.getTargets`
|
|
14
|
+
* and `Target.attachToTarget` to talk to a specific page.
|
|
15
|
+
*
|
|
16
|
+
* Closes with `4404` if the session isn't running. Closes with `4502` if
|
|
17
|
+
* the upstream Chromium WS handshake fails.
|
|
18
|
+
*/
|
|
19
|
+
export const browserCdpRoute = async (app) => {
|
|
20
|
+
app.get('/cdp/:session', { websocket: true }, (client, req) => {
|
|
21
|
+
const sessionName = req.params?.session;
|
|
22
|
+
if (!sessionName) {
|
|
23
|
+
client.close(4400, 'session is required');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const info = getSessionCdpInfo(sessionName);
|
|
27
|
+
if (!info) {
|
|
28
|
+
client.close(4404, `browser session "${sessionName}" is not running`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
gatewayLog(`browser cdp proxy: session=${sessionName} → ${info.wsEndpoint}`);
|
|
32
|
+
const upstream = new WebSocket(info.wsEndpoint, {
|
|
33
|
+
perMessageDeflate: false,
|
|
34
|
+
});
|
|
35
|
+
// 1005/1006/1015 etc. are reserved "received-only" codes — passing them
|
|
36
|
+
// to ws.close() throws. Forward only sendable codes; fall back to 1000.
|
|
37
|
+
const sanitizeCode = (code) => code === 1000 || (code >= 3000 && code <= 4999) ? code : 1000;
|
|
38
|
+
const closeBoth = (code = 1000, reason = '') => {
|
|
39
|
+
const safe = sanitizeCode(code);
|
|
40
|
+
try {
|
|
41
|
+
if (client.readyState === client.OPEN)
|
|
42
|
+
client.close(safe, reason);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* already closing */
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
if (upstream.readyState === upstream.OPEN)
|
|
49
|
+
upstream.close(safe, reason);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* already closing */
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
// CDP frames are JSON text — `ws` delivers them as Buffer by default,
|
|
56
|
+
// and `send(buffer)` would re-emit them as a binary frame, which
|
|
57
|
+
// Chromium rejects (it closes the socket on a binary frame against
|
|
58
|
+
// a text protocol). Normalize to UTF-8 strings before forwarding so
|
|
59
|
+
// the relay always emits text frames in both directions.
|
|
60
|
+
const toText = (data) => {
|
|
61
|
+
if (typeof data === 'string')
|
|
62
|
+
return data;
|
|
63
|
+
if (Buffer.isBuffer(data))
|
|
64
|
+
return data.toString('utf8');
|
|
65
|
+
if (Array.isArray(data))
|
|
66
|
+
return Buffer.concat(data).toString('utf8');
|
|
67
|
+
if (data instanceof ArrayBuffer)
|
|
68
|
+
return Buffer.from(data).toString('utf8');
|
|
69
|
+
return String(data);
|
|
70
|
+
};
|
|
71
|
+
// Fastify accepts the client WS upgrade before this handler runs, so
|
|
72
|
+
// the browser may have already sent its first CDP frames (e.g.
|
|
73
|
+
// `Target.setDiscoverTargets`) by the time we get here. Buffer them
|
|
74
|
+
// until upstream is open so nothing is dropped.
|
|
75
|
+
const queue = [];
|
|
76
|
+
let upstreamReady = false;
|
|
77
|
+
let clientFrames = 0;
|
|
78
|
+
let upstreamFrames = 0;
|
|
79
|
+
const previewFrame = (frame) => {
|
|
80
|
+
try {
|
|
81
|
+
const parsed = JSON.parse(frame);
|
|
82
|
+
return parsed.method ?? `id=${parsed.id ?? '?'}`;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return frame.slice(0, 60);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
client.on('message', data => {
|
|
89
|
+
const frame = toText(data);
|
|
90
|
+
clientFrames += 1;
|
|
91
|
+
if (clientFrames <= 2) {
|
|
92
|
+
gatewayLog(`cdp client→upstream [${clientFrames}]: ${previewFrame(frame)} (queued=${!upstreamReady})`);
|
|
93
|
+
}
|
|
94
|
+
if (upstreamReady && upstream.readyState === upstream.OPEN) {
|
|
95
|
+
upstream.send(frame);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
queue.push(frame);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
upstream.on('open', () => {
|
|
102
|
+
upstreamReady = true;
|
|
103
|
+
gatewayLog(`cdp upstream open, flushing ${queue.length} queued frame(s)`);
|
|
104
|
+
for (const frame of queue) {
|
|
105
|
+
if (upstream.readyState === upstream.OPEN)
|
|
106
|
+
upstream.send(frame);
|
|
107
|
+
}
|
|
108
|
+
queue.length = 0;
|
|
109
|
+
upstream.on('message', data => {
|
|
110
|
+
const frame = toText(data);
|
|
111
|
+
upstreamFrames += 1;
|
|
112
|
+
if (upstreamFrames <= 2) {
|
|
113
|
+
gatewayLog(`cdp upstream→client [${upstreamFrames}]: ${previewFrame(frame)}`);
|
|
114
|
+
}
|
|
115
|
+
if (client.readyState === client.OPEN)
|
|
116
|
+
client.send(frame);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
upstream.on('close', (code, reason) => {
|
|
120
|
+
gatewayLog(`cdp upstream closed: code=${code} reason=${reason?.toString() ?? ''}`);
|
|
121
|
+
closeBoth(code, reason?.toString());
|
|
122
|
+
});
|
|
123
|
+
client.on('close', (code, reason) => {
|
|
124
|
+
gatewayLog(`cdp client closed: code=${code} reason=${reason?.toString() ?? ''}`);
|
|
125
|
+
closeBoth(code, reason?.toString());
|
|
126
|
+
});
|
|
127
|
+
upstream.on('error', err => {
|
|
128
|
+
gatewayLog(`browser cdp upstream error: ${err.message}`);
|
|
129
|
+
closeBoth(4502, 'upstream cdp error');
|
|
130
|
+
});
|
|
131
|
+
client.on('error', err => {
|
|
132
|
+
gatewayLog(`browser cdp client error: ${err instanceof Error ? err.message : String(err)}`);
|
|
133
|
+
closeBoth(1011, 'client error');
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=cdp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../../../src/server/api/browser/cdp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/api/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAMhD,eAAO,MAAM,aAAa,EAAE,kBAI3B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { browserTools, executeBrowserTool } from '../../../server/tools/browser-tools.js';
|
|
2
|
+
import { makeToolGroupRoutes } from '../tool-group.js';
|
|
3
|
+
import { browserCdpRoute } from './cdp.js';
|
|
4
|
+
import { browserLaunchRoute } from './launch.js';
|
|
5
|
+
export const browserRoutes = async (app) => {
|
|
6
|
+
await app.register(makeToolGroupRoutes(browserTools, executeBrowserTool));
|
|
7
|
+
await app.register(browserCdpRoute);
|
|
8
|
+
await app.register(browserLaunchRoute);
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/api/browser/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAC,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,eAAe,EAAC,MAAM,OAAO,CAAC;AACtC,OAAO,EAAC,kBAAkB,EAAC,MAAM,UAAU,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAuB,KAAK,EAAE,GAAG,EAAE,EAAE;IAC9D,MAAM,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAC1E,MAAM,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACpC,MAAM,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AACxC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
/**
|
|
3
|
+
* Lazy-launch (or attach to) a configured browser session by name.
|
|
4
|
+
*
|
|
5
|
+
* POST /api/browser/launch
|
|
6
|
+
* body: { session }
|
|
7
|
+
* → 200 { ok: true } on success
|
|
8
|
+
* → 404 / 500 on failure with `error`
|
|
9
|
+
*
|
|
10
|
+
* Always launches headless — the live view is delivered via CDP screencast
|
|
11
|
+
* (`/api/browser/cdp/<session>`), so no visible window is needed and remote
|
|
12
|
+
* gateways (Docker / Railway) work the same way as laptop ones. Idempotent —
|
|
13
|
+
* `getOrLaunchSession` reuses the cached `BrowserSession` if it's already
|
|
14
|
+
* running.
|
|
15
|
+
*/
|
|
16
|
+
export declare const browserLaunchRoute: FastifyPluginAsync;
|
|
17
|
+
//# sourceMappingURL=launch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../../../src/server/api/browser/launch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAIhD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAyBhC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getOrLaunchSession } from '../../../utils/browser-manager.js';
|
|
2
|
+
import { gatewayLog } from '../../../server/gateway-log.js';
|
|
3
|
+
/**
|
|
4
|
+
* Lazy-launch (or attach to) a configured browser session by name.
|
|
5
|
+
*
|
|
6
|
+
* POST /api/browser/launch
|
|
7
|
+
* body: { session }
|
|
8
|
+
* → 200 { ok: true } on success
|
|
9
|
+
* → 404 / 500 on failure with `error`
|
|
10
|
+
*
|
|
11
|
+
* Always launches headless — the live view is delivered via CDP screencast
|
|
12
|
+
* (`/api/browser/cdp/<session>`), so no visible window is needed and remote
|
|
13
|
+
* gateways (Docker / Railway) work the same way as laptop ones. Idempotent —
|
|
14
|
+
* `getOrLaunchSession` reuses the cached `BrowserSession` if it's already
|
|
15
|
+
* running.
|
|
16
|
+
*/
|
|
17
|
+
export const browserLaunchRoute = async (app) => {
|
|
18
|
+
app.post('/launch', async (req, reply) => {
|
|
19
|
+
const body = (req.body ?? {});
|
|
20
|
+
if (!body.session) {
|
|
21
|
+
reply.code(400);
|
|
22
|
+
return { ok: false, error: '`session` is required' };
|
|
23
|
+
}
|
|
24
|
+
gatewayLog(`browser launch: session=${body.session}`);
|
|
25
|
+
const result = await getOrLaunchSession(body.session, false);
|
|
26
|
+
if (result.error) {
|
|
27
|
+
gatewayLog(`browser launch FAILED: ${result.error}`);
|
|
28
|
+
reply.code(500);
|
|
29
|
+
return { ok: false, error: result.error };
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
ok: true,
|
|
33
|
+
session: {
|
|
34
|
+
name: result.session.sessionName,
|
|
35
|
+
profile: result.session.profile,
|
|
36
|
+
cdpReady: Boolean(result.session.cdpWsEndpoint),
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../../../../src/server/api/browser/launch.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAEhD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAuB,KAAK,EAAE,GAAG,EAAE,EAAE;IACnE,GAAG,CAAC,IAAI,CAEL,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAuB,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAC,CAAC;QACpD,CAAC;QACD,UAAU,CAAC,2BAA2B,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7D,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,UAAU,CAAC,0BAA0B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAC,CAAC;QACzC,CAAC;QACD,OAAO;YACN,EAAE,EAAE,IAAI;YACR,OAAO,EAAE;gBACR,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW;gBAChC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO;gBAC/B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;aAC/C;SACD,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
/**
|
|
3
|
+
* Spawn (or resume) a coding agent's interactive TUI so the xterm WS has a
|
|
4
|
+
* PTY to attach to. This is a webapp-only primitive — LLM callers use
|
|
5
|
+
* `coding_ask` which requires a prompt.
|
|
6
|
+
*
|
|
7
|
+
* POST /api/coding/spawn
|
|
8
|
+
* body: { agent, dir, sessionId? }
|
|
9
|
+
* → 200 { ok: true, sessionId, pid, status }
|
|
10
|
+
*
|
|
11
|
+
* Semantics (mirrors the old Tauri PTY reconnect logic):
|
|
12
|
+
* - No `sessionId` → new interactive session. A UUID is allocated; for
|
|
13
|
+
* codex-cli we re-key to the session id codex writes to disk.
|
|
14
|
+
* - `sessionId` present:
|
|
15
|
+
* • PTY is live for that id → noop; xterm attach will reconnect.
|
|
16
|
+
* • PTY exited / not present → spawn fresh using `resumeArgs`.
|
|
17
|
+
*
|
|
18
|
+
* `status` is one of `"new" | "reconnect" | "resumed"` so the caller knows
|
|
19
|
+
* what happened.
|
|
20
|
+
*/
|
|
21
|
+
export declare const codingSpawnRoute: FastifyPluginAsync;
|
|
22
|
+
//# sourceMappingURL=coding_spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coding_spawn.d.ts","sourceRoot":"","sources":["../../../../src/server/api/coding/coding_spawn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAehD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAqH9B,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { getAgentConfig, buildStartArgs, buildResumeArgs, startAgentProcess, } from '../../../utils/coding-runner.js';
|
|
4
|
+
import { upsertSession, deleteSession } from '../../../utils/coding-sessions.js';
|
|
5
|
+
import { listFolders, resolveFolderForPath } from '../../../config/folders.js';
|
|
6
|
+
import { ptyManager } from '../../../server/pty/manager.js';
|
|
7
|
+
import { findLatestCodexSession } from '../../../utils/coding-agents/index.js';
|
|
8
|
+
import { gatewayLog } from '../../../server/gateway-log.js';
|
|
9
|
+
/**
|
|
10
|
+
* Spawn (or resume) a coding agent's interactive TUI so the xterm WS has a
|
|
11
|
+
* PTY to attach to. This is a webapp-only primitive — LLM callers use
|
|
12
|
+
* `coding_ask` which requires a prompt.
|
|
13
|
+
*
|
|
14
|
+
* POST /api/coding/spawn
|
|
15
|
+
* body: { agent, dir, sessionId? }
|
|
16
|
+
* → 200 { ok: true, sessionId, pid, status }
|
|
17
|
+
*
|
|
18
|
+
* Semantics (mirrors the old Tauri PTY reconnect logic):
|
|
19
|
+
* - No `sessionId` → new interactive session. A UUID is allocated; for
|
|
20
|
+
* codex-cli we re-key to the session id codex writes to disk.
|
|
21
|
+
* - `sessionId` present:
|
|
22
|
+
* • PTY is live for that id → noop; xterm attach will reconnect.
|
|
23
|
+
* • PTY exited / not present → spawn fresh using `resumeArgs`.
|
|
24
|
+
*
|
|
25
|
+
* `status` is one of `"new" | "reconnect" | "resumed"` so the caller knows
|
|
26
|
+
* what happened.
|
|
27
|
+
*/
|
|
28
|
+
export const codingSpawnRoute = async (app) => {
|
|
29
|
+
app.post('/spawn', async (req, reply) => {
|
|
30
|
+
const body = (req.body ?? {});
|
|
31
|
+
if (!body.agent || !body.dir) {
|
|
32
|
+
reply.code(400);
|
|
33
|
+
return { ok: false, error: 'agent and dir are required' };
|
|
34
|
+
}
|
|
35
|
+
if (!existsSync(body.dir)) {
|
|
36
|
+
reply.code(400);
|
|
37
|
+
return { ok: false, error: `dir "${body.dir}" does not exist` };
|
|
38
|
+
}
|
|
39
|
+
if (listFolders().length > 0) {
|
|
40
|
+
const folder = resolveFolderForPath(body.dir, 'coding');
|
|
41
|
+
if (!folder) {
|
|
42
|
+
reply.code(403);
|
|
43
|
+
return {
|
|
44
|
+
ok: false,
|
|
45
|
+
error: `dir "${body.dir}" is not inside a coding-scoped folder`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const config = getAgentConfig(body.agent);
|
|
50
|
+
if (!config) {
|
|
51
|
+
reply.code(400);
|
|
52
|
+
return {
|
|
53
|
+
ok: false,
|
|
54
|
+
error: `agent "${body.agent}" is not configured on this gateway`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const isResume = Boolean(body.sessionId);
|
|
58
|
+
// Reconnect short-circuit: if the PTY is live for this id, don't respawn
|
|
59
|
+
// — xterm `attach` will replay the scrollback and keep streaming. Stale
|
|
60
|
+
// (exited) handles at the same id are dropped by `ptyManager.spawn`.
|
|
61
|
+
if (isResume && ptyManager.isRunning(body.sessionId)) {
|
|
62
|
+
return {
|
|
63
|
+
ok: true,
|
|
64
|
+
sessionId: body.sessionId,
|
|
65
|
+
pid: ptyManager.getPid(body.sessionId),
|
|
66
|
+
status: 'reconnect',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
let sessionId = body.sessionId ?? randomUUID();
|
|
70
|
+
const args = isResume
|
|
71
|
+
? buildResumeArgs(config, { sessionId })
|
|
72
|
+
: buildStartArgs(config, { sessionId });
|
|
73
|
+
if (isResume && args.length === 0) {
|
|
74
|
+
reply.code(400);
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
error: `agent "${body.agent}" has no resumeArgs configured`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const startedAt = Date.now();
|
|
81
|
+
upsertSession({ sessionId, agent: body.agent, dir: body.dir, startedAt });
|
|
82
|
+
gatewayLog(`spawn: agent=${body.agent} dir=${body.dir} sessionId=${sessionId} ${isResume ? 'resume' : 'new'}`);
|
|
83
|
+
const { pid, error } = startAgentProcess(sessionId, config, args, body.dir, gatewayLog);
|
|
84
|
+
if (error) {
|
|
85
|
+
deleteSession(sessionId);
|
|
86
|
+
gatewayLog(`spawn FAILED: ${error}`);
|
|
87
|
+
reply.code(500);
|
|
88
|
+
return { ok: false, error: `failed to spawn: ${error}` };
|
|
89
|
+
}
|
|
90
|
+
upsertSession({
|
|
91
|
+
sessionId,
|
|
92
|
+
agent: body.agent,
|
|
93
|
+
dir: body.dir,
|
|
94
|
+
pid,
|
|
95
|
+
startedAt,
|
|
96
|
+
});
|
|
97
|
+
// codex-cli writes a session file named with its own UUID. Re-key our
|
|
98
|
+
// record so downstream lookups (read_session, resume) find the right file.
|
|
99
|
+
if (!isResume && body.agent === 'codex-cli') {
|
|
100
|
+
const found = await findLatestCodexSession(body.dir, startedAt);
|
|
101
|
+
if (found && found.sessionId !== sessionId) {
|
|
102
|
+
deleteSession(sessionId);
|
|
103
|
+
sessionId = found.sessionId;
|
|
104
|
+
upsertSession({
|
|
105
|
+
sessionId,
|
|
106
|
+
agent: body.agent,
|
|
107
|
+
dir: body.dir,
|
|
108
|
+
pid,
|
|
109
|
+
startedAt,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
ok: true,
|
|
115
|
+
sessionId,
|
|
116
|
+
pid,
|
|
117
|
+
status: isResume ? 'resumed' : 'new',
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=coding_spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coding_spawn.js","sourceRoot":"","sources":["../../../../src/server/api/coding/coding_spawn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coding_xterm_session.d.ts","sourceRoot":"","sources":["../../../../src/server/api/coding/coding_xterm_session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AA4GhD,eAAO,MAAM,iBAAiB,EAAE,kBAqG/B,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { ptyManager } from '../../../server/pty/manager.js';
|
|
2
|
+
import { upsertSession } from '../../../utils/coding-sessions.js';
|
|
3
|
+
import { scanAllSessions } from '../../../utils/coding-agents/index.js';
|
|
4
|
+
import { getAgentConfig, buildResumeArgs, startAgentProcess, } from '../../../utils/coding-runner.js';
|
|
5
|
+
import { gatewayLog } from '../../../server/gateway-log.js';
|
|
6
|
+
/**
|
|
7
|
+
* WebSocket endpoint that attaches to a coding session's PTY, automatically
|
|
8
|
+
* resuming the agent when the PTY no longer exists.
|
|
9
|
+
*
|
|
10
|
+
* GET /api/coding/coding_xterm_session?session_id=<id>
|
|
11
|
+
*
|
|
12
|
+
* Resume metadata is read from the agent's own on-disk transcripts (claude
|
|
13
|
+
* `.jsonl` / codex session files) — `sessions.json` carries a stale `dir`
|
|
14
|
+
* (the path the user asked for) whereas the transcript records the agent's
|
|
15
|
+
* real `cwd`, which is what `--resume` needs. If the session id isn't found
|
|
16
|
+
* on disk anywhere, we close with 4404 — there's nothing to resume.
|
|
17
|
+
*
|
|
18
|
+
* Behavior on connect (after attach):
|
|
19
|
+
* - Replays the scrollback buffer (≤256 KB).
|
|
20
|
+
* - Streams new PTY output bytes as raw WS text frames.
|
|
21
|
+
* - Forwards incoming WS messages to the PTY — plain text is written to stdin;
|
|
22
|
+
* JSON `{"kind":"input","data":"..."}` writes `data`; JSON
|
|
23
|
+
* `{"kind":"resize","cols":N,"rows":M}` resizes the PTY.
|
|
24
|
+
* - If the PTY has already exited, replays the buffer then closes.
|
|
25
|
+
*/
|
|
26
|
+
async function resolveSessionMeta(sessionId) {
|
|
27
|
+
try {
|
|
28
|
+
const { sessions } = await scanAllSessions({});
|
|
29
|
+
gatewayLog(`xterm resolve: scanned ${sessions.length} sessions for ${sessionId}`);
|
|
30
|
+
const found = sessions.find(s => s.sessionId === sessionId);
|
|
31
|
+
if (!found) {
|
|
32
|
+
gatewayLog(`xterm resolve: session ${sessionId} not in any agent dir`);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
gatewayLog(`xterm resolve: session ${sessionId} agent=${found.agent} dir=${found.dir}`);
|
|
36
|
+
if (!found.dir || !found.agent) {
|
|
37
|
+
gatewayLog(`xterm resolve: incomplete metadata (agent=${found.agent}, dir=${found.dir})`);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return { agent: found.agent, dir: found.dir };
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
gatewayLog(`xterm resolve: scan failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function tryRespawn(sessionId, meta) {
|
|
48
|
+
const config = getAgentConfig(meta.agent);
|
|
49
|
+
if (!config) {
|
|
50
|
+
return {
|
|
51
|
+
ok: false,
|
|
52
|
+
reason: `agent "${meta.agent}" not configured on this gateway`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const args = buildResumeArgs(config, { sessionId });
|
|
56
|
+
if (args.length === 0) {
|
|
57
|
+
return {
|
|
58
|
+
ok: false,
|
|
59
|
+
reason: `agent "${meta.agent}" has no resumeArgs configured`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const startedAt = Date.now();
|
|
63
|
+
upsertSession({ sessionId, agent: meta.agent, dir: meta.dir, startedAt });
|
|
64
|
+
gatewayLog(`xterm resume: agent=${meta.agent} dir=${meta.dir} sessionId=${sessionId}`);
|
|
65
|
+
const { pid, error } = startAgentProcess(sessionId, config, args, meta.dir, gatewayLog);
|
|
66
|
+
if (error) {
|
|
67
|
+
gatewayLog(`xterm resume FAILED: ${error}`);
|
|
68
|
+
return { ok: false, reason: `failed to spawn: ${error}` };
|
|
69
|
+
}
|
|
70
|
+
upsertSession({
|
|
71
|
+
sessionId,
|
|
72
|
+
agent: meta.agent,
|
|
73
|
+
dir: meta.dir,
|
|
74
|
+
pid,
|
|
75
|
+
startedAt,
|
|
76
|
+
});
|
|
77
|
+
return { ok: true, pid };
|
|
78
|
+
}
|
|
79
|
+
export const xtermSessionRoute = async (app) => {
|
|
80
|
+
app.get('/coding_xterm_session', { websocket: true }, async (socket, req) => {
|
|
81
|
+
const sessionId = req.query?.session_id;
|
|
82
|
+
if (!sessionId) {
|
|
83
|
+
socket.close(4400, 'session_id query param required');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const onData = (data) => {
|
|
87
|
+
if (socket.readyState === socket.OPEN) {
|
|
88
|
+
socket.send(data);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const onExit = ({ exitCode, signal, }) => {
|
|
92
|
+
if (socket.readyState === socket.OPEN) {
|
|
93
|
+
socket.send(JSON.stringify({ kind: 'exit', exitCode, signal }));
|
|
94
|
+
socket.close(1000, `pty exited (${exitCode})`);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
let attach = ptyManager.attach(sessionId, onData, onExit);
|
|
98
|
+
// Resume only when there's no handle for this id at all. If a handle
|
|
99
|
+
// exists but exited (e.g. user typed `exit` in a shell session), fall
|
|
100
|
+
// through to the standard "replay buffer + emit exit + close" path
|
|
101
|
+
// below — re-spawning a fresh agent over a non-coding PTY would be
|
|
102
|
+
// surprising. `resolveSessionMeta` deliberately scans agent
|
|
103
|
+
// transcripts only, so resume targets coding sessions.
|
|
104
|
+
if (!attach) {
|
|
105
|
+
const meta = await resolveSessionMeta(sessionId);
|
|
106
|
+
if (!meta) {
|
|
107
|
+
socket.close(4404, `no session "${sessionId}" — cannot resume`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const result = tryRespawn(sessionId, meta);
|
|
111
|
+
if (!result.ok) {
|
|
112
|
+
socket.close(4500, result.reason);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
attach = ptyManager.attach(sessionId, onData, onExit);
|
|
116
|
+
if (!attach) {
|
|
117
|
+
socket.close(4500, 'spawned session but failed to attach');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Replay scrollback buffer
|
|
122
|
+
if (attach.replayed) {
|
|
123
|
+
socket.send(attach.replayed);
|
|
124
|
+
}
|
|
125
|
+
// If it already exited, replay + close
|
|
126
|
+
if (attach.exited) {
|
|
127
|
+
socket.send(JSON.stringify({
|
|
128
|
+
kind: 'exit',
|
|
129
|
+
exitCode: attach.exitInfo?.exitCode ?? null,
|
|
130
|
+
signal: attach.exitInfo?.signal ?? null,
|
|
131
|
+
}));
|
|
132
|
+
socket.close(1000, 'pty already exited');
|
|
133
|
+
attach.detach();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
socket.on('message', (raw) => {
|
|
137
|
+
const msg = typeof raw === 'string' ? raw : raw.toString('utf8');
|
|
138
|
+
// Try JSON envelope first
|
|
139
|
+
try {
|
|
140
|
+
const parsed = JSON.parse(msg);
|
|
141
|
+
if (parsed && typeof parsed === 'object') {
|
|
142
|
+
if (parsed.kind === 'input' && typeof parsed.data === 'string') {
|
|
143
|
+
ptyManager.write(sessionId, parsed.data);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (parsed.kind === 'resize' && typeof parsed.cols === 'number' && typeof parsed.rows === 'number') {
|
|
147
|
+
ptyManager.resize(sessionId, parsed.cols, parsed.rows);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
/* not JSON — fall through to raw */
|
|
154
|
+
}
|
|
155
|
+
// Fallback: write raw bytes (CLI xterm clients send keystrokes directly)
|
|
156
|
+
ptyManager.write(sessionId, msg);
|
|
157
|
+
});
|
|
158
|
+
socket.on('close', () => {
|
|
159
|
+
attach.detach();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=coding_xterm_session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coding_xterm_session.js","sourceRoot":"","sources":["../../../../src/server/api/coding/coding_xterm_session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
/**
|
|
3
|
+
* Mounted at `/api/coding`. Registers one POST route per coding tool, the
|
|
4
|
+
* xterm WebSocket attach route, and the webapp-only `spawn` primitive used
|
|
5
|
+
* by the new coding session flow. Agent authentication is set up via env
|
|
6
|
+
* vars (`CLAUDE_CODE_OAUTH_TOKEN`, `OPENAI_API_KEY`) at gateway boot — no
|
|
7
|
+
* web UI for it.
|
|
8
|
+
*/
|
|
9
|
+
export declare const codingRoutes: FastifyPluginAsync;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/api/coding/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAMhD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,kBAI1B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { codingTools, executeCodingTool } from '../../../server/tools/coding-tools.js';
|
|
2
|
+
import { makeToolGroupRoutes } from '../tool-group.js';
|
|
3
|
+
import { xtermSessionRoute } from './coding_xterm_session.js';
|
|
4
|
+
import { codingSpawnRoute } from './coding_spawn.js';
|
|
5
|
+
/**
|
|
6
|
+
* Mounted at `/api/coding`. Registers one POST route per coding tool, the
|
|
7
|
+
* xterm WebSocket attach route, and the webapp-only `spawn` primitive used
|
|
8
|
+
* by the new coding session flow. Agent authentication is set up via env
|
|
9
|
+
* vars (`CLAUDE_CODE_OAUTH_TOKEN`, `OPENAI_API_KEY`) at gateway boot — no
|
|
10
|
+
* web UI for it.
|
|
11
|
+
*/
|
|
12
|
+
export const codingRoutes = async (app) => {
|
|
13
|
+
await app.register(makeToolGroupRoutes(codingTools, executeCodingTool));
|
|
14
|
+
await app.register(xtermSessionRoute);
|
|
15
|
+
await app.register(codingSpawnRoute);
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/api/coding/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAE,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAC,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAC,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAuB,KAAK,EAAE,GAAG,EAAE,EAAE;IAC7D,MAAM,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACxE,MAAM,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IACtC,MAAM,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACtC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/api/exec/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAIhD,eAAO,MAAM,UAAU,EAAE,kBAExB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { execTools, executeExecTool } from '../../../server/tools/exec-tools.js';
|
|
2
|
+
import { makeToolGroupRoutes } from '../tool-group.js';
|
|
3
|
+
export const execRoutes = async (app) => {
|
|
4
|
+
await app.register(makeToolGroupRoutes(execTools, executeExecTool));
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/api/exec/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAC,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAElD,MAAM,CAAC,MAAM,UAAU,GAAuB,KAAK,EAAE,GAAG,EAAE,EAAE;IAC3D,MAAM,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC"}
|