agents-bridge 0.3.6 → 0.3.10
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/README.md +14 -0
- package/config.multi-agent.example.json +4 -1
- package/dist/agents/agent-resolver.d.ts.map +1 -1
- package/dist/agents/agent-resolver.js +8 -2
- package/dist/agents/agent-resolver.js.map +1 -1
- package/dist/agents/cli-runner.d.ts +3 -3
- package/dist/agents/cli-runner.d.ts.map +1 -1
- package/dist/agents/cli-runner.js +87 -76
- package/dist/agents/cli-runner.js.map +1 -1
- package/dist/agents/cli-session-store.d.ts +3 -0
- package/dist/agents/cli-session-store.d.ts.map +1 -1
- package/dist/agents/cli-session-store.js +31 -10
- package/dist/agents/cli-session-store.js.map +1 -1
- package/dist/agents/codex-app-server-runtime.d.ts +37 -1
- package/dist/agents/codex-app-server-runtime.d.ts.map +1 -1
- package/dist/agents/codex-app-server-runtime.js +37 -14
- package/dist/agents/codex-app-server-runtime.js.map +1 -1
- package/dist/agents/managed-backend.d.ts +4 -0
- package/dist/agents/managed-backend.d.ts.map +1 -0
- package/dist/agents/managed-backend.js +18 -0
- package/dist/agents/managed-backend.js.map +1 -0
- package/dist/agents/managed-role.d.ts +17 -0
- package/dist/agents/managed-role.d.ts.map +1 -0
- package/dist/agents/managed-role.js +13 -0
- package/dist/agents/managed-role.js.map +1 -0
- package/dist/agents/model-control-files.d.ts +10 -4
- package/dist/agents/model-control-files.d.ts.map +1 -1
- package/dist/agents/model-control-files.js +127 -79
- package/dist/agents/model-control-files.js.map +1 -1
- package/dist/agents/trusted-launcher.js +5 -1
- package/dist/agents/trusted-launcher.js.map +1 -1
- package/dist/agents/windows-model-control-security.d.ts +4 -0
- package/dist/agents/windows-model-control-security.d.ts.map +1 -0
- package/dist/agents/windows-model-control-security.js +86 -0
- package/dist/agents/windows-model-control-security.js.map +1 -0
- package/dist/channels/bot-run-protocol.d.ts +13 -0
- package/dist/channels/bot-run-protocol.d.ts.map +1 -0
- package/dist/channels/bot-run-protocol.js +20 -0
- package/dist/channels/bot-run-protocol.js.map +1 -0
- package/dist/channels/bot-run-receipts.d.ts +14 -0
- package/dist/channels/bot-run-receipts.d.ts.map +1 -0
- package/dist/channels/bot-run-receipts.js +88 -0
- package/dist/channels/bot-run-receipts.js.map +1 -0
- package/dist/channels/botlink.d.ts +3 -0
- package/dist/channels/botlink.d.ts.map +1 -1
- package/dist/channels/botlink.js +95 -17
- package/dist/channels/botlink.js.map +1 -1
- package/dist/channels/managed-receipts.d.ts +14 -0
- package/dist/channels/managed-receipts.d.ts.map +1 -0
- package/dist/channels/managed-receipts.js +136 -0
- package/dist/channels/managed-receipts.js.map +1 -0
- package/dist/cli/cmd-start.d.ts.map +1 -1
- package/dist/cli/cmd-start.js +44 -5
- package/dist/cli/cmd-start.js.map +1 -1
- package/dist/cloud/main.d.ts +2 -0
- package/dist/cloud/main.d.ts.map +1 -0
- package/dist/cloud/main.js +14 -0
- package/dist/cloud/main.js.map +1 -0
- package/dist/cloud/worker.d.ts +98 -0
- package/dist/cloud/worker.d.ts.map +1 -0
- package/dist/cloud/worker.js +212 -0
- package/dist/cloud/worker.js.map +1 -0
- package/dist/config/agent-dirs.d.ts.map +1 -1
- package/dist/config/agent-dirs.js +2 -0
- package/dist/config/agent-dirs.js.map +1 -1
- package/dist/config/attachment-handoff.d.ts +5 -0
- package/dist/config/attachment-handoff.d.ts.map +1 -0
- package/dist/config/attachment-handoff.js +60 -0
- package/dist/config/attachment-handoff.js.map +1 -0
- package/dist/config/zod-schema.d.ts +281 -228
- package/dist/config/zod-schema.d.ts.map +1 -1
- package/dist/config/zod-schema.js +3 -0
- package/dist/config/zod-schema.js.map +1 -1
- package/dist/types/index.d.ts +12 -4
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { mkdirSync, writeFileSync, renameSync, openSync, fsyncSync, closeSync, existsSync, readFileSync, copyFileSync, chmodSync } from 'node:fs';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { performance } from 'node:perf_hooks';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { managedRole } from '../agents/managed-role.js';
|
|
8
|
+
export function workerConfig(env) {
|
|
9
|
+
const api = env.CLOUD_AGENT_API_URL, gateway = env.CLOUD_BOT_GATEWAY_URL, token = env.CLOUD_AGENT_WORKER_TOKEN, codexHome = env.CLOUD_CODEX_AUTH_DIR;
|
|
10
|
+
if (!api || !gateway || !token || token.length < 32 || !codexHome || !env.CLOUD_WORKER_STATE_DIR)
|
|
11
|
+
throw new Error('Missing cloud Worker configuration');
|
|
12
|
+
const allowHttp = env.CLOUD_WORKER_ALLOW_HTTP === 'true';
|
|
13
|
+
for (const raw of [api, gateway]) {
|
|
14
|
+
const u = new URL(raw);
|
|
15
|
+
if (u.username || u.password || u.search || u.hash || (!allowHttp && u.protocol !== 'https:') || !['https:', 'http:'].includes(u.protocol))
|
|
16
|
+
throw new Error('Invalid cloud Worker endpoint');
|
|
17
|
+
}
|
|
18
|
+
const maxAgents = Number(env.CLOUD_WORKER_MAX_AGENTS || 10);
|
|
19
|
+
if (!Number.isInteger(maxAgents) || maxAgents < 1 || maxAgents > 100)
|
|
20
|
+
throw new Error('Invalid cloud Worker capacity');
|
|
21
|
+
return { api: api.replace(/\/$/u, ''), gateway: gateway.replace(/\/$/u, ''), token, poolId: env.CLOUD_AGENT_POOL_ID || 'default', workerId: env.CLOUD_WORKER_ID || randomUUID(), root: resolve(env.CLOUD_WORKER_STATE_DIR), codexHome: resolve(codexHome), maxAgents, allowHttp };
|
|
22
|
+
}
|
|
23
|
+
function writePrivate(path, value) {
|
|
24
|
+
const tmp = path + '.' + randomUUID() + '.tmp', fd = openSync(tmp, 'wx', 0o600);
|
|
25
|
+
try {
|
|
26
|
+
writeFileSync(fd, JSON.stringify(value));
|
|
27
|
+
fsyncSync(fd);
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
closeSync(fd);
|
|
31
|
+
}
|
|
32
|
+
renameSync(tmp, path);
|
|
33
|
+
}
|
|
34
|
+
export function bridgeConfig(claim, home, gateway) {
|
|
35
|
+
managedRole({ roleConfig: claim.config, roleVersionId: claim.roleVersionId }, { model: { primary: 'codex-cli/gpt-6-luna' } });
|
|
36
|
+
const id = 'cloud-' + claim.botId.replaceAll('-', '');
|
|
37
|
+
return { channels: { botlink: { accounts: { [id]: { gateway_url: gateway, openapi_base_url: gateway, bot_token: claim.botToken, managed_runtime: true, poll_timeout: 20, retry_interval: 2, max_retry_interval: 10 } } } },
|
|
38
|
+
agents: { defaults: { model: { primary: 'codex-cli/gpt-6-luna', fallbacks: [] } }, list: [{ id, default: true, name: id, model: { primary: 'codex-cli/gpt-6-luna', fallbacks: [] }, modelControl: false, allowModelSwitch: false, workspace: join(home, 'workspace'), systemPrompt: claim.config.systemPrompt }] },
|
|
39
|
+
bindings: [{ agentId: id, match: { channel: 'botlink', accountId: id } }], concurrency: { maxGlobal: 1, maxPerAgent: 1 }, logging: { pretty: false, level: 'warn' } };
|
|
40
|
+
}
|
|
41
|
+
export class CloudWorker {
|
|
42
|
+
config;
|
|
43
|
+
fetchImpl;
|
|
44
|
+
spawnImpl;
|
|
45
|
+
agents = new Map();
|
|
46
|
+
polling = false;
|
|
47
|
+
stopped = false;
|
|
48
|
+
reachable = false;
|
|
49
|
+
constructor(config, fetchImpl = fetch, spawnImpl = spawn) {
|
|
50
|
+
this.config = config;
|
|
51
|
+
this.fetchImpl = fetchImpl;
|
|
52
|
+
this.spawnImpl = spawnImpl;
|
|
53
|
+
mkdirSync(config.root, { recursive: true, mode: 0o700 });
|
|
54
|
+
}
|
|
55
|
+
health() { return { status: this.stopped ? 'stopped' : this.reachable ? 'ok' : 'waiting', activeAgents: this.agents.size, capacity: this.config.maxAgents }; }
|
|
56
|
+
async api(action, input) {
|
|
57
|
+
const response = await this.fetchImpl(this.config.api + '/' + action, { method: 'POST', headers: { authorization: 'Bearer ' + this.config.token, 'content-type': 'application/json' }, body: JSON.stringify(input), signal: AbortSignal.timeout(5000) });
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
await response.body?.cancel();
|
|
60
|
+
throw new Error(response.status === 409 ? 'WORKER_LEASE_LOST' : 'WORKER_CONTROL_UNAVAILABLE');
|
|
61
|
+
}
|
|
62
|
+
this.reachable = true;
|
|
63
|
+
return await response.json();
|
|
64
|
+
}
|
|
65
|
+
arm(row, leaseMs) {
|
|
66
|
+
clearTimeout(row.watchdog);
|
|
67
|
+
row.deadline = performance.now() + leaseMs - 15000;
|
|
68
|
+
row.watchdog = setTimeout(() => void this.stop(row, 'WORKER_LEASE_EXPIRED'), Math.max(1, leaseMs - 15000));
|
|
69
|
+
row.watchdog.unref();
|
|
70
|
+
}
|
|
71
|
+
start(claim) {
|
|
72
|
+
if (!/^[a-f\d]{8}-(?:[a-f\d]{4}-){3}[a-f\d]{12}$/iu.test(claim.botId) || typeof claim.botToken !== 'string' || !claim.botToken.startsWith('bot_')
|
|
73
|
+
|| typeof claim.permit !== 'string' || claim.leaseMs !== 45000)
|
|
74
|
+
throw new Error('INVALID_WORKER_ASSIGNMENT');
|
|
75
|
+
if (this.agents.has(claim.botId))
|
|
76
|
+
throw new Error('DUPLICATE_WORKER_ASSIGNMENT');
|
|
77
|
+
const home = join(this.config.root, claim.botId), config = bridgeConfig(claim, home, this.config.gateway);
|
|
78
|
+
mkdirSync(home, { recursive: true, mode: 0o700 });
|
|
79
|
+
mkdirSync(join(home, 'codex'), { recursive: true, mode: 0o700 });
|
|
80
|
+
mkdirSync(join(home, 'workspace'), { recursive: true, mode: 0o700 });
|
|
81
|
+
const auth = join(this.config.codexHome, 'auth.json');
|
|
82
|
+
if (!existsSync(auth))
|
|
83
|
+
throw new Error('EXECUTOR_AUTH_UNAVAILABLE');
|
|
84
|
+
copyFileSync(auth, join(home, 'codex', 'auth.json'));
|
|
85
|
+
chmodSync(join(home, 'codex', 'auth.json'), 0o600);
|
|
86
|
+
// Personal config may start MCP/plugin subprocesses or completion hooks.
|
|
87
|
+
// Only executor authentication is shared; every instance gets a fresh restricted config.
|
|
88
|
+
writeFileSync(join(home, 'codex', 'config.toml'), 'approval_policy = "never"\nsandbox_mode = "read-only"\n[features]\nshell_tool = false\nmulti_agent = false\napps = false\n', { mode: 0o600 });
|
|
89
|
+
chmodSync(join(home, 'codex', 'config.toml'), 0o600);
|
|
90
|
+
writePrivate(join(home, 'config.json'), config);
|
|
91
|
+
writePrivate(join(home, 'role.json'), { roleVersionId: claim.roleVersionId, config: claim.config });
|
|
92
|
+
writeFileSync(join(home, 'workspace', 'AGENTS.md'), 'Cloud managed role Agent. Plain text only; no tools or external actions. Every request is independently scoped.\n', { mode: 0o600 });
|
|
93
|
+
const env = { PATH: process.env.PATH, LANG: process.env.LANG, HOME: home, AGENT_BRIDGE_HOME: home, CODEX_HOME: join(home, 'codex'), NODE_ENV: 'production' };
|
|
94
|
+
for (const name of ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'NODE_EXTRA_CA_CERTS'])
|
|
95
|
+
if (process.env[name])
|
|
96
|
+
env[name] = process.env[name];
|
|
97
|
+
const child = this.spawnImpl(process.execPath, [fileURLToPath(new URL('../entry.js', import.meta.url)), 'start', '--config', join(home, 'config.json')], { cwd: home, env, stdio: 'ignore', detached: true });
|
|
98
|
+
const row = { claim, child, home, deadline: 0, watchdog: undefined, version: claim.roleVersionId, stopping: false };
|
|
99
|
+
child.once('error', () => { row.error = 'WORKER_START_FAILED'; });
|
|
100
|
+
child.once('exit', () => { if (!row.stopping)
|
|
101
|
+
row.error = 'WORKER_PROCESS_EXITED'; });
|
|
102
|
+
this.agents.set(claim.botId, row);
|
|
103
|
+
this.arm(row, claim.leaseMs);
|
|
104
|
+
}
|
|
105
|
+
stop(row, error) {
|
|
106
|
+
if (!row.stopPromise)
|
|
107
|
+
row.stopPromise = this.stopProcess(row, error);
|
|
108
|
+
return row.stopPromise;
|
|
109
|
+
}
|
|
110
|
+
async stopProcess(row, error) {
|
|
111
|
+
row.stopping = true;
|
|
112
|
+
clearTimeout(row.watchdog);
|
|
113
|
+
const child = row.child;
|
|
114
|
+
if (child.pid) {
|
|
115
|
+
// The Bridge may have exited while its CLI descendant is still alive.
|
|
116
|
+
// Stop the owned process group before releasing the assignment.
|
|
117
|
+
try {
|
|
118
|
+
process.kill(-child.pid, 'SIGTERM');
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
if (child.exitCode === null)
|
|
122
|
+
child.kill('SIGTERM');
|
|
123
|
+
}
|
|
124
|
+
const deadline = performance.now() + 5000;
|
|
125
|
+
while (performance.now() < deadline) {
|
|
126
|
+
try {
|
|
127
|
+
process.kill(-child.pid, 0);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
await new Promise(done => setTimeout(done, 100));
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
if (child.exitCode === null)
|
|
139
|
+
child.kill('SIGKILL');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
this.agents.delete(row.claim.botId);
|
|
143
|
+
try {
|
|
144
|
+
await this.api('heartbeat', { botId: row.claim.botId, workerId: this.config.workerId, permit: row.claim.permit, state: 'stopped', appliedRoleVersionId: row.version, ...(error ? { error } : {}) });
|
|
145
|
+
}
|
|
146
|
+
catch { }
|
|
147
|
+
}
|
|
148
|
+
async poll() {
|
|
149
|
+
if (this.polling || this.stopped)
|
|
150
|
+
return;
|
|
151
|
+
this.polling = true;
|
|
152
|
+
try {
|
|
153
|
+
for (const row of [...this.agents.values()]) {
|
|
154
|
+
if (row.stopping)
|
|
155
|
+
continue;
|
|
156
|
+
if (performance.now() >= row.deadline || row.error) {
|
|
157
|
+
await this.stop(row, row.error || 'WORKER_LEASE_EXPIRED');
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const runtimePath = join(row.home, 'runtime.json');
|
|
161
|
+
let ready = false;
|
|
162
|
+
if (existsSync(runtimePath)) {
|
|
163
|
+
try {
|
|
164
|
+
const runtime = JSON.parse(readFileSync(runtimePath, 'utf8'));
|
|
165
|
+
ready = runtime.pid === row.child.pid;
|
|
166
|
+
}
|
|
167
|
+
catch { }
|
|
168
|
+
}
|
|
169
|
+
const result = await this.api('heartbeat', { botId: row.claim.botId, workerId: this.config.workerId, permit: row.claim.permit, state: ready ? 'running' : 'starting', appliedRoleVersionId: row.version });
|
|
170
|
+
if (row.stopping || this.stopped)
|
|
171
|
+
continue;
|
|
172
|
+
if (result.desiredState !== 'running') {
|
|
173
|
+
await this.stop(row);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
managedRole({ roleConfig: result.config, roleVersionId: result.roleVersionId }, { model: { primary: 'codex-cli/gpt-6-luna' } });
|
|
177
|
+
if (row.version !== result.roleVersionId) {
|
|
178
|
+
writePrivate(join(row.home, 'role.json'), { roleVersionId: result.roleVersionId, config: result.config });
|
|
179
|
+
row.version = result.roleVersionId;
|
|
180
|
+
}
|
|
181
|
+
this.arm(row, result.leaseMs);
|
|
182
|
+
}
|
|
183
|
+
if (this.agents.size < this.config.maxAgents) {
|
|
184
|
+
const result = await this.api('acquire', { workerId: this.config.workerId, poolId: this.config.poolId, limit: Math.min(5, this.config.maxAgents - this.agents.size) });
|
|
185
|
+
if (this.stopped) {
|
|
186
|
+
for (const claim of result.claims || [])
|
|
187
|
+
await this.api('heartbeat', { botId: claim.botId, workerId: this.config.workerId, permit: claim.permit, state: 'stopped' });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (!Array.isArray(result.claims) || result.claims.length > this.config.maxAgents - this.agents.size || new Set(result.claims.map((c) => c.botId)).size !== result.claims.length || result.claims.some((c) => this.agents.has(c.botId)))
|
|
191
|
+
throw new Error('INVALID_WORKER_ASSIGNMENT');
|
|
192
|
+
for (const claim of result.claims) {
|
|
193
|
+
try {
|
|
194
|
+
this.start(claim);
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
await this.api('heartbeat', { botId: claim.botId, workerId: this.config.workerId, permit: claim.permit, state: 'stopped', error: 'WORKER_START_FAILED' });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
this.reachable = false;
|
|
204
|
+
console.warn(JSON.stringify({ event: 'cloud_worker_deferred', code: error instanceof Error && error.message === 'WORKER_LEASE_LOST' ? 'WORKER_LEASE_LOST' : 'WORKER_CONTROL_UNAVAILABLE' }));
|
|
205
|
+
}
|
|
206
|
+
finally {
|
|
207
|
+
this.polling = false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async shutdown() { this.stopped = true; await Promise.all([...this.agents.values()].map(row => this.stop(row))); }
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/cloud/worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-dirs.d.ts","sourceRoot":"","sources":["../../src/config/agent-dirs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-dirs.d.ts","sourceRoot":"","sources":["../../src/config/agent-dirs.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBrD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAoBrF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdirSync, existsSync, copyFileSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
+
import { restoreAttachmentHandoff } from './attachment-handoff.js';
|
|
3
4
|
import { DATA_DIR, DATA_SESSIONS_DIR, DATA_CLI_SESSION_STORE_PATH, DATA_FILES_DIR, DATA_LOGS_DIR, DATA_SKILLS_DIR, agentStatePath, agentSessionStorePath, } from './paths.js';
|
|
4
5
|
/**
|
|
5
6
|
* Ensure data directories exist.
|
|
@@ -30,6 +31,7 @@ export function ensureDataDirs(tempDir) {
|
|
|
30
31
|
mkdirSync(resolved, { recursive: true });
|
|
31
32
|
}
|
|
32
33
|
}
|
|
34
|
+
restoreAttachmentHandoff();
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* Ensure per-agent state directories exist.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-dirs.js","sourceRoot":"","sources":["../../src/config/agent-dirs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAc,YAAY,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,2BAA2B,EAC3B,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE;QACV,iBAAiB,EAAE;QACnB,cAAc,EAAE;QAChB,aAAa,EAAE;QACf,eAAe,EAAE;QACjB,OAAO;KACR,CAAC,MAAM,CAAC,OAAO,CAAa,CAAA;IAE7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC7B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-dirs.js","sourceRoot":"","sources":["../../src/config/agent-dirs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAc,YAAY,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,2BAA2B,EAC3B,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,IAAI,GAAG;QACX,QAAQ,EAAE;QACV,iBAAiB,EAAE;QACnB,cAAc,EAAE;QAChB,aAAa,EAAE;QACf,eAAe,EAAE;QACjB,OAAO;KACR,CAAC,MAAM,CAAC,OAAO,CAAa,CAAA;IAE7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC7B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IACD,wBAAwB,EAAE,CAAA;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAkB,EAAE,cAAsB;IAC7E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC9B,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,2CAA2C,QAAQ,UAAU,OAAO,+BAA+B,GAAG,EAAE,CACzG,CAAA;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAEtB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,yBAAyB,CAAC,cAAc,CAAC,CAAA;AAC3C,CAAC;AAED;;;GAGG;AACH,SAAS,yBAAyB,CAAC,cAAsB;IACvD,MAAM,UAAU,GAAG,OAAO,CAAC,2BAA2B,EAAE,CAAC,CAAA;IACzD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAM;IAEnC,MAAM,UAAU,GAAG,OAAO,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC,CAAA;IACjE,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,OAAM;IAElC,uEAAuE;IACvE,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** The archive stays private; only explicitly handed-off attachments reach the CLI. */
|
|
2
|
+
export declare function publishAttachment(source: string, fileId: string): string;
|
|
3
|
+
/** Rebuild the ephemeral exchange from the encrypted Bridge archive after wake. */
|
|
4
|
+
export declare function restoreAttachmentHandoff(): void;
|
|
5
|
+
//# sourceMappingURL=attachment-handoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-handoff.d.ts","sourceRoot":"","sources":["../../src/config/attachment-handoff.ts"],"names":[],"mappings":"AAKA,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA0BxE;AAED,mFAAmF;AACnF,wBAAgB,wBAAwB,IAAI,IAAI,CAkB/C"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { constants, copyFileSync, chmodSync, chownSync, lstatSync, mkdirSync, readdirSync, renameSync, rmSync } from 'node:fs';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { basename, join, resolve } from 'node:path';
|
|
4
|
+
import { DATA_FILES_DIR } from './paths.js';
|
|
5
|
+
/** The archive stays private; only explicitly handed-off attachments reach the CLI. */
|
|
6
|
+
export function publishAttachment(source, fileId) {
|
|
7
|
+
const configured = process.env.AGENT_BRIDGE_TEMP_DIR?.trim();
|
|
8
|
+
if (!configured)
|
|
9
|
+
return source;
|
|
10
|
+
if (!fileId || basename(fileId) !== fileId || fileId === '.' || fileId === '..') {
|
|
11
|
+
throw new Error('invalid attachment file id');
|
|
12
|
+
}
|
|
13
|
+
if (!lstatSync(source).isFile())
|
|
14
|
+
throw new Error('attachment archive is not a regular file');
|
|
15
|
+
const root = resolve(configured);
|
|
16
|
+
const directory = join(root, fileId);
|
|
17
|
+
mkdirSync(directory, { recursive: true, mode: 0o2750 });
|
|
18
|
+
for (const path of [root, directory]) {
|
|
19
|
+
if (!lstatSync(path).isDirectory())
|
|
20
|
+
throw new Error('unsafe attachment exchange directory');
|
|
21
|
+
chmodSync(path, 0o2750);
|
|
22
|
+
}
|
|
23
|
+
const target = join(directory, basename(source));
|
|
24
|
+
const staging = join(directory, `.handoff-${randomUUID()}`);
|
|
25
|
+
try {
|
|
26
|
+
copyFileSync(source, staging, constants.COPYFILE_EXCL);
|
|
27
|
+
// copyFile may preserve the private source group; use the exchange group.
|
|
28
|
+
chownSync(staging, -1, lstatSync(directory).gid);
|
|
29
|
+
chmodSync(staging, 0o640);
|
|
30
|
+
renameSync(staging, target);
|
|
31
|
+
return target;
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
rmSync(staging, { force: true });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Rebuild the ephemeral exchange from the encrypted Bridge archive after wake. */
|
|
38
|
+
export function restoreAttachmentHandoff() {
|
|
39
|
+
if (!process.env.AGENT_BRIDGE_TEMP_DIR?.trim())
|
|
40
|
+
return;
|
|
41
|
+
const archive = DATA_FILES_DIR();
|
|
42
|
+
let remaining = 128 * 1024 * 1024;
|
|
43
|
+
const folders = readdirSync(archive, { withFileTypes: true })
|
|
44
|
+
.filter(entry => entry.isDirectory())
|
|
45
|
+
.map(entry => ({ name: entry.name, time: lstatSync(join(archive, entry.name)).mtimeMs }))
|
|
46
|
+
.sort((a, b) => b.time - a.time);
|
|
47
|
+
for (const folder of folders) {
|
|
48
|
+
for (const entry of readdirSync(join(archive, folder.name), { withFileTypes: true })) {
|
|
49
|
+
if (!entry.isFile() || entry.name.startsWith('.download-'))
|
|
50
|
+
continue;
|
|
51
|
+
const source = join(archive, folder.name, entry.name);
|
|
52
|
+
const size = lstatSync(source).size;
|
|
53
|
+
if (size > remaining)
|
|
54
|
+
continue;
|
|
55
|
+
publishAttachment(source, folder.name);
|
|
56
|
+
remaining -= size;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=attachment-handoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-handoff.js","sourceRoot":"","sources":["../../src/config/attachment-handoff.ts"],"names":[],"mappings":"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"}
|