@dmrlzz/davecode 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +5 -4
  2. package/bin/davecode.js +0 -0
  3. package/dist/{ChatApp-FO5SABXB.js → ChatApp-CJBICQGA.js} +289 -137
  4. package/dist/ChatApp-CJBICQGA.js.map +1 -0
  5. package/dist/{RunnerView-DLVR7C22.js → RunnerView-A7JSPUW5.js} +5 -5
  6. package/dist/account-QWDPJWAA.js +23 -0
  7. package/dist/accounts-IQMR72FC.js +37 -0
  8. package/dist/{budget-RBHCEDPP.js → budget-XANOUVWO.js} +6 -6
  9. package/dist/chat-KDDRNC5V.js +359 -0
  10. package/dist/chat-KDDRNC5V.js.map +1 -0
  11. package/dist/{accounts-MTMGYKEP.js → chunk-44AFJL2X.js} +24 -17
  12. package/dist/chunk-44AFJL2X.js.map +1 -0
  13. package/dist/{chunk-BOLFK3BH.js → chunk-5LKOJBUL.js} +2 -2
  14. package/dist/{chunk-23KTE7IK.js → chunk-AZKACMME.js} +2 -2
  15. package/dist/{chunk-PIIJ3RSI.js → chunk-FYPMA55O.js} +1269 -1265
  16. package/dist/chunk-FYPMA55O.js.map +1 -0
  17. package/dist/{chunk-OYEYNDOO.js → chunk-GE22VBCY.js} +3 -3
  18. package/dist/{chunk-C7FDRA3U.js → chunk-HSBJDV3O.js} +660 -139
  19. package/dist/chunk-HSBJDV3O.js.map +1 -0
  20. package/dist/chunk-JLATEHS7.js +20 -0
  21. package/dist/chunk-JLATEHS7.js.map +1 -0
  22. package/dist/{chunk-VVCXGQMY.js → chunk-MC7RIPL7.js} +17 -8
  23. package/dist/chunk-MC7RIPL7.js.map +1 -0
  24. package/dist/{chunk-MSLLH5XP.js → chunk-PGAJIGUF.js} +4 -4
  25. package/dist/{chunk-OXRMGR72.js → chunk-PGPXE6LF.js} +2 -2
  26. package/dist/chunk-QA3O6RA2.js +81 -0
  27. package/dist/chunk-QA3O6RA2.js.map +1 -0
  28. package/dist/chunk-W7GPBEBZ.js +144 -0
  29. package/dist/chunk-W7GPBEBZ.js.map +1 -0
  30. package/dist/{chunk-IVZHKUCD.js → chunk-WQ7MEWDF.js} +3 -3
  31. package/dist/{config-FRMY5OHG.js → config-YTUPIYZT.js} +5 -5
  32. package/dist/dashboard/assets/Accounts-cq8RLMoI.js +1 -0
  33. package/dist/dashboard/assets/Badge-Z4RBdO9j.js +55 -0
  34. package/dist/dashboard/assets/Callout-w8BTYh4k.js +1 -0
  35. package/dist/dashboard/assets/Field-Cmpgg_1z.js +1 -0
  36. package/dist/dashboard/assets/Goals-Bw02to72.js +1 -0
  37. package/dist/dashboard/assets/Library-DK7mlpRb.js +1 -0
  38. package/dist/dashboard/assets/{Markdown-ClRsddnB.js → Markdown-DCZ4Awcc.js} +8 -8
  39. package/dist/dashboard/assets/Panes-_KTf8pbZ.js +8 -0
  40. package/dist/dashboard/assets/Panes-kHJ-D0s7.css +1 -0
  41. package/dist/dashboard/assets/RoutesPage-QV0oPRW9.js +4 -0
  42. package/dist/dashboard/assets/Runner-CkHBLQl0.js +1 -0
  43. package/dist/dashboard/assets/Settings-BLz2gTBR.js +1 -0
  44. package/dist/dashboard/assets/Switch-DPYlLseH.js +1 -0
  45. package/dist/dashboard/assets/Tasks-BiUQSTpt.js +2 -0
  46. package/dist/dashboard/assets/Traffic-BVfBuC70.js +1 -0
  47. package/dist/dashboard/assets/Workspace-CJTgiiU5.js +1 -0
  48. package/dist/dashboard/assets/arrow-up-DjhzZprp.js +1 -0
  49. package/dist/dashboard/assets/cn-BwE4cei0.js +1 -0
  50. package/dist/dashboard/assets/forms-DVIUAxAc.js +1 -0
  51. package/dist/dashboard/assets/index-BDBa5cb0.js +104 -0
  52. package/dist/dashboard/assets/index-BEmBgsbP.css +2 -0
  53. package/dist/dashboard/assets/task-errors-Daqwi0ue.js +1 -0
  54. package/dist/dashboard/assets/trash-BTuDcSaQ.js +1 -0
  55. package/dist/dashboard/favicon.svg +1 -7
  56. package/dist/dashboard/index.html +4 -4
  57. package/dist/{dist-ZPXEVBEC.js → dist-37VQSHHA.js} +24 -2
  58. package/dist/dist-37VQSHHA.js.map +1 -0
  59. package/dist/{doctor-7RUD4D3A.js → doctor-PYUQRRCB.js} +5 -5
  60. package/dist/{goal-JFRNPBSD.js → goal-SXZUDUCL.js} +5 -5
  61. package/dist/index.js +48 -30
  62. package/dist/index.js.map +1 -1
  63. package/dist/{init-NFYNO3A3.js → init-Z2AFQEEP.js} +6 -6
  64. package/dist/{prompts-L37J72YW.js → prompts-TZ7UC42M.js} +9 -5
  65. package/dist/prompts-TZ7UC42M.js.map +1 -0
  66. package/dist/{run-ARUPXFFB.js → run-AOS7L3RT.js} +10 -10
  67. package/dist/runtime.js +18 -0
  68. package/dist/runtime.js.map +1 -0
  69. package/dist/{start-CFPOVIAR.js → start-CEPXKZUE.js} +5 -5
  70. package/dist/{status-E4EACVE2.js → status-WNJ3GGKU.js} +6 -6
  71. package/dist/status-WNJ3GGKU.js.map +1 -0
  72. package/dist/{tasks-ZIK6BVEX.js → tasks-TFUTUMWB.js} +6 -6
  73. package/package.json +21 -15
  74. package/dist/ChatApp-FO5SABXB.js.map +0 -1
  75. package/dist/accounts-MTMGYKEP.js.map +0 -1
  76. package/dist/chat-ZDXX3N6X.js +0 -95
  77. package/dist/chat-ZDXX3N6X.js.map +0 -1
  78. package/dist/chunk-C7FDRA3U.js.map +0 -1
  79. package/dist/chunk-DYQ56FBT.js +0 -47
  80. package/dist/chunk-DYQ56FBT.js.map +0 -1
  81. package/dist/chunk-PIIJ3RSI.js.map +0 -1
  82. package/dist/chunk-VVCXGQMY.js.map +0 -1
  83. package/dist/dashboard/assets/Accounts-BR3ZfVk4.js +0 -1
  84. package/dist/dashboard/assets/Badge-B-qzNRrZ.js +0 -55
  85. package/dist/dashboard/assets/Callout-B9g_wPDi.js +0 -1
  86. package/dist/dashboard/assets/Field-BfabPEcY.js +0 -1
  87. package/dist/dashboard/assets/Goals-BsV-6m94.js +0 -1
  88. package/dist/dashboard/assets/Library-CEA9P1m-.js +0 -1
  89. package/dist/dashboard/assets/Panel-B9tSgX6l.js +0 -1
  90. package/dist/dashboard/assets/RoutesPage-Dh-BJ3ir.js +0 -4
  91. package/dist/dashboard/assets/Runner-C_e9l5l2.js +0 -1
  92. package/dist/dashboard/assets/Settings-C6Yc1Gjg.js +0 -1
  93. package/dist/dashboard/assets/Switch-CUpOJjUT.js +0 -1
  94. package/dist/dashboard/assets/Tasks-CTku0rR3.js +0 -2
  95. package/dist/dashboard/assets/Traffic-CE6wZSMr.js +0 -1
  96. package/dist/dashboard/assets/Workspace-CxFxvkA6.js +0 -1
  97. package/dist/dashboard/assets/arrow-up-DL3CuFOO.js +0 -1
  98. package/dist/dashboard/assets/forms-D6UIYgC5.js +0 -1
  99. package/dist/dashboard/assets/index-1iH716Xy.css +0 -2
  100. package/dist/dashboard/assets/index-BMWr9EKo.js +0 -104
  101. package/dist/dashboard/assets/task-errors-CE4oEr8H.js +0 -1
  102. package/dist/dashboard/assets/trash-CWqeZ7eg.js +0 -1
  103. package/dist/prompts-L37J72YW.js.map +0 -1
  104. /package/dist/{RunnerView-DLVR7C22.js.map → RunnerView-A7JSPUW5.js.map} +0 -0
  105. /package/dist/{dist-ZPXEVBEC.js.map → account-QWDPJWAA.js.map} +0 -0
  106. /package/dist/{status-E4EACVE2.js.map → accounts-IQMR72FC.js.map} +0 -0
  107. /package/dist/{budget-RBHCEDPP.js.map → budget-XANOUVWO.js.map} +0 -0
  108. /package/dist/{chunk-BOLFK3BH.js.map → chunk-5LKOJBUL.js.map} +0 -0
  109. /package/dist/{chunk-23KTE7IK.js.map → chunk-AZKACMME.js.map} +0 -0
  110. /package/dist/{chunk-OYEYNDOO.js.map → chunk-GE22VBCY.js.map} +0 -0
  111. /package/dist/{chunk-MSLLH5XP.js.map → chunk-PGAJIGUF.js.map} +0 -0
  112. /package/dist/{chunk-OXRMGR72.js.map → chunk-PGPXE6LF.js.map} +0 -0
  113. /package/dist/{chunk-IVZHKUCD.js.map → chunk-WQ7MEWDF.js.map} +0 -0
  114. /package/dist/{config-FRMY5OHG.js.map → config-YTUPIYZT.js.map} +0 -0
  115. /package/dist/{doctor-7RUD4D3A.js.map → doctor-PYUQRRCB.js.map} +0 -0
  116. /package/dist/{goal-JFRNPBSD.js.map → goal-SXZUDUCL.js.map} +0 -0
  117. /package/dist/{init-NFYNO3A3.js.map → init-Z2AFQEEP.js.map} +0 -0
  118. /package/dist/{run-ARUPXFFB.js.map → run-AOS7L3RT.js.map} +0 -0
  119. /package/dist/{start-CFPOVIAR.js.map → start-CEPXKZUE.js.map} +0 -0
  120. /package/dist/{tasks-ZIK6BVEX.js.map → tasks-TFUTUMWB.js.map} +0 -0
