@dmrlzz/davecode 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChatApp-CJBICQGA.js → ChatApp-Z6PQIZ5J.js} +7 -6
- package/dist/{ChatApp-CJBICQGA.js.map → ChatApp-Z6PQIZ5J.js.map} +1 -1
- package/dist/{account-QWDPJWAA.js → account-RTPS2V6O.js} +4 -3
- package/dist/{accounts-IQMR72FC.js → accounts-IYQ4ZRL7.js} +6 -5
- package/dist/{budget-XANOUVWO.js → budget-N2ZB66FF.js} +5 -4
- package/dist/{budget-XANOUVWO.js.map → budget-N2ZB66FF.js.map} +1 -1
- package/dist/{chat-KDDRNC5V.js → chat-6TX6JX45.js} +9 -8
- package/dist/{chat-KDDRNC5V.js.map → chat-6TX6JX45.js.map} +1 -1
- package/dist/chunk-732GIHRQ.js +23 -0
- package/dist/chunk-732GIHRQ.js.map +1 -0
- package/dist/{chunk-AZKACMME.js → chunk-BJTXMET2.js} +2 -2
- package/dist/{chunk-FYPMA55O.js → chunk-KUY3QHGS.js} +239 -106
- package/dist/chunk-KUY3QHGS.js.map +1 -0
- package/dist/{chunk-JLATEHS7.js → chunk-LEU46DGH.js} +2 -2
- package/dist/{chunk-HSBJDV3O.js → chunk-QKY3OKVG.js} +309 -23
- package/dist/chunk-QKY3OKVG.js.map +1 -0
- package/dist/{chunk-WQ7MEWDF.js → chunk-UEV5K3DH.js} +10 -4
- package/dist/chunk-UEV5K3DH.js.map +1 -0
- package/dist/{chunk-44AFJL2X.js → chunk-UNK3EQD6.js} +6 -5
- package/dist/chunk-UNK3EQD6.js.map +1 -0
- package/dist/{chunk-W7GPBEBZ.js → chunk-WAARDGCZ.js} +5 -21
- package/dist/chunk-WAARDGCZ.js.map +1 -0
- package/dist/{chunk-PGAJIGUF.js → chunk-YNAMNQLW.js} +3 -3
- package/dist/{config-YTUPIYZT.js → config-YQKY2AA4.js} +4 -3
- package/dist/{config-YTUPIYZT.js.map → config-YQKY2AA4.js.map} +1 -1
- package/dist/dashboard/assets/Accounts-DXiGsutB.js +1 -0
- package/dist/dashboard/assets/{Badge-Z4RBdO9j.js → Badge-DUGKlx3Z.js} +1 -1
- package/dist/dashboard/assets/{Callout-w8BTYh4k.js → Callout-1E8Wsl9W.js} +1 -1
- package/dist/dashboard/assets/{Goals-Bw02to72.js → Goals-kL4VAxw3.js} +1 -1
- package/dist/dashboard/assets/{Library-DK7mlpRb.js → Library-DZxBVUo_.js} +1 -1
- package/dist/dashboard/assets/Markdown-CGgIydUh.js +71 -0
- package/dist/dashboard/assets/{Panes-_KTf8pbZ.js → Panes-C-TJekjs.js} +1 -1
- package/dist/dashboard/assets/{RoutesPage-QV0oPRW9.js → RoutesPage-DWYm9tW8.js} +1 -1
- package/dist/dashboard/assets/{Runner-CkHBLQl0.js → Runner-CmHBjECR.js} +1 -1
- package/dist/dashboard/assets/{Settings-BLz2gTBR.js → Settings-BANphxva.js} +1 -1
- package/dist/dashboard/assets/{Tasks-BiUQSTpt.js → Tasks-cSx1PKyQ.js} +1 -1
- package/dist/dashboard/assets/{Traffic-BVfBuC70.js → Traffic-DEAuM6jq.js} +1 -1
- package/dist/dashboard/assets/{Workspace-CJTgiiU5.js → Workspace-BQFjc1jH.js} +1 -1
- package/dist/dashboard/assets/index-B8kld9xo.js +104 -0
- package/dist/dashboard/assets/{task-errors-Daqwi0ue.js → task-errors-r-WYZ_S3.js} +1 -1
- package/dist/dashboard/index.html +2 -2
- package/dist/{dist-37VQSHHA.js → dist-PIC255RX.js} +20 -2
- package/dist/{doctor-PYUQRRCB.js → doctor-PQC7JQPP.js} +4 -3
- package/dist/{doctor-PYUQRRCB.js.map → doctor-PQC7JQPP.js.map} +1 -1
- package/dist/{goal-SXZUDUCL.js → goal-STLEU7C7.js} +4 -3
- package/dist/{goal-SXZUDUCL.js.map → goal-STLEU7C7.js.map} +1 -1
- package/dist/index.js +31 -31
- package/dist/{init-Z2AFQEEP.js → init-NHU5LJSS.js} +4 -3
- package/dist/{init-Z2AFQEEP.js.map → init-NHU5LJSS.js.map} +1 -1
- package/dist/{run-AOS7L3RT.js → run-7HWSHMRJ.js} +4 -3
- package/dist/{run-AOS7L3RT.js.map → run-7HWSHMRJ.js.map} +1 -1
- package/dist/runtime.js +3 -2
- package/dist/{start-CEPXKZUE.js → start-WVAEAQWL.js} +4 -3
- package/dist/{start-CEPXKZUE.js.map → start-WVAEAQWL.js.map} +1 -1
- package/dist/{status-WNJ3GGKU.js → status-ZRHPFLFT.js} +5 -4
- package/dist/{tasks-TFUTUMWB.js → tasks-JVWXUNXN.js} +5 -4
- package/dist/{tasks-TFUTUMWB.js.map → tasks-JVWXUNXN.js.map} +1 -1
- package/package.json +6 -6
- package/dist/chunk-44AFJL2X.js.map +0 -1
- package/dist/chunk-FYPMA55O.js.map +0 -1
- package/dist/chunk-HSBJDV3O.js.map +0 -1
- package/dist/chunk-W7GPBEBZ.js.map +0 -1
- package/dist/chunk-WQ7MEWDF.js.map +0 -1
- package/dist/dashboard/assets/Accounts-cq8RLMoI.js +0 -1
- package/dist/dashboard/assets/Markdown-DCZ4Awcc.js +0 -69
- package/dist/dashboard/assets/index-BDBa5cb0.js +0 -104
- /package/dist/{account-QWDPJWAA.js.map → account-RTPS2V6O.js.map} +0 -0
- /package/dist/{accounts-IQMR72FC.js.map → accounts-IYQ4ZRL7.js.map} +0 -0
- /package/dist/{chunk-AZKACMME.js.map → chunk-BJTXMET2.js.map} +0 -0
- /package/dist/{chunk-JLATEHS7.js.map → chunk-LEU46DGH.js.map} +0 -0
- /package/dist/{chunk-PGAJIGUF.js.map → chunk-YNAMNQLW.js.map} +0 -0
- /package/dist/{dist-37VQSHHA.js.map → dist-PIC255RX.js.map} +0 -0
- /package/dist/{status-WNJ3GGKU.js.map → status-ZRHPFLFT.js.map} +0 -0
|
@@ -116,7 +116,7 @@ import { z as z8 } from "zod";
|
|
|
116
116
|
import { randomBytes as randomBytes7 } from "crypto";
|
|
117
117
|
import { createServer } from "http";
|
|
118
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";
|
|
119
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync3, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
120
120
|
import { dirname as dirname6, join as join6 } from "path";
|
|
121
121
|
import { z as z9 } from "zod";
|
|
122
122
|
import { z as z10 } from "zod";
|
|
@@ -155,6 +155,8 @@ var ENDPOINTS = {
|
|
|
155
155
|
}
|
|
156
156
|
};
|
|
157
157
|
var PENDING_MS = 10 * 6e4;
|
|
158
|
+
var PENDING_MAX = 1e3;
|
|
159
|
+
var PENDING_PER_PEER = 20;
|
|
158
160
|
var SESSION_MS = 8 * 60 * 6e4;
|
|
159
161
|
var random = () => randomBytes(32).toString("base64url");
|
|
160
162
|
var digest = (value) => createHash("sha256").update(value).digest("base64url");
|
|
@@ -200,10 +202,29 @@ var LoginService = class {
|
|
|
200
202
|
logout(session) {
|
|
201
203
|
if (session) this.sessions.delete(digest(session));
|
|
202
204
|
}
|
|
203
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Start a sign-in. `peer` is the connection's address as the HTTP server sees it (never a
|
|
207
|
+
* forwarded header unless the server was configured to trust its proxy). Unfinished sign-ins
|
|
208
|
+
* never block a new one: each peer keeps a few, and when the table is full the oldest goes.
|
|
209
|
+
*/
|
|
210
|
+
begin(provider, peer = "unknown") {
|
|
204
211
|
this.prune();
|
|
205
212
|
const client = this.options.providers[provider];
|
|
206
|
-
if (!client
|
|
213
|
+
if (!client) throw new LoginError();
|
|
214
|
+
let mine = 0;
|
|
215
|
+
for (const value of this.pending.values()) if (value.peer === peer) mine++;
|
|
216
|
+
for (const [key, value] of this.pending) {
|
|
217
|
+
if (mine < PENDING_PER_PEER) break;
|
|
218
|
+
if (value.peer === peer) {
|
|
219
|
+
this.pending.delete(key);
|
|
220
|
+
mine--;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
while (this.pending.size >= PENDING_MAX) {
|
|
224
|
+
const oldest = this.pending.keys().next().value;
|
|
225
|
+
if (oldest === void 0) break;
|
|
226
|
+
this.pending.delete(oldest);
|
|
227
|
+
}
|
|
207
228
|
const state = random();
|
|
208
229
|
const binding = random();
|
|
209
230
|
const verifier = random();
|
|
@@ -211,6 +232,7 @@ var LoginService = class {
|
|
|
211
232
|
provider,
|
|
212
233
|
binding: digest(binding),
|
|
213
234
|
verifier,
|
|
235
|
+
peer,
|
|
214
236
|
expires: this.now() + PENDING_MS
|
|
215
237
|
});
|
|
216
238
|
const url = new URL(ENDPOINTS[provider].authorize);
|
|
@@ -1471,6 +1493,53 @@ ${message}`, options);
|
|
|
1471
1493
|
this.source = source;
|
|
1472
1494
|
}
|
|
1473
1495
|
};
|
|
1496
|
+
var PROJECT_SETTABLE_KEYS = {
|
|
1497
|
+
logLevel: true,
|
|
1498
|
+
routing: true,
|
|
1499
|
+
goal: true,
|
|
1500
|
+
runner: {
|
|
1501
|
+
maxRepairCycles: true,
|
|
1502
|
+
branchPrefix: true,
|
|
1503
|
+
baseBranch: true,
|
|
1504
|
+
route: true,
|
|
1505
|
+
executor: true,
|
|
1506
|
+
pullRequests: true,
|
|
1507
|
+
commitBrain: true,
|
|
1508
|
+
commandTimeoutMs: true,
|
|
1509
|
+
idlePollMs: true,
|
|
1510
|
+
maxIterations: true,
|
|
1511
|
+
maxTaskTokens: true,
|
|
1512
|
+
validate: true,
|
|
1513
|
+
claudeCli: { accountId: true, model: true, timeoutMs: true },
|
|
1514
|
+
judge: { kind: true, model: true, threshold: true }
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
function filterProjectLayer(layer) {
|
|
1518
|
+
const dropped = [];
|
|
1519
|
+
const walk = (value, tree, prefix) => {
|
|
1520
|
+
const out = {};
|
|
1521
|
+
for (const [key, v] of Object.entries(value)) {
|
|
1522
|
+
const rule = Object.hasOwn(tree, key) ? tree[key] : void 0;
|
|
1523
|
+
const path8 = prefix ? `${prefix}.${key}` : key;
|
|
1524
|
+
if (rule === true) {
|
|
1525
|
+
out[key] = v;
|
|
1526
|
+
} else if (rule && isPlainObject(v)) {
|
|
1527
|
+
const inner = walk(v, rule, path8);
|
|
1528
|
+
if (Object.keys(inner).length > 0) out[key] = inner;
|
|
1529
|
+
} else {
|
|
1530
|
+
dropped.push(path8);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
return out;
|
|
1534
|
+
};
|
|
1535
|
+
return { allowed: walk(layer, PROJECT_SETTABLE_KEYS, ""), dropped };
|
|
1536
|
+
}
|
|
1537
|
+
var warned = /* @__PURE__ */ new Set();
|
|
1538
|
+
function defaultWarn(message) {
|
|
1539
|
+
if (warned.has(message)) return;
|
|
1540
|
+
warned.add(message);
|
|
1541
|
+
process.emitWarning(message, "DaveCodeConfigWarning");
|
|
1542
|
+
}
|
|
1474
1543
|
function isPlainObject(value) {
|
|
1475
1544
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1476
1545
|
}
|
|
@@ -1483,7 +1552,7 @@ function deepMerge(base, override) {
|
|
|
1483
1552
|
}
|
|
1484
1553
|
return out;
|
|
1485
1554
|
}
|
|
1486
|
-
function readLayer(path8) {
|
|
1555
|
+
function readLayer(path8, project) {
|
|
1487
1556
|
let raw;
|
|
1488
1557
|
try {
|
|
1489
1558
|
raw = readFileSync(path8, "utf8");
|
|
@@ -1498,9 +1567,15 @@ function readLayer(path8) {
|
|
|
1498
1567
|
throw new ConfigError(path8, `malformed JSON: ${err.message}`, { cause: err });
|
|
1499
1568
|
}
|
|
1500
1569
|
if (!isPlainObject(parsed)) throw new ConfigError(path8, "expected a JSON object");
|
|
1501
|
-
|
|
1570
|
+
let layer = parsed;
|
|
1571
|
+
if (project) {
|
|
1572
|
+
const { allowed, dropped } = filterProjectLayer(parsed);
|
|
1573
|
+
if (dropped.length > 0) project(dropped);
|
|
1574
|
+
layer = allowed;
|
|
1575
|
+
}
|
|
1576
|
+
const result = configSchema.safeParse(layer);
|
|
1502
1577
|
if (!result.success) throw new ConfigError(path8, z4.prettifyError(result.error));
|
|
1503
|
-
return
|
|
1578
|
+
return layer;
|
|
1504
1579
|
}
|
|
1505
1580
|
var TRUE_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
|
|
1506
1581
|
var FALSE_VALUES = /* @__PURE__ */ new Set(["0", "false", "no", "off", ""]);
|
|
@@ -1558,7 +1633,14 @@ function loadConfig(options = {}) {
|
|
|
1558
1633
|
const globalLayer = readLayer(globalPaths(home).config);
|
|
1559
1634
|
if (globalLayer) merged = deepMerge(merged, globalLayer);
|
|
1560
1635
|
if (options.projectRoot) {
|
|
1561
|
-
const
|
|
1636
|
+
const projectFile = projectPaths(options.projectRoot).config;
|
|
1637
|
+
const warn = options.onWarning ?? defaultWarn;
|
|
1638
|
+
const projectLayer = readLayer(
|
|
1639
|
+
projectFile,
|
|
1640
|
+
(dropped) => warn(
|
|
1641
|
+
`Ignored ${dropped.join(", ")} in ${projectFile}: project config cannot set these keys. Set them in your user config (~/.davecode/config.json) or with DAVECODE_* environment variables.`
|
|
1642
|
+
)
|
|
1643
|
+
);
|
|
1562
1644
|
if (projectLayer) merged = deepMerge(merged, projectLayer);
|
|
1563
1645
|
}
|
|
1564
1646
|
merged = deepMerge(merged, envLayer(env));
|
|
@@ -3875,6 +3957,76 @@ function createProviders(options = {}) {
|
|
|
3875
3957
|
];
|
|
3876
3958
|
return new Map(providers.map((p) => [p.kind, p]));
|
|
3877
3959
|
}
|
|
3960
|
+
var ENDPOINT_CONFIG_KEYS = ["baseUrl"];
|
|
3961
|
+
var MODEL_KEYS = ["models", "defaultModel"];
|
|
3962
|
+
var API_CONFIG_KEYS = {
|
|
3963
|
+
anthropic: ["baseUrl", ...MODEL_KEYS],
|
|
3964
|
+
openai: ["baseUrl", "includeUsage", ...MODEL_KEYS],
|
|
3965
|
+
gemini: ["baseUrl", ...MODEL_KEYS],
|
|
3966
|
+
"openai-compatible": ["baseUrl", "includeUsage", ...MODEL_KEYS],
|
|
3967
|
+
"claude-cli": [...MODEL_KEYS],
|
|
3968
|
+
"codex-cli": [...MODEL_KEYS],
|
|
3969
|
+
"gemini-cli": [...MODEL_KEYS],
|
|
3970
|
+
"antigravity-cli": [...MODEL_KEYS],
|
|
3971
|
+
"gemini-web": ["models"]
|
|
3972
|
+
};
|
|
3973
|
+
function isStringList(value) {
|
|
3974
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string" && v.length > 0);
|
|
3975
|
+
}
|
|
3976
|
+
function apiConfigIssues(provider, config, existing = {}) {
|
|
3977
|
+
const allowed = API_CONFIG_KEYS[provider];
|
|
3978
|
+
const issues = [];
|
|
3979
|
+
for (const [key, value] of Object.entries(config)) {
|
|
3980
|
+
if (!allowed.includes(key)) {
|
|
3981
|
+
if (key in existing && JSON.stringify(existing[key]) === JSON.stringify(value)) continue;
|
|
3982
|
+
issues.push(
|
|
3983
|
+
`config.${key} cannot be set through the API for ${provider} accounts` + (allowed.length > 0 ? ` (allowed: ${allowed.join(", ")})` : "")
|
|
3984
|
+
);
|
|
3985
|
+
continue;
|
|
3986
|
+
}
|
|
3987
|
+
if (key === "baseUrl") {
|
|
3988
|
+
if (typeof value !== "string" || !isHttpUrl(value)) {
|
|
3989
|
+
issues.push("config.baseUrl must be an http(s) URL without embedded credentials");
|
|
3990
|
+
}
|
|
3991
|
+
} else if (key === "models") {
|
|
3992
|
+
if (!isStringList(value)) issues.push("config.models must be a list of model ids");
|
|
3993
|
+
} else if (key === "defaultModel") {
|
|
3994
|
+
if (typeof value !== "string" || !value) issues.push("config.defaultModel must be a string");
|
|
3995
|
+
} else if (key === "includeUsage" && typeof value !== "boolean") {
|
|
3996
|
+
issues.push("config.includeUsage must be true or false");
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
return issues;
|
|
4000
|
+
}
|
|
4001
|
+
function isHttpUrl(value) {
|
|
4002
|
+
try {
|
|
4003
|
+
const url = new URL(value);
|
|
4004
|
+
return (url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password;
|
|
4005
|
+
} catch {
|
|
4006
|
+
return false;
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
function mergeApiConfig(provider, existing, incoming) {
|
|
4010
|
+
const allowed = API_CONFIG_KEYS[provider];
|
|
4011
|
+
const kept = Object.fromEntries(
|
|
4012
|
+
Object.entries(existing).filter(([key]) => !allowed.includes(key))
|
|
4013
|
+
);
|
|
4014
|
+
return { ...kept, ...incoming };
|
|
4015
|
+
}
|
|
4016
|
+
function endpointOf(config) {
|
|
4017
|
+
return ENDPOINT_CONFIG_KEYS.map((key) => {
|
|
4018
|
+
const value = config[key];
|
|
4019
|
+
return typeof value === "string" ? value.trim().replace(/\/+$/, "") : "";
|
|
4020
|
+
}).join("\n");
|
|
4021
|
+
}
|
|
4022
|
+
function endpointChanged(existing, next) {
|
|
4023
|
+
return endpointOf(existing) !== endpointOf(next);
|
|
4024
|
+
}
|
|
4025
|
+
function endpointRebindIssue(existing, nextConfig, secretSupplied) {
|
|
4026
|
+
if (!nextConfig || secretSupplied || !existing.hasSecret) return void 0;
|
|
4027
|
+
if (!endpointChanged(existing.config, nextConfig)) return void 0;
|
|
4028
|
+
return "Changing the endpoint of an account that has a stored secret requires sending the secret again in the same request";
|
|
4029
|
+
}
|
|
3878
4030
|
var EXPERIMENTAL_PROVIDER_KINDS = ["gemini-web"];
|
|
3879
4031
|
var SUBSCRIPTION_PROVIDER_KINDS = [
|
|
3880
4032
|
"claude-cli",
|
|
@@ -3883,7 +4035,7 @@ var SUBSCRIPTION_PROVIDER_KINDS = [
|
|
|
3883
4035
|
"antigravity-cli",
|
|
3884
4036
|
"gemini-web"
|
|
3885
4037
|
];
|
|
3886
|
-
var VERSION = "0.5.
|
|
4038
|
+
var VERSION = "0.5.2";
|
|
3887
4039
|
var QUOTA_WINDOWS = ["1m", "5h", "24h"];
|
|
3888
4040
|
var WINDOW_MS = {
|
|
3889
4041
|
"1m": 6e4,
|
|
@@ -8070,12 +8222,14 @@ function accountService(env = process.env) {
|
|
|
8070
8222
|
}
|
|
8071
8223
|
var OAUTH_PROVIDERS = ["google", "github"];
|
|
8072
8224
|
var AccountError = class extends Error {
|
|
8073
|
-
constructor(message, status) {
|
|
8225
|
+
constructor(message, status, code) {
|
|
8074
8226
|
super(message);
|
|
8075
8227
|
this.status = status;
|
|
8228
|
+
this.code = code;
|
|
8076
8229
|
this.name = "AccountError";
|
|
8077
8230
|
}
|
|
8078
8231
|
status;
|
|
8232
|
+
code;
|
|
8079
8233
|
};
|
|
8080
8234
|
var userSchema = z8.object({
|
|
8081
8235
|
id: z8.string().min(1),
|
|
@@ -8211,7 +8365,8 @@ var AccountClient = class {
|
|
|
8211
8365
|
const detail = error.success ? error.data.error_description ?? error.data.msg ?? error.data.message : void 0;
|
|
8212
8366
|
throw new AccountError(
|
|
8213
8367
|
detail ?? `Sign-in failed (HTTP ${response.status}).`,
|
|
8214
|
-
response.status
|
|
8368
|
+
response.status,
|
|
8369
|
+
error.success ? error.data.error : void 0
|
|
8215
8370
|
);
|
|
8216
8371
|
}
|
|
8217
8372
|
return raw;
|
|
@@ -8287,8 +8442,9 @@ async function startAccountLogin(options) {
|
|
|
8287
8442
|
() => setTimeout(() => void close(), 1e3).unref(),
|
|
8288
8443
|
() => setTimeout(() => void close(), 1e3).unref()
|
|
8289
8444
|
);
|
|
8445
|
+
const redirectTo = `http://127.0.0.1:${port}${callbackPath}`;
|
|
8290
8446
|
return {
|
|
8291
|
-
url: client.
|
|
8447
|
+
url: options.provider ? client.authorizeUrl(options.provider, redirectTo, pkce.challenge) : client.loginUrl(redirectTo, pkce.challenge),
|
|
8292
8448
|
session,
|
|
8293
8449
|
close: async () => {
|
|
8294
8450
|
clearTimeout(timeout);
|
|
@@ -8299,6 +8455,16 @@ async function startAccountLogin(options) {
|
|
|
8299
8455
|
}
|
|
8300
8456
|
var AAD = Buffer.from("davecode-account", "utf8");
|
|
8301
8457
|
var REFRESH_MARGIN_MS = 6e4;
|
|
8458
|
+
var LOCK_STALE_MS = 6e4;
|
|
8459
|
+
var LOCK_WAIT_MS = 3e4;
|
|
8460
|
+
var LOCK_POLL_MS = 50;
|
|
8461
|
+
var INVALID_TOKEN_CODES = /* @__PURE__ */ new Set([
|
|
8462
|
+
"invalid_grant",
|
|
8463
|
+
"refresh_token_not_found",
|
|
8464
|
+
"refresh_token_already_used",
|
|
8465
|
+
"session_not_found",
|
|
8466
|
+
"session_expired"
|
|
8467
|
+
]);
|
|
8302
8468
|
var fileSchema = z9.object({
|
|
8303
8469
|
v: z9.literal(1),
|
|
8304
8470
|
iv: z9.string(),
|
|
@@ -8375,22 +8541,133 @@ var AccountStore = class {
|
|
|
8375
8541
|
* or when the service revoked the session; offline, an unexpired session is still returned.
|
|
8376
8542
|
*/
|
|
8377
8543
|
async current(client, now = Date.now()) {
|
|
8378
|
-
const
|
|
8379
|
-
if (!
|
|
8380
|
-
if (
|
|
8544
|
+
const first = this.load();
|
|
8545
|
+
if (!first) return void 0;
|
|
8546
|
+
if (first.expiresAt - REFRESH_MARGIN_MS > now) return first;
|
|
8547
|
+
const release = await this.lock();
|
|
8381
8548
|
try {
|
|
8382
|
-
const
|
|
8383
|
-
|
|
8384
|
-
return
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
this.
|
|
8388
|
-
return
|
|
8549
|
+
const session = this.load();
|
|
8550
|
+
if (!session) return void 0;
|
|
8551
|
+
if (session.expiresAt - REFRESH_MARGIN_MS > now) return session;
|
|
8552
|
+
try {
|
|
8553
|
+
const fresh = await client.refresh(session.refreshToken);
|
|
8554
|
+
this.save(fresh);
|
|
8555
|
+
return fresh;
|
|
8556
|
+
} catch (err) {
|
|
8557
|
+
if (isInvalidToken(err)) {
|
|
8558
|
+
if (this.load()?.refreshToken === session.refreshToken) this.clear();
|
|
8559
|
+
return this.load();
|
|
8560
|
+
}
|
|
8561
|
+
return session;
|
|
8389
8562
|
}
|
|
8390
|
-
|
|
8563
|
+
} finally {
|
|
8564
|
+
release();
|
|
8565
|
+
}
|
|
8566
|
+
}
|
|
8567
|
+
/**
|
|
8568
|
+
* A cross-process lock: a file created exclusively next to account.json. A lock older than
|
|
8569
|
+
* LOCK_STALE_MS belongs to a process that died, and is taken over. After LOCK_WAIT_MS the
|
|
8570
|
+
* refresh goes ahead without it (the service tolerates two refreshes racing).
|
|
8571
|
+
*/
|
|
8572
|
+
async lock() {
|
|
8573
|
+
const path8 = `${this.path}.lock`;
|
|
8574
|
+
const owner = `${process.pid}:${randomBytes8(8).toString("hex")}`;
|
|
8575
|
+
mkdirSync7(dirname6(path8), { recursive: true });
|
|
8576
|
+
const deadline = Date.now() + LOCK_WAIT_MS;
|
|
8577
|
+
for (; ; ) {
|
|
8578
|
+
try {
|
|
8579
|
+
writeFileSync3(path8, owner, { flag: "wx", mode: 384 });
|
|
8580
|
+
return () => {
|
|
8581
|
+
try {
|
|
8582
|
+
if (readFileSync3(path8, "utf8") === owner) rmSync3(path8, { force: true });
|
|
8583
|
+
} catch {
|
|
8584
|
+
}
|
|
8585
|
+
};
|
|
8586
|
+
} catch (err) {
|
|
8587
|
+
if (err.code !== "EEXIST" && !isWindowsBusy(err))
|
|
8588
|
+
return () => void 0;
|
|
8589
|
+
}
|
|
8590
|
+
try {
|
|
8591
|
+
if (Date.now() - statSync2(path8).mtimeMs > LOCK_STALE_MS) rmSync3(path8, { force: true });
|
|
8592
|
+
} catch {
|
|
8593
|
+
}
|
|
8594
|
+
if (Date.now() >= deadline) return () => void 0;
|
|
8595
|
+
await new Promise((resolve5) => setTimeout(resolve5, LOCK_POLL_MS));
|
|
8391
8596
|
}
|
|
8392
8597
|
}
|
|
8393
8598
|
};
|
|
8599
|
+
function isInvalidToken(err) {
|
|
8600
|
+
if (!(err instanceof AccountError) || err.status === void 0) return false;
|
|
8601
|
+
if (err.code) return INVALID_TOKEN_CODES.has(err.code);
|
|
8602
|
+
return err.status === 400 || err.status === 401;
|
|
8603
|
+
}
|
|
8604
|
+
var isWindowsBusy = (err) => ["EPERM", "EBUSY"].includes(err.code ?? "");
|
|
8605
|
+
var SIGN_IN_FAILED = "Sign-in did not finish. Please try again.";
|
|
8606
|
+
function createAccountControl(options) {
|
|
8607
|
+
const service = options.service ?? accountService(options.env);
|
|
8608
|
+
if (!service) return void 0;
|
|
8609
|
+
const client = new AccountClient(service, options.fetch ? { fetch: options.fetch } : {});
|
|
8610
|
+
const store = () => new AccountStore(options.home, options.env);
|
|
8611
|
+
let active;
|
|
8612
|
+
let error = null;
|
|
8613
|
+
async function stop() {
|
|
8614
|
+
const login = active;
|
|
8615
|
+
active = void 0;
|
|
8616
|
+
await login?.close();
|
|
8617
|
+
}
|
|
8618
|
+
async function finish(login) {
|
|
8619
|
+
try {
|
|
8620
|
+
const session = await login.session;
|
|
8621
|
+
if (active !== login) return;
|
|
8622
|
+
active = void 0;
|
|
8623
|
+
store().save(session);
|
|
8624
|
+
} catch {
|
|
8625
|
+
if (active !== login) return;
|
|
8626
|
+
active = void 0;
|
|
8627
|
+
error = SIGN_IN_FAILED;
|
|
8628
|
+
}
|
|
8629
|
+
}
|
|
8630
|
+
return {
|
|
8631
|
+
async state() {
|
|
8632
|
+
const session = await store().current(client);
|
|
8633
|
+
return {
|
|
8634
|
+
signedIn: Boolean(session),
|
|
8635
|
+
user: session?.user ?? null,
|
|
8636
|
+
pending: active !== void 0,
|
|
8637
|
+
error
|
|
8638
|
+
};
|
|
8639
|
+
},
|
|
8640
|
+
async login(provider) {
|
|
8641
|
+
await stop();
|
|
8642
|
+
error = null;
|
|
8643
|
+
const login = await startAccountLogin({
|
|
8644
|
+
client,
|
|
8645
|
+
...provider ? { provider } : {},
|
|
8646
|
+
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
|
|
8647
|
+
});
|
|
8648
|
+
active = login;
|
|
8649
|
+
void finish(login);
|
|
8650
|
+
const opened = await options.open(login.url).catch(() => false);
|
|
8651
|
+
return { url: login.url, opened };
|
|
8652
|
+
},
|
|
8653
|
+
async cancel() {
|
|
8654
|
+
error = null;
|
|
8655
|
+
await stop();
|
|
8656
|
+
},
|
|
8657
|
+
async logout() {
|
|
8658
|
+
await stop();
|
|
8659
|
+
error = null;
|
|
8660
|
+
const accounts = store();
|
|
8661
|
+
const session = accounts.load();
|
|
8662
|
+
try {
|
|
8663
|
+
if (session) await client.signOut(session.accessToken);
|
|
8664
|
+
} catch {
|
|
8665
|
+
}
|
|
8666
|
+
accounts.clear();
|
|
8667
|
+
},
|
|
8668
|
+
close: stop
|
|
8669
|
+
};
|
|
8670
|
+
}
|
|
8394
8671
|
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
8672
|
var LOGO_ART = [
|
|
8396
8673
|
" \u2584\u2584\u2584\u2588\u2584\u2584\u2584",
|
|
@@ -9462,6 +9739,8 @@ export {
|
|
|
9462
9739
|
routeSchema,
|
|
9463
9740
|
configSchema,
|
|
9464
9741
|
ConfigError,
|
|
9742
|
+
PROJECT_SETTABLE_KEYS,
|
|
9743
|
+
filterProjectLayer,
|
|
9465
9744
|
deepMerge,
|
|
9466
9745
|
envLayer,
|
|
9467
9746
|
loadConfig,
|
|
@@ -9486,6 +9765,12 @@ export {
|
|
|
9486
9765
|
OpenAIProvider,
|
|
9487
9766
|
OpenAICompatibleProvider,
|
|
9488
9767
|
createProviders,
|
|
9768
|
+
ENDPOINT_CONFIG_KEYS,
|
|
9769
|
+
API_CONFIG_KEYS,
|
|
9770
|
+
apiConfigIssues,
|
|
9771
|
+
mergeApiConfig,
|
|
9772
|
+
endpointChanged,
|
|
9773
|
+
endpointRebindIssue,
|
|
9489
9774
|
EXPERIMENTAL_PROVIDER_KINDS,
|
|
9490
9775
|
SUBSCRIPTION_PROVIDER_KINDS,
|
|
9491
9776
|
VERSION,
|
|
@@ -9587,6 +9872,7 @@ export {
|
|
|
9587
9872
|
startAccountLogin,
|
|
9588
9873
|
accountFile,
|
|
9589
9874
|
AccountStore,
|
|
9875
|
+
createAccountControl,
|
|
9590
9876
|
BRAND_MARK_SVG,
|
|
9591
9877
|
brandLogo,
|
|
9592
9878
|
DEFAULT_ROLES,
|
|
@@ -9605,4 +9891,4 @@ export {
|
|
|
9605
9891
|
GoalStore,
|
|
9606
9892
|
createGoalService
|
|
9607
9893
|
};
|
|
9608
|
-
//# sourceMappingURL=chunk-
|
|
9894
|
+
//# sourceMappingURL=chunk-QKY3OKVG.js.map
|