@jmanuelcorral/openteam 0.1.27 → 0.1.29

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.
@@ -3,6 +3,7 @@ import type { OpenTeamConfig } from "../config/schema";
3
3
  import { type ConsoleClient } from "../console/opencodeClient";
4
4
  import { type PtyClient } from "../console/pty";
5
5
  import type { CommitView } from "../console/types";
6
+ import type { StorageProvider } from "../storage/provider";
6
7
  import type { ConsoleRuntime, ConsoleRuntimeDeps } from "../web/start";
7
8
  /** Dependencias inyectables del launcher `openteam console`. */
8
9
  export type ConsoleServeDeps = {
@@ -15,8 +16,8 @@ export type ConsoleServeDeps = {
15
16
  agentDir: string;
16
17
  /** Telemetry legacy a fusionar como route events. Opcional. */
17
18
  legacyTelemetryPath?: string;
18
- readText: (path: string) => Promise<string | undefined>;
19
- listFiles: (dir: string) => Promise<string[]>;
19
+ /** Backend de persistencia (logs de sesión, decisiones, backlog). */
20
+ storage: StorageProvider;
20
21
  listAgentFiles: (dir: string) => Promise<AgentFile[]>;
21
22
  now: () => string;
22
23
  gitLastCommit?: () => Promise<CommitView | undefined>;
@@ -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,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,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxD,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,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,CAyE7B"}
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"}
package/dist/cli.js CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  // src/cli.ts
4
4
  import { execFile, spawn } from "node:child_process";
5
- import { access, mkdir as mkdir2, readdir, readFile, writeFile as writeFile2 } from "node:fs/promises";
6
- import { dirname as dirname2, join as join2 } from "node:path";
5
+ import { access, mkdir as mkdir3, readdir as readdir2, readFile as readFile2, writeFile as writeFile3 } from "node:fs/promises";
6
+ import { dirname as dirname3, join as join3 } from "node:path";
7
7
  import { promisify } from "node:util";
8
8
 
9
9
  // src/cli/consoleServe.ts
@@ -1181,6 +1181,38 @@ function aggregateEvents(events) {
1181
1181
  };
1182
1182
  }
1183
1183
 
1184
+ // src/storage/path.ts
1185
+ class StoragePathError extends Error {
1186
+ constructor(message) {
1187
+ super(message);
1188
+ this.name = "StoragePathError";
1189
+ }
1190
+ }
1191
+ function normalizeVirtualPath(input) {
1192
+ const segments = [];
1193
+ for (const rawSegment of input.split(/[\\/]+/)) {
1194
+ if (rawSegment === "" || rawSegment === ".") {
1195
+ continue;
1196
+ }
1197
+ if (rawSegment === "..") {
1198
+ if (segments.length === 0) {
1199
+ throw new StoragePathError(`la ruta "${input}" escapa por encima de la raíz`);
1200
+ }
1201
+ segments.pop();
1202
+ continue;
1203
+ }
1204
+ segments.push(rawSegment);
1205
+ }
1206
+ return segments.join("/");
1207
+ }
1208
+ function joinVirtualPath(...segments) {
1209
+ return normalizeVirtualPath(segments.join("/"));
1210
+ }
1211
+ function splitVirtualPath(path) {
1212
+ const normalized = normalizeVirtualPath(path);
1213
+ return normalized === "" ? [] : normalized.split("/");
1214
+ }
1215
+
1184
1216
  // src/telemetry/events.ts
1185
1217
  import { z as z4 } from "zod";
1186
1218
 
@@ -1453,9 +1485,6 @@ function parseCostRecordsJsonl(text) {
1453
1485
  // src/telemetry/eventLog.ts
1454
1486
  var DEFAULT_SESSIONS_DIR = ".opencode/openteam/sessions";
1455
1487
  var LEGACY_SESSION_ID = "legacy";
1456
- function defaultJoin(dir, file) {
1457
- return dir.endsWith("/") ? `${dir}${file}` : `${dir}/${file}`;
1458
- }
1459
1488
  function parseEventsJsonl(text) {
1460
1489
  const events = [];
1461
1490
  for (const line of text.split(`
@@ -1536,15 +1565,14 @@ async function readRouteCostRecords(dir, deps) {
1536
1565
  return records;
1537
1566
  }
1538
1567
  async function readSessionEvents(dir, deps) {
1539
- const join = deps.join ?? defaultJoin;
1540
- const files = (await deps.listFiles(dir)).filter((file) => file.endsWith(".jsonl"));
1568
+ const files = (await deps.storage.list(dir)).filter((file) => file.endsWith(".jsonl"));
1541
1569
  const perFile = await Promise.all(files.map(async (file) => {
1542
- const text = await deps.readText(join(dir, file));
1570
+ const text = await deps.storage.read(joinVirtualPath(dir, file));
1543
1571
  return text === undefined ? [] : parseEventsJsonl(text);
1544
1572
  }));
1545
1573
  const events = perFile.flat();
1546
1574
  if (deps.legacyTelemetryPath !== undefined) {
1547
- const legacyText = await deps.readText(deps.legacyTelemetryPath);
1575
+ const legacyText = await deps.storage.read(deps.legacyTelemetryPath);
1548
1576
  if (legacyText !== undefined) {
1549
1577
  for (const record of parseCostRecordsJsonl(legacyText)) {
1550
1578
  events.push(costRecordToRouteEvent(record));
@@ -2297,15 +2325,14 @@ function parseDecisionsMarkdown(text, options = {}) {
2297
2325
  // src/web/snapshot.ts
2298
2326
  function createSnapshotReader(deps, paths, context = {}) {
2299
2327
  const readEventsDeps = {
2300
- listFiles: deps.listFiles,
2301
- readText: deps.readText,
2328
+ storage: deps.storage,
2302
2329
  ...paths.legacyTelemetryPath !== undefined ? { legacyTelemetryPath: paths.legacyTelemetryPath } : {}
2303
2330
  };
2304
2331
  return async () => {
2305
2332
  const [sessionEvents, decisionsText, backlogText, agentFiles, lastCommit] = await Promise.all([
2306
2333
  readSessionEvents(paths.sessionsDir, readEventsDeps),
2307
- deps.readText(paths.decisionsPath),
2308
- deps.readText(paths.backlogPath),
2334
+ deps.storage.read(paths.decisionsPath),
2335
+ deps.storage.read(paths.backlogPath),
2309
2336
  deps.listAgentFiles(paths.agentDir),
2310
2337
  deps.gitLastCommit?.() ?? Promise.resolve(undefined)
2311
2338
  ]);
@@ -2378,8 +2405,7 @@ async function createConsoleRuntime(deps) {
2378
2405
  const backlogPath = deps.backlogPath ?? DEFAULT_BACKLOG_PATH;
2379
2406
  const decisionsPath = deps.decisionsPath ?? DEFAULT_DECISIONS_PATH;
2380
2407
  const readSnapshot = createSnapshotReader({
2381
- readText: deps.readText,
2382
- listFiles: deps.listFiles,
2408
+ storage: deps.storage,
2383
2409
  listAgentFiles: deps.listAgentFiles,
2384
2410
  now: deps.now,
2385
2411
  ...deps.gitLastCommit !== undefined ? { gitLastCommit: deps.gitLastCommit } : {}
@@ -2445,8 +2471,7 @@ async function runConsoleServe(deps, options) {
2445
2471
  backlogPath: deps.backlogPath,
2446
2472
  agentDir: deps.agentDir,
2447
2473
  ...deps.legacyTelemetryPath !== undefined ? { legacyTelemetryPath: deps.legacyTelemetryPath } : {},
2448
- readText: deps.readText,
2449
- listFiles: deps.listFiles,
2474
+ storage: deps.storage,
2450
2475
  listAgentFiles: deps.listAgentFiles,
2451
2476
  now: deps.now,
2452
2477
  ...deps.gitLastCommit !== undefined ? { gitLastCommit: deps.gitLastCommit } : {},
@@ -4503,6 +4528,101 @@ function loadOpenTeamConfig(raw) {
4503
4528
  return OpenTeamConfigSchema.parse(raw ?? {});
4504
4529
  }
4505
4530
 
4531
+ // src/storage/fsStorageProvider.ts
4532
+ import {
4533
+ appendFile,
4534
+ mkdir as mkdir2,
4535
+ readdir,
4536
+ readFile,
4537
+ rm,
4538
+ stat,
4539
+ writeFile as writeFile2
4540
+ } from "node:fs/promises";
4541
+ import { dirname as dirname2, join as join2 } from "node:path";
4542
+ function isMissing(error) {
4543
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
4544
+ }
4545
+ function createFsStorageProvider(root) {
4546
+ function toDisk(path) {
4547
+ return join2(root, ...splitVirtualPath(path));
4548
+ }
4549
+ return {
4550
+ async read(path) {
4551
+ try {
4552
+ return await readFile(toDisk(path), "utf8");
4553
+ } catch (error) {
4554
+ if (isMissing(error)) {
4555
+ return;
4556
+ }
4557
+ throw error;
4558
+ }
4559
+ },
4560
+ async write(path, content) {
4561
+ const disk = toDisk(path);
4562
+ await mkdir2(dirname2(disk), { recursive: true });
4563
+ await writeFile2(disk, content, "utf8");
4564
+ },
4565
+ async append(path, content) {
4566
+ const disk = toDisk(path);
4567
+ await mkdir2(dirname2(disk), { recursive: true });
4568
+ await appendFile(disk, content, "utf8");
4569
+ },
4570
+ async exists(path) {
4571
+ try {
4572
+ await stat(toDisk(path));
4573
+ return true;
4574
+ } catch (error) {
4575
+ if (isMissing(error)) {
4576
+ return false;
4577
+ }
4578
+ throw error;
4579
+ }
4580
+ },
4581
+ async list(dir) {
4582
+ try {
4583
+ const names = await readdir(toDisk(dir));
4584
+ return names.sort();
4585
+ } catch (error) {
4586
+ if (isMissing(error)) {
4587
+ return [];
4588
+ }
4589
+ throw error;
4590
+ }
4591
+ },
4592
+ async isDirectory(path) {
4593
+ try {
4594
+ return (await stat(toDisk(path))).isDirectory();
4595
+ } catch (error) {
4596
+ if (isMissing(error)) {
4597
+ return false;
4598
+ }
4599
+ throw error;
4600
+ }
4601
+ },
4602
+ async mkdir(dir) {
4603
+ await mkdir2(toDisk(dir), { recursive: true });
4604
+ },
4605
+ async delete(path) {
4606
+ await rm(toDisk(path), { force: true });
4607
+ },
4608
+ async stat(path) {
4609
+ try {
4610
+ const stats = await stat(toDisk(path));
4611
+ return {
4612
+ size: stats.size,
4613
+ mtimeMs: stats.mtimeMs,
4614
+ isDirectory: stats.isDirectory()
4615
+ };
4616
+ } catch (error) {
4617
+ if (isMissing(error)) {
4618
+ return;
4619
+ }
4620
+ throw error;
4621
+ }
4622
+ }
4623
+ };
4624
+ }
4625
+
4506
4626
  // src/web/git.ts
4507
4627
  function createGitLastCommit(exec) {
4508
4628
  return async () => {
@@ -4524,7 +4644,7 @@ function createGitLastCommit(exec) {
4524
4644
 
4525
4645
  // src/cli.ts
4526
4646
  var execFileAsync = promisify(execFile);
4527
- var AGENT_DIR = dirname2(ORCHESTRATOR_AGENT_PATH);
4647
+ var AGENT_DIR = dirname3(ORCHESTRATOR_AGENT_PATH);
4528
4648
  function isMissingFile(error) {
4529
4649
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
4530
4650
  }
@@ -4543,7 +4663,7 @@ var nodeExec = async (command, args) => {
4543
4663
  };
4544
4664
  async function loadConfig(path) {
4545
4665
  try {
4546
- const content = await readFile(path, "utf8");
4666
+ const content = await readFile2(path, "utf8");
4547
4667
  return loadOpenTeamConfig(JSON.parse(content));
4548
4668
  } catch (error) {
4549
4669
  if (isMissingFile(error)) {
@@ -4552,26 +4672,7 @@ async function loadConfig(path) {
4552
4672
  throw error;
4553
4673
  }
4554
4674
  }
4555
- async function readTextOptional(path) {
4556
- try {
4557
- return await readFile(path, "utf8");
4558
- } catch (error) {
4559
- if (isMissingFile(error)) {
4560
- return;
4561
- }
4562
- throw error;
4563
- }
4564
- }
4565
- async function listDirFiles(dir) {
4566
- try {
4567
- return await readdir(dir);
4568
- } catch (error) {
4569
- if (isMissingFile(error)) {
4570
- return [];
4571
- }
4572
- throw error;
4573
- }
4574
- }
4675
+ var storage = createFsStorageProvider(process.cwd());
4575
4676
  async function openBrowser(url) {
4576
4677
  if (process.platform === "win32") {
4577
4678
  await nodeExec("cmd", ["/c", "start", "", url]);
@@ -4593,7 +4694,7 @@ var deps = {
4593
4694
  saveConfig: (config, path) => writeOpenTeamConfigFile(config, path),
4594
4695
  readOpencodeConfig: async (path) => {
4595
4696
  try {
4596
- const content = await readFile(path, "utf8");
4697
+ const content = await readFile2(path, "utf8");
4597
4698
  return JSON.parse(content);
4598
4699
  } catch (error) {
4599
4700
  if (isMissingFile(error)) {
@@ -4603,18 +4704,18 @@ var deps = {
4603
4704
  }
4604
4705
  },
4605
4706
  writeOpencodeConfig: async (config, path) => {
4606
- await mkdir2(dirname2(path), { recursive: true });
4607
- await writeFile2(path, `${JSON.stringify(config, null, 2)}
4707
+ await mkdir3(dirname3(path), { recursive: true });
4708
+ await writeFile3(path, `${JSON.stringify(config, null, 2)}
4608
4709
  `, "utf8");
4609
4710
  },
4610
4711
  writeOrchestratorAgent: async (contents, path) => {
4611
- await mkdir2(dirname2(path), { recursive: true });
4612
- await writeFile2(path, contents, "utf8");
4712
+ await mkdir3(dirname3(path), { recursive: true });
4713
+ await writeFile3(path, contents, "utf8");
4613
4714
  },
4614
4715
  listAgentFiles: async (dir) => {
4615
4716
  let entries;
4616
4717
  try {
4617
- entries = await readdir(dir);
4718
+ entries = await readdir2(dir);
4618
4719
  } catch (error) {
4619
4720
  if (isMissingFile(error)) {
4620
4721
  return [];
@@ -4624,7 +4725,7 @@ var deps = {
4624
4725
  const mdFiles = entries.filter((entry) => entry.endsWith(".md"));
4625
4726
  return Promise.all(mdFiles.map(async (entry) => ({
4626
4727
  name: entry.replace(/\.md$/, ""),
4627
- contents: await readFile(join2(dir, entry), "utf8")
4728
+ contents: await readFile2(join3(dir, entry), "utf8")
4628
4729
  })));
4629
4730
  },
4630
4731
  probe: (config) => {
@@ -4636,8 +4737,7 @@ var deps = {
4636
4737
  return registry.probe(config.local.runtimes);
4637
4738
  },
4638
4739
  readTelemetry: (path) => readRouteCostRecords(DEFAULT_SESSIONS_DIR, {
4639
- listFiles: listDirFiles,
4640
- readText: readTextOptional,
4740
+ storage,
4641
4741
  legacyTelemetryPath: path
4642
4742
  }),
4643
4743
  configPath: DEFAULT_CONFIG_PATH,
@@ -4654,8 +4754,8 @@ function createSetupDeps() {
4654
4754
  loadFrontierProfiles: createLoadFrontierProfiles(),
4655
4755
  prompt: clackPrompter,
4656
4756
  writeFile: async (path, contents) => {
4657
- await mkdir2(dirname2(path), { recursive: true });
4658
- await writeFile2(path, contents, "utf8");
4757
+ await mkdir3(dirname3(path), { recursive: true });
4758
+ await writeFile3(path, contents, "utf8");
4659
4759
  },
4660
4760
  fileExists: async (path) => {
4661
4761
  try {
@@ -4689,8 +4789,7 @@ async function main() {
4689
4789
  backlogPath: DEFAULT_BACKLOG_PATH,
4690
4790
  agentDir: AGENT_DIR,
4691
4791
  legacyTelemetryPath: DEFAULT_TELEMETRY_PATH,
4692
- readText: readTextOptional,
4693
- listFiles: listDirFiles,
4792
+ storage,
4694
4793
  listAgentFiles: deps.listAgentFiles,
4695
4794
  now: () => new Date().toISOString(),
4696
4795
  gitLastCommit: createGitLastCommit(nodeExec),
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import type { Plugin, PluginModule } from "@opencode-ai/plugin";
3
3
  import type { CliDeps } from "./commands/dispatch";
4
4
  import type { OpenTeamConfig } from "./config/schema";
5
5
  import { RuntimeRegistry } from "./local/registry";
6
+ import type { StorageProvider } from "./storage/provider";
6
7
  import { type EventSink } from "./telemetry/eventLog";
7
8
  type FileAppenderDeps = {
8
9
  mkdir?: typeof mkdir;
@@ -11,15 +12,13 @@ type FileAppenderDeps = {
11
12
  export declare function logAvailabilityRefreshError(error: unknown): void;
12
13
  export declare function logTelemetryError(error: unknown): void;
13
14
  export declare function createFileAppender(filePath: string, deps?: FileAppenderDeps): (line: string) => Promise<void>;
14
- /** Appender genérico: crea el directorio destino y añade una línea al fichero. */
15
- export declare function createPathAppender(deps?: FileAppenderDeps): (path: string, line: string) => Promise<void>;
16
15
  /**
17
16
  * Crea el sink de eventos por sesión (`<sessionsDir>/<sessionID>.jsonl`). Si la
18
17
  * telemetría está desactivada devuelve un sink no-op.
19
18
  */
20
- export declare function createEventSink(rawOptions: unknown): EventSink;
19
+ export declare function createEventSink(rawOptions: unknown, storage?: StorageProvider): EventSink;
21
20
  export declare function isMissingFile(error: unknown): boolean;
22
- export declare function createCliDeps(config: OpenTeamConfig, registry: RuntimeRegistry, telemetryPath: string, sessionsDir?: string): CliDeps;
21
+ export declare function createCliDeps(config: OpenTeamConfig, registry: RuntimeRegistry, telemetryPath: string, sessionsDir?: string, storage?: StorageProvider): CliDeps;
23
22
  export declare const server: Plugin;
24
23
  declare const plugin: PluginModule;
25
24
  export default plugin;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,EAIN,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,MAAM,EAAe,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAUnD,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,sBAAsB,CAAC;AAS9B,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;CAChC,CAAC;AAcF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGhE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGtD;AAgCD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,gBAAqB,GAC1B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAQjC;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAChC,IAAI,GAAE,gBAAqB,GAC1B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAQ/C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,OAAO,GAAG,SAAS,CAa9D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOrD;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,MAA6B,GACzC,OAAO,CAmFT;AAED,eAAO,MAAM,MAAM,EAAE,MAmEpB,CAAC;AAEF,QAAA,MAAM,MAAM,EAAE,YAGb,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,EAIN,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,MAAM,EAAe,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAWnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,sBAAsB,CAAC;AAS9B,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;CAChC,CAAC;AAcF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGhE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGtD;AAgCD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,gBAAqB,GAC1B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAQjC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,EACnB,OAAO,GAAE,eAAwD,GAChE,SAAS,CAYX;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOrD;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,MAA6B,EAC1C,OAAO,GAAE,eAAwD,GAChE,OAAO,CAgET;AAED,eAAO,MAAM,MAAM,EAAE,MA0EpB,CAAC;AAEF,QAAA,MAAM,MAAM,EAAE,YAGb,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  // src/index.ts
2
2
  import {
3
- appendFile,
4
- mkdir as mkdir2,
5
- readdir,
6
- readFile,
7
- writeFile as writeFile2
3
+ appendFile as appendFile2,
4
+ mkdir as mkdir3,
5
+ readdir as readdir2,
6
+ readFile as readFile2,
7
+ writeFile as writeFile3
8
8
  } from "node:fs/promises";
9
- import { dirname as dirname2, join } from "node:path";
9
+ import { dirname as dirname3, join as join2 } from "node:path";
10
10
 
11
11
  // src/commands/orchestratorAgent.ts
12
12
  var ORCHESTRATOR_AGENT_PATH = ".opencode/agent/openteam.md";
@@ -2042,6 +2042,38 @@ function toCostRecord(decision2, context) {
2042
2042
  return record;
2043
2043
  }
2044
2044
 
2045
+ // src/storage/path.ts
2046
+ class StoragePathError extends Error {
2047
+ constructor(message) {
2048
+ super(message);
2049
+ this.name = "StoragePathError";
2050
+ }
2051
+ }
2052
+ function normalizeVirtualPath(input) {
2053
+ const segments = [];
2054
+ for (const rawSegment of input.split(/[\\/]+/)) {
2055
+ if (rawSegment === "" || rawSegment === ".") {
2056
+ continue;
2057
+ }
2058
+ if (rawSegment === "..") {
2059
+ if (segments.length === 0) {
2060
+ throw new StoragePathError(`la ruta "${input}" escapa por encima de la raíz`);
2061
+ }
2062
+ segments.pop();
2063
+ continue;
2064
+ }
2065
+ segments.push(rawSegment);
2066
+ }
2067
+ return segments.join("/");
2068
+ }
2069
+ function joinVirtualPath(...segments) {
2070
+ return normalizeVirtualPath(segments.join("/"));
2071
+ }
2072
+ function splitVirtualPath(path) {
2073
+ const normalized = normalizeVirtualPath(path);
2074
+ return normalized === "" ? [] : normalized.split("/");
2075
+ }
2076
+
2045
2077
  // src/telemetry/types.ts
2046
2078
  import { z as z4 } from "zod";
2047
2079
  var CostRecordSchema = z4.object({
@@ -2092,17 +2124,13 @@ function sessionFileName(sessionID) {
2092
2124
  const safe = sessionID.replace(/[^A-Za-z0-9._-]/g, "_");
2093
2125
  return `${safe}.jsonl`;
2094
2126
  }
2095
- function defaultJoin(dir, file) {
2096
- return dir.endsWith("/") ? `${dir}${file}` : `${dir}/${file}`;
2097
- }
2098
2127
  function createEventLogSink(deps) {
2099
- const join = deps.join ?? defaultJoin;
2100
2128
  return {
2101
2129
  emit: async (event) => {
2102
2130
  try {
2103
2131
  const parsed = OpenTeamEventSchema.parse(event);
2104
- const path = join(deps.dir, sessionFileName(parsed.sessionID));
2105
- await deps.appendLine(path, `${JSON.stringify(parsed)}
2132
+ const path = joinVirtualPath(deps.dir, sessionFileName(parsed.sessionID));
2133
+ await deps.storage.append(path, `${JSON.stringify(parsed)}
2106
2134
  `);
2107
2135
  } catch (error) {
2108
2136
  deps.onError?.(error);
@@ -2193,15 +2221,14 @@ async function readRouteCostRecords(dir, deps) {
2193
2221
  return records;
2194
2222
  }
2195
2223
  async function readSessionEvents(dir, deps) {
2196
- const join = deps.join ?? defaultJoin;
2197
- const files = (await deps.listFiles(dir)).filter((file) => file.endsWith(".jsonl"));
2224
+ const files = (await deps.storage.list(dir)).filter((file) => file.endsWith(".jsonl"));
2198
2225
  const perFile = await Promise.all(files.map(async (file) => {
2199
- const text = await deps.readText(join(dir, file));
2226
+ const text = await deps.storage.read(joinVirtualPath(dir, file));
2200
2227
  return text === undefined ? [] : parseEventsJsonl(text);
2201
2228
  }));
2202
2229
  const events = perFile.flat();
2203
2230
  if (deps.legacyTelemetryPath !== undefined) {
2204
- const legacyText = await deps.readText(deps.legacyTelemetryPath);
2231
+ const legacyText = await deps.storage.read(deps.legacyTelemetryPath);
2205
2232
  if (legacyText !== undefined) {
2206
2233
  for (const record of parseCostRecordsJsonl(legacyText)) {
2207
2234
  events.push(costRecordToRouteEvent(record));
@@ -2338,6 +2365,101 @@ function createToolcallTracker(deps) {
2338
2365
  };
2339
2366
  }
2340
2367
 
2368
+ // src/storage/fsStorageProvider.ts
2369
+ import {
2370
+ appendFile,
2371
+ mkdir as mkdir2,
2372
+ readdir,
2373
+ readFile,
2374
+ rm,
2375
+ stat,
2376
+ writeFile as writeFile2
2377
+ } from "node:fs/promises";
2378
+ import { dirname as dirname2, join } from "node:path";
2379
+ function isMissing(error) {
2380
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
2381
+ }
2382
+ function createFsStorageProvider(root) {
2383
+ function toDisk(path) {
2384
+ return join(root, ...splitVirtualPath(path));
2385
+ }
2386
+ return {
2387
+ async read(path) {
2388
+ try {
2389
+ return await readFile(toDisk(path), "utf8");
2390
+ } catch (error) {
2391
+ if (isMissing(error)) {
2392
+ return;
2393
+ }
2394
+ throw error;
2395
+ }
2396
+ },
2397
+ async write(path, content) {
2398
+ const disk = toDisk(path);
2399
+ await mkdir2(dirname2(disk), { recursive: true });
2400
+ await writeFile2(disk, content, "utf8");
2401
+ },
2402
+ async append(path, content) {
2403
+ const disk = toDisk(path);
2404
+ await mkdir2(dirname2(disk), { recursive: true });
2405
+ await appendFile(disk, content, "utf8");
2406
+ },
2407
+ async exists(path) {
2408
+ try {
2409
+ await stat(toDisk(path));
2410
+ return true;
2411
+ } catch (error) {
2412
+ if (isMissing(error)) {
2413
+ return false;
2414
+ }
2415
+ throw error;
2416
+ }
2417
+ },
2418
+ async list(dir) {
2419
+ try {
2420
+ const names = await readdir(toDisk(dir));
2421
+ return names.sort();
2422
+ } catch (error) {
2423
+ if (isMissing(error)) {
2424
+ return [];
2425
+ }
2426
+ throw error;
2427
+ }
2428
+ },
2429
+ async isDirectory(path) {
2430
+ try {
2431
+ return (await stat(toDisk(path))).isDirectory();
2432
+ } catch (error) {
2433
+ if (isMissing(error)) {
2434
+ return false;
2435
+ }
2436
+ throw error;
2437
+ }
2438
+ },
2439
+ async mkdir(dir) {
2440
+ await mkdir2(toDisk(dir), { recursive: true });
2441
+ },
2442
+ async delete(path) {
2443
+ await rm(toDisk(path), { force: true });
2444
+ },
2445
+ async stat(path) {
2446
+ try {
2447
+ const stats = await stat(toDisk(path));
2448
+ return {
2449
+ size: stats.size,
2450
+ mtimeMs: stats.mtimeMs,
2451
+ isDirectory: stats.isDirectory()
2452
+ };
2453
+ } catch (error) {
2454
+ if (isMissing(error)) {
2455
+ return;
2456
+ }
2457
+ throw error;
2458
+ }
2459
+ }
2460
+ };
2461
+ }
2462
+
2341
2463
  // src/index.ts
2342
2464
  function createShellExec($) {
2343
2465
  return async (command, args) => {
@@ -2369,41 +2491,32 @@ function telemetryOptions(rawOptions) {
2369
2491
  };
2370
2492
  }
2371
2493
  function createFileAppender(filePath, deps = {}) {
2372
- const mkdirFn = deps.mkdir ?? mkdir2;
2373
- const appendFileFn = deps.appendFile ?? appendFile;
2494
+ const mkdirFn = deps.mkdir ?? mkdir3;
2495
+ const appendFileFn = deps.appendFile ?? appendFile2;
2374
2496
  return async (line) => {
2375
- await mkdirFn(dirname2(filePath), { recursive: true });
2497
+ await mkdirFn(dirname3(filePath), { recursive: true });
2376
2498
  await appendFileFn(filePath, line, "utf8");
2377
2499
  };
2378
2500
  }
2379
- function createPathAppender(deps = {}) {
2380
- const mkdirFn = deps.mkdir ?? mkdir2;
2381
- const appendFileFn = deps.appendFile ?? appendFile;
2382
- return async (path, line) => {
2383
- await mkdirFn(dirname2(path), { recursive: true });
2384
- await appendFileFn(path, line, "utf8");
2385
- };
2386
- }
2387
- function createEventSink(rawOptions) {
2501
+ function createEventSink(rawOptions, storage = createFsStorageProvider(process.cwd())) {
2388
2502
  const options = telemetryOptions(rawOptions);
2389
2503
  if (!options.enabled) {
2390
2504
  return createNullEventSink();
2391
2505
  }
2392
2506
  return createEventLogSink({
2393
2507
  dir: options.sessionsDir,
2394
- appendLine: createPathAppender(),
2395
- join,
2508
+ storage,
2396
2509
  onError: logTelemetryError
2397
2510
  });
2398
2511
  }
2399
2512
  function isMissingFile(error) {
2400
2513
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
2401
2514
  }
2402
- function createCliDeps(config, registry, telemetryPath, sessionsDir = DEFAULT_SESSIONS_DIR) {
2515
+ function createCliDeps(config, registry, telemetryPath, sessionsDir = DEFAULT_SESSIONS_DIR, storage = createFsStorageProvider(process.cwd())) {
2403
2516
  return {
2404
2517
  loadConfig: async (path) => {
2405
2518
  try {
2406
- return loadOpenTeamConfig(JSON.parse(await readFile(path, "utf8")));
2519
+ return loadOpenTeamConfig(JSON.parse(await readFile2(path, "utf8")));
2407
2520
  } catch (error) {
2408
2521
  if (isMissingFile(error)) {
2409
2522
  return config;
@@ -2414,7 +2527,7 @@ function createCliDeps(config, registry, telemetryPath, sessionsDir = DEFAULT_SE
2414
2527
  saveConfig: (nextConfig, path) => writeOpenTeamConfigFile(nextConfig, path),
2415
2528
  readOpencodeConfig: async (path) => {
2416
2529
  try {
2417
- return JSON.parse(await readFile(path, "utf8"));
2530
+ return JSON.parse(await readFile2(path, "utf8"));
2418
2531
  } catch (error) {
2419
2532
  if (isMissingFile(error)) {
2420
2533
  return;
@@ -2423,18 +2536,18 @@ function createCliDeps(config, registry, telemetryPath, sessionsDir = DEFAULT_SE
2423
2536
  }
2424
2537
  },
2425
2538
  writeOpencodeConfig: async (nextConfig, path) => {
2426
- await mkdir2(dirname2(path), { recursive: true });
2427
- await writeFile2(path, `${JSON.stringify(nextConfig, null, 2)}
2539
+ await mkdir3(dirname3(path), { recursive: true });
2540
+ await writeFile3(path, `${JSON.stringify(nextConfig, null, 2)}
2428
2541
  `, "utf8");
2429
2542
  },
2430
2543
  writeOrchestratorAgent: async (contents, path) => {
2431
- await mkdir2(dirname2(path), { recursive: true });
2432
- await writeFile2(path, contents, "utf8");
2544
+ await mkdir3(dirname3(path), { recursive: true });
2545
+ await writeFile3(path, contents, "utf8");
2433
2546
  },
2434
2547
  listAgentFiles: async (dir) => {
2435
2548
  let entries;
2436
2549
  try {
2437
- entries = await readdir(dir);
2550
+ entries = await readdir2(dir);
2438
2551
  } catch (error) {
2439
2552
  if (isMissingFile(error)) {
2440
2553
  return [];
@@ -2444,38 +2557,19 @@ function createCliDeps(config, registry, telemetryPath, sessionsDir = DEFAULT_SE
2444
2557
  const mdFiles = entries.filter((entry) => entry.endsWith(".md"));
2445
2558
  return Promise.all(mdFiles.map(async (entry) => ({
2446
2559
  name: entry.replace(/\.md$/, ""),
2447
- contents: await readFile(join(dir, entry), "utf8")
2560
+ contents: await readFile2(join2(dir, entry), "utf8")
2448
2561
  })));
2449
2562
  },
2450
2563
  probe: (nextConfig) => registry.probe(nextConfig.local.runtimes),
2451
2564
  readTelemetry: (path) => readRouteCostRecords(sessionsDir, {
2452
- listFiles: async (dir) => {
2453
- try {
2454
- return await readdir(dir);
2455
- } catch (error) {
2456
- if (isMissingFile(error)) {
2457
- return [];
2458
- }
2459
- throw error;
2460
- }
2461
- },
2462
- readText: async (filePath) => {
2463
- try {
2464
- return await readFile(filePath, "utf8");
2465
- } catch (error) {
2466
- if (isMissingFile(error)) {
2467
- return;
2468
- }
2469
- throw error;
2470
- }
2471
- },
2565
+ storage,
2472
2566
  legacyTelemetryPath: path
2473
2567
  }),
2474
2568
  configPath: DEFAULT_CONFIG_PATH,
2475
2569
  telemetryPath,
2476
2570
  opencodeConfigPath: OPENCODE_CONFIG_PATH,
2477
2571
  orchestratorAgentPath: ORCHESTRATOR_AGENT_PATH,
2478
- agentDir: dirname2(ORCHESTRATOR_AGENT_PATH)
2572
+ agentDir: dirname3(ORCHESTRATOR_AGENT_PATH)
2479
2573
  };
2480
2574
  }
2481
2575
  var server = async (ctx, rawOptions) => {
@@ -2493,9 +2587,10 @@ var server = async (ctx, rawOptions) => {
2493
2587
  cache.refresh();
2494
2588
  const telemetryPath = telemetryOptions(rawOptions).path;
2495
2589
  const sessionsDir = telemetryOptions(rawOptions).sessionsDir;
2496
- const sink = createEventSink(rawOptions);
2590
+ const storage = createFsStorageProvider(process.cwd());
2591
+ const sink = createEventSink(rawOptions, storage);
2497
2592
  const hooks = createHooks(config, cache.get, { sink });
2498
- const cliDeps = createCliDeps(config, registry, telemetryPath, sessionsDir);
2593
+ const cliDeps = createCliDeps(config, registry, telemetryPath, sessionsDir, storage);
2499
2594
  const toolcalls = createToolcallTracker({ sink });
2500
2595
  const now = () => Date.now();
2501
2596
  const announcedSessions = new Set;
@@ -2554,7 +2649,6 @@ export {
2554
2649
  logAvailabilityRefreshError,
2555
2650
  isMissingFile,
2556
2651
  src_default as default,
2557
- createPathAppender,
2558
2652
  createFileAppender,
2559
2653
  createEventSink,
2560
2654
  createCliDeps
@@ -0,0 +1,11 @@
1
+ import type { StorageProvider } from "./provider";
2
+ /**
3
+ * `StorageProvider` sobre `node:fs/promises`. Mapea rutas virtuales POSIX a
4
+ * disco bajo `root`. Es el adapter por defecto en producción.
5
+ *
6
+ * Semántica: `read`/`stat` devuelven `undefined` ante ENOENT; `write`/`append`
7
+ * crean directorios intermedios; `list` devuelve `[]` si el directorio no
8
+ * existe; `delete` es idempotente (usa `rm` con `force`).
9
+ */
10
+ export declare function createFsStorageProvider(root: string): StorageProvider;
11
+ //# sourceMappingURL=fsStorageProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsStorageProvider.d.ts","sourceRoot":"","sources":["../../src/storage/fsStorageProvider.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,YAAY,CAAC;AAW/D;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAgFrE"}
@@ -0,0 +1,5 @@
1
+ export { createFsStorageProvider } from "./fsStorageProvider";
2
+ export { createMemoryStorageProvider } from "./memoryStorageProvider";
3
+ export { joinVirtualPath, normalizeVirtualPath, parentVirtualPath, StoragePathError, splitVirtualPath, } from "./path";
4
+ export type { StorageProvider, StorageStat } from "./provider";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { StorageProvider } from "./provider";
2
+ /**
3
+ * `StorageProvider` en memoria basado en `Map`. Determinista y sin I/O real:
4
+ * pensado para tests y como implementación de referencia del contrato.
5
+ *
6
+ * Los directorios son implícitos (derivados de los ficheros existentes) pero
7
+ * también pueden crearse vacíos con `mkdir`. Un contador monótono provee
8
+ * `mtimeMs` reproducible por secuencia de operaciones.
9
+ */
10
+ export declare function createMemoryStorageProvider(): StorageProvider;
11
+ //# sourceMappingURL=memoryStorageProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryStorageProvider.d.ts","sourceRoot":"","sources":["../../src/storage/memoryStorageProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,YAAY,CAAC;AAE/D;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,IAAI,eAAe,CAwH7D"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Normalización **pura** de rutas virtuales del `StorageProvider`.
3
+ *
4
+ * Las rutas son POSIX (`/`), relativas a la raíz lógica del provider. No hay
5
+ * I/O aquí: solo manipulación de strings determinista. La raíz se representa
6
+ * como cadena vacía `""`.
7
+ */
8
+ /** Error lanzado cuando una ruta intenta escapar por encima de la raíz. */
9
+ export declare class StoragePathError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ /**
13
+ * Normaliza una ruta virtual a POSIX relativa sin `.`/`..` ni segmentos vacíos.
14
+ * Acepta separadores `\` o `/`. Un `..` que escape por encima de la raíz lanza
15
+ * `StoragePathError`. La raíz (`""`, `"/"`, `"."`) se normaliza a `""`.
16
+ */
17
+ export declare function normalizeVirtualPath(input: string): string;
18
+ /** Une segmentos y normaliza el resultado a una ruta virtual. */
19
+ export declare function joinVirtualPath(...segments: string[]): string;
20
+ /**
21
+ * Devuelve el directorio padre de una ruta virtual normalizada (`""` si es un
22
+ * hijo directo de la raíz o la propia raíz).
23
+ */
24
+ export declare function parentVirtualPath(path: string): string;
25
+ /** Descompone una ruta virtual normalizada en sus segmentos (`[]` para la raíz). */
26
+ export declare function splitVirtualPath(path: string): string[];
27
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/storage/path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,2EAA2E;AAC3E,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAkB1D;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAE7D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAGvD"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `StorageProvider` — boundary de persistencia de openteam.
3
+ *
4
+ * Modela un **sistema de ficheros virtual** (`path → content`) con rutas POSIX
5
+ * relativas a una raíz lógica (ver `path.ts`). Es la única superficie de I/O
6
+ * para artefactos del equipo (roster/decisions/backlog en Markdown y logs de
7
+ * sesión en JSONL). Los adapters concretos (`fsStorageProvider`,
8
+ * `memoryStorageProvider`, futuros remotos) implementan este contrato.
9
+ *
10
+ * Reglas del contrato (verificadas por `tests/storage/contract.ts`):
11
+ * - `read`/`stat` devuelven `undefined` si la ruta no existe (nunca lanzan por
12
+ * fichero inexistente).
13
+ * - `write`/`append` crean los directorios intermedios necesarios.
14
+ * - `list` devuelve los nombres de los hijos **inmediatos** (no recursivo),
15
+ * ordenados alfabéticamente, y `[]` si el directorio no existe.
16
+ * - `mkdir` es idempotente y recursivo.
17
+ * - `delete` es idempotente (no lanza si la ruta no existe).
18
+ *
19
+ * Este módulo **no** contiene I/O: solo tipos. `router/` nunca lo importa.
20
+ */
21
+ /** Metadatos de una entrada del storage. */
22
+ export type StorageStat = {
23
+ /** Tamaño en bytes del contenido (0 para directorios). */
24
+ size: number;
25
+ /** Última modificación en epoch ms. */
26
+ mtimeMs: number;
27
+ /** `true` si la entrada es un directorio. */
28
+ isDirectory: boolean;
29
+ };
30
+ /** Contrato de persistencia con semántica de sistema de ficheros virtual. */
31
+ export interface StorageProvider {
32
+ /** Lee el contenido de un fichero; `undefined` si no existe. */
33
+ read(path: string): Promise<string | undefined>;
34
+ /** Escribe (sobrescribe) un fichero, creando directorios intermedios. */
35
+ write(path: string, content: string): Promise<void>;
36
+ /** Añade contenido al final de un fichero, creándolo si no existe. */
37
+ append(path: string, content: string): Promise<void>;
38
+ /** `true` si la ruta existe como fichero o directorio. */
39
+ exists(path: string): Promise<boolean>;
40
+ /** Nombres de los hijos inmediatos de un directorio, ordenados; `[]` si no existe. */
41
+ list(dir: string): Promise<string[]>;
42
+ /** `true` solo si la ruta existe y es un directorio. */
43
+ isDirectory(path: string): Promise<boolean>;
44
+ /** Crea un directorio (recursivo, idempotente). */
45
+ mkdir(dir: string): Promise<void>;
46
+ /** Borra un fichero; idempotente si no existe. */
47
+ delete(path: string): Promise<void>;
48
+ /** Metadatos de la entrada; `undefined` si no existe. */
49
+ stat(path: string): Promise<StorageStat | undefined>;
50
+ }
51
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/storage/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,4CAA4C;AAC5C,MAAM,MAAM,WAAW,GAAG;IACxB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChD,yEAAyE;IACzE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,sEAAsE;IACtE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,0DAA0D;IAC1D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,sFAAsF;IACtF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,wDAAwD;IACxD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,mDAAmD;IACnD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,kDAAkD;IAClD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,yDAAyD;IACzD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;CACtD"}
@@ -1,3 +1,4 @@
1
+ import type { StorageProvider } from "../storage/provider";
1
2
  import { type OpenTeamEvent, type RouteEvent } from "./events";
2
3
  import type { CostRecord } from "./types";
3
4
  /** Directorio por defecto de los logs de sesión que alimentan el console. */
@@ -13,10 +14,8 @@ export declare function sessionFileName(sessionID: string): string;
13
14
  export type EventLogSinkDeps = {
14
15
  /** Directorio destino (`sessions/`). */
15
16
  dir: string;
16
- /** Añade una línea al fichero indicado (crea dir/fichero si hace falta). */
17
- appendLine: (path: string, line: string) => Promise<void> | void;
18
- /** Une segmentos de ruta (por defecto `node:path.join`). Inyectable en tests. */
19
- join?: (dir: string, file: string) => string;
17
+ /** Backend de persistencia (escribe con `append`). */
18
+ storage: StorageProvider;
20
19
  onError?: (error: unknown) => void;
21
20
  };
22
21
  /**
@@ -46,11 +45,8 @@ export declare function routeEventToCostRecord(event: RouteEvent): CostRecord;
46
45
  */
47
46
  export declare function readRouteCostRecords(dir: string, deps: ReadSessionEventsDeps): Promise<CostRecord[]>;
48
47
  export type ReadSessionEventsDeps = {
49
- /** Lista los ficheros del directorio; `[]` si no existe. */
50
- listFiles: (dir: string) => Promise<string[]>;
51
- /** Lee texto; `undefined` si el fichero no existe. */
52
- readText: (path: string) => Promise<string | undefined>;
53
- join?: (dir: string, file: string) => string;
48
+ /** Backend de persistencia (lista con `list`, lee con `read`). */
49
+ storage: StorageProvider;
54
50
  /** Telemetry legacy a fusionar como `route` events. Opcional. */
55
51
  legacyTelemetryPath?: string;
56
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"eventLog.d.ts","sourceRoot":"","sources":["../../src/telemetry/eventLog.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAElB,KAAK,UAAU,EAChB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAElE,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,sEAAsE;AACtE,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACtD,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjE,iFAAiF;IACjF,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,CAAC;AAMF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAapE;AAED,wBAAgB,mBAAmB,IAAI,SAAS,CAE/C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAmB9D;AAED,wFAAwF;AACxF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAwBrE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAsBpE;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC,CASvB;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,4DAA4D;IAC5D,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,sDAAsD;IACtD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,CAyB1B"}
1
+ {"version":3,"file":"eventLog.d.ts","sourceRoot":"","sources":["../../src/telemetry/eventLog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAEL,KAAK,aAAa,EAElB,KAAK,UAAU,EAChB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAElE,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,sEAAsE;AACtE,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACtD,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAepE;AAED,wBAAgB,mBAAmB,IAAI,SAAS,CAE/C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAmB9D;AAED,wFAAwF;AACxF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAwBrE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAsBpE;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC,CASvB;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,kEAAkE;IAClE,OAAO,EAAE,eAAe,CAAC;IACzB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,CAwB1B"}
@@ -1,12 +1,11 @@
1
1
  import type { AgentFile } from "../commands/agents";
2
2
  import type { ConsoleInputs } from "../console/state";
3
3
  import type { CommitView } from "../console/types";
4
+ import type { StorageProvider } from "../storage/provider";
4
5
  /** Dependencias de I/O que el driver inyecta para leer las fuentes del console. */
5
6
  export type SnapshotDeps = {
6
- /** Lee un fichero de texto; devuelve `undefined` si no existe (ENOENT). */
7
- readText: (path: string) => Promise<string | undefined>;
8
- /** Lista los nombres de fichero de un directorio; `[]` si no existe. */
9
- listFiles: (dir: string) => Promise<string[]>;
7
+ /** Backend de persistencia (logs de sesión, decisiones, backlog). */
8
+ storage: StorageProvider;
10
9
  /** Lista los ficheros `.md` de `.opencode/agent/`. */
11
10
  listAgentFiles: (dir: string) => Promise<AgentFile[]>;
12
11
  /** Reloj: ISO-8601. Fuera del core puro. */
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/web/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,oBAAoB,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD,mFAAmF;AACnF,MAAM,MAAM,YAAY,GAAG;IACzB,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxD,wEAAwE;IACxE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,sDAAsD;IACtD,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtD,4CAA4C;IAC5C,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,eAAoB,GAC5B,MAAM,OAAO,CAAC,aAAa,CAAC,CAiD9B"}
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/web/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,oBAAoB,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQ3D,mFAAmF;AACnF,MAAM,MAAM,YAAY,GAAG;IACzB,qEAAqE;IACrE,OAAO,EAAE,eAAe,CAAC;IACzB,sDAAsD;IACtD,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtD,4CAA4C;IAC5C,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,eAAoB,GAC5B,MAAM,OAAO,CAAC,aAAa,CAAC,CAgD9B"}
@@ -4,6 +4,7 @@ import type { ConsoleConfig } from "../config/schema";
4
4
  import type { ConsoleClient } from "../console/opencodeClient";
5
5
  import type { PtyClient } from "../console/pty";
6
6
  import type { CommitView } from "../console/types";
7
+ import type { StorageProvider } from "../storage/provider";
7
8
  export type ConsoleRuntimeDeps = {
8
9
  config: ConsoleConfig;
9
10
  /** Directorio de logs de sesión (`sessions/*.jsonl`). */
@@ -13,8 +14,8 @@ export type ConsoleRuntimeDeps = {
13
14
  backlogPath?: string;
14
15
  /** Telemetry legacy a fusionar como route events. Opcional. */
15
16
  legacyTelemetryPath?: string;
16
- readText: (path: string) => Promise<string | undefined>;
17
- listFiles: (dir: string) => Promise<string[]>;
17
+ /** Backend de persistencia (logs de sesión, decisiones, backlog). */
18
+ storage: StorageProvider;
18
19
  listAgentFiles: (dir: string) => Promise<AgentFile[]>;
19
20
  now: () => string;
20
21
  gitLastCommit?: () => Promise<CommitView | undefined>;
@@ -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;AAMnD,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,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxD,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,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;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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmanuelcorral/openteam",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
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",