@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.
- package/README.md +5 -4
- package/bin/davecode.js +0 -0
- package/dist/{ChatApp-FO5SABXB.js → ChatApp-CJBICQGA.js} +289 -137
- package/dist/ChatApp-CJBICQGA.js.map +1 -0
- package/dist/{RunnerView-DLVR7C22.js → RunnerView-A7JSPUW5.js} +5 -5
- package/dist/account-QWDPJWAA.js +23 -0
- package/dist/accounts-IQMR72FC.js +37 -0
- package/dist/{budget-RBHCEDPP.js → budget-XANOUVWO.js} +6 -6
- package/dist/chat-KDDRNC5V.js +359 -0
- package/dist/chat-KDDRNC5V.js.map +1 -0
- package/dist/{accounts-MTMGYKEP.js → chunk-44AFJL2X.js} +24 -17
- package/dist/chunk-44AFJL2X.js.map +1 -0
- package/dist/{chunk-BOLFK3BH.js → chunk-5LKOJBUL.js} +2 -2
- package/dist/{chunk-23KTE7IK.js → chunk-AZKACMME.js} +2 -2
- package/dist/{chunk-PIIJ3RSI.js → chunk-FYPMA55O.js} +1269 -1265
- package/dist/chunk-FYPMA55O.js.map +1 -0
- package/dist/{chunk-OYEYNDOO.js → chunk-GE22VBCY.js} +3 -3
- package/dist/{chunk-C7FDRA3U.js → chunk-HSBJDV3O.js} +660 -139
- package/dist/chunk-HSBJDV3O.js.map +1 -0
- package/dist/chunk-JLATEHS7.js +20 -0
- package/dist/chunk-JLATEHS7.js.map +1 -0
- package/dist/{chunk-VVCXGQMY.js → chunk-MC7RIPL7.js} +17 -8
- package/dist/chunk-MC7RIPL7.js.map +1 -0
- package/dist/{chunk-MSLLH5XP.js → chunk-PGAJIGUF.js} +4 -4
- package/dist/{chunk-OXRMGR72.js → chunk-PGPXE6LF.js} +2 -2
- package/dist/chunk-QA3O6RA2.js +81 -0
- package/dist/chunk-QA3O6RA2.js.map +1 -0
- package/dist/chunk-W7GPBEBZ.js +144 -0
- package/dist/chunk-W7GPBEBZ.js.map +1 -0
- package/dist/{chunk-IVZHKUCD.js → chunk-WQ7MEWDF.js} +3 -3
- package/dist/{config-FRMY5OHG.js → config-YTUPIYZT.js} +5 -5
- package/dist/dashboard/assets/Accounts-cq8RLMoI.js +1 -0
- package/dist/dashboard/assets/Badge-Z4RBdO9j.js +55 -0
- package/dist/dashboard/assets/Callout-w8BTYh4k.js +1 -0
- package/dist/dashboard/assets/Field-Cmpgg_1z.js +1 -0
- package/dist/dashboard/assets/Goals-Bw02to72.js +1 -0
- package/dist/dashboard/assets/Library-DK7mlpRb.js +1 -0
- package/dist/dashboard/assets/{Markdown-ClRsddnB.js → Markdown-DCZ4Awcc.js} +8 -8
- package/dist/dashboard/assets/Panes-_KTf8pbZ.js +8 -0
- package/dist/dashboard/assets/Panes-kHJ-D0s7.css +1 -0
- package/dist/dashboard/assets/RoutesPage-QV0oPRW9.js +4 -0
- package/dist/dashboard/assets/Runner-CkHBLQl0.js +1 -0
- package/dist/dashboard/assets/Settings-BLz2gTBR.js +1 -0
- package/dist/dashboard/assets/Switch-DPYlLseH.js +1 -0
- package/dist/dashboard/assets/Tasks-BiUQSTpt.js +2 -0
- package/dist/dashboard/assets/Traffic-BVfBuC70.js +1 -0
- package/dist/dashboard/assets/Workspace-CJTgiiU5.js +1 -0
- package/dist/dashboard/assets/arrow-up-DjhzZprp.js +1 -0
- package/dist/dashboard/assets/cn-BwE4cei0.js +1 -0
- package/dist/dashboard/assets/forms-DVIUAxAc.js +1 -0
- package/dist/dashboard/assets/index-BDBa5cb0.js +104 -0
- package/dist/dashboard/assets/index-BEmBgsbP.css +2 -0
- package/dist/dashboard/assets/task-errors-Daqwi0ue.js +1 -0
- package/dist/dashboard/assets/trash-BTuDcSaQ.js +1 -0
- package/dist/dashboard/favicon.svg +1 -7
- package/dist/dashboard/index.html +4 -4
- package/dist/{dist-ZPXEVBEC.js → dist-37VQSHHA.js} +24 -2
- package/dist/dist-37VQSHHA.js.map +1 -0
- package/dist/{doctor-7RUD4D3A.js → doctor-PYUQRRCB.js} +5 -5
- package/dist/{goal-JFRNPBSD.js → goal-SXZUDUCL.js} +5 -5
- package/dist/index.js +48 -30
- package/dist/index.js.map +1 -1
- package/dist/{init-NFYNO3A3.js → init-Z2AFQEEP.js} +6 -6
- package/dist/{prompts-L37J72YW.js → prompts-TZ7UC42M.js} +9 -5
- package/dist/prompts-TZ7UC42M.js.map +1 -0
- package/dist/{run-ARUPXFFB.js → run-AOS7L3RT.js} +10 -10
- package/dist/runtime.js +18 -0
- package/dist/runtime.js.map +1 -0
- package/dist/{start-CFPOVIAR.js → start-CEPXKZUE.js} +5 -5
- package/dist/{status-E4EACVE2.js → status-WNJ3GGKU.js} +6 -6
- package/dist/status-WNJ3GGKU.js.map +1 -0
- package/dist/{tasks-ZIK6BVEX.js → tasks-TFUTUMWB.js} +6 -6
- package/package.json +21 -15
- package/dist/ChatApp-FO5SABXB.js.map +0 -1
- package/dist/accounts-MTMGYKEP.js.map +0 -1
- package/dist/chat-ZDXX3N6X.js +0 -95
- package/dist/chat-ZDXX3N6X.js.map +0 -1
- package/dist/chunk-C7FDRA3U.js.map +0 -1
- package/dist/chunk-DYQ56FBT.js +0 -47
- package/dist/chunk-DYQ56FBT.js.map +0 -1
- package/dist/chunk-PIIJ3RSI.js.map +0 -1
- package/dist/chunk-VVCXGQMY.js.map +0 -1
- package/dist/dashboard/assets/Accounts-BR3ZfVk4.js +0 -1
- package/dist/dashboard/assets/Badge-B-qzNRrZ.js +0 -55
- package/dist/dashboard/assets/Callout-B9g_wPDi.js +0 -1
- package/dist/dashboard/assets/Field-BfabPEcY.js +0 -1
- package/dist/dashboard/assets/Goals-BsV-6m94.js +0 -1
- package/dist/dashboard/assets/Library-CEA9P1m-.js +0 -1
- package/dist/dashboard/assets/Panel-B9tSgX6l.js +0 -1
- package/dist/dashboard/assets/RoutesPage-Dh-BJ3ir.js +0 -4
- package/dist/dashboard/assets/Runner-C_e9l5l2.js +0 -1
- package/dist/dashboard/assets/Settings-C6Yc1Gjg.js +0 -1
- package/dist/dashboard/assets/Switch-CUpOJjUT.js +0 -1
- package/dist/dashboard/assets/Tasks-CTku0rR3.js +0 -2
- package/dist/dashboard/assets/Traffic-CE6wZSMr.js +0 -1
- package/dist/dashboard/assets/Workspace-CxFxvkA6.js +0 -1
- package/dist/dashboard/assets/arrow-up-DL3CuFOO.js +0 -1
- package/dist/dashboard/assets/forms-D6UIYgC5.js +0 -1
- package/dist/dashboard/assets/index-1iH716Xy.css +0 -2
- package/dist/dashboard/assets/index-BMWr9EKo.js +0 -104
- package/dist/dashboard/assets/task-errors-CE4oEr8H.js +0 -1
- package/dist/dashboard/assets/trash-CWqeZ7eg.js +0 -1
- package/dist/prompts-L37J72YW.js.map +0 -1
- /package/dist/{RunnerView-DLVR7C22.js.map → RunnerView-A7JSPUW5.js.map} +0 -0
- /package/dist/{dist-ZPXEVBEC.js.map → account-QWDPJWAA.js.map} +0 -0
- /package/dist/{status-E4EACVE2.js.map → accounts-IQMR72FC.js.map} +0 -0
- /package/dist/{budget-RBHCEDPP.js.map → budget-XANOUVWO.js.map} +0 -0
- /package/dist/{chunk-BOLFK3BH.js.map → chunk-5LKOJBUL.js.map} +0 -0
- /package/dist/{chunk-23KTE7IK.js.map → chunk-AZKACMME.js.map} +0 -0
- /package/dist/{chunk-OYEYNDOO.js.map → chunk-GE22VBCY.js.map} +0 -0
- /package/dist/{chunk-MSLLH5XP.js.map → chunk-PGAJIGUF.js.map} +0 -0
- /package/dist/{chunk-OXRMGR72.js.map → chunk-PGPXE6LF.js.map} +0 -0
- /package/dist/{chunk-IVZHKUCD.js.map → chunk-WQ7MEWDF.js.map} +0 -0
- /package/dist/{config-FRMY5OHG.js.map → config-YTUPIYZT.js.map} +0 -0
- /package/dist/{doctor-7RUD4D3A.js.map → doctor-PYUQRRCB.js.map} +0 -0
- /package/dist/{goal-JFRNPBSD.js.map → goal-SXZUDUCL.js.map} +0 -0
- /package/dist/{init-NFYNO3A3.js.map → init-Z2AFQEEP.js.map} +0 -0
- /package/dist/{run-ARUPXFFB.js.map → run-AOS7L3RT.js.map} +0 -0
- /package/dist/{start-CFPOVIAR.js.map → start-CEPXKZUE.js.map} +0 -0
- /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 {
|
|
115
|
-
import {
|
|
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(
|
|
548
|
-
await mkdir(dirname(
|
|
549
|
-
const 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,
|
|
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(
|
|
576
|
+
async function readFileIfExists(path8) {
|
|
568
577
|
try {
|
|
569
|
-
return await readFile(
|
|
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(
|
|
1010
|
+
async function readLockInfo(path8) {
|
|
1002
1011
|
try {
|
|
1003
|
-
const parsed = JSON.parse(await readFile2(
|
|
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(
|
|
1012
|
-
const info = await readLockInfo(
|
|
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(
|
|
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(
|
|
1071
|
+
async function exists(path8) {
|
|
1063
1072
|
try {
|
|
1064
|
-
await access(
|
|
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(
|
|
1124
|
-
super(`Missing project brain file: ${
|
|
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 [
|
|
1163
|
-
if (!await exists(
|
|
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(
|
|
1276
|
-
const content = await readFileIfExists(
|
|
1284
|
+
async readText(path8) {
|
|
1285
|
+
const content = await readFileIfExists(path8);
|
|
1277
1286
|
if (content === void 0) {
|
|
1278
|
-
throw new MissingBrainError(
|
|
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(
|
|
1486
|
+
function readLayer(path8) {
|
|
1477
1487
|
let raw;
|
|
1478
1488
|
try {
|
|
1479
|
-
raw = readFileSync(
|
|
1489
|
+
raw = readFileSync(path8, "utf8");
|
|
1480
1490
|
} catch (err) {
|
|
1481
1491
|
if (err.code === "ENOENT") return void 0;
|
|
1482
|
-
throw new ConfigError(
|
|
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(
|
|
1498
|
+
throw new ConfigError(path8, `malformed JSON: ${err.message}`, { cause: err });
|
|
1489
1499
|
}
|
|
1490
|
-
if (!isPlainObject(parsed)) throw new ConfigError(
|
|
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(
|
|
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
|
|
1574
|
+
const path8 = globalPaths(home).config;
|
|
1565
1575
|
return withFileLock(
|
|
1566
|
-
`${
|
|
1576
|
+
`${path8}.lock`,
|
|
1567
1577
|
async () => {
|
|
1568
1578
|
let current = {};
|
|
1569
1579
|
try {
|
|
1570
|
-
const parsed = JSON.parse(await readFile3(
|
|
1571
|
-
if (!isPlainObject2(parsed)) throw new ConfigError(
|
|
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(
|
|
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(
|
|
1592
|
-
await atomicWriteFile(
|
|
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:
|
|
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,
|
|
1684
|
-
return `${base.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(
|
|
2502
|
-
return isShellSafeArg(
|
|
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 (!
|
|
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") ??
|
|
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
|
|
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 (!
|
|
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") ??
|
|
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
|
|
3487
|
+
var SAFE_MODEL4 = /^[\w.:[\]-]+$/;
|
|
3365
3488
|
function geminiCliEnv(sandboxDir) {
|
|
3366
3489
|
return {
|
|
3367
|
-
...geminiHomeEnv(
|
|
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 && !
|
|
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") ??
|
|
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.
|
|
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
|
-
"
|
|
4293
|
-
|
|
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(
|
|
5376
|
-
if (
|
|
5377
|
-
const db = new BetterSqlite3(
|
|
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 =
|
|
5632
|
-
env[key] = 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 =
|
|
5799
|
-
return rel === "" || rel !== ".." && !rel.startsWith(`..${
|
|
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 ?
|
|
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 =
|
|
5970
|
+
const parent = path7.dirname(current);
|
|
5812
5971
|
if (parent === current) return target;
|
|
5813
|
-
missing.push(
|
|
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 =
|
|
5821
|
-
const abs =
|
|
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 =
|
|
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) =>
|
|
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 =
|
|
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(
|
|
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 =
|
|
6135
|
-
if (ignored(rel,
|
|
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 =
|
|
6157
|
-
const rel =
|
|
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(
|
|
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
|
|
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 (!
|
|
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 =
|
|
7986
|
-
id:
|
|
7987
|
-
title:
|
|
7988
|
-
description:
|
|
7989
|
-
role:
|
|
7990
|
-
kind:
|
|
7991
|
-
dependsOn:
|
|
7992
|
-
acceptance:
|
|
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 =
|
|
7995
|
-
summary:
|
|
7996
|
-
tasks:
|
|
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 =
|
|
8508
|
+
var reviewSchema = z10.object({
|
|
7999
8509
|
/** The objective is achieved as far as DaveCode can take it. */
|
|
8000
|
-
done:
|
|
8001
|
-
summary:
|
|
8510
|
+
done: z10.boolean(),
|
|
8511
|
+
summary: z10.string().max(8e3),
|
|
8002
8512
|
/** Ids of FAILED tasks worth another attempt. */
|
|
8003
|
-
retry:
|
|
8513
|
+
retry: z10.array(z10.string()).max(50).default([]),
|
|
8004
8514
|
/** New tasks for the next round. */
|
|
8005
|
-
tasks:
|
|
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 =
|
|
8770
|
-
id:
|
|
8771
|
-
title:
|
|
8772
|
-
description:
|
|
8773
|
-
role:
|
|
8774
|
-
kind:
|
|
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:
|
|
8777
|
-
acceptance:
|
|
8778
|
-
round:
|
|
8779
|
-
attempts:
|
|
8780
|
-
artifact:
|
|
8781
|
-
runnerTaskId:
|
|
8782
|
-
notes:
|
|
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 =
|
|
8785
|
-
id:
|
|
8786
|
-
objective:
|
|
8787
|
-
status:
|
|
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:
|
|
8798
|
-
limits:
|
|
8799
|
-
maxRounds:
|
|
8800
|
-
maxTasks:
|
|
8801
|
-
maxTokens:
|
|
8802
|
-
tokensUsed:
|
|
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:
|
|
8805
|
-
|
|
9314
|
+
roles: z11.array(
|
|
9315
|
+
z11.object({ id: z11.string(), description: z11.string(), route: z11.string().optional() })
|
|
8806
9316
|
),
|
|
8807
|
-
tasks:
|
|
8808
|
-
activeTaskId:
|
|
8809
|
-
summary:
|
|
8810
|
-
lastError:
|
|
8811
|
-
dryRun:
|
|
8812
|
-
createdAt:
|
|
8813
|
-
updatedAt:
|
|
8814
|
-
finishedAt:
|
|
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 =
|
|
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
|
|
9338
|
+
return join7(this.dir, id);
|
|
8829
9339
|
}
|
|
8830
9340
|
async save(goal) {
|
|
8831
9341
|
await atomicWriteFile(
|
|
8832
|
-
|
|
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(
|
|
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
|
|
8866
|
-
await atomicWriteFile(
|
|
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,
|
|
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(
|
|
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-
|
|
9608
|
+
//# sourceMappingURL=chunk-HSBJDV3O.js.map
|