@victor-software-house/pi-acp 0.11.0 → 0.12.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.
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { a as removeStaleSocketIfAny, i as releaseLock, n as controlSocketPath, o as socketPath, r as ensureSocketParentDir, t as acquireLock } from "./socket-wvV053VI.mjs";
|
|
3
3
|
import { t as piChangelogPath } from "./pi-package-aHs6rWNo.mjs";
|
|
4
4
|
import { createServer } from "node:net";
|
|
5
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
-
import { homedir } from "node:os";
|
|
5
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
6
|
+
import { homedir, tmpdir } from "node:os";
|
|
7
7
|
import { isAbsolute, join, resolve } from "node:path";
|
|
8
8
|
import { Hono } from "hono";
|
|
9
9
|
import { AgentSideConnection, RequestError, ndJsonStream } from "@agentclientprotocol/sdk";
|
|
@@ -876,6 +876,7 @@ var PiAcpSession = class {
|
|
|
876
876
|
lastAssistantStopReason = null;
|
|
877
877
|
lastEmit = Promise.resolve();
|
|
878
878
|
unsubscribe;
|
|
879
|
+
cleanups;
|
|
879
880
|
constructor(opts) {
|
|
880
881
|
this.sessionId = opts.sessionId;
|
|
881
882
|
this.cwd = opts.cwd;
|
|
@@ -883,11 +884,15 @@ var PiAcpSession = class {
|
|
|
883
884
|
this.piSession = opts.piSession;
|
|
884
885
|
this.conn = opts.conn;
|
|
885
886
|
this.supportsTerminalOutput = opts.supportsTerminalOutput ?? false;
|
|
887
|
+
this.cleanups = opts.cleanups ?? [];
|
|
886
888
|
this.unsubscribe = this.piSession.subscribe((ev) => this.handlePiEvent(ev));
|
|
887
889
|
}
|
|
888
890
|
dispose() {
|
|
889
891
|
this.unsubscribe?.();
|
|
890
892
|
this.piSession.dispose();
|
|
893
|
+
for (const cleanup of this.cleanups) try {
|
|
894
|
+
cleanup();
|
|
895
|
+
} catch {}
|
|
891
896
|
}
|
|
892
897
|
/**
|
|
893
898
|
* Drop event subscription without disposing the underlying piSession.
|
|
@@ -1679,6 +1684,58 @@ function tryFromFile(path, source, diagnostics) {
|
|
|
1679
1684
|
return null;
|
|
1680
1685
|
}
|
|
1681
1686
|
//#endregion
|
|
1687
|
+
//#region src/resources/modes.ts
|
|
1688
|
+
/**
|
|
1689
|
+
* Cwd-independence modes (PRD-002 §FR-5).
|
|
1690
|
+
*
|
|
1691
|
+
* | Mode | cwd handling | Tool target |
|
|
1692
|
+
* |-----------|--------------------------------------------|---------------|
|
|
1693
|
+
* | `local` | ACP params.cwd (must be absolute) | params.cwd |
|
|
1694
|
+
* | `overlay` | same as local — manifest aux roots compose | params.cwd |
|
|
1695
|
+
* | `none` | substitute ephemeral tmpdir | tmpdir |
|
|
1696
|
+
*
|
|
1697
|
+
* `local` and `overlay` are functionally identical in the current substrate
|
|
1698
|
+
* because `VirtualResourceLoader` always overlays manifest roots on top of
|
|
1699
|
+
* the implicit local root. The `overlay` keyword is retained for
|
|
1700
|
+
* forward-compatibility and operator clarity (declaring `mode: overlay`
|
|
1701
|
+
* documents the intent even if the runtime path is the same).
|
|
1702
|
+
*
|
|
1703
|
+
* `none` mints `mkdtemp(...)` under the OS tmpdir and returns a cleanup
|
|
1704
|
+
* thunk the caller must invoke at session close. The cleanup is
|
|
1705
|
+
* best-effort — never throws — so a session dispose path that runs it
|
|
1706
|
+
* after the directory has already been removed is safe.
|
|
1707
|
+
*/
|
|
1708
|
+
const TMPDIR_PREFIX = "pi-acp-session-";
|
|
1709
|
+
function resolveMode(input) {
|
|
1710
|
+
const mode = input.manifest.mode;
|
|
1711
|
+
if (mode === "none") {
|
|
1712
|
+
const dir = mkdtempSync(join(tmpdir(), TMPDIR_PREFIX));
|
|
1713
|
+
let removed = false;
|
|
1714
|
+
const cleanup = () => {
|
|
1715
|
+
if (removed) return;
|
|
1716
|
+
removed = true;
|
|
1717
|
+
try {
|
|
1718
|
+
rmSync(dir, {
|
|
1719
|
+
recursive: true,
|
|
1720
|
+
force: true
|
|
1721
|
+
});
|
|
1722
|
+
} catch {}
|
|
1723
|
+
};
|
|
1724
|
+
return {
|
|
1725
|
+
mode,
|
|
1726
|
+
cwd: dir,
|
|
1727
|
+
cleanup,
|
|
1728
|
+
ephemeral: true
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
return {
|
|
1732
|
+
mode,
|
|
1733
|
+
cwd: input.requestedCwd,
|
|
1734
|
+
cleanup: () => {},
|
|
1735
|
+
ephemeral: false
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
//#endregion
|
|
1682
1739
|
//#region src/resources/sources/http.ts
|
|
1683
1740
|
const DEFAULT_CACHE_TTL_SECONDS = 300;
|
|
1684
1741
|
const DEFAULT_TIMEOUT_MS$1 = 5e3;
|
|
@@ -1897,7 +1954,7 @@ var SshBackend = class {
|
|
|
1897
1954
|
//#endregion
|
|
1898
1955
|
//#region package.json
|
|
1899
1956
|
var name = "@victor-software-house/pi-acp";
|
|
1900
|
-
var version = "0.
|
|
1957
|
+
var version = "0.12.0";
|
|
1901
1958
|
//#endregion
|
|
1902
1959
|
//#region src/acp/agent.ts
|
|
1903
1960
|
/** Builtin ACP slash commands handled directly by the adapter. */
|
|
@@ -2034,13 +2091,18 @@ var PiAcpAgent = class {
|
|
|
2034
2091
|
cwd,
|
|
2035
2092
|
sessionParams
|
|
2036
2093
|
});
|
|
2094
|
+
const modeResult = resolveMode({
|
|
2095
|
+
manifest: loaded.manifest,
|
|
2096
|
+
requestedCwd: cwd
|
|
2097
|
+
});
|
|
2098
|
+
const effectiveCwd = modeResult.cwd;
|
|
2037
2099
|
const diagnostics = [...loaded.diagnostics];
|
|
2038
2100
|
const sources = [];
|
|
2039
2101
|
for (const root of loaded.manifest.roots) {
|
|
2040
2102
|
if (root.kind === "local") {
|
|
2041
2103
|
sources.push(new LocalBackend({
|
|
2042
2104
|
id: root.id,
|
|
2043
|
-
cwd: root.paths.cwd ??
|
|
2105
|
+
cwd: root.paths.cwd ?? effectiveCwd,
|
|
2044
2106
|
agentDir: root.paths.agentDir ?? getAgentDir()
|
|
2045
2107
|
}));
|
|
2046
2108
|
continue;
|
|
@@ -2073,7 +2135,7 @@ var PiAcpAgent = class {
|
|
|
2073
2135
|
diagnostics.push(diag);
|
|
2074
2136
|
}
|
|
2075
2137
|
if (!sources.some((s) => s.kind === "local")) sources.unshift(new LocalBackend({
|
|
2076
|
-
cwd,
|
|
2138
|
+
cwd: effectiveCwd,
|
|
2077
2139
|
agentDir: getAgentDir()
|
|
2078
2140
|
}));
|
|
2079
2141
|
const loader = new VirtualResourceLoader({
|
|
@@ -2085,7 +2147,10 @@ var PiAcpAgent = class {
|
|
|
2085
2147
|
const where = d.path !== void 0 ? ` ${d.path}` : "";
|
|
2086
2148
|
process.stderr.write(`pi-acp manifest [${d.source}${where}]: ${d.message}\n`);
|
|
2087
2149
|
}
|
|
2088
|
-
return
|
|
2150
|
+
return {
|
|
2151
|
+
loader,
|
|
2152
|
+
modeResult
|
|
2153
|
+
};
|
|
2089
2154
|
}
|
|
2090
2155
|
/**
|
|
2091
2156
|
* PRD-002 §FR-6 — `read` tool ACP-FS delegation overlay.
|
|
@@ -2158,13 +2223,22 @@ var PiAcpAgent = class {
|
|
|
2158
2223
|
};
|
|
2159
2224
|
}
|
|
2160
2225
|
async newSession(params) {
|
|
2161
|
-
|
|
2162
|
-
|
|
2226
|
+
const { loader: resourceLoader, modeResult } = await this.buildResourceLoader(params.cwd, params).catch((e) => {
|
|
2227
|
+
const authErr = detectAuthError(e);
|
|
2228
|
+
if (authErr !== null) throw authErr;
|
|
2229
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2230
|
+
throw RequestError.internalError({}, `Failed to load pi-acp manifest: ${msg}`);
|
|
2231
|
+
});
|
|
2232
|
+
const effectiveCwd = modeResult.cwd;
|
|
2233
|
+
if (modeResult.mode !== "none" && !isAbsolute(params.cwd)) {
|
|
2234
|
+
modeResult.cleanup();
|
|
2235
|
+
throw RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
2236
|
+
}
|
|
2237
|
+
const acpReadOverlay = this.buildAcpReadOverlay(effectiveCwd);
|
|
2163
2238
|
let result;
|
|
2164
2239
|
try {
|
|
2165
|
-
const resourceLoader = await this.buildResourceLoader(params.cwd, params);
|
|
2166
2240
|
result = await createAgentSession({
|
|
2167
|
-
cwd:
|
|
2241
|
+
cwd: effectiveCwd,
|
|
2168
2242
|
resourceLoader,
|
|
2169
2243
|
...acpReadOverlay ? {
|
|
2170
2244
|
tools: acpReadOverlay.tools,
|
|
@@ -2172,6 +2246,7 @@ var PiAcpAgent = class {
|
|
|
2172
2246
|
} : {}
|
|
2173
2247
|
});
|
|
2174
2248
|
} catch (e) {
|
|
2249
|
+
modeResult.cleanup();
|
|
2175
2250
|
const authErr = detectAuthError(e);
|
|
2176
2251
|
if (authErr !== null) throw authErr;
|
|
2177
2252
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -2181,6 +2256,7 @@ var PiAcpAgent = class {
|
|
|
2181
2256
|
if (acpReadOverlay !== null) acpReadOverlay.sessionIdRef.current = piSession.sessionManager.getSessionId();
|
|
2182
2257
|
if (piSession.modelRegistry.getAvailable().length === 0) {
|
|
2183
2258
|
piSession.dispose();
|
|
2259
|
+
modeResult.cleanup();
|
|
2184
2260
|
throw RequestError.authRequired({ authMethods: buildAuthMethods() }, "Configure an API key or log in with an OAuth provider.");
|
|
2185
2261
|
}
|
|
2186
2262
|
const sessionId = piSession.sessionManager.getSessionId();
|
|
@@ -2188,11 +2264,12 @@ var PiAcpAgent = class {
|
|
|
2188
2264
|
if (sessionFile !== void 0) this.sessionPaths.set(sessionId, sessionFile);
|
|
2189
2265
|
const session = new PiAcpSession({
|
|
2190
2266
|
sessionId,
|
|
2191
|
-
cwd:
|
|
2267
|
+
cwd: effectiveCwd,
|
|
2192
2268
|
mcpServers: params.mcpServers,
|
|
2193
2269
|
piSession,
|
|
2194
2270
|
conn: this.conn,
|
|
2195
|
-
supportsTerminalOutput: this.clientCapabilities.terminalOutput
|
|
2271
|
+
supportsTerminalOutput: this.clientCapabilities.terminalOutput,
|
|
2272
|
+
cleanups: modeResult.ephemeral ? [modeResult.cleanup] : []
|
|
2196
2273
|
});
|
|
2197
2274
|
this.sessions.register(session);
|
|
2198
2275
|
this.registerWithDaemon({
|
|
@@ -2442,7 +2519,7 @@ var PiAcpAgent = class {
|
|
|
2442
2519
|
let result;
|
|
2443
2520
|
try {
|
|
2444
2521
|
const sm = SessionManager.open(sessionFile);
|
|
2445
|
-
const resourceLoader = await this.buildResourceLoader(params.cwd, params);
|
|
2522
|
+
const { loader: resourceLoader } = await this.buildResourceLoader(params.cwd, params);
|
|
2446
2523
|
result = await createAgentSession({
|
|
2447
2524
|
cwd: params.cwd,
|
|
2448
2525
|
sessionManager: sm,
|
|
@@ -2548,7 +2625,7 @@ var PiAcpAgent = class {
|
|
|
2548
2625
|
let result;
|
|
2549
2626
|
try {
|
|
2550
2627
|
const sm = SessionManager.open(sessionFile);
|
|
2551
|
-
const resourceLoader = await this.buildResourceLoader(params.cwd, params);
|
|
2628
|
+
const { loader: resourceLoader } = await this.buildResourceLoader(params.cwd, params);
|
|
2552
2629
|
result = await createAgentSession({
|
|
2553
2630
|
cwd: params.cwd,
|
|
2554
2631
|
sessionManager: sm,
|
|
@@ -2613,7 +2690,7 @@ var PiAcpAgent = class {
|
|
|
2613
2690
|
let result;
|
|
2614
2691
|
try {
|
|
2615
2692
|
const sm = SessionManager.forkFrom(sourceFile, params.cwd);
|
|
2616
|
-
const resourceLoader = await this.buildResourceLoader(params.cwd, params);
|
|
2693
|
+
const { loader: resourceLoader } = await this.buildResourceLoader(params.cwd, params);
|
|
2617
2694
|
result = await createAgentSession({
|
|
2618
2695
|
cwd: params.cwd,
|
|
2619
2696
|
sessionManager: sm,
|
|
@@ -3250,4 +3327,4 @@ async function runDaemon() {
|
|
|
3250
3327
|
//#endregion
|
|
3251
3328
|
export { runDaemon };
|
|
3252
3329
|
|
|
3253
|
-
//# sourceMappingURL=daemon-
|
|
3330
|
+
//# sourceMappingURL=daemon-D6QKWz5C.mjs.map
|