@jait/gateway 0.1.517 → 0.1.519
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/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/routes/chat.d.ts.map +1 -1
- package/dist/routes/chat.js +13 -4
- package/dist/routes/chat.js.map +1 -1
- package/dist/security/consent-executor.d.ts +11 -0
- package/dist/security/consent-executor.d.ts.map +1 -1
- package/dist/security/consent-executor.js +11 -2
- package/dist/security/consent-executor.js.map +1 -1
- package/dist/tools/agent-loop.d.ts +6 -0
- package/dist/tools/agent-loop.d.ts.map +1 -1
- package/dist/tools/agent-loop.js +13 -8
- package/dist/tools/agent-loop.js.map +1 -1
- package/dist/tools/core/get-fs.d.ts +18 -9
- package/dist/tools/core/get-fs.d.ts.map +1 -1
- package/dist/tools/core/get-fs.js +113 -21
- package/dist/tools/core/get-fs.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared helper — resolve the FileSystemSurface for the
|
|
2
|
+
* Shared helper — resolve the FileSystemSurface (local or remote) for the
|
|
3
|
+
* current session.
|
|
3
4
|
*
|
|
4
5
|
* Priority:
|
|
5
|
-
* 1. If
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* 1. If the session has a running RemoteFileSystemSurface (project lives on
|
|
7
|
+
* another device, e.g. a Windows desktop while the gateway runs on
|
|
8
|
+
* Linux), route file ops to it. We never resolve a foreign-platform path
|
|
9
|
+
* against the gateway's local filesystem — that produced broken paths
|
|
10
|
+
* like `/home/jakob/E:\Zinsrechner/E:\Zinsrechner`.
|
|
11
|
+
* 2. If `targetPath` is absolute and outside the current project boundary,
|
|
12
|
+
* find or create a local surface scoped to contain that path.
|
|
13
|
+
* 3. Look for an existing surface with the conventional ID `fs-{sessionId}`
|
|
8
14
|
* that is running (the auto-created surface for the session).
|
|
9
|
-
*
|
|
15
|
+
* 4. Look for *any* running filesystem surface belonging to the session
|
|
10
16
|
* (e.g. one started via `surfaces.start` with a custom project root).
|
|
11
|
-
*
|
|
17
|
+
* 5. If nothing exists, auto-start one with `context.projectRoot`.
|
|
12
18
|
*
|
|
13
19
|
* This ensures that when the user asks to read/edit files anywhere on their
|
|
14
20
|
* local filesystem, the agent can access them without "escapes project
|
|
@@ -17,6 +23,22 @@
|
|
|
17
23
|
import { resolve, isAbsolute, dirname } from "node:path";
|
|
18
24
|
import { stat } from "node:fs/promises";
|
|
19
25
|
import { FileSystemSurface } from "../../surfaces/filesystem.js";
|
|
26
|
+
import { RemoteFileSystemSurface } from "../../surfaces/remote-filesystem.js";
|
|
27
|
+
/**
|
|
28
|
+
* Detect whether a path belongs to a *different* OS than the one the
|
|
29
|
+
* gateway is running on (e.g. a Windows drive path `E:\...` while the
|
|
30
|
+
* gateway runs on Linux). Such paths cannot be resolved locally and must
|
|
31
|
+
* always be served by a remote node surface.
|
|
32
|
+
*/
|
|
33
|
+
function isForeignPlatformPath(targetPath) {
|
|
34
|
+
const isWindowsPath = /^[A-Za-z]:[\\/]/.test(targetPath);
|
|
35
|
+
const gatewayIsWindows = process.platform === "win32";
|
|
36
|
+
if (gatewayIsWindows) {
|
|
37
|
+
// A POSIX-absolute path (`/home/...`) on a Windows gateway is foreign.
|
|
38
|
+
return targetPath.startsWith("/") && !isWindowsPath;
|
|
39
|
+
}
|
|
40
|
+
return isWindowsPath;
|
|
41
|
+
}
|
|
20
42
|
/**
|
|
21
43
|
* Given a `targetPath`, determine the correct project root.
|
|
22
44
|
* If the path is a directory, use it directly.
|
|
@@ -60,13 +82,89 @@ function pickMostSpecific(surfaces, targetPath) {
|
|
|
60
82
|
}
|
|
61
83
|
return best;
|
|
62
84
|
}
|
|
85
|
+
/** Get the project root of any filesystem surface (local or remote). */
|
|
86
|
+
function getSurfaceRoot(surface) {
|
|
87
|
+
const meta = surface.snapshot().metadata;
|
|
88
|
+
return meta?.projectRoot ?? null;
|
|
89
|
+
}
|
|
90
|
+
/** Normalize a path for cross-platform prefix comparison. */
|
|
91
|
+
function normalizePath(p) {
|
|
92
|
+
return p.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check whether a surface (local or remote) covers `targetPath`.
|
|
96
|
+
* Uses forward-slash-normalized, case-insensitive prefix matching so a
|
|
97
|
+
* Windows surface root (`E:\Zinsrechner`) matches a Windows path.
|
|
98
|
+
*/
|
|
99
|
+
function coversAny(surface, targetPath, normTarget = normalizePath(targetPath)) {
|
|
100
|
+
// Prefer the surface's own isPathAllowed when it returns true.
|
|
101
|
+
try {
|
|
102
|
+
if (surface.isPathAllowed(targetPath))
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// fall through to manual check
|
|
107
|
+
}
|
|
108
|
+
const root = getSurfaceRoot(surface);
|
|
109
|
+
if (!root)
|
|
110
|
+
return false;
|
|
111
|
+
const normRoot = normalizePath(root);
|
|
112
|
+
if (!normRoot)
|
|
113
|
+
return false;
|
|
114
|
+
return normTarget === normRoot || normTarget.startsWith(normRoot + "/");
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Among multiple surfaces (local or remote) that cover a path, prefer the
|
|
118
|
+
* most specific one (deepest project root).
|
|
119
|
+
*/
|
|
120
|
+
function pickMostSpecificAny(surfaces, targetPath) {
|
|
121
|
+
const normTarget = normalizePath(targetPath);
|
|
122
|
+
let best = null;
|
|
123
|
+
let bestLen = -1;
|
|
124
|
+
for (const s of surfaces) {
|
|
125
|
+
if (!coversAny(s, targetPath, normTarget))
|
|
126
|
+
continue;
|
|
127
|
+
const root = getSurfaceRoot(s);
|
|
128
|
+
const len = root?.length ?? 0;
|
|
129
|
+
if (len > bestLen) {
|
|
130
|
+
best = s;
|
|
131
|
+
bestLen = len;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return best;
|
|
135
|
+
}
|
|
63
136
|
export async function getFs(registry, context, targetPath) {
|
|
137
|
+
const fsId = `fs-${context.sessionId}`;
|
|
138
|
+
// ── Prefer a running remote-filesystem surface for this session ──
|
|
139
|
+
// When the project lives on a remote node (e.g. a Windows desktop while
|
|
140
|
+
// the gateway runs on Linux), the session's surface is a
|
|
141
|
+
// RemoteFileSystemSurface. Route file ops to it instead of resolving the
|
|
142
|
+
// foreign path against the gateway's local filesystem.
|
|
143
|
+
const remoteSurfaces = registry
|
|
144
|
+
.getBySession(context.sessionId)
|
|
145
|
+
.filter((s) => s instanceof RemoteFileSystemSurface && s.state === "running");
|
|
146
|
+
if (remoteSurfaces.length > 0) {
|
|
147
|
+
if (targetPath) {
|
|
148
|
+
const covered = pickMostSpecificAny(remoteSurfaces, targetPath);
|
|
149
|
+
if (covered)
|
|
150
|
+
return covered;
|
|
151
|
+
}
|
|
152
|
+
const conventionalRemote = remoteSurfaces.find((s) => s.id === fsId);
|
|
153
|
+
return conventionalRemote ?? remoteSurfaces[0];
|
|
154
|
+
}
|
|
155
|
+
// ── Foreign-platform path with no remote surface ──
|
|
156
|
+
// The target path belongs to a different OS than the gateway and there is
|
|
157
|
+
// no remote node surface available. Do NOT try to resolve it locally —
|
|
158
|
+
// that would create a bogus local surface and throw ENOENT.
|
|
159
|
+
if (targetPath && isForeignPlatformPath(targetPath)) {
|
|
160
|
+
throw new Error(`Path "${targetPath}" belongs to a different platform than the gateway ` +
|
|
161
|
+
`(${process.platform}) and no remote node surface is available for this session. ` +
|
|
162
|
+
`Open the project on its device first via /api/project/open.`);
|
|
163
|
+
}
|
|
164
|
+
// ── Local filesystem surfaces ──
|
|
64
165
|
const absTarget = targetPath ? resolve(context.projectRoot, targetPath) : undefined;
|
|
65
|
-
// ── If target is absolute and we already have a surface that covers it, use it ──
|
|
66
166
|
if (absTarget) {
|
|
67
|
-
// Collect all running FS surfaces for this session
|
|
68
167
|
const candidates = [];
|
|
69
|
-
const fsId = `fs-${context.sessionId}`;
|
|
70
168
|
const conventional = registry.getSurface(fsId);
|
|
71
169
|
if (conventional?.state === "running")
|
|
72
170
|
candidates.push(conventional);
|
|
@@ -75,14 +173,12 @@ export async function getFs(registry, context, targetPath) {
|
|
|
75
173
|
candidates.push(s);
|
|
76
174
|
}
|
|
77
175
|
}
|
|
78
|
-
// Pick the most specific surface that covers this path
|
|
79
176
|
const best = pickMostSpecific(candidates, absTarget);
|
|
80
177
|
if (best)
|
|
81
178
|
return best;
|
|
82
|
-
// No existing surface covers this path — create one scoped to the target
|
|
83
179
|
if (isAbsolute(targetPath)) {
|
|
84
180
|
const newRoot = await deriveProjectRoot(absTarget);
|
|
85
|
-
const safeName = newRoot.replace(/[
|
|
181
|
+
const safeName = newRoot.replace(/[:\\/]/g, "_").replace(/_+$/, "").toLowerCase();
|
|
86
182
|
const surfaceId = `fs-${context.sessionId}-${safeName}`;
|
|
87
183
|
const existing = registry.getSurface(surfaceId);
|
|
88
184
|
if (existing?.state === "running")
|
|
@@ -95,20 +191,15 @@ export async function getFs(registry, context, targetPath) {
|
|
|
95
191
|
}
|
|
96
192
|
}
|
|
97
193
|
// ── Default: find or create the conventional session surface ──
|
|
98
|
-
// 1. Conventional per-session ID
|
|
99
|
-
const fsId = `fs-${context.sessionId}`;
|
|
100
194
|
const conventional = registry.getSurface(fsId);
|
|
101
195
|
if (conventional && conventional.state === "running")
|
|
102
196
|
return conventional;
|
|
103
|
-
// 2. Any running filesystem surface for this session
|
|
104
197
|
const sessionSurfaces = registry.getBySession(context.sessionId);
|
|
105
198
|
for (const s of sessionSurfaces) {
|
|
106
|
-
if (s instanceof FileSystemSurface &&
|
|
107
|
-
s.state === "running") {
|
|
199
|
+
if (s instanceof FileSystemSurface && s.state === "running") {
|
|
108
200
|
return s;
|
|
109
201
|
}
|
|
110
202
|
}
|
|
111
|
-
// 3. Nothing found — auto-start one
|
|
112
203
|
const started = await registry.startSurface("filesystem", fsId, {
|
|
113
204
|
sessionId: context.sessionId,
|
|
114
205
|
projectRoot: context.projectRoot,
|
|
@@ -119,8 +210,8 @@ export async function getFs(registry, context, targetPath) {
|
|
|
119
210
|
* Resolve the effective project root for a session.
|
|
120
211
|
*
|
|
121
212
|
* Prefers the most specific (deepest) project root among all running
|
|
122
|
-
* filesystem surfaces for this session — avoids returning
|
|
123
|
-
* when a more specific project surface exists.
|
|
213
|
+
* filesystem surfaces (local AND remote) for this session — avoids returning
|
|
214
|
+
* a broad drive root when a more specific project surface exists.
|
|
124
215
|
* Falls back to `process.cwd()`.
|
|
125
216
|
*/
|
|
126
217
|
export function resolveProjectRoot(registry, sessionId,
|
|
@@ -129,7 +220,8 @@ sessionProjectPath) {
|
|
|
129
220
|
let best = null;
|
|
130
221
|
let bestLen = -1;
|
|
131
222
|
for (const s of registry.getBySession(sessionId)) {
|
|
132
|
-
if (s instanceof FileSystemSurface
|
|
223
|
+
if ((s instanceof FileSystemSurface || s instanceof RemoteFileSystemSurface) &&
|
|
224
|
+
s.state === "running") {
|
|
133
225
|
const root = s.snapshot().metadata
|
|
134
226
|
?.projectRoot;
|
|
135
227
|
if (root && root.length > bestLen) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-fs.js","sourceRoot":"","sources":["../../../src/tools/core/get-fs.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"get-fs.js","sourceRoot":"","sources":["../../../src/tools/core/get-fs.ts"],"names":[],"mappings":"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"}
|