@@ -86,6 +86,7 @@ import { existsSync, mkdirSync, statSync } from "fs";
86
86
  import path from "path";
87
87
  import path3 from "path";
88
88
  import path4 from "path";
89
+ import path5 from "path";
89
90
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, rmSync, writeFileSync } from "fs";
90
91
  import { isAbsolute, join as join4, relative, resolve as resolve2 } from "path";
91
92
  import { mkdirSync as mkdirSync6 } from "fs";
@@ -103,17 +104,25 @@ import { mkdirSync as mkdirSync5 } from "fs";
103
104
  import { dirname as dirname5 } from "path";
104
105
  import BetterSqlite3 from "better-sqlite3";
105
106
  import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
106
- import path5 from "path";
107
- import { mkdir as mkdir4, readdir as readdir2, readFile as readFile4, realpath, stat as stat3, writeFile as writeFile2 } from "fs/promises";
108
107
  import path6 from "path";
108
+ import { mkdir as mkdir4, readdir as readdir2, readFile as readFile4, realpath, stat as stat3, writeFile as writeFile2 } from "fs/promises";
109
+ import path7 from "path";
109
110
  import { z as z6 } from "zod";
110
111
  import { execFile } from "child_process";
111
112
  import { z as z7 } from "zod";
112
113
  import { basename as basename2, resolve as resolve4 } from "path";
114
+ import { createHash as createHash2, randomBytes as randomBytes6 } from "crypto";
113
115
  import { z as z8 } from "zod";
