@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.
@@ -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,CAwE7B"}
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 JSON_HEADERS2 = { "content-type": "application/json" };
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, JSON_HEADERS2).end(await stateJson(deps));
2305
+ response.writeHead(200, JSON_HEADERS3).end(await stateJson(deps));
2137
2306
  return;
2138
2307
  }
2139
2308
  if (path === "/healthz") {
2140
- response.writeHead(200, JSON_HEADERS2).end(JSON.stringify({ ok: true }));
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);
@@ -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;;;;;;;;;;;;;;kBA4B5B,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"}
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"}
@@ -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;
@@ -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;AAatD,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;CACH,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,CA4HxB"}
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"}
@@ -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>;
@@ -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;AAM3D,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,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"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmanuelcorral/openteam",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "description": "Plugin opencode de routing coste-consciente local-first con orquestación Squad.",
5
5
  "license": "MIT",
6
6
  "author": "Jose Manuel Corral",