@rivus/agent 0.9.0 → 0.10.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/dist/acp.d.ts +31 -1
- package/dist/acp.js +188 -11
- package/dist/cli.js +2 -2
- package/dist/index.js +1 -1
- package/dist/pi.js +1 -1
- package/dist/rivus-daemon-cli.js +2 -2
- package/examples/acp-stdio-proxy.mjs +3 -0
- package/package.json +1 -1
package/dist/acp.d.ts
CHANGED
|
@@ -77,6 +77,23 @@ interface AcpAgentServerOptions {
|
|
|
77
77
|
declare function createAcpAgentServer(options: AcpAgentServerOptions): acp.AgentApp;
|
|
78
78
|
declare function serveAcpAgentOnStdio(app: acp.AgentApp): Promise<void>;
|
|
79
79
|
//#endregion
|
|
80
|
+
//#region src/infrastructure/acp/acp-session-store.d.ts
|
|
81
|
+
interface AcpSessionRecord {
|
|
82
|
+
readonly sessionId: string;
|
|
83
|
+
}
|
|
84
|
+
interface AcpSessionStore {
|
|
85
|
+
load(sessionKey: string): Promise<AcpSessionRecord | undefined>;
|
|
86
|
+
save(sessionKey: string, record: AcpSessionRecord): Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
interface JsonAcpSessionStoreOptions {
|
|
89
|
+
readonly filePath: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A small deployment-owned store for ACP provider session identities.
|
|
93
|
+
* The file contains no prompts or credentials, only session-key bindings.
|
|
94
|
+
*/
|
|
95
|
+
declare function createJsonAcpSessionStore(options: JsonAcpSessionStoreOptions): AcpSessionStore;
|
|
96
|
+
//#endregion
|
|
80
97
|
//#region src/infrastructure/acp/acp-stdio-agent-loop.d.ts
|
|
81
98
|
interface AcpMcpServerEnvironmentVariable {
|
|
82
99
|
readonly name: string;
|
|
@@ -97,6 +114,8 @@ interface AcpStdioAgentLoopOptions {
|
|
|
97
114
|
readonly mcpServers?: (input: AgentLoopInput) => ReadonlyArray<AcpMcpServer>;
|
|
98
115
|
readonly onStderr?: (text: string) => void;
|
|
99
116
|
readonly permissionPolicy?: AcpSessionPermissionPolicy;
|
|
117
|
+
/** Persist provider session IDs so a restarted ACP child can load/resume them. */
|
|
118
|
+
readonly sessionStore?: AcpSessionStore;
|
|
100
119
|
readonly terminationTimeoutMs?: number;
|
|
101
120
|
readonly workingDirectory: string;
|
|
102
121
|
}
|
|
@@ -105,5 +124,16 @@ interface AcpStdioAgentLoopHandle {
|
|
|
105
124
|
dispose(): Promise<void>;
|
|
106
125
|
}
|
|
107
126
|
declare function createAcpStdioAgentLoop(options: AcpStdioAgentLoopOptions): AcpStdioAgentLoopHandle;
|
|
127
|
+
declare class AcpSessionResumeUnavailable extends Error {
|
|
128
|
+
readonly sessionId: string;
|
|
129
|
+
readonly name = "AcpSessionResumeUnavailable";
|
|
130
|
+
constructor(sessionId: string);
|
|
131
|
+
}
|
|
132
|
+
declare class AcpSessionResumeFailed extends Error {
|
|
133
|
+
readonly sessionId: string;
|
|
134
|
+
readonly cause: unknown;
|
|
135
|
+
readonly name = "AcpSessionResumeFailed";
|
|
136
|
+
constructor(sessionId: string, cause: unknown);
|
|
137
|
+
}
|
|
108
138
|
//#endregion
|
|
109
|
-
export { type AcpAgentLoopOptions, type AcpAgentServerOptions, type AcpAgentSession, type AcpPermissionBridge, type AcpPermissionDecision, type AcpPermissionOption, type AcpPermissionPolicy, type AcpPermissionRequest, type AcpPermissionSelection, type AcpPermissionToolCall, type AcpPromptResult, type AcpSessionPermissionContext, type AcpSessionPermissionPolicy, type AcpSessionUpdate, type AcpStdioAgentLoopHandle, type AcpStdioAgentLoopOptions, type AcpToolCallStatus, createAcpAgentLoop, createAcpAgentServer, createAcpPermissionBridge, createAcpStdioAgentLoop, decideAcpPermission, serveAcpAgentOnStdio };
|
|
139
|
+
export { type AcpAgentLoopOptions, type AcpAgentServerOptions, type AcpAgentSession, type AcpPermissionBridge, type AcpPermissionDecision, type AcpPermissionOption, type AcpPermissionPolicy, type AcpPermissionRequest, type AcpPermissionSelection, type AcpPermissionToolCall, type AcpPromptResult, type AcpSessionPermissionContext, type AcpSessionPermissionPolicy, type AcpSessionRecord, AcpSessionResumeFailed, AcpSessionResumeUnavailable, type AcpSessionStore, type AcpSessionUpdate, type AcpStdioAgentLoopHandle, type AcpStdioAgentLoopOptions, type AcpToolCallStatus, type JsonAcpSessionStoreOptions, createAcpAgentLoop, createAcpAgentServer, createAcpPermissionBridge, createAcpStdioAgentLoop, createJsonAcpSessionStore, decideAcpPermission, serveAcpAgentOnStdio };
|
package/dist/acp.js
CHANGED
|
@@ -4,6 +4,8 @@ import { randomUUID } from "node:crypto";
|
|
|
4
4
|
import { Readable, Writable } from "node:stream";
|
|
5
5
|
import * as acp from "@agentclientprotocol/sdk";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
8
|
+
import { dirname } from "node:path";
|
|
7
9
|
//#region src/infrastructure/acp/acp-agent-loop.ts
|
|
8
10
|
function createAcpAgentLoop(options) {
|
|
9
11
|
return createAsyncIterableAgentLoop({ run: (input) => runAcpSession(input, options) });
|
|
@@ -109,10 +111,10 @@ function mapAcpSessionUpdate(update, tools) {
|
|
|
109
111
|
})];
|
|
110
112
|
}
|
|
111
113
|
function readTextContent(content) {
|
|
112
|
-
if (!isRecord(content) || content.type !== "text" || typeof content.text !== "string") return void 0;
|
|
114
|
+
if (!isRecord$1(content) || content.type !== "text" || typeof content.text !== "string") return void 0;
|
|
113
115
|
return content.text;
|
|
114
116
|
}
|
|
115
|
-
function isRecord(value) {
|
|
117
|
+
function isRecord$1(value) {
|
|
116
118
|
return typeof value === "object" && value !== null;
|
|
117
119
|
}
|
|
118
120
|
//#endregion
|
|
@@ -252,17 +254,48 @@ async function decideAcpPermission(request, policy) {
|
|
|
252
254
|
//#endregion
|
|
253
255
|
//#region src/infrastructure/acp/acp-stdio-agent-loop.ts
|
|
254
256
|
async function buildAcpSession(processConnection, options, input) {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
+
const mcpServers = createMcpServers(options, input);
|
|
258
|
+
const persisted = await options.sessionStore?.load(input.sessionKey);
|
|
259
|
+
if (persisted) return restoreAcpSession(processConnection, options, persisted.sessionId, mcpServers);
|
|
260
|
+
const session = await processConnection.connection.agent.buildSession({
|
|
261
|
+
cwd: options.workingDirectory,
|
|
262
|
+
mcpServers
|
|
263
|
+
}).start();
|
|
264
|
+
await options.sessionStore?.save(input.sessionKey, { sessionId: session.sessionId });
|
|
265
|
+
return session;
|
|
266
|
+
}
|
|
267
|
+
function createMcpServers(options, input) {
|
|
268
|
+
return (options.mcpServers?.(input) ?? []).map((server) => ({
|
|
257
269
|
args: [...server.args],
|
|
258
270
|
command: server.command,
|
|
259
271
|
env: server.env.map(({ name, value }) => ({
|
|
260
272
|
name,
|
|
261
273
|
value
|
|
262
274
|
})),
|
|
263
|
-
name: server.name
|
|
264
|
-
|
|
265
|
-
|
|
275
|
+
name: server.name,
|
|
276
|
+
type: "stdio"
|
|
277
|
+
}));
|
|
278
|
+
}
|
|
279
|
+
async function restoreAcpSession(processConnection, options, sessionId, mcpServers) {
|
|
280
|
+
const session = new ResumedAcpSession(processConnection, sessionId);
|
|
281
|
+
try {
|
|
282
|
+
if (processConnection.agentCapabilities?.loadSession) await processConnection.connection.agent.request(acp.methods.agent.session.load, {
|
|
283
|
+
cwd: options.workingDirectory,
|
|
284
|
+
mcpServers,
|
|
285
|
+
sessionId
|
|
286
|
+
});
|
|
287
|
+
else if (processConnection.agentCapabilities?.sessionCapabilities?.resume) await processConnection.connection.agent.request(acp.methods.agent.session.resume, {
|
|
288
|
+
cwd: options.workingDirectory,
|
|
289
|
+
mcpServers,
|
|
290
|
+
sessionId
|
|
291
|
+
});
|
|
292
|
+
else throw new AcpSessionResumeUnavailable(sessionId);
|
|
293
|
+
session.clearReplay();
|
|
294
|
+
return session;
|
|
295
|
+
} catch (error) {
|
|
296
|
+
session.dispose();
|
|
297
|
+
throw new AcpSessionResumeFailed(sessionId, error);
|
|
298
|
+
}
|
|
266
299
|
}
|
|
267
300
|
function createAcpStdioAgentLoop(options) {
|
|
268
301
|
let pendingConnection;
|
|
@@ -291,6 +324,7 @@ function createAcpStdioAgentLoop(options) {
|
|
|
291
324
|
sessionKeys.clear();
|
|
292
325
|
for (const session of processConnection.sessions.values()) session.dispose();
|
|
293
326
|
processConnection.sessions.clear();
|
|
327
|
+
processConnection.sessionUpdateHandlers.clear();
|
|
294
328
|
terminateChild(processConnection.child, options.terminationTimeoutMs);
|
|
295
329
|
});
|
|
296
330
|
}, () => {
|
|
@@ -312,6 +346,7 @@ function createAcpStdioAgentLoop(options) {
|
|
|
312
346
|
if (processConnection) {
|
|
313
347
|
for (const session of processConnection.sessions.values()) session.dispose();
|
|
314
348
|
processConnection.sessions.clear();
|
|
349
|
+
processConnection.sessionUpdateHandlers.clear();
|
|
315
350
|
processConnection.connection.close();
|
|
316
351
|
}
|
|
317
352
|
sessionKeys.clear();
|
|
@@ -330,7 +365,7 @@ function createAcpStdioAgentLoop(options) {
|
|
|
330
365
|
current.dispose();
|
|
331
366
|
processConnection.sessions.delete(input.sessionKey);
|
|
332
367
|
}
|
|
333
|
-
const session = new SdkAcpAgentSession(await buildAcpSession(processConnection, options, input), processConnection.connection.agent);
|
|
368
|
+
const session = new SdkAcpAgentSession(await buildAcpSession(processConnection, options, input), processConnection.connection.agent, options.sessionStore !== void 0);
|
|
334
369
|
sessionKeys.set(session.sessionId, input.sessionKey);
|
|
335
370
|
processConnection.sessions.set(input.sessionKey, session);
|
|
336
371
|
return session;
|
|
@@ -341,10 +376,12 @@ function createAcpStdioAgentLoop(options) {
|
|
|
341
376
|
var SdkAcpAgentSession = class {
|
|
342
377
|
session;
|
|
343
378
|
agent;
|
|
379
|
+
preserveOnCancel;
|
|
344
380
|
reusable = true;
|
|
345
|
-
constructor(session, agent) {
|
|
381
|
+
constructor(session, agent, preserveOnCancel) {
|
|
346
382
|
this.session = session;
|
|
347
383
|
this.agent = agent;
|
|
384
|
+
this.preserveOnCancel = preserveOnCancel;
|
|
348
385
|
}
|
|
349
386
|
get sessionId() {
|
|
350
387
|
return this.session.sessionId;
|
|
@@ -353,7 +390,7 @@ var SdkAcpAgentSession = class {
|
|
|
353
390
|
return this.reusable;
|
|
354
391
|
}
|
|
355
392
|
cancel() {
|
|
356
|
-
this.reusable = false;
|
|
393
|
+
if (!this.preserveOnCancel) this.reusable = false;
|
|
357
394
|
return this.agent.notify(acp.methods.agent.session.cancel, { sessionId: this.session.sessionId });
|
|
358
395
|
}
|
|
359
396
|
dispose() {
|
|
@@ -369,6 +406,88 @@ var SdkAcpAgentSession = class {
|
|
|
369
406
|
}
|
|
370
407
|
}
|
|
371
408
|
};
|
|
409
|
+
var ResumedAcpSession = class {
|
|
410
|
+
processConnection;
|
|
411
|
+
sessionId;
|
|
412
|
+
updates = [];
|
|
413
|
+
waiters = [];
|
|
414
|
+
disposed = false;
|
|
415
|
+
failure;
|
|
416
|
+
constructor(processConnection, sessionId) {
|
|
417
|
+
this.processConnection = processConnection;
|
|
418
|
+
this.sessionId = sessionId;
|
|
419
|
+
processConnection.sessionUpdateHandlers.set(sessionId, (notification) => {
|
|
420
|
+
this.enqueue({
|
|
421
|
+
kind: "session_update",
|
|
422
|
+
update: notification.update
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
clearReplay() {
|
|
427
|
+
this.updates.splice(0);
|
|
428
|
+
}
|
|
429
|
+
dispose() {
|
|
430
|
+
if (this.disposed) return;
|
|
431
|
+
this.disposed = true;
|
|
432
|
+
this.processConnection.sessionUpdateHandlers.delete(this.sessionId);
|
|
433
|
+
const error = /* @__PURE__ */ new Error(`ACP session ${this.sessionId} observer disposed`);
|
|
434
|
+
for (const waiter of this.waiters.splice(0)) waiter.reject(error);
|
|
435
|
+
this.updates.splice(0);
|
|
436
|
+
}
|
|
437
|
+
nextUpdate() {
|
|
438
|
+
if (this.updates.length > 0) return Promise.resolve(this.updates.shift());
|
|
439
|
+
if (this.failure !== void 0) return Promise.reject(this.failure);
|
|
440
|
+
if (this.disposed) return Promise.reject(/* @__PURE__ */ new Error(`ACP session ${this.sessionId} observer disposed`));
|
|
441
|
+
return new Promise((resolve, reject) => this.waiters.push({
|
|
442
|
+
reject,
|
|
443
|
+
resolve
|
|
444
|
+
}));
|
|
445
|
+
}
|
|
446
|
+
prompt(text) {
|
|
447
|
+
if (this.disposed) return Promise.reject(/* @__PURE__ */ new Error(`ACP session ${this.sessionId} observer disposed`));
|
|
448
|
+
const response = this.processConnection.connection.agent.request(acp.methods.agent.session.prompt, {
|
|
449
|
+
prompt: [{
|
|
450
|
+
text,
|
|
451
|
+
type: "text"
|
|
452
|
+
}],
|
|
453
|
+
sessionId: this.sessionId
|
|
454
|
+
});
|
|
455
|
+
response.then((result) => this.enqueue({
|
|
456
|
+
kind: "stop",
|
|
457
|
+
stopReason: result.stopReason
|
|
458
|
+
}), (error) => this.fail(error));
|
|
459
|
+
return response;
|
|
460
|
+
}
|
|
461
|
+
enqueue(message) {
|
|
462
|
+
if (this.disposed) return;
|
|
463
|
+
const waiter = this.waiters.shift();
|
|
464
|
+
if (waiter) waiter.resolve(message);
|
|
465
|
+
else this.updates.push(message);
|
|
466
|
+
}
|
|
467
|
+
fail(error) {
|
|
468
|
+
if (this.failure !== void 0 || this.disposed) return;
|
|
469
|
+
this.failure = error;
|
|
470
|
+
for (const waiter of this.waiters.splice(0)) waiter.reject(error);
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
var AcpSessionResumeUnavailable = class extends Error {
|
|
474
|
+
sessionId;
|
|
475
|
+
name = "AcpSessionResumeUnavailable";
|
|
476
|
+
constructor(sessionId) {
|
|
477
|
+
super(`ACP Agent cannot load or resume persisted session ${sessionId}`);
|
|
478
|
+
this.sessionId = sessionId;
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
var AcpSessionResumeFailed = class extends Error {
|
|
482
|
+
sessionId;
|
|
483
|
+
cause;
|
|
484
|
+
name = "AcpSessionResumeFailed";
|
|
485
|
+
constructor(sessionId, cause) {
|
|
486
|
+
super(`ACP Agent failed to restore persisted session ${sessionId}`);
|
|
487
|
+
this.sessionId = sessionId;
|
|
488
|
+
this.cause = cause;
|
|
489
|
+
}
|
|
490
|
+
};
|
|
372
491
|
async function openConnection(options, sessionKeys, onSpawn) {
|
|
373
492
|
const child = spawn(options.command, [...options.arguments ?? []], {
|
|
374
493
|
cwd: options.workingDirectory,
|
|
@@ -383,9 +502,12 @@ async function openConnection(options, sessionKeys, onSpawn) {
|
|
|
383
502
|
child.stderr.setEncoding("utf8");
|
|
384
503
|
if (options.onStderr) child.stderr.on("data", options.onStderr);
|
|
385
504
|
else child.stderr.resume();
|
|
505
|
+
const sessionUpdateHandlers = /* @__PURE__ */ new Map();
|
|
386
506
|
const app = acp.client({ name: options.clientName ?? "rivus" }).onRequest(acp.methods.client.session.requestPermission, async ({ params }) => {
|
|
387
507
|
const sessionKey = sessionKeys.get(params.sessionId);
|
|
388
508
|
return { outcome: await decideAcpPermission(toPermissionRequest(params), sessionKey && options.permissionPolicy ? (request) => options.permissionPolicy?.(request, { sessionKey }) : void 0) };
|
|
509
|
+
}).onNotification(acp.methods.client.session.update, ({ params }) => {
|
|
510
|
+
sessionUpdateHandlers.get(params.sessionId)?.(params);
|
|
389
511
|
});
|
|
390
512
|
const stream = acp.ndJsonStream(Writable.toWeb(child.stdin), Readable.toWeb(child.stdout));
|
|
391
513
|
const connection = app.connect(stream);
|
|
@@ -400,8 +522,10 @@ async function openConnection(options, sessionKeys, onSpawn) {
|
|
|
400
522
|
}), options.initializationTimeoutMs ?? 1e4, "ACP initialization timed out");
|
|
401
523
|
if (initialized.protocolVersion !== acp.PROTOCOL_VERSION) throw new Error(`ACP protocol version ${initialized.protocolVersion} is not supported`);
|
|
402
524
|
return {
|
|
525
|
+
...initialized.agentCapabilities ? { agentCapabilities: initialized.agentCapabilities } : {},
|
|
403
526
|
child,
|
|
404
527
|
connection,
|
|
528
|
+
sessionUpdateHandlers,
|
|
405
529
|
sessions: /* @__PURE__ */ new Map()
|
|
406
530
|
};
|
|
407
531
|
} catch (error) {
|
|
@@ -456,4 +580,57 @@ function withTimeout(promise, timeoutMs, message) {
|
|
|
456
580
|
});
|
|
457
581
|
}
|
|
458
582
|
//#endregion
|
|
459
|
-
|
|
583
|
+
//#region src/infrastructure/acp/acp-session-store.ts
|
|
584
|
+
/**
|
|
585
|
+
* A small deployment-owned store for ACP provider session identities.
|
|
586
|
+
* The file contains no prompts or credentials, only session-key bindings.
|
|
587
|
+
*/
|
|
588
|
+
function createJsonAcpSessionStore(options) {
|
|
589
|
+
let recordsPromise;
|
|
590
|
+
let writeChain = Promise.resolve();
|
|
591
|
+
const readRecords = async () => {
|
|
592
|
+
try {
|
|
593
|
+
const raw = await readFile(options.filePath, "utf8");
|
|
594
|
+
const parsed = JSON.parse(raw);
|
|
595
|
+
if (!isRecord(parsed)) throw new Error("ACP session store must contain an object");
|
|
596
|
+
const records = /* @__PURE__ */ new Map();
|
|
597
|
+
for (const [sessionKey, value] of Object.entries(parsed)) {
|
|
598
|
+
if (!isRecord(value) || typeof value.sessionId !== "string" || value.sessionId.trim() === "") throw new Error(`invalid ACP session record for ${sessionKey}`);
|
|
599
|
+
records.set(sessionKey, { sessionId: value.sessionId });
|
|
600
|
+
}
|
|
601
|
+
return records;
|
|
602
|
+
} catch (error) {
|
|
603
|
+
if (isMissingFile(error)) return /* @__PURE__ */ new Map();
|
|
604
|
+
throw error;
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
const records = async () => {
|
|
608
|
+
recordsPromise ??= readRecords();
|
|
609
|
+
return recordsPromise;
|
|
610
|
+
};
|
|
611
|
+
const persist = async (value) => {
|
|
612
|
+
const temporaryPath = `${options.filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
613
|
+
await mkdir(dirname(options.filePath), { recursive: true });
|
|
614
|
+
await writeFile(temporaryPath, `${JSON.stringify(Object.fromEntries(value), null, 2)}\n`, "utf8");
|
|
615
|
+
await rename(temporaryPath, options.filePath);
|
|
616
|
+
};
|
|
617
|
+
return {
|
|
618
|
+
load: async (sessionKey) => (await records()).get(sessionKey),
|
|
619
|
+
save: async (sessionKey, record) => {
|
|
620
|
+
writeChain = writeChain.then(async () => {
|
|
621
|
+
const current = await records();
|
|
622
|
+
current.set(sessionKey, { sessionId: record.sessionId });
|
|
623
|
+
await persist(current);
|
|
624
|
+
});
|
|
625
|
+
await writeChain;
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
function isMissingFile(error) {
|
|
630
|
+
return isRecord(error) && error.code === "ENOENT";
|
|
631
|
+
}
|
|
632
|
+
function isRecord(value) {
|
|
633
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
634
|
+
}
|
|
635
|
+
//#endregion
|
|
636
|
+
export { AcpSessionResumeFailed, AcpSessionResumeUnavailable, createAcpAgentLoop, createAcpAgentServer, createAcpPermissionBridge, createAcpStdioAgentLoop, createJsonAcpSessionStore, decideAcpPermission, serveAcpAgentOnStdio };
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { D as loadRivusDeploymentManifest, T as resolveNodeRivusPluginModulePath, X as resolveFeishuEndpointCredentials, Z as loadMergedLocalEnvFile, et as validateRivusDeploymentManifest, t as runRivusDaemonCli } from "./rivus-daemon-cli.js";
|
|
3
3
|
import { Effect } from "effect";
|
|
4
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
-
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
6
4
|
import { lstat, mkdir, readFile, rmdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
5
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
7
|
//#region src/infrastructure/project/rivus-project-doctor.ts
|
|
8
8
|
const REQUIRED_FILES = Object.freeze([
|
|
9
9
|
"package.json",
|
package/dist/index.js
CHANGED
|
@@ -8,8 +8,8 @@ import { a as readBackgroundSessionWaitInput, i as readBackgroundSessionString,
|
|
|
8
8
|
import { n as assertRivusPluginConforms, r as createFakeRivusPlugin, t as RivusPluginConformanceError } from "./rivus-plugin-testkit.js";
|
|
9
9
|
import { Cause, Deferred, Effect, Either, Exit, Fiber, Option, Stream } from "effect";
|
|
10
10
|
import { createHash, randomUUID } from "node:crypto";
|
|
11
|
-
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
12
11
|
import { appendFile, lstat, mkdir, readFile, readdir, realpath, rename, stat, truncate, unlink, writeFile } from "node:fs/promises";
|
|
12
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
13
13
|
import { isDeepStrictEqual } from "node:util";
|
|
14
14
|
import { createServer } from "node:http";
|
|
15
15
|
import { Buffer as Buffer$1 } from "node:buffer";
|
package/dist/pi.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { d as requiresToolApproval } from "./agent-memory.js";
|
|
2
2
|
import { l as createPiSkillRuntime, o as createInvocationAuthority, r as createToolInputDigest } from "./tool-input-digest.js";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
|
-
import { isAbsolute, relative } from "node:path";
|
|
5
4
|
import { readFile, realpath, stat } from "node:fs/promises";
|
|
5
|
+
import { isAbsolute, relative } from "node:path";
|
|
6
6
|
import { Unsafe } from "typebox";
|
|
7
7
|
import { createReadToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
//#region src/infrastructure/pi/pi-project-skill-read-tool.ts
|
package/dist/rivus-daemon-cli.js
CHANGED
|
@@ -4,9 +4,9 @@ import { n as resolveRivusAgentDefinition, r as deepFreeze, t as createRivusPlug
|
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { Effect } from "effect";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
|
-
import { pathToFileURL } from "node:url";
|
|
8
|
-
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
9
7
|
import { lstat, open, readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
8
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
10
|
import { constants } from "node:fs";
|
|
11
11
|
//#region src/application/plugin/rivus-automation-runtime-definition.ts
|
|
12
12
|
function resolveRivusAutomationRuntimeDefinition(definition, requestedToolIds, requestedSkillIds) {
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
createAcpAgentServer,
|
|
5
5
|
createAcpPermissionBridge,
|
|
6
6
|
createAcpStdioAgentLoop,
|
|
7
|
+
createJsonAcpSessionStore,
|
|
7
8
|
serveAcpAgentOnStdio
|
|
8
9
|
} from "@rivus/agent/acp";
|
|
9
10
|
|
|
@@ -11,6 +12,7 @@ const command = process.env.RIVUS_ACP_SERVER_COMMAND?.trim();
|
|
|
11
12
|
if (!command) throw new Error("RIVUS_ACP_SERVER_COMMAND is required and must resolve to an explicit executable");
|
|
12
13
|
|
|
13
14
|
const workingDirectory = process.env.RIVUS_ACP_WORKING_DIRECTORY?.trim() || process.cwd();
|
|
15
|
+
const sessionStorePath = process.env.RIVUS_ACP_SESSION_STORE?.trim();
|
|
14
16
|
const permissionBridge = createAcpPermissionBridge();
|
|
15
17
|
const downstream = createAcpStdioAgentLoop({
|
|
16
18
|
arguments: parseArguments(process.env.RIVUS_ACP_SERVER_ARGUMENTS),
|
|
@@ -18,6 +20,7 @@ const downstream = createAcpStdioAgentLoop({
|
|
|
18
20
|
environment: selectEnvironment(process.env.RIVUS_ACP_SERVER_ENV_KEYS),
|
|
19
21
|
onStderr: (text) => process.stderr.write(text),
|
|
20
22
|
permissionPolicy: permissionBridge.policy,
|
|
23
|
+
...(sessionStorePath ? { sessionStore: createJsonAcpSessionStore({ filePath: sessionStorePath }) } : {}),
|
|
21
24
|
workingDirectory
|
|
22
25
|
});
|
|
23
26
|
const server = createAcpAgentServer({
|