114
- import { readdir as readdir3 } from "fs/promises";
115
- import { join as join6, relative as relative2 } from "path";
116
+ import { randomBytes as randomBytes7 } from "crypto";
117
+ import { createServer } from "http";
118
+ import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes8 } from "crypto";
119
+ import { mkdirSync as mkdirSync7, readFileSync as readFileSync3, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "fs";
120
+ import { dirname as dirname6, join as join6 } from "path";
116
121
  import { z as z9 } from "zod";
122
+ import { z as z10 } from "zod";
123
+ import { readdir as readdir3 } from "fs/promises";
124
+ import { join as join7, relative as relative2 } from "path";
125
+ import { z as z11 } from "zod";
117
126
  var credentials = z.object({ clientId: z.string().min(1), clientSecret: z.string().min(1) });
118
127
  var optionsSchema = z.object({
119
128
  origin: z.string().url().refine((value) => {
@@ -544,14 +553,14 @@ function projectPaths(root) {
544
553
  }
545
554
  var sleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
546
555
  var RETRYABLE_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES"]);
547
- async function atomicWriteFile(path7, content) {
548
- await mkdir(dirname(path7), { recursive: true });
549
- const tmp = `${path7}.${process.pid}.${randomBytes2(4).toString("hex")}.tmp`;
556
+ async function atomicWriteFile(path8, content) {
557
+ await mkdir(dirname(path8), { recursive: true });
558
+ const tmp = `${path8}.${process.pid}.${randomBytes2(4).toString("hex")}.tmp`;
550
559
  try {
551
560
  await writeFile(tmp, content, "utf8");
552
561
  for (let attempt = 0; ; attempt++) {
553
562
  try {
554
- await rename(tmp, path7);
563
+ await rename(tmp, path8);
555
564
  return;
556
565
  } catch (err) {
557
566
  const code = err.code;
@@ -564,9 +573,9 @@ async function atomicWriteFile(path7, content) {
564
573
  throw err;
565
574
  }
566
575
  }
567
- async function readFileIfExists(path7) {
576
+ async function readFileIfExists(path8) {
568
577
  try {
569
- return await readFile(path7, "utf8");
578
+ return await readFile(path8, "utf8");
570
579
  } catch (err) {
571
580
  if (err.code === "ENOENT") return void 0;
572
581
  throw err;
@@ -998,9 +1007,9 @@ var LockTimeoutError = class extends Error {
998
1007
  };
999
1008
  var TRANSIENT_OPEN_ERRORS = ["EPERM", "EACCES", "EBUSY"];
1000
1009
  var sleep2 = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
1001
- async function readLockInfo(path7) {
1010
+ async function readLockInfo(path8) {
1002
1011
  try {
1003
- const parsed = JSON.parse(await readFile2(path7, "utf8"));
1012
+ const parsed = JSON.parse(await readFile2(path8, "utf8"));
1004
1013
  if (typeof parsed === "object" && parsed !== null && typeof parsed.ts === "number" && typeof parsed.pid === "number") {
1005
1014
  return parsed;
1006
1015
  }
@@ -1008,11 +1017,11 @@ async function readLockInfo(path7) {
1008
1017
  }
1009
1018
  return void 0;
1010
1019
  }
1011
- async function lockAge(path7) {
1012
- const info = await readLockInfo(path7);
1020
+ async function lockAge(path8) {
1021
+ const info = await readLockInfo(path8);
1013
1022
  if (info) return Date.now() - info.ts;
1014
1023
  try {
1015
- return Date.now() - (await stat2(path7)).mtimeMs;
1024
+ return Date.now() - (await stat2(path8)).mtimeMs;
1016
1025
  } catch {
1017
1026
  return void 0;
1018
1027
  }
@@ -1059,9 +1068,9 @@ async function withFileLock(lockPath, fn2, opts = {}) {
1059
1068
  }
1060
1069
  }
1061
1070
  }
1062
- async function exists(path7) {
1071
+ async function exists(path8) {
1063
1072
  try {
1064
- await access(path7);
1073
+ await access(path8);
1065
1074
  return true;
1066
1075
  } catch {
1067
1076
  return false;
@@ -1120,8 +1129,8 @@ var MissingBrainError = class extends Error {
1120
1129
  /** HTTP status hint and machine-readable code for the gateway's error handler. */
1121
1130
  statusCode = 409;
1122
1131
  code = "no_brain";
1123
- constructor(path7) {
1124
- super(`Missing project brain file: ${path7} (run ProjectBrain.init first)`);
1132
+ constructor(path8) {
1133
+ super(`Missing project brain file: ${path8} (run ProjectBrain.init first)`);
1125
1134
  this.name = "MissingBrainError";
1126
1135
  }
1127
1136
  };
@@ -1159,8 +1168,8 @@ var ProjectBrain = class _ProjectBrain {
1159
1168
  [brain.paths.architecture, architectureTemplate(name)],
1160
1169
  [brain.paths.taskGraph, serializeGraph(taskGraphTemplate())]
1161
1170
  ];
1162
- for (const [path7, content] of files) {
1163
- if (!await exists(path7)) await atomicWriteFile(path7, content);
1171
+ for (const [path8, content] of files) {
1172
+ if (!await exists(path8)) await atomicWriteFile(path8, content);
1164
1173
  }
1165
1174
  return brain;
1166
1175
  }
@@ -1272,10 +1281,10 @@ ${line}` : line);
1272
1281
  this.events?.emit({ type: "task.updated", task });
1273
1282
  return task;
1274
1283
  }
1275
- async readText(path7) {
1276
- const content = await readFileIfExists(path7);
1284
+ async readText(path8) {
1285
+ const content = await readFileIfExists(path8);
1277
1286
  if (content === void 0) {
1278
- throw new MissingBrainError(path7);
1287
+ throw new MissingBrainError(path8);
1279
1288
  }
1280
1289
  return content;
1281
1290
  }
@@ -1288,6 +1297,7 @@ var providerKind = z3.enum([
1288
1297
  "claude-cli",
1289
1298
  "codex-cli",
1290
1299
  "gemini-cli",
1300
+ "antigravity-cli",
1291
1301
  "gemini-web"
1292
1302
  ]);
1293
1303
  var routeTargetSchema = z3.object({
@@ -1473,23 +1483,23 @@ function deepMerge(base, override) {
1473
1483
  }
1474
1484
  return out;
1475
1485
  }
1476
- function readLayer(path7) {
1486
+ function readLayer(path8) {
1477
1487
  let raw;
1478
1488
  try {
1479
- raw = readFileSync(path7, "utf8");
1489
+ raw = readFileSync(path8, "utf8");
1480
1490
  } catch (err) {
1481
1491
  if (err.code === "ENOENT") return void 0;
1482
- throw new ConfigError(path7, `cannot read file: ${err.message}`, { cause: err });
1492
+ throw new ConfigError(path8, `cannot read file: ${err.message}`, { cause: err });
1483
1493
  }
1484
1494
  let parsed;
1485
1495
  try {
1486
1496
  parsed = JSON.parse(raw);
1487
1497
  } catch (err) {
1488
- throw new ConfigError(path7, `malformed JSON: ${err.message}`, { cause: err });
1498
+ throw new ConfigError(path8, `malformed JSON: ${err.message}`, { cause: err });
1489
1499
  }
1490
- if (!isPlainObject(parsed)) throw new ConfigError(path7, "expected a JSON object");
1500
+ if (!isPlainObject(parsed)) throw new ConfigError(path8, "expected a JSON object");
1491
1501
  const result = configSchema.safeParse(parsed);
1492
- if (!result.success) throw new ConfigError(path7, z4.prettifyError(result.error));
1502
+ if (!result.success) throw new ConfigError(path8, z4.prettifyError(result.error));
1493
1503
  return parsed;
1494
1504
  }
1495
1505
  var TRUE_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
@@ -1561,19 +1571,19 @@ function loadConfig(options = {}) {
1561
1571
  }
1562
1572
  var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1563
1573
  async function writeGlobalRouting(home, update, lock = {}) {
1564
- const path7 = globalPaths(home).config;
1574
+ const path8 = globalPaths(home).config;
1565
1575
  return withFileLock(
1566
- `${path7}.lock`,
1576
+ `${path8}.lock`,
1567
1577
  async () => {
1568
1578
  let current = {};
1569
1579
  try {
1570
- const parsed = JSON.parse(await readFile3(path7, "utf8"));
1571
- if (!isPlainObject2(parsed)) throw new ConfigError(path7, "expected a JSON object");
1580
+ const parsed = JSON.parse(await readFile3(path8, "utf8"));
1581
+ if (!isPlainObject2(parsed)) throw new ConfigError(path8, "expected a JSON object");
1572
1582
  current = parsed;
1573
1583
  } catch (err) {
1574
1584
  if (err instanceof ConfigError) throw err;
1575
1585
  if (!isNodeError(err, "ENOENT")) {
1576
- throw new ConfigError(path7, `cannot update this file: ${err.message}`, {
1586
+ throw new ConfigError(path8, `cannot update this file: ${err.message}`, {
1577
1587
  cause: err
1578
1588
  });
1579
1589
  }
@@ -1588,11 +1598,11 @@ async function writeGlobalRouting(home, update, lock = {}) {
1588
1598
  }
1589
1599
  };
1590
1600
  const checked = configSchema.safeParse(next);
1591
- if (!checked.success) throw new ConfigError(path7, z5.prettifyError(checked.error));
1592
- await atomicWriteFile(path7, `${JSON.stringify(next, null, 2)}
1601
+ if (!checked.success) throw new ConfigError(path8, z5.prettifyError(checked.error));
1602
+ await atomicWriteFile(path8, `${JSON.stringify(next, null, 2)}
1593
1603
  `);
1594
1604
  return {
1595
- path: path7,
1605
+ path: path8,
1596
1606
  routes: checked.data.routing.routes,
1597
1607
  defaultRoute: checked.data.routing.defaultRoute
1598
1608
  };
@@ -1680,8 +1690,8 @@ function makeUsage(prompt, completion) {
1680
1690
  function stripProviderPrefix(model, provider) {
1681
1691
  return model.startsWith(`${provider}/`) ? model.slice(provider.length + 1) : model;
1682
1692
  }
1683
- function joinUrl(base, path7) {
1684
- return `${base.replace(/\/+$/, "")}/${path7.replace(/^\/+/, "")}`;
1693
+ function joinUrl(base, path8) {
1694
+ return `${base.replace(/\/+$/, "")}/${path8.replace(/^\/+/, "")}`;
1685
1695
  }
1686
1696
  function configString(config, key) {
1687
1697
  const value = config[key];
@@ -2498,8 +2508,8 @@ var SHELL_SAFE = /^[\w.:=@+\-/\\[\]]+$/;
2498
2508
  function isShellSafeArg(arg) {
2499
2509
  return SHELL_SAFE.test(arg);
2500
2510
  }
2501
- function quoteCommand(path7) {
2502
- return isShellSafeArg(path7) ? path7 : `"${path7}"`;
2511
+ function quoteCommand(path8) {
2512
+ return isShellSafeArg(path8) ? path8 : `"${path8}"`;
2503
2513
  }
2504
2514
  function killTree(child) {
2505
2515
  if (child.pid === void 0 || child.exitCode !== null) return;
@@ -2709,8 +2719,121 @@ async function collectCompletion(chunks, model) {
2709
2719
  usage
2710
2720
  };
2711
2721
  }
2712
- var DEFAULT_MODELS = ["default", "sonnet", "opus", "haiku"];
2713
2722
  var SAFE_MODEL = /^[\w.:[\]-]+$/;
2723
+ var AntigravityCliProvider = class {
2724
+ kind = "antigravity-cli";
2725
+ async listModels(ctx) {
2726
+ const configured = configStringArray(ctx.account.config, "models");
2727
+ return modelList(configured.length > 0 ? configured : ["default"], this.kind);
2728
+ }
2729
+ async complete(req, ctx) {
2730
+ return collectCompletion(this.stream(req, ctx), stripProviderPrefix(req.model, this.kind));
2731
+ }
2732
+ async *stream(req, ctx) {
2733
+ const model = stripProviderPrefix(req.model, this.kind);
2734
+ if (model && !SAFE_MODEL.test(model)) {
2735
+ throw new ProviderError("antigravity-cli: unsupported characters in model id", {
2736
+ kind: "bad_request",
2737
+ provider: this.kind,
2738
+ accountId: ctx.account.id
2739
+ });
2740
+ }
2741
+ const args = [
2742
+ "--input-format",
2743
+ "stream-json",
2744
+ "--output-format",
2745
+ "stream-json",
2746
+ "--sandbox",
2747
+ "--disable-slash-commands"
2748
+ ];
2749
+ if (model && model !== "default") args.push("--model", model);
2750
+ args.push("--print=");
2751
+ const run = runCli({
2752
+ provider: this.kind,
2753
+ accountId: ctx.account.id,
2754
+ settings: cliSettings(ctx, "agy"),
2755
+ args,
2756
+ env: {},
2757
+ cwd: configString(ctx.account.config, "cwd") ?? path2.resolve(ctx.sandboxDir),
2758
+ stdin: `${JSON.stringify({
2759
+ event: "user",
2760
+ message: { content: renderTranscript(req.messages, true) }
2761
+ })}
2762
+ `,
2763
+ signal: ctx.signal
2764
+ });
2765
+ const id = newId();
2766
+ const created = nowSeconds();
2767
+ let started = false;
2768
+ let streamed = false;
2769
+ let completed = false;
2770
+ let failure;
2771
+ const fail = (message) => {
2772
+ const { kind, retryAfterMs } = classifyCliText(message);
2773
+ return new ProviderError(`antigravity-cli: ${redact(message, ctx.secret).slice(0, 500)}`, {
2774
+ kind,
2775
+ retryAfterMs,
2776
+ provider: this.kind,
2777
+ accountId: ctx.account.id
2778
+ });
2779
+ };
2780
+ const start = function* () {
2781
+ if (started) return;
2782
+ started = true;
2783
+ yield makeChunk(id, model, created, { role: "assistant", content: "" });
2784
+ };
2785
+ for await (const raw of run.events) {
2786
+ if (!isRecord(raw)) continue;
2787
+ const event = asString(raw.event);
2788
+ if (event === "step_update" && isRecord(raw.step_update)) {
2789
+ const step = raw.step_update;
2790
+ const delta = asString(step.text_delta);
2791
+ if (asString(step.step_type) === "agent_response" && delta) {
2792
+ yield* start();
2793
+ streamed = true;
2794
+ yield makeChunk(id, model, created, { content: delta });
2795
+ }
2796
+ continue;
2797
+ }
2798
+ if (event === "result" && isRecord(raw.result)) {
2799
+ const result = raw.result;
2800
+ if (asString(result.status) !== "SUCCESS") {
2801
+ failure = asString(result.error) ?? `Antigravity ended with ${result.status}`;
2802
+ break;
2803
+ }
2804
+ completed = true;
2805
+ yield* start();
2806
+ const response = asString(result.response);
2807
+ if (!streamed && response) yield makeChunk(id, model, created, { content: response });
2808
+ const u = isRecord(result.usage) ? result.usage : {};
2809
+ const output = (asNumber(u.output_tokens) ?? 0) + (asNumber(u.thinking_tokens) ?? 0);
2810
+ yield makeChunk(
2811
+ id,
2812
+ model,
2813
+ created,
2814
+ {},
2815
+ "stop",
2816
+ makeUsage(asNumber(u.input_tokens) ?? 0, output)
2817
+ );
2818
+ break;
2819
+ }
2820
+ }
2821
+ const exit = await run.exit;
2822
+ if (exit.aborted || ctx.signal?.aborted) {
2823
+ throw new ProviderError("antigravity-cli request aborted", {
2824
+ kind: "timeout",
2825
+ provider: this.kind,
2826
+ accountId: ctx.account.id
2827
+ });
2828
+ }
2829
+ if (failure) throw fail(failure);
2830
+ if (!completed) {
2831
+ throw fail(exit.stderr.trim() || `process exited with code ${exit.code ?? "unknown"}`);
2832
+ }
2833
+ }
2834
+ };
2835
+ var DEFAULT_MODELS = ["default", "sonnet", "opus", "haiku"];
2836
+ var SAFE_MODEL2 = /^[\w.:[\]-]+$/;
2714
2837
  var ClaudeCliProvider = class {
2715
2838
  kind = "claude-cli";
2716
2839
  async listModels(ctx) {
@@ -2734,7 +2857,7 @@ var ClaudeCliProvider = class {
2734
2857
  ];
2735
2858
  args.push("--no-session-persistence");
2736
2859
  if (model && model !== "default") {
2737
- if (!SAFE_MODEL.test(model)) {
2860
+ if (!SAFE_MODEL2.test(model)) {
2738
2861
  throw new ProviderError("claude-cli: unsupported characters in model id", {
2739
2862
  kind: "bad_request",
2740
2863
  provider: this.kind,
@@ -2753,7 +2876,7 @@ var ClaudeCliProvider = class {
2753
2876
  settings,
2754
2877
  args,
2755
2878
  env: { CLAUDE_CONFIG_DIR: ctx.sandboxDir },
2756
- cwd: configString(ctx.account.config, "cwd") ?? path2.resolve(ctx.sandboxDir),
2879
+ cwd: configString(ctx.account.config, "cwd") ?? path3.resolve(ctx.sandboxDir),
2757
2880
  stdin: renderTranscript(req.messages, shell),
2758
2881
  signal: ctx.signal
2759
2882
  });
@@ -2854,7 +2977,7 @@ var ClaudeCliProvider = class {
2854
2977
  }
2855
2978
  }
2856
2979
  };
2857
- var SAFE_MODEL2 = /^[\w.:[\]-]+$/;
2980
+ var SAFE_MODEL3 = /^[\w.:[\]-]+$/;
2858
2981
  function agentText(item) {
2859
2982
  const type = asString(item.type);
2860
2983
  if (type && type !== "agent_message" && type !== "assistant_message") return void 0;
@@ -2882,7 +3005,7 @@ var CodexCliProvider = class {
2882
3005
  async *stream(req, ctx) {
2883
3006
  const model = stripProviderPrefix(req.model, this.kind);
2884
3007
  const sandbox = configString(ctx.account.config, "sandbox") ?? "read-only";
2885
- if (!SAFE_MODEL2.test(sandbox) || model && !SAFE_MODEL2.test(model)) {
3008
+ if (!SAFE_MODEL3.test(sandbox) || model && !SAFE_MODEL3.test(model)) {
2886
3009
  throw new ProviderError("codex-cli: unsupported characters in model or sandbox setting", {
2887
3010
  kind: "bad_request",
2888
3011
  provider: this.kind,
@@ -2898,7 +3021,7 @@ var CodexCliProvider = class {
2898
3021
  settings: cliSettings(ctx, "codex"),
2899
3022
  args,
2900
3023
  env: { CODEX_HOME: ctx.sandboxDir },
2901
- cwd: configString(ctx.account.config, "cwd") ?? path3.resolve(ctx.sandboxDir),
3024
+ cwd: configString(ctx.account.config, "cwd") ?? path4.resolve(ctx.sandboxDir),
2902
3025
  stdin: renderTranscript(req.messages, true),
2903
3026
  signal: ctx.signal
2904
3027
  });
@@ -3361,10 +3484,10 @@ var SandboxManager = class {
3361
3484
  }
3362
3485
  };
3363
3486
  var DEFAULT_MODELS2 = ["default", "gemini-2.5-pro", "gemini-2.5-flash"];
3364
- var SAFE_MODEL3 = /^[\w.:[\]-]+$/;
3487
+ var SAFE_MODEL4 = /^[\w.:[\]-]+$/;
3365
3488
  function geminiCliEnv(sandboxDir) {
3366
3489
  return {
3367
- ...geminiHomeEnv(path4.resolve(sandboxDir)),
3490
+ ...geminiHomeEnv(path5.resolve(sandboxDir)),
3368
3491
  GEMINI_API_KEY: "",
3369
3492
  GOOGLE_API_KEY: "",
3370
3493
  GOOGLE_GENAI_USE_VERTEXAI: ""
@@ -3386,7 +3509,7 @@ var GeminiCliProvider = class {
3386
3509
  }
3387
3510
  async *stream(req, ctx) {
3388
3511
  const model = stripProviderPrefix(req.model, this.kind);
3389
- if (model && !SAFE_MODEL3.test(model)) {
3512
+ if (model && !SAFE_MODEL4.test(model)) {
3390
3513
  throw new ProviderError("gemini-cli: unsupported characters in model id", {
3391
3514
  kind: "bad_request",
3392
3515
  provider: this.kind,
@@ -3402,7 +3525,7 @@ var GeminiCliProvider = class {
3402
3525
  settings: cliSettings(ctx, "gemini"),
3403
3526
  args,
3404
3527
  env: geminiCliEnv(ctx.sandboxDir),
3405
- cwd: configString(ctx.account.config, "cwd") ?? path4.resolve(ctx.sandboxDir),
3528
+ cwd: configString(ctx.account.config, "cwd") ?? path5.resolve(ctx.sandboxDir),
3406
3529
  stdin: renderTranscript(req.messages, true),
3407
3530
  signal: ctx.signal
3408
3531
  });
@@ -3747,6 +3870,7 @@ function createProviders(options = {}) {
3747
3870
  new ClaudeCliProvider(),
3748
3871
  new CodexCliProvider(),
3749
3872
  new GeminiCliProvider(),
3873
+ new AntigravityCliProvider(),
3750
3874
  new GeminiWebProvider(options.geminiWebDriver)
3751
3875
  ];
3752
3876
  return new Map(providers.map((p) => [p.kind, p]));
@@ -3756,9 +3880,10 @@ var SUBSCRIPTION_PROVIDER_KINDS = [
3756
3880
  "claude-cli",
3757
3881
  "codex-cli",
3758
3882
  "gemini-cli",
3883
+ "antigravity-cli",
3759
3884
  "gemini-web"
3760
3885
  ];
3761
- var VERSION = "0.3.0";
3886
+ var VERSION = "0.5.0";
3762
3887
  var QUOTA_WINDOWS = ["1m", "5h", "24h"];
3763
3888
  var WINDOW_MS = {
3764
3889
  "1m": 6e4,
@@ -4152,6 +4277,13 @@ var CLI_LOGINS = {
4152
4277
  installHint: "Install Codex: npm install -g @openai/codex",
4153
4278
  instructions: "Codex opens the ChatGPT sign-in page and exits once you are logged in."
4154
4279
  },
4280
+ "antigravity-cli": {
4281
+ binary: "agy",
4282
+ loginArgs: [],
4283
+ statusArgs: ["models"],
4284
+ installHint: "Install Antigravity: https://antigravity.google/docs/cli/install",
4285
+ instructions: "Antigravity opens Google sign-in the first time it starts. Once its prompt appears, type /quit."
4286
+ },
4155
4287
  "gemini-cli": {
4156
4288
  binary: "gemini",
4157
4289
  loginArgs: [],
@@ -4288,11 +4420,17 @@ var ConnectionChecker = class {
4288
4420
  if (!loggedIn)
4289
4421
  return result("not_connected", "Claude Code is not logged in for this account.");
4290
4422
  const isolated = this.platform === "darwin" || existsSync3(join5(dir, ".credentials.json"));
4291
- return result(
4292
- "connected",
4293
- isolated ? "Claude Code reports a login for this account." : "Claude Code reports a login, but none is stored in this account\u2019s sandbox: it is probably your global Claude Code login, so this account is not isolated."
4423
+ return isolated ? result("connected", "Claude Code reports a login for this account.") : result(
4424
+ "not_connected",
4425
+ "Claude Code is signed in globally, but not for this account: sign in once for DaveCode."
4294
4426
  );
4295
4427
  }
4428
+ if (account.provider === "antigravity-cli") {
4429
+ return probed.code === 0 ? result(
4430
+ "connected",
4431
+ "Antigravity is signed in. Its login is shared by every Antigravity account on this machine."
4432
+ ) : result("not_connected", "Antigravity is not signed in on this machine.");
4433
+ }
4296
4434
  return probed.code === 0 ? result("connected", "Codex reports a login for this account.") : result("not_connected", "Codex is not logged in for this account.");
4297
4435
  }
4298
4436
  };
@@ -4499,6 +4637,7 @@ var PROVIDER_KINDS = [
4499
4637
  "claude-cli",
4500
4638
  "codex-cli",
4501
4639
  "gemini-cli",
4640
+ "antigravity-cli",
4502
4641
  "gemini-web"
4503
4642
  ];
4504
4643
  var ROUTE_PREFIX = "davecode/";
@@ -4536,7 +4675,7 @@ function inferProviders(model) {
4536
4675
  const id = model.toLowerCase();
4537
4676
  if (id.startsWith("claude")) return ["anthropic", "claude-cli"];
4538
4677
  if (/^(gpt-|chatgpt|codex|o\d)/.test(id)) return ["openai", "codex-cli"];
4539
- if (id.startsWith("gemini")) return ["gemini", "gemini-cli", "gemini-web"];
4678
+ if (id.startsWith("gemini")) return ["gemini", "gemini-cli", "antigravity-cli", "gemini-web"];
4540
4679
  return [];
4541
4680
  }
4542
4681
  function accountServes(account, model, provider) {
@@ -4675,8 +4814,23 @@ function messageText(message) {
4675
4814
  }
4676
4815
  return text;
4677
4816
  }
4817
+ function signInMessage(account) {
4818
+ if (!CLI_LOGINS[account.provider]) return void 0;
4819
+ return `${account.label} needs you to sign in again. Run: ${loginCommandFor(account.id)}`;
4820
+ }
4821
+ function withSignInHint(error, account) {
4822
+ const message = error.kind === "auth" ? signInMessage(account) : void 0;
4823
+ if (!message) return error;
4824
+ return new ProviderError(message, {
4825
+ kind: "auth",
4826
+ provider: error.provider,
4827
+ accountId: error.accountId,
4828
+ ...error.status !== void 0 ? { status: error.status } : {},
4829
+ cause: error
4830
+ });
4831
+ }
4678
4832
  function toProviderError2(err, account) {
4679
- if (err instanceof ProviderError) return err;
4833
+ if (err instanceof ProviderError) return withSignInHint(err, account);
4680
4834
  if (err instanceof KeyringError) {
4681
4835
  return new ProviderError(err.message, {
4682
4836
  kind: "auth",
@@ -4805,6 +4959,11 @@ var Router = class {
4805
4959
  { requestId }
4806
4960
  );
4807
4961
  }
4962
+ if (reasons.size === 1 && reasons.has("error")) {
4963
+ const failed = this.options.accounts.get(plan.skipped[0].accountId);
4964
+ const message = failed && (signInMessage(failed) ?? failed.lastError);
4965
+ if (message) return new RouterError("no_available_account", message, { requestId });
4966
+ }
4808
4967
  return new RouterError(
4809
4968
  "no_available_account",
4810
4969
  `No available account for "${req.model}" (${[...reasons].join(", ")})`,
@@ -5372,9 +5531,9 @@ function migrate(db, migrations = MIGRATIONS) {
5372
5531
  }
5373
5532
  return version;
5374
5533
  }
5375
- function openDatabase(path7, options = {}) {
5376
- if (path7 !== ":memory:") mkdirSync5(dirname5(path7), { recursive: true });
5377
- const db = new BetterSqlite3(path7);
5534
+ function openDatabase(path8, options = {}) {
5535
+ if (path8 !== ":memory:") mkdirSync5(dirname5(path8), { recursive: true });
5536
+ const db = new BetterSqlite3(path8);
5378
5537
  try {
5379
5538
  db.pragma("journal_mode = WAL");
5380
5539
  db.pragma("foreign_keys = ON");
@@ -5628,8 +5787,8 @@ function truncateHead(text, max) {
5628
5787
  function projectEnv(cwd, base = process.env) {
5629
5788
  const env = { ...base };
5630
5789
  const key = Object.keys(env).find((k) => k.toUpperCase() === "PATH") ?? "PATH";
5631
- const bin = path5.join(cwd, "node_modules", ".bin");
5632
- env[key] = env[key] ? `${bin}${path5.delimiter}${env[key]}` : bin;
5790
+ const bin = path6.join(cwd, "node_modules", ".bin");
5791
+ env[key] = env[key] ? `${bin}${path6.delimiter}${env[key]}` : bin;
5633
5792
  return env;
5634
5793
  }
5635
5794
  function killTree2(child) {
@@ -5795,8 +5954,8 @@ var MAX_FILE_BYTES = 1024 * 1024;
5795
5954
  var isWindows = process.platform === "win32";
5796
5955
  var same = (a, b) => isWindows ? a.toLowerCase() === b.toLowerCase() : a === b;
5797
5956
  function isInside(base, target) {
5798
- const rel = path6.relative(base, target);
5799
- return rel === "" || rel !== ".." && !rel.startsWith(`..${path6.sep}`) && !path6.isAbsolute(rel);
5957
+ const rel = path7.relative(base, target);
5958
+ return rel === "" || rel !== ".." && !rel.startsWith(`..${path7.sep}`) && !path7.isAbsolute(rel);
5800
5959
  }
5801
5960
  async function realpathLenient(target) {
5802
5961
  const missing = [];
@@ -5804,21 +5963,21 @@ async function realpathLenient(target) {
5804
5963
  for (; ; ) {
5805
5964
  try {
5806
5965
  const real = await realpath(current);
5807
- return missing.length > 0 ? path6.join(real, ...missing.reverse()) : real;
5966
+ return missing.length > 0 ? path7.join(real, ...missing.reverse()) : real;
5808
5967
  } catch (err) {
5809
5968
  const code = err.code;
5810
5969
  if (code !== "ENOENT" && code !== "ENOTDIR") throw err;
5811
- const parent = path6.dirname(current);
5970
+ const parent = path7.dirname(current);
5812
5971
  if (parent === current) return target;
5813
- missing.push(path6.basename(current));
5972
+ missing.push(path7.basename(current));
5814
5973
  current = parent;
5815
5974
  }
5816
5975
  }
5817
5976
  }
5818
5977
  async function resolveRepoPath(root, input, mode = "read") {
5819
5978
  if (input.includes("\0")) throw new PathEscapeError("path contains a NUL byte");
5820
- const base = path6.resolve(root);
5821
- const abs = path6.resolve(base, input.trim() === "" ? "." : input);
5979
+ const base = path7.resolve(root);
5980
+ const abs = path7.resolve(base, input.trim() === "" ? "." : input);
5822
5981
  if (!isInside(base, abs)) {
5823
5982
  throw new PathEscapeError(`path "${input}" is outside the repository`);
5824
5983
  }
@@ -5827,7 +5986,7 @@ async function resolveRepoPath(root, input, mode = "read") {
5827
5986
  if (!isInside(realBase, real)) {
5828
5987
  throw new PathEscapeError(`path "${input}" resolves outside the repository (symlink)`);
5829
5988
  }
5830
- const rel = path6.relative(base, abs).split(path6.sep).join("/") || ".";
5989
+ const rel = path7.relative(base, abs).split(path7.sep).join("/") || ".";
5831
5990
  const first = rel.split("/")[0] ?? "";
5832
5991
  if (same(first, ".git")) throw new PathEscapeError("the .git directory is off-limits");
5833
5992
  if (mode === "write" && same(first, ".davecode")) {
@@ -5983,7 +6142,7 @@ function countOccurrences(haystack, needle) {
5983
6142
  }
5984
6143
  return count;
5985
6144
  }
5986
- var commandName = (command) => path6.basename(command).replace(/\.(exe|cmd|bat|com)$/i, "").toLowerCase();
6145
+ var commandName = (command) => path7.basename(command).replace(/\.(exe|cmd|bat|com)$/i, "").toLowerCase();
5987
6146
  var WorkspaceTools = class {
5988
6147
  root;
5989
6148
  readOnly;
@@ -5996,7 +6155,7 @@ var WorkspaceTools = class {
5996
6155
  maxOutput;
5997
6156
  env;
5998
6157
  constructor(opts) {
5999
- this.root = path6.resolve(opts.root);
6158
+ this.root = path7.resolve(opts.root);
6000
6159
  this.readOnly = opts.readOnly ?? false;
6001
6160
  this.allowedCommands = (opts.allowedCommands ?? DEFAULT_ALLOWED_COMMANDS).map(
6002
6161
  (c) => c.toLowerCase()
@@ -6075,7 +6234,7 @@ var WorkspaceTools = class {
6075
6234
  }
6076
6235
  async writeFile(args) {
6077
6236
  const { abs, rel } = await resolveRepoPath(this.root, args.path, "write");
6078
- await mkdir4(path6.dirname(abs), { recursive: true });
6237
+ await mkdir4(path7.dirname(abs), { recursive: true });
6079
6238
  const content = repairDoubleEscaped(args.content);
6080
6239
  await writeFile2(abs, content, "utf8");
6081
6240
  this.changedFiles.add(rel);
@@ -6131,8 +6290,8 @@ var WorkspaceTools = class {
6131
6290
  const ignored = await this.loadGitignoreMatcher();
6132
6291
  const results = [];
6133
6292
  const visitFile = async (file) => {
6134
- const rel = path6.relative(this.root, file).split(path6.sep).join("/");
6135
- if (ignored(rel, path6.basename(file), false)) return;
6293
+ const rel = path7.relative(this.root, file).split(path7.sep).join("/");
6294
+ if (ignored(rel, path7.basename(file), false)) return;
6136
6295
  const info2 = await stat3(file);
6137
6296
  if (info2.size > MAX_FILE_BYTES) return;
6138
6297
  const buffer = await readFile4(file);
@@ -6153,8 +6312,8 @@ var WorkspaceTools = class {
6153
6312
  entries.sort((a, b) => a.name.localeCompare(b.name));
6154
6313
  for (const entry of entries) {
6155
6314
  if (results.length >= args.max_results) return;
6156
- const full = path6.join(dir, entry.name);
6157
- const rel = path6.relative(this.root, full).split(path6.sep).join("/");
6315
+ const full = path7.join(dir, entry.name);
6316
+ const rel = path7.relative(this.root, full).split(path7.sep).join("/");
6158
6317
  if (entry.isDirectory()) {
6159
6318
  if (!SKIP_DIRS.has(entry.name) && !ignored(rel, entry.name, true)) await walk(full);
6160
6319
  } else if (entry.isFile()) {
@@ -6173,7 +6332,7 @@ var WorkspaceTools = class {
6173
6332
  async loadGitignoreMatcher() {
6174
6333
  let raw = "";
6175
6334
  try {
6176
- raw = await readFile4(path6.join(this.root, ".gitignore"), "utf8");
6335
+ raw = await readFile4(path7.join(this.root, ".gitignore"), "utf8");
6177
6336
  } catch {
6178
6337
  return () => false;
6179
6338
  }
@@ -6467,7 +6626,7 @@ Rules:
6467
6626
  - Do not edit anything under .davecode/ (the runner maintains it) and do not commit, merge, push or switch branches: the runner owns git.
6468
6627
  - You may run the project's checks before finishing.
6469
6628
  - When the task is complete, reply with a concise summary of the change (it becomes the commit message body).`;
6470
- var SAFE_MODEL4 = /^[\w.:[\]-]+$/;
6629
+ var SAFE_MODEL5 = /^[\w.:[\]-]+$/;
6471
6630
  var SAFE_SESSION = /^[A-Za-z0-9-]{8,128}$/;
6472
6631
  function selectClaudeAccount(accounts, accountId) {
6473
6632
  if (accountId) {
@@ -6518,7 +6677,7 @@ var ClaudeCliExecutor = class {
6518
6677
  const args = ["-p", "--output-format", "stream-json", "--verbose"];
6519
6678
  args.push("--permission-mode", "acceptEdits");
6520
6679
  if (opts.model) {
6521
- if (!SAFE_MODEL4.test(opts.model)) {
6680
+ if (!SAFE_MODEL5.test(opts.model)) {
6522
6681
  throw new ExecutorError("runner.claudeCli.model contains unsupported characters");
6523
6682
  }
6524
6683
  args.push("--model", opts.model);
@@ -7900,6 +8059,357 @@ var ProjectBrainSource = class {
7900
8059
  return await readFileIfExists(this.brain.paths.architecture) ?? "";
7901
8060
  }
7902
8061
  };
8062
+ var ACCOUNT_SERVICE = {
8063
+ url: "https://auth.davecode.app",
8064
+ publishableKey: "davecode-cli"
8065
+ };
8066
+ function accountService(env = process.env) {
8067
+ const url = env.DAVECODE_ACCOUNT_URL ?? ACCOUNT_SERVICE.url;
8068
+ const publishableKey = env.DAVECODE_ACCOUNT_KEY ?? ACCOUNT_SERVICE.publishableKey;
8069
+ return url && publishableKey ? { url: url.replace(/\/+$/, ""), publishableKey } : void 0;
8070
+ }
8071
+ var OAUTH_PROVIDERS = ["google", "github"];
8072
+ var AccountError = class extends Error {
8073
+ constructor(message, status) {
8074
+ super(message);
8075
+ this.status = status;
8076
+ this.name = "AccountError";
8077
+ }
8078
+ status;
8079
+ };
8080
+ var userSchema = z8.object({
8081
+ id: z8.string().min(1),
8082
+ email: z8.string().optional().nullable(),
8083
+ app_metadata: z8.object({ provider: z8.string().optional() }).passthrough().optional(),
8084
+ user_metadata: z8.object({ full_name: z8.string().optional(), name: z8.string().optional() }).passthrough().optional()
8085
+ });
8086
+ var sessionSchema = z8.object({
8087
+ access_token: z8.string().min(1),
8088
+ refresh_token: z8.string().min(1),
8089
+ expires_in: z8.number().positive(),
8090
+ user: userSchema
8091
+ });
8092
+ var settingsSchema = z8.object({ external: z8.record(z8.string(), z8.boolean()) });
8093
+ var errorSchema = z8.object({
8094
+ error_description: z8.string().optional(),
8095
+ msg: z8.string().optional(),
8096
+ message: z8.string().optional(),
8097
+ error: z8.string().optional()
8098
+ }).passthrough();
8099
+ function pkcePair() {
8100
+ const verifier = randomBytes6(48).toString("base64url");
8101
+ return { verifier, challenge: createHash2("sha256").update(verifier).digest("base64url") };
8102
+ }
8103
+ function toSession(raw, now) {
8104
+ const parsed = sessionSchema.safeParse(raw);
8105
+ if (!parsed.success) throw new AccountError("The account service sent an unexpected reply.");
8106
+ const { user } = parsed.data;
8107
+ return {
8108
+ accessToken: parsed.data.access_token,
8109
+ refreshToken: parsed.data.refresh_token,
8110
+ expiresAt: now + parsed.data.expires_in * 1e3,
8111
+ user: {
8112
+ id: user.id,
8113
+ ...user.email ? { email: user.email } : {},
8114
+ ...user.user_metadata?.full_name ?? user.user_metadata?.name ? { name: user.user_metadata?.full_name ?? user.user_metadata?.name } : {},
8115
+ ...user.app_metadata?.provider ? { provider: user.app_metadata.provider } : {}
8116
+ }
8117
+ };
8118
+ }
8119
+ var AccountClient = class {
8120
+ constructor(service, options = {}) {
8121
+ this.service = service;
8122
+ this.fetch = options.fetch ?? globalThis.fetch;
8123
+ this.now = options.now ?? Date.now;
8124
+ }
8125
+ service;
8126
+ fetch;
8127
+ now;
8128
+ /**
8129
+ * The hosted sign-in page (Google, GitHub or email). Every method ends by sending the browser
8130
+ * to `redirectTo` with `?code=` bound to `challenge`.
8131
+ */
8132
+ loginUrl(redirectTo, challenge) {
8133
+ const url = new URL(`${this.service.url}/login`);
8134
+ url.searchParams.set("redirect_to", redirectTo);
8135
+ url.searchParams.set("code_challenge", challenge);
8136
+ return url.toString();
8137
+ }
8138
+ /** A page of the hosted service, such as `/login/done`. */
8139
+ pageUrl(path8) {
8140
+ return `${this.service.url}${path8}`;
8141
+ }
8142
+ /** Browser URL that starts Google or GitHub sign-in and returns to `redirectTo` with `?code=`. */
8143
+ authorizeUrl(provider, redirectTo, challenge) {
8144
+ const url = new URL(`${this.service.url}/auth/v1/authorize`);
8145
+ url.searchParams.set("provider", provider);
8146
+ url.searchParams.set("redirect_to", redirectTo);
8147
+ url.searchParams.set("code_challenge", challenge);
8148
+ url.searchParams.set("code_challenge_method", "s256");
8149
+ return url.toString();
8150
+ }
8151
+ exchangeCode(code, verifier) {
8152
+ return this.session("token?grant_type=pkce", { auth_code: code, code_verifier: verifier });
8153
+ }
8154
+ signInWithPassword(email, password) {
8155
+ return this.session("token?grant_type=password", { email, password });
8156
+ }
8157
+ /** Create an e-mail account. With confirmation on, the link returns to `redirectTo`. */
8158
+ async signUp(email, password, redirectTo, challenge) {
8159
+ const raw = await this.post(`signup?redirect_to=${encodeURIComponent(redirectTo)}`, {
8160
+ email,
8161
+ password,
8162
+ code_challenge: challenge,
8163
+ code_challenge_method: "s256"
8164
+ });
8165
+ if (sessionSchema.safeParse(raw).success) return { session: toSession(raw, this.now()) };
8166
+ return { confirmEmail: true };
8167
+ }
8168
+ /** Sign-in methods the service has enabled; on any failure, assume all of them. */
8169
+ async providers() {
8170
+ try {
8171
+ const response = await this.fetch(`${this.service.url}/auth/v1/settings`, {
8172
+ headers: { apikey: this.service.publishableKey },
8173
+ signal: AbortSignal.timeout(1e4)
8174
+ });
8175
+ const parsed = settingsSchema.safeParse(await response.json());
8176
+ if (!response.ok || !parsed.success) return [...OAUTH_PROVIDERS];
8177
+ return OAUTH_PROVIDERS.filter((p) => parsed.data.external[p] !== false);
8178
+ } catch {
8179
+ return [...OAUTH_PROVIDERS];
8180
+ }
8181
+ }
8182
+ refresh(refreshToken) {
8183
+ return this.session("token?grant_type=refresh_token", { refresh_token: refreshToken });
8184
+ }
8185
+ /** Revoke the session on the server. Best effort: the local copy is removed regardless. */
8186
+ async signOut(accessToken) {
8187
+ await this.fetch(`${this.service.url}/auth/v1/logout?scope=local`, {
8188
+ method: "POST",
8189
+ headers: { apikey: this.service.publishableKey, Authorization: `Bearer ${accessToken}` },
8190
+ signal: AbortSignal.timeout(1e4)
8191
+ }).catch(() => void 0);
8192
+ }
8193
+ async session(path8, body) {
8194
+ return toSession(await this.post(path8, body), this.now());
8195
+ }
8196
+ async post(path8, body) {
8197
+ let response;
8198
+ try {
8199
+ response = await this.fetch(`${this.service.url}/auth/v1/${path8}`, {
8200
+ method: "POST",
8201
+ headers: { apikey: this.service.publishableKey, "Content-Type": "application/json" },
8202
+ body: JSON.stringify(body),
8203
+ signal: AbortSignal.timeout(2e4)
8204
+ });
8205
+ } catch {
8206
+ throw new AccountError("Cannot reach the DaveCode account service. Check your connection.");
8207
+ }
8208
+ const raw = await response.json().catch(() => void 0);
8209
+ if (!response.ok) {
8210
+ const error = errorSchema.safeParse(raw);
8211
+ const detail = error.success ? error.data.error_description ?? error.data.msg ?? error.data.message : void 0;
8212
+ throw new AccountError(
8213
+ detail ?? `Sign-in failed (HTTP ${response.status}).`,
8214
+ response.status
8215
+ );
8216
+ }
8217
+ return raw;
8218
+ }
8219
+ };
8220
+ function redirect(res, location) {
8221
+ res.writeHead(302, { Location: location, "Cache-Control": "no-store" });
8222
+ res.end();
8223
+ }
8224
+ async function startAccountLogin(options) {
8225
+ const { client } = options;
8226
+ const callbackPath = `/s/${randomBytes7(18).toString("base64url")}/callback`;
8227
+ const pkce = pkcePair();
8228
+ let finish = () => {
8229
+ };
8230
+ let fail = () => {
8231
+ };
8232
+ let settled = false;
8233
+ const session = new Promise((resolve5, reject) => {
8234
+ finish = resolve5;
8235
+ fail = reject;
8236
+ });
8237
+ session.catch(() => {
8238
+ });
8239
+ const server = createServer((req, res) => {
8240
+ void (async () => {
8241
+ const url = new URL(req.url ?? "/", "http://127.0.0.1");
8242
+ if (req.method !== "GET" || url.pathname !== callbackPath || settled) {
8243
+ res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
8244
+ res.end("Not found");
8245
+ return;
8246
+ }
8247
+ const code = url.searchParams.get("code");
8248
+ if (!code) {
8249
+ settled = true;
8250
+ fail(
8251
+ new AccountError(
8252
+ url.searchParams.get("error_description") ?? "The sign-in was not completed."
8253
+ )
8254
+ );
8255
+ redirect(res, client.pageUrl("/login/failed"));
8256
+ return;
8257
+ }
8258
+ settled = true;
8259
+ try {
8260
+ finish(await client.exchangeCode(code, pkce.verifier));
8261
+ redirect(res, client.pageUrl("/login/done"));
8262
+ } catch (err) {
8263
+ fail(err instanceof AccountError ? err : new AccountError("Sign-in failed."));
8264
+ redirect(res, client.pageUrl("/login/failed"));
8265
+ }
8266
+ })().catch(() => {
8267
+ if (!res.headersSent) res.writeHead(500).end();
8268
+ });
8269
+ });
8270
+ await new Promise((resolve5, reject) => {
8271
+ server.once("error", reject);
8272
+ server.listen(0, "127.0.0.1", () => resolve5());
8273
+ });
8274
+ const port = server.address().port;
8275
+ const close = () => new Promise((resolve5) => {
8276
+ server.closeAllConnections();
8277
+ server.close(() => resolve5());
8278
+ });
8279
+ const timeout = setTimeout(
8280
+ () => {
8281
+ fail(new AccountError("Sign-in timed out. Run davecode login to try again."));
8282
+ },
8283
+ options.timeoutMs ?? 10 * 6e4
8284
+ );
8285
+ timeout.unref();
8286
+ void session.then(
8287
+ () => setTimeout(() => void close(), 1e3).unref(),
8288
+ () => setTimeout(() => void close(), 1e3).unref()
8289
+ );
8290
+ return {
8291
+ url: client.loginUrl(`http://127.0.0.1:${port}${callbackPath}`, pkce.challenge),
8292
+ session,
8293
+ close: async () => {
8294
+ clearTimeout(timeout);
8295
+ fail(new AccountError("Sign-in cancelled."));
8296
+ await close();
8297
+ }
8298
+ };
8299
+ }
8300
+ var AAD = Buffer.from("davecode-account", "utf8");
8301
+ var REFRESH_MARGIN_MS = 6e4;
8302
+ var fileSchema = z9.object({
8303
+ v: z9.literal(1),
8304
+ iv: z9.string(),
8305
+ tag: z9.string(),
8306
+ data: z9.string()
8307
+ });
8308
+ var sessionSchema2 = z9.object({
8309
+ accessToken: z9.string().min(1),
8310
+ refreshToken: z9.string().min(1),
8311
+ expiresAt: z9.number(),
8312
+ user: z9.object({
8313
+ id: z9.string().min(1),
8314
+ email: z9.string().optional(),
8315
+ name: z9.string().optional(),
8316
+ provider: z9.string().optional()
8317
+ })
8318
+ });
8319
+ function accountFile(home) {
8320
+ return join6(home, "account.json");
8321
+ }
8322
+ var AccountStore = class {
8323
+ constructor(home, env = process.env) {
8324
+ this.home = home;
8325
+ this.path = accountFile(home);
8326
+ this.key = loadMasterKey(globalPaths(home).masterKey, env);
8327
+ }
8328
+ home;
8329
+ path;
8330
+ key;
8331
+ load() {
8332
+ let raw;
8333
+ try {
8334
+ raw = readFileSync3(this.path, "utf8");
8335
+ } catch {
8336
+ return void 0;
8337
+ }
8338
+ try {
8339
+ const file = fileSchema.parse(JSON.parse(raw));
8340
+ const decipher = createDecipheriv2("aes-256-gcm", this.key, Buffer.from(file.iv, "base64"));
8341
+ decipher.setAAD(AAD);
8342
+ decipher.setAuthTag(Buffer.from(file.tag, "base64"));
8343
+ const plain = Buffer.concat([
8344
+ decipher.update(Buffer.from(file.data, "base64")),
8345
+ decipher.final()
8346
+ ]).toString("utf8");
8347
+ return sessionSchema2.parse(JSON.parse(plain));
8348
+ } catch {
8349
+ return void 0;
8350
+ }
8351
+ }
8352
+ save(session) {
8353
+ const iv = randomBytes8(12);
8354
+ const cipher = createCipheriv2("aes-256-gcm", this.key, iv);
8355
+ cipher.setAAD(AAD);
8356
+ const data = Buffer.concat([cipher.update(JSON.stringify(session), "utf8"), cipher.final()]);
8357
+ mkdirSync7(dirname6(this.path), { recursive: true });
8358
+ writeFileSync3(
8359
+ this.path,
8360
+ `${JSON.stringify({
8361
+ v: 1,
8362
+ iv: iv.toString("base64"),
8363
+ tag: cipher.getAuthTag().toString("base64"),
8364
+ data: data.toString("base64")
8365
+ })}
8366
+ `,
8367
+ { mode: 384 }
8368
+ );
8369
+ }
8370
+ clear() {
8371
+ rmSync3(this.path, { force: true });
8372
+ }
8373
+ /**
8374
+ * The current session, refreshed when it is about to expire. Returns undefined when signed out
8375
+ * or when the service revoked the session; offline, an unexpired session is still returned.
8376
+ */
8377
+ async current(client, now = Date.now()) {
8378
+ const session = this.load();
8379
+ if (!session) return void 0;
8380
+ if (session.expiresAt - REFRESH_MARGIN_MS > now) return session;
8381
+ try {
8382
+ const fresh = await client.refresh(session.refreshToken);
8383
+ this.save(fresh);
8384
+ return fresh;
8385
+ } catch (err) {
8386
+ if (err instanceof AccountError && err.status !== void 0 && err.status < 500) {
8387
+ this.clear();
8388
+ return void 0;
8389
+ }
8390
+ return session;
8391
+ }
8392
+ }
8393
+ };
8394
+ var BRAND_MARK_SVG = '<svg viewBox="0 0 1214 1214" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill="currentColor" fill-rule="evenodd" d="M324.3 1096.5C324.6 1095.4 326.5 1088.3 328.5 1080.8C341.4 1031.3 375.8 953.4 419.7 874.0C445.8 826.9 448.4 822.4 471.8 783.0C501.5 733.1 530.1 687.6 556.4 648.5C563.7 637.5 569.7 628.4 569.5 628.2C569.4 628.1 563.1 631.7 555.4 636.3C513.8 661.4 468.0 683.9 411.0 707.5C337.2 737.9 321.7 744.7 296.0 757.2C241.9 783.5 199.1 809.4 152.0 844.3C119.5 868.4 98.8 885.9 71.3 912.4C64.0 919.5 58.0 925.0 58.0 924.7C58.0 923.1 64.7 902.4 68.8 891.0C116.1 762.1 215.0 644.2 351.0 554.8C385.2 532.3 411.6 516.9 445.5 499.4C521.4 460.4 589.4 435.7 636.0 430.0C676.8 425.1 715.1 437.0 743.9 463.6C763.4 481.6 779.0 509.9 785.2 538.5C787.7 550.1 788.7 579.7 787.1 592.5C782.6 626.4 769.7 661.5 746.5 702.0C717.7 752.5 675.6 806.9 627.0 856.4C599.5 884.4 575.9 905.4 542.5 931.6C510.0 957.1 500.7 964.2 432.5 1015.0C409.4 1032.3 382.6 1052.5 373.0 1060.0C354.5 1074.4 327.4 1095.5 325.1 1097.4C324.0 1098.3 323.8 1098.1 324.3 1096.5ZM783.2 1017.8C797.1 999.5 820.2 966.0 831.7 947.5C868.5 888.3 888.8 840.5 903.4 778.5C917.9 716.9 921.2 643.7 912.0 591.0C904.6 549.3 889.7 511.9 866.7 477.5C856.6 462.3 853.1 457.8 837.4 439.6C817.4 416.6 806.6 402.0 800.5 389.5C793.6 375.5 791.7 368.1 791.7 356.0C791.7 335.3 799.3 319.6 819.0 299.9C849.7 269.2 900.2 247.9 956.8 241.9C963.0 241.2 967.7 240.3 967.3 239.9C966.1 238.8 948.5 236.3 933.0 234.9C913.6 233.2 875.2 234.3 859.0 237.0C839.7 240.2 827.8 242.9 813.0 247.5C753.9 265.9 700.6 300.9 659.2 348.5C648.9 360.4 636.6 376.5 632.4 383.5C630.3 387.1 629.0 388.2 624.7 389.6C603.8 396.4 554.6 417.6 513.5 437.5C447.6 469.4 395.4 496.8 341.5 528.1L337.5 530.4L339.5 527.9C340.6 526.6 346.2 520.3 352.0 514.0C374.4 489.6 390.2 470.8 411.2 443.5C429.3 419.9 444.6 398.2 488.5 333.5C510.5 301.0 529.1 278.0 550.9 256.3C593.0 214.1 640.3 183.6 691.5 165.5C727.7 152.8 756.5 147.7 792.5 147.7C854.3 147.8 906.4 164.9 954.1 200.6C967.5 210.8 974.1 214.6 981.5 217.0C991.4 220.1 1022.1 231.9 1038.5 238.8C1061.9 248.7 1099.0 267.4 1097.7 268.7C1097.4 268.9 1089.3 268.5 1079.7 267.9C1033.7 264.7 984.5 274.1 946.2 293.4C932.3 300.4 915.0 313.0 903.4 324.5C881.0 346.6 870.0 369.6 870.0 394.4C870.0 413.7 876.8 433.1 894.7 465.2C908.8 490.3 914.6 501.1 922.8 517.5C961.3 594.3 980.0 662.5 980.0 725.4C980.0 770.9 967.3 818.9 944.4 860.4C927.6 890.8 912.0 911.0 882.5 940.6C856.5 966.7 828.5 989.7 797.0 1010.7C779.6 1022.2 780.0 1022.0 783.2 1017.8Z"/></svg>';
8395
+ var LOGO_ART = [
8396
+ " \u2584\u2584\u2584\u2588\u2584\u2584\u2584",
8397
+ " \u2584\u2588\u2588\u2588\u2580\u2580\u2588\u2588\u2588\u2580\u2580",
8398
+ " \u2588\u2588\u2588\u2580 \u2588\u2580",
8399
+ " \u2588\u2588\u2584\u2584\u2588\u2588\u2584 \u2580\u2588",
8400
+ " \u2584\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588",
8401
+ " \u2584\u2588\u2588\u2588\u2588\u2580\u2588\u2588\u2588\u2588\u2588 \u2588",
8402
+ " \u2584\u2588\u2588\u2580\u2580 \u2584\u2588\u2588\u2588\u2588\u2580 \u2588\u2580",
8403
+ "\u2584\u2580\u2580 \u2584\u2588\u2588\u2588\u2580 \u2584\u2588",
8404
+ " \u2584\u2588\u2588\u2580 \u2584\u2580",
8405
+ " \u2580"
8406
+ ];
8407
+ function brandLogo(unicode = true) {
8408
+ if (unicode) return [...LOGO_ART];
8409
+ return LOGO_ART.map(
8410
+ (line) => line.replaceAll("\u2588", "#").replaceAll("\u2580", '"').replaceAll("\u2584", ".")
8411
+ );
8412
+ }
7903
8413
  var DEFAULT_ROLES = [
7904
8414
  {
7905
8415
  id: "planner",
@@ -7982,27 +8492,27 @@ ${task.description ?? ""}`;
7982
8492
  const description = [task.description?.trim(), DRAFT_NOTICE].filter(Boolean).join("\n\n");
7983
8493
  return { ...task, kind: "artifact", title: title.slice(0, 300), description };
7984
8494
  }
7985
- var plannedTaskSchema = z8.object({
7986
- id: z8.string().min(1).max(80),
7987
- title: z8.string().trim().min(1).max(300),
7988
- description: z8.string().max(8e3).optional(),
7989
- role: z8.string().min(1).max(40),
7990
- kind: z8.enum(["code", "artifact"]).optional(),
7991
- dependsOn: z8.array(z8.string().min(1)).max(50).default([]),
7992
- acceptance: z8.array(z8.string().min(1).max(1e3)).max(20).optional()
8495
+ var plannedTaskSchema = z10.object({
8496
+ id: z10.string().min(1).max(80),
8497
+ title: z10.string().trim().min(1).max(300),
8498
+ description: z10.string().max(8e3).optional(),
8499
+ role: z10.string().min(1).max(40),
8500
+ kind: z10.enum(["code", "artifact"]).optional(),
8501
+ dependsOn: z10.array(z10.string().min(1)).max(50).default([]),
8502
+ acceptance: z10.array(z10.string().min(1).max(1e3)).max(20).optional()
7993
8503
  });
7994
- var planSchema = z8.object({
7995
- summary: z8.string().max(4e3).optional(),
7996
- tasks: z8.array(plannedTaskSchema).min(1).max(100)
8504
+ var planSchema = z10.object({
8505
+ summary: z10.string().max(4e3).optional(),
8506
+ tasks: z10.array(plannedTaskSchema).min(1).max(100)
7997
8507
  });
7998
- var reviewSchema = z8.object({
8508
+ var reviewSchema = z10.object({
7999
8509
  /** The objective is achieved as far as DaveCode can take it. */
8000
- done: z8.boolean(),
8001
- summary: z8.string().max(8e3),
8510
+ done: z10.boolean(),
8511
+ summary: z10.string().max(8e3),
8002
8512
  /** Ids of FAILED tasks worth another attempt. */
8003
- retry: z8.array(z8.string()).max(50).default([]),
8513
+ retry: z10.array(z10.string()).max(50).default([]),
8004
8514
  /** New tasks for the next round. */
8005
- tasks: z8.array(plannedTaskSchema).max(50).default([])
8515
+ tasks: z10.array(plannedTaskSchema).max(50).default([])
8006
8516
  });
8007
8517
  var TASK_ID = /^[a-z0-9]+(?:[-_.][a-z0-9]+)*$/;
8008
8518
  function sanitizeTaskId(raw) {
@@ -8766,25 +9276,25 @@ var GoalService = class {
8766
9276
  }
8767
9277
  };
8768
9278
  var GOAL_ID = /^goal_[a-z0-9]{6,32}$/;
8769
- var goalTaskSchema = z9.object({
8770
- id: z9.string().min(1),
8771
- title: z9.string(),
8772
- description: z9.string().optional(),
8773
- role: z9.string(),
8774
- kind: z9.enum(["code", "artifact"]),
9279
+ var goalTaskSchema = z11.object({
9280
+ id: z11.string().min(1),
9281
+ title: z11.string(),
9282
+ description: z11.string().optional(),
9283
+ role: z11.string(),
9284
+ kind: z11.enum(["code", "artifact"]),
8775
9285
  status: taskStatusSchema,
8776
- dependsOn: z9.array(z9.string()),
8777
- acceptance: z9.array(z9.string()).optional(),
8778
- round: z9.number().int().min(1),
8779
- attempts: z9.number().int().min(0),
8780
- artifact: z9.string().optional(),
8781
- runnerTaskId: z9.string().optional(),
8782
- notes: z9.string().optional()
9286
+ dependsOn: z11.array(z11.string()),
9287
+ acceptance: z11.array(z11.string()).optional(),
9288
+ round: z11.number().int().min(1),
9289
+ attempts: z11.number().int().min(0),
9290
+ artifact: z11.string().optional(),
9291
+ runnerTaskId: z11.string().optional(),
9292
+ notes: z11.string().optional()
8783
9293
  });
8784
- var goalSchema = z9.object({
8785
- id: z9.string().regex(GOAL_ID),
8786
- objective: z9.string().min(1),
8787
- status: z9.enum([
9294
+ var goalSchema = z11.object({
9295
+ id: z11.string().regex(GOAL_ID),
9296
+ objective: z11.string().min(1),
9297
+ status: z11.enum([
8788
9298
  "planning",
8789
9299
  "running",
8790
9300
  "reviewing",
@@ -8794,24 +9304,24 @@ var goalSchema = z9.object({
8794
9304
  "cancelled",
8795
9305
  "budget_exhausted"
8796
9306
  ]),
8797
- round: z9.number().int().min(0),
8798
- limits: z9.object({
8799
- maxRounds: z9.number().int().min(1),
8800
- maxTasks: z9.number().int().min(1),
8801
- maxTokens: z9.number().int().min(1),
8802
- tokensUsed: z9.number().int().min(0)
9307
+ round: z11.number().int().min(0),
9308
+ limits: z11.object({
9309
+ maxRounds: z11.number().int().min(1),
9310
+ maxTasks: z11.number().int().min(1),
9311
+ maxTokens: z11.number().int().min(1),
9312
+ tokensUsed: z11.number().int().min(0)
8803
9313
  }),
8804
- roles: z9.array(
8805
- z9.object({ id: z9.string(), description: z9.string(), route: z9.string().optional() })
9314
+ roles: z11.array(
9315
+ z11.object({ id: z11.string(), description: z11.string(), route: z11.string().optional() })
8806
9316
  ),
8807
- tasks: z9.array(goalTaskSchema),
8808
- activeTaskId: z9.string().optional(),
8809
- summary: z9.string().optional(),
8810
- lastError: z9.string().optional(),
8811
- dryRun: z9.boolean().optional(),
8812
- createdAt: z9.string(),
8813
- updatedAt: z9.string(),
8814
- finishedAt: z9.string().optional()
9317
+ tasks: z11.array(goalTaskSchema),
9318
+ activeTaskId: z11.string().optional(),
9319
+ summary: z11.string().optional(),
9320
+ lastError: z11.string().optional(),
9321
+ dryRun: z11.boolean().optional(),
9322
+ createdAt: z11.string(),
9323
+ updatedAt: z11.string(),
9324
+ finishedAt: z11.string().optional()
8815
9325
  });
8816
9326
  function isGoalId(id) {
8817
9327
  return GOAL_ID.test(id);
@@ -8819,17 +9329,17 @@ function isGoalId(id) {
8819
9329
  var GoalStore = class {
8820
9330
  constructor(root) {
8821
9331
  this.root = root;
8822
- this.dir = join6(projectPaths(root).dir, "goals");
9332
+ this.dir = join7(projectPaths(root).dir, "goals");
8823
9333
  }
8824
9334
  root;
8825
9335
  dir;
8826
9336
  goalDir(id) {
8827
9337
  if (!isGoalId(id)) throw new Error(`invalid goal id: ${id}`);
8828
- return join6(this.dir, id);
9338
+ return join7(this.dir, id);
8829
9339
  }
8830
9340
  async save(goal) {
8831
9341
  await atomicWriteFile(
8832
- join6(this.goalDir(goal.id), "goal.json"),
9342
+ join7(this.goalDir(goal.id), "goal.json"),
8833
9343
  `${JSON.stringify(goal, null, 2)}
8834
9344
  `
8835
9345
  );
@@ -8837,7 +9347,7 @@ var GoalStore = class {
8837
9347
  /** The goal, or `undefined` when unknown. Throws when `goal.json` is corrupt. */
8838
9348
  async load(id) {
8839
9349
  if (!isGoalId(id)) return void 0;
8840
- const text = await readFileIfExists(join6(this.goalDir(id), "goal.json"));
9350
+ const text = await readFileIfExists(join7(this.goalDir(id), "goal.json"));
8841
9351
  if (text === void 0) return void 0;
8842
9352
  return goalSchema.parse(JSON.parse(text));
8843
9353
  }
@@ -8862,14 +9372,14 @@ var GoalStore = class {
8862
9372
  }
8863
9373
  /** Writes a task's markdown artifact and returns its repository-relative path (`/`-separated). */
8864
9374
  async writeArtifact(goalId, taskId, markdown) {
8865
- const path7 = join6(this.goalDir(goalId), `${taskId}.md`);
8866
- await atomicWriteFile(path7, markdown.endsWith("\n") ? markdown : `${markdown}
9375
+ const path8 = join7(this.goalDir(goalId), `${taskId}.md`);
9376
+ await atomicWriteFile(path8, markdown.endsWith("\n") ? markdown : `${markdown}
8867
9377
  `);
8868
- return relative2(this.root, path7).split("\\").join("/");
9378
+ return relative2(this.root, path8).split("\\").join("/");
8869
9379
  }
8870
9380
  async readArtifact(goalId, taskId) {
8871
9381
  if (!isGoalId(goalId) || !/^[-a-zA-Z0-9_]{1,64}$/.test(taskId)) return void 0;
8872
- return readFileIfExists(join6(this.goalDir(goalId), `${taskId}.md`));
9382
+ return readFileIfExists(join7(this.goalDir(goalId), `${taskId}.md`));
8873
9383
  }
8874
9384
  };
8875
9385
  var PROJECT_CONTEXT_CHARS = 3e3;
@@ -9068,6 +9578,17 @@ export {
9068
9578
  createRunner,
9069
9579
  WorkspaceLock,
9070
9580
  ProjectBrainSource,
9581
+ ACCOUNT_SERVICE,
9582
+ accountService,
9583
+ OAUTH_PROVIDERS,
9584
+ AccountError,
9585
+ pkcePair,
9586
+ AccountClient,
9587
+ startAccountLogin,
9588
+ accountFile,
9589
+ AccountStore,
9590
+ BRAND_MARK_SVG,
9591
+ brandLogo,
9071
9592
  DEFAULT_ROLES,
9072
9593
  resolveRoles,
9073
9594
  outboundAction,
@@ -9084,4 +9605,4 @@ export {
9084
9605
  GoalStore,
9085
9606
  createGoalService
9086
9607
  };
9087
- //# sourceMappingURL=chunk-C7FDRA3U.js.map
9608
+ //# sourceMappingURL=chunk-HSBJDV3O.js.map