@jmanuelcorral/openteam 0.1.30 → 0.1.31
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/cli/consoleServe.d.ts.map +1 -1
- package/dist/cli.js +191 -4
- package/dist/config/schema.d.ts +3 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/storage/httpStorageProvider.d.ts +21 -0
- package/dist/storage/httpStorageProvider.d.ts.map +1 -0
- package/dist/web/server.d.ts +6 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/start.d.ts +3 -0
- package/dist/web/start.d.ts.map +1 -1
- package/dist/web/storageRoute.d.ts +36 -0
- package/dist/web/storageRoute.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consoleServe.d.ts","sourceRoot":"","sources":["../../src/cli/consoleServe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvE,gEAAgE;AAChE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACtD,oEAAoE;IACpE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC;IAC1D,oDAAoD;IACpD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;IAClD,yDAAyD;IACzD,YAAY,CAAC,EAAE,CACb,IAAI,EAAE,kBAAkB,KACrB,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9C,sEAAsE;IACtE,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf,CAMA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"consoleServe.d.ts","sourceRoot":"","sources":["../../src/cli/consoleServe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvE,gEAAgE;AAChE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACtD,oEAAoE;IACpE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC;IAC1D,oDAAoD;IACpD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;IAClD,yDAAyD;IACzD,YAAY,CAAC,EAAE,CACb,IAAI,EAAE,kBAAkB,KACrB,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9C,sEAAsE;IACtE,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf,CAMA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CA+F7B"}
|
package/dist/cli.js
CHANGED
|
@@ -1271,6 +1271,7 @@ var ConsoleConfigSchema = z3.object({
|
|
|
1271
1271
|
refreshMs: z3.number().int().min(250).default(2000),
|
|
1272
1272
|
recentRoutes: z3.number().int().positive().default(50),
|
|
1273
1273
|
openBrowser: z3.boolean().default(false),
|
|
1274
|
+
remoteStorage: z3.boolean().default(false),
|
|
1274
1275
|
terminal: z3.object({
|
|
1275
1276
|
enabled: z3.boolean().default(true),
|
|
1276
1277
|
pty: z3.boolean().optional()
|
|
@@ -1282,6 +1283,7 @@ var ConsoleConfigSchema = z3.object({
|
|
|
1282
1283
|
refreshMs: 2000,
|
|
1283
1284
|
recentRoutes: 50,
|
|
1284
1285
|
openBrowser: false,
|
|
1286
|
+
remoteStorage: false,
|
|
1285
1287
|
terminal: { enabled: true }
|
|
1286
1288
|
});
|
|
1287
1289
|
var defaultLocalModel = {
|
|
@@ -2053,13 +2055,177 @@ async function handleConsoleRoute(request, response, url, deps) {
|
|
|
2053
2055
|
return true;
|
|
2054
2056
|
}
|
|
2055
2057
|
|
|
2058
|
+
// src/web/storageRoute.ts
|
|
2059
|
+
var JSON_HEADERS2 = { "content-type": "application/json" };
|
|
2060
|
+
var READ_OPS = new Set(["read", "exists", "list", "isDirectory", "stat"]);
|
|
2061
|
+
var WRITE_OPS = new Set(["write", "append", "mkdir", "delete"]);
|
|
2062
|
+
function bearerFromHeader2(request) {
|
|
2063
|
+
const header = request.headers.authorization;
|
|
2064
|
+
if (typeof header !== "string" || !header.startsWith("Bearer ")) {
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
2067
|
+
const value = header.slice("Bearer ".length).trim();
|
|
2068
|
+
return value.length === 0 ? undefined : value;
|
|
2069
|
+
}
|
|
2070
|
+
function authorized2(request, query, token) {
|
|
2071
|
+
const provided = tokenFromQuery(query) ?? bearerFromHeader2(request);
|
|
2072
|
+
return provided !== undefined && safeEqualToken(provided, token);
|
|
2073
|
+
}
|
|
2074
|
+
function pathAllowed(path, allowPrefixes) {
|
|
2075
|
+
if (allowPrefixes === undefined) {
|
|
2076
|
+
return true;
|
|
2077
|
+
}
|
|
2078
|
+
return allowPrefixes.some((rawPrefix) => {
|
|
2079
|
+
const prefix = normalizeVirtualPath(rawPrefix);
|
|
2080
|
+
if (prefix === "") {
|
|
2081
|
+
return true;
|
|
2082
|
+
}
|
|
2083
|
+
return path === prefix || path.startsWith(`${prefix}/`);
|
|
2084
|
+
});
|
|
2085
|
+
}
|
|
2086
|
+
async function readJsonBody2(request, limit) {
|
|
2087
|
+
return new Promise((resolve) => {
|
|
2088
|
+
let raw = "";
|
|
2089
|
+
let aborted = false;
|
|
2090
|
+
request.on("data", (chunk) => {
|
|
2091
|
+
if (aborted) {
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
raw += chunk.toString("utf8");
|
|
2095
|
+
if (raw.length > limit) {
|
|
2096
|
+
aborted = true;
|
|
2097
|
+
resolve(undefined);
|
|
2098
|
+
}
|
|
2099
|
+
});
|
|
2100
|
+
request.on("end", () => {
|
|
2101
|
+
if (!aborted) {
|
|
2102
|
+
try {
|
|
2103
|
+
resolve(JSON.parse(raw));
|
|
2104
|
+
} catch {
|
|
2105
|
+
resolve(undefined);
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
});
|
|
2109
|
+
request.on("error", () => resolve(undefined));
|
|
2110
|
+
});
|
|
2111
|
+
}
|
|
2112
|
+
function sendJson(response, status, body) {
|
|
2113
|
+
response.writeHead(status, JSON_HEADERS2).end(JSON.stringify(body));
|
|
2114
|
+
}
|
|
2115
|
+
async function handleRead(response, op, path, storage) {
|
|
2116
|
+
if (op === "read") {
|
|
2117
|
+
sendJson(response, 200, { content: await storage.read(path) ?? null });
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
2120
|
+
if (op === "list") {
|
|
2121
|
+
sendJson(response, 200, { entries: await storage.list(path) });
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
if (op === "exists") {
|
|
2125
|
+
sendJson(response, 200, { value: await storage.exists(path) });
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
if (op === "isDirectory") {
|
|
2129
|
+
sendJson(response, 200, { value: await storage.isDirectory(path) });
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
sendJson(response, 200, { stat: await storage.stat(path) ?? null });
|
|
2133
|
+
}
|
|
2134
|
+
async function handleWrite(request, response, op, deps) {
|
|
2135
|
+
if (deps.readOnly === true) {
|
|
2136
|
+
sendJson(response, 403, { error: "read-only" });
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
const body = await readJsonBody2(request, 8 * 1024 * 1024);
|
|
2140
|
+
const record = typeof body === "object" && body !== null ? body : undefined;
|
|
2141
|
+
const rawPath = record?.path;
|
|
2142
|
+
if (typeof rawPath !== "string") {
|
|
2143
|
+
sendJson(response, 400, { error: "invalid path" });
|
|
2144
|
+
return;
|
|
2145
|
+
}
|
|
2146
|
+
let path;
|
|
2147
|
+
try {
|
|
2148
|
+
path = normalizeVirtualPath(rawPath);
|
|
2149
|
+
} catch (error) {
|
|
2150
|
+
if (error instanceof StoragePathError) {
|
|
2151
|
+
sendJson(response, 400, { error: "invalid path" });
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
throw error;
|
|
2155
|
+
}
|
|
2156
|
+
if (!pathAllowed(path, deps.allowPrefixes)) {
|
|
2157
|
+
sendJson(response, 403, { error: "path not allowed" });
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
if (op === "write" || op === "append") {
|
|
2161
|
+
const content = record?.content;
|
|
2162
|
+
if (typeof content !== "string") {
|
|
2163
|
+
sendJson(response, 400, { error: "invalid content" });
|
|
2164
|
+
return;
|
|
2165
|
+
}
|
|
2166
|
+
if (op === "write") {
|
|
2167
|
+
await deps.storage.write(path, content);
|
|
2168
|
+
} else {
|
|
2169
|
+
await deps.storage.append(path, content);
|
|
2170
|
+
}
|
|
2171
|
+
} else if (op === "mkdir") {
|
|
2172
|
+
await deps.storage.mkdir(path);
|
|
2173
|
+
} else {
|
|
2174
|
+
await deps.storage.delete(path);
|
|
2175
|
+
}
|
|
2176
|
+
sendJson(response, 200, { ok: true });
|
|
2177
|
+
}
|
|
2178
|
+
async function handleStorageRoute(request, response, url, deps) {
|
|
2179
|
+
if (!url.pathname.startsWith("/storage/")) {
|
|
2180
|
+
return false;
|
|
2181
|
+
}
|
|
2182
|
+
const op = url.pathname.slice("/storage/".length);
|
|
2183
|
+
if (!READ_OPS.has(op) && !WRITE_OPS.has(op)) {
|
|
2184
|
+
sendJson(response, 404, { error: "not found" });
|
|
2185
|
+
return true;
|
|
2186
|
+
}
|
|
2187
|
+
if (!authorized2(request, url.searchParams, deps.token)) {
|
|
2188
|
+
sendJson(response, 401, { error: "unauthorized" });
|
|
2189
|
+
return true;
|
|
2190
|
+
}
|
|
2191
|
+
if (READ_OPS.has(op)) {
|
|
2192
|
+
if (request.method !== "GET") {
|
|
2193
|
+
sendJson(response, 405, { error: "method not allowed" });
|
|
2194
|
+
return true;
|
|
2195
|
+
}
|
|
2196
|
+
const rawPath = url.searchParams.get("path") ?? "";
|
|
2197
|
+
let path;
|
|
2198
|
+
try {
|
|
2199
|
+
path = normalizeVirtualPath(rawPath);
|
|
2200
|
+
} catch (error) {
|
|
2201
|
+
if (error instanceof StoragePathError) {
|
|
2202
|
+
sendJson(response, 400, { error: "invalid path" });
|
|
2203
|
+
return true;
|
|
2204
|
+
}
|
|
2205
|
+
throw error;
|
|
2206
|
+
}
|
|
2207
|
+
if (!pathAllowed(path, deps.allowPrefixes)) {
|
|
2208
|
+
sendJson(response, 403, { error: "path not allowed" });
|
|
2209
|
+
return true;
|
|
2210
|
+
}
|
|
2211
|
+
await handleRead(response, op, path, deps.storage);
|
|
2212
|
+
return true;
|
|
2213
|
+
}
|
|
2214
|
+
if (request.method !== "POST") {
|
|
2215
|
+
sendJson(response, 405, { error: "method not allowed" });
|
|
2216
|
+
return true;
|
|
2217
|
+
}
|
|
2218
|
+
await handleWrite(request, response, op, deps);
|
|
2219
|
+
return true;
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2056
2222
|
// src/web/server.ts
|
|
2057
2223
|
var SSE_HEADERS2 = {
|
|
2058
2224
|
"content-type": "text/event-stream",
|
|
2059
2225
|
"cache-control": "no-cache",
|
|
2060
2226
|
connection: "keep-alive"
|
|
2061
2227
|
};
|
|
2062
|
-
var
|
|
2228
|
+
var JSON_HEADERS3 = { "content-type": "application/json" };
|
|
2063
2229
|
var HTML_HEADERS = { "content-type": "text/html; charset=utf-8" };
|
|
2064
2230
|
function isAddressInUse(error) {
|
|
2065
2231
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EADDRINUSE";
|
|
@@ -2123,6 +2289,9 @@ async function createConsoleServer(deps) {
|
|
|
2123
2289
|
if (consoleDeps !== undefined && await handleConsoleRoute(request, response, url2, consoleDeps)) {
|
|
2124
2290
|
return;
|
|
2125
2291
|
}
|
|
2292
|
+
if (deps.storageApi !== undefined && await handleStorageRoute(request, response, url2, deps.storageApi)) {
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2126
2295
|
if (request.method !== "GET") {
|
|
2127
2296
|
response.writeHead(405).end("method not allowed");
|
|
2128
2297
|
return;
|
|
@@ -2133,11 +2302,11 @@ async function createConsoleServer(deps) {
|
|
|
2133
2302
|
return;
|
|
2134
2303
|
}
|
|
2135
2304
|
if (path === "/api/state") {
|
|
2136
|
-
response.writeHead(200,
|
|
2305
|
+
response.writeHead(200, JSON_HEADERS3).end(await stateJson(deps));
|
|
2137
2306
|
return;
|
|
2138
2307
|
}
|
|
2139
2308
|
if (path === "/healthz") {
|
|
2140
|
-
response.writeHead(200,
|
|
2309
|
+
response.writeHead(200, JSON_HEADERS3).end(JSON.stringify({ ok: true }));
|
|
2141
2310
|
return;
|
|
2142
2311
|
}
|
|
2143
2312
|
if (path === "/favicon.ico") {
|
|
@@ -2518,7 +2687,8 @@ async function createConsoleRuntime(deps) {
|
|
|
2518
2687
|
readSnapshot,
|
|
2519
2688
|
config: deps.config,
|
|
2520
2689
|
...deps.log !== undefined ? { log: deps.log } : {},
|
|
2521
|
-
...deps.console !== undefined ? { console: deps.console } : {}
|
|
2690
|
+
...deps.console !== undefined ? { console: deps.console } : {},
|
|
2691
|
+
...deps.storageApi !== undefined ? { storageApi: deps.storageApi } : {}
|
|
2522
2692
|
});
|
|
2523
2693
|
const watchFn = deps.watch ?? ((path, listener) => fsWatch(path, { persistent: false }, listener));
|
|
2524
2694
|
const watcher = watchSources([deps.sessionsDir, decisionsPath, backlogPath, deps.agentDir], () => {
|
|
@@ -2576,6 +2746,20 @@ async function runConsoleServe(deps, options) {
|
|
|
2576
2746
|
createClient: makeClient,
|
|
2577
2747
|
createPtyClient: makePtyClient
|
|
2578
2748
|
},
|
|
2749
|
+
...config.console.remoteStorage ? {
|
|
2750
|
+
storageApi: {
|
|
2751
|
+
storage: deps.storage,
|
|
2752
|
+
token,
|
|
2753
|
+
readOnly: true,
|
|
2754
|
+
allowPrefixes: [
|
|
2755
|
+
deps.sessionsDir,
|
|
2756
|
+
deps.decisionsPath,
|
|
2757
|
+
deps.backlogPath,
|
|
2758
|
+
deps.agentDir,
|
|
2759
|
+
...deps.legacyTelemetryPath !== undefined ? [deps.legacyTelemetryPath] : []
|
|
2760
|
+
]
|
|
2761
|
+
}
|
|
2762
|
+
} : {},
|
|
2579
2763
|
log: deps.log
|
|
2580
2764
|
});
|
|
2581
2765
|
} catch (error) {
|
|
@@ -2584,6 +2768,9 @@ async function runConsoleServe(deps, options) {
|
|
|
2584
2768
|
return { exitCode: 1 };
|
|
2585
2769
|
}
|
|
2586
2770
|
deps.log("Escuchando en loopback. Pulsa Ctrl+C para parar.");
|
|
2771
|
+
if (config.console.remoteStorage) {
|
|
2772
|
+
deps.log("Storage remoto expuesto en /storage/* (read-only, requiere token).");
|
|
2773
|
+
}
|
|
2587
2774
|
if (options.open && deps.openBrowser !== undefined) {
|
|
2588
2775
|
try {
|
|
2589
2776
|
await deps.openBrowser(runtime.url);
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare const ConsoleConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
31
31
|
refreshMs: z.ZodDefault<z.ZodNumber>;
|
|
32
32
|
recentRoutes: z.ZodDefault<z.ZodNumber>;
|
|
33
33
|
openBrowser: z.ZodDefault<z.ZodBoolean>;
|
|
34
|
+
remoteStorage: z.ZodDefault<z.ZodBoolean>;
|
|
34
35
|
terminal: z.ZodDefault<z.ZodObject<{
|
|
35
36
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
36
37
|
pty: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -123,6 +124,7 @@ export declare const OpenTeamConfigObjectSchema: z.ZodObject<{
|
|
|
123
124
|
refreshMs: z.ZodDefault<z.ZodNumber>;
|
|
124
125
|
recentRoutes: z.ZodDefault<z.ZodNumber>;
|
|
125
126
|
openBrowser: z.ZodDefault<z.ZodBoolean>;
|
|
127
|
+
remoteStorage: z.ZodDefault<z.ZodBoolean>;
|
|
126
128
|
terminal: z.ZodDefault<z.ZodObject<{
|
|
127
129
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
128
130
|
pty: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -199,6 +201,7 @@ export declare const OpenTeamConfigSchema: z.ZodObject<{
|
|
|
199
201
|
refreshMs: z.ZodDefault<z.ZodNumber>;
|
|
200
202
|
recentRoutes: z.ZodDefault<z.ZodNumber>;
|
|
201
203
|
openBrowser: z.ZodDefault<z.ZodBoolean>;
|
|
204
|
+
remoteStorage: z.ZodDefault<z.ZodBoolean>;
|
|
202
205
|
terminal: z.ZodDefault<z.ZodObject<{
|
|
203
206
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
204
207
|
pty: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,cAAc;;;iBAGzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;EAA6C,CAAC;AAC3E,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAC;AACH,eAAO,MAAM,kBAAkB;;;EAA6B,CAAC;AAE7D,eAAO,MAAM,iBAAiB;;;EAAqC,CAAC;AAEpE,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,cAAc;;;iBAGzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;EAA6C,CAAC;AAC3E,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAC;AACH,eAAO,MAAM,kBAAkB;;;EAA6B,CAAC;AAE7D,eAAO,MAAM,iBAAiB;;;EAAqC,CAAC;AAEpE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;kBAmC5B,CAAC;AAeL,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;iBAM7B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2DrC,CAAC;AAEH,gDAAgD;AAChD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA6B,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -341,6 +341,7 @@ var ConsoleConfigSchema = z.object({
|
|
|
341
341
|
refreshMs: z.number().int().min(250).default(2000),
|
|
342
342
|
recentRoutes: z.number().int().positive().default(50),
|
|
343
343
|
openBrowser: z.boolean().default(false),
|
|
344
|
+
remoteStorage: z.boolean().default(false),
|
|
344
345
|
terminal: z.object({
|
|
345
346
|
enabled: z.boolean().default(true),
|
|
346
347
|
pty: z.boolean().optional()
|
|
@@ -352,6 +353,7 @@ var ConsoleConfigSchema = z.object({
|
|
|
352
353
|
refreshMs: 2000,
|
|
353
354
|
recentRoutes: 50,
|
|
354
355
|
openBrowser: false,
|
|
356
|
+
remoteStorage: false,
|
|
355
357
|
terminal: { enabled: true }
|
|
356
358
|
});
|
|
357
359
|
var defaultLocalModel = {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { StorageProvider } from "./provider";
|
|
2
|
+
/**
|
|
3
|
+
* `createHttpStorageProvider` — adapter remoto del `StorageProvider` (§ Fase 4).
|
|
4
|
+
*
|
|
5
|
+
* Habla con el endpoint `/storage/...` servido por la Console (ver
|
|
6
|
+
* `web/storageRoute.ts`) para leer/escribir el estado del equipo a través del
|
|
7
|
+
* tunnel. Es un proxy transparente del contrato: cada operación se traduce a una
|
|
8
|
+
* petición HTTP autenticada con el token efímero de la Console.
|
|
9
|
+
*
|
|
10
|
+
* `fetch` es inyectable para tests deterministas; en producción usa el global.
|
|
11
|
+
*/
|
|
12
|
+
export type HttpStorageProviderOptions = {
|
|
13
|
+
/** Origen del endpoint, p. ej. `http://127.0.0.1:4599`. Sin barra final. */
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
/** Token efímero de la Console (bearer). */
|
|
16
|
+
token: string;
|
|
17
|
+
/** Implementación de `fetch` (inyectable). Por defecto el global. */
|
|
18
|
+
fetch?: typeof fetch;
|
|
19
|
+
};
|
|
20
|
+
export declare function createHttpStorageProvider(options: HttpStorageProviderOptions): StorageProvider;
|
|
21
|
+
//# sourceMappingURL=httpStorageProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpStorageProvider.d.ts","sourceRoot":"","sources":["../../src/storage/httpStorageProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;GASG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC;AAOF,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,0BAA0B,GAClC,eAAe,CA2CjB"}
|
package/dist/web/server.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { ConsoleConfig } from "../config/schema";
|
|
|
3
3
|
import type { ConsoleClient } from "../console/opencodeClient";
|
|
4
4
|
import type { PtyClient } from "../console/pty";
|
|
5
5
|
import type { ConsoleInputs } from "../console/state";
|
|
6
|
+
import { type StorageRouteDeps } from "./storageRoute";
|
|
6
7
|
export type ConsoleServerDeps = {
|
|
7
8
|
/** Relee las fuentes y produce los inputs crudos del console. */
|
|
8
9
|
readSnapshot: () => Promise<ConsoleInputs>;
|
|
@@ -20,6 +21,11 @@ export type ConsoleServerDeps = {
|
|
|
20
21
|
createClient: (endpoint: string) => ConsoleClient;
|
|
21
22
|
createPtyClient?: (endpoint: string) => PtyClient;
|
|
22
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Endpoint remoto de storage (`/storage/*`). Opcional y opt-in: expone el
|
|
26
|
+
* estado del equipo autenticado con token para una Console remota vía tunnel.
|
|
27
|
+
*/
|
|
28
|
+
storageApi?: StorageRouteDeps;
|
|
23
29
|
};
|
|
24
30
|
export type ConsoleServer = {
|
|
25
31
|
url: string;
|
package/dist/web/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,IAAI,gBAAgB,EAIjC,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,IAAI,gBAAgB,EAIjC,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAW3E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,iEAAiE;IACjE,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,EAAE,aAAa,CAAC;IACtB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,gBAAgB,CAAC;IACvC,sCAAsC;IACtC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,8EAA8E;IAC9E,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,OAAO,CAAC;QACzB,+DAA+D;QAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC;QAClD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;KACnD,CAAC;IACF;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AA2DF;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,aAAa,CAAC,CAmIxB"}
|
package/dist/web/start.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { ConsoleClient } from "../console/opencodeClient";
|
|
|
5
5
|
import type { PtyClient } from "../console/pty";
|
|
6
6
|
import type { CommitView } from "../console/types";
|
|
7
7
|
import type { StorageProvider } from "../storage/provider";
|
|
8
|
+
import type { StorageRouteDeps } from "./storageRoute";
|
|
8
9
|
export type ConsoleRuntimeDeps = {
|
|
9
10
|
config: ConsoleConfig;
|
|
10
11
|
/** Directorio de logs de sesión (`sessions/*.jsonl`). */
|
|
@@ -31,6 +32,8 @@ export type ConsoleRuntimeDeps = {
|
|
|
31
32
|
createClient: (endpoint: string) => ConsoleClient;
|
|
32
33
|
createPtyClient?: (endpoint: string) => PtyClient;
|
|
33
34
|
};
|
|
35
|
+
/** Endpoint remoto de storage (`/storage/*`). Opcional y opt-in. */
|
|
36
|
+
storageApi?: StorageRouteDeps;
|
|
34
37
|
/** Inyectables para tests. */
|
|
35
38
|
serve?: typeof import("./server").createConsoleServer;
|
|
36
39
|
watch?: (path: string, listener: () => void) => ReturnType<typeof fsWatch>;
|
package/dist/web/start.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/web/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/web/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAI3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,sEAAsE;IACtE,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC;QAClD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;KACnD,CAAC;IACF,oEAAoE;IACpE,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,cAAc,UAAU,EAAE,mBAAmB,CAAC;IACtD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;IAC3E,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,CAAC,CAEzB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { StorageProvider } from "../storage/provider";
|
|
3
|
+
/**
|
|
4
|
+
* Endpoint HTTP que expone un `StorageProvider` sobre la red (§ Fase 4). Permite
|
|
5
|
+
* que una Console/sesión remota lea el estado del equipo a través del tunnel ya
|
|
6
|
+
* existente, reutilizando el token efímero de la Console.
|
|
7
|
+
*
|
|
8
|
+
* Seguridad:
|
|
9
|
+
* - Exige el token (bearer `Authorization` o `?token=`), como el resto de la
|
|
10
|
+
* Console. Sin token válido → 401.
|
|
11
|
+
* - `readOnly` (por defecto activo cuando se expone remoto) rechaza cualquier
|
|
12
|
+
* mutación (`write`/`append`/`mkdir`/`delete`) con 403.
|
|
13
|
+
* - `allowPrefixes` restringe las rutas accesibles a un allowlist normalizado;
|
|
14
|
+
* fuera de él → 403. Así solo se expone lo pactado (sessions/decisions/backlog/
|
|
15
|
+
* agentes), nunca ficheros arbitrarios del disco.
|
|
16
|
+
*
|
|
17
|
+
* El storage de openteam solo contiene telemetría hasheada y artefactos Markdown
|
|
18
|
+
* del equipo: nunca prompts crudos ni PII.
|
|
19
|
+
*/
|
|
20
|
+
export type StorageRouteDeps = {
|
|
21
|
+
storage: StorageProvider;
|
|
22
|
+
token: string;
|
|
23
|
+
/** Si es `true`, rechaza toda mutación con 403. Por defecto `false`. */
|
|
24
|
+
readOnly?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Allowlist de prefijos virtuales accesibles. Si es `undefined`, se permite
|
|
27
|
+
* cualquier ruta (útil en tests). En producción se acota al estado del equipo.
|
|
28
|
+
*/
|
|
29
|
+
allowPrefixes?: readonly string[];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Enruta las peticiones de `/storage/...`. Devuelve `true` si la petición fue
|
|
33
|
+
* atendida (y respondida), `false` para que el servidor siga con sus rutas.
|
|
34
|
+
*/
|
|
35
|
+
export declare function handleStorageRoute(request: IncomingMessage, response: ServerResponse, url: URL, deps: StorageRouteDeps): Promise<boolean>;
|
|
36
|
+
//# sourceMappingURL=storageRoute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageRoute.d.ts","sourceRoot":"","sources":["../../src/web/storageRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAgKF;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,OAAO,CAAC,CA4ClB"}
|