@inerrata-corporation/errata 2.0.0-dev.32 → 2.0.0-dev.34
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/errata.mjs +106 -32
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -20434,6 +20434,37 @@ async function postToken(fetchFn, tokenEndpoint, params, timeoutMs = 15e3) {
|
|
|
20434
20434
|
clearTimeout(tid);
|
|
20435
20435
|
}
|
|
20436
20436
|
}
|
|
20437
|
+
async function registerOAuthClient(fetchFn, registrationEndpoint, p, timeoutMs = 15e3) {
|
|
20438
|
+
const ac = new AbortController();
|
|
20439
|
+
const tid = setTimeout(() => ac.abort(), timeoutMs);
|
|
20440
|
+
try {
|
|
20441
|
+
const res = await fetchFn(registrationEndpoint, {
|
|
20442
|
+
method: "POST",
|
|
20443
|
+
headers: {
|
|
20444
|
+
"content-type": "application/json",
|
|
20445
|
+
accept: "application/json"
|
|
20446
|
+
},
|
|
20447
|
+
body: JSON.stringify({
|
|
20448
|
+
redirect_uris: [p.redirectUri],
|
|
20449
|
+
token_endpoint_auth_method: "none",
|
|
20450
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
20451
|
+
response_types: ["code"],
|
|
20452
|
+
client_name: p.clientName ?? "errata daemon",
|
|
20453
|
+
scope: p.scope
|
|
20454
|
+
}),
|
|
20455
|
+
signal: ac.signal
|
|
20456
|
+
});
|
|
20457
|
+
if (!res.ok) {
|
|
20458
|
+
const text = await res.text();
|
|
20459
|
+
throw new Error(`client registration failed: HTTP ${res.status} ${text.slice(0, 200)}`);
|
|
20460
|
+
}
|
|
20461
|
+
const j = await res.json();
|
|
20462
|
+
if (!j.client_id) throw new Error("client registration returned no client_id");
|
|
20463
|
+
return { clientId: j.client_id };
|
|
20464
|
+
} finally {
|
|
20465
|
+
clearTimeout(tid);
|
|
20466
|
+
}
|
|
20467
|
+
}
|
|
20437
20468
|
function exchangeAuthorizationCode(fetchFn, tokenEndpoint, p) {
|
|
20438
20469
|
return postToken(fetchFn, tokenEndpoint, {
|
|
20439
20470
|
grant_type: "authorization_code",
|
|
@@ -20921,6 +20952,7 @@ function defaultConfig() {
|
|
|
20921
20952
|
accessToken: null,
|
|
20922
20953
|
refreshToken: null,
|
|
20923
20954
|
tokenEndpoint: null,
|
|
20955
|
+
oauthClientId: null,
|
|
20924
20956
|
userId: null,
|
|
20925
20957
|
email: null,
|
|
20926
20958
|
consent: { sync: false, telemetry: false, contributePackages: false },
|
|
@@ -21189,7 +21221,7 @@ function authedCloudClient(cfg, opts = {}) {
|
|
|
21189
21221
|
...tokenEndpoint && cfg.refreshToken ? {
|
|
21190
21222
|
refreshFn: (rt) => refreshAccessToken(opts.fetchFn ?? fetch, tokenEndpoint, {
|
|
21191
21223
|
refreshToken: rt,
|
|
21192
|
-
clientId: oauthClientId()
|
|
21224
|
+
clientId: cfg.oauthClientId ?? oauthClientId()
|
|
21193
21225
|
}),
|
|
21194
21226
|
// Persist the rotated tokens so the next process starts fresh.
|
|
21195
21227
|
onTokens: (t) => {
|
|
@@ -41846,7 +41878,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
41846
41878
|
}
|
|
41847
41879
|
|
|
41848
41880
|
// src/engine.ts
|
|
41849
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
41881
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.34" : "2.0.0-alpha.0";
|
|
41850
41882
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
41851
41883
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
41852
41884
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -43037,6 +43069,7 @@ async function startDaemon(opts) {
|
|
|
43037
43069
|
merged.accessToken = null;
|
|
43038
43070
|
merged.refreshToken = null;
|
|
43039
43071
|
merged.tokenEndpoint = null;
|
|
43072
|
+
merged.oauthClientId = null;
|
|
43040
43073
|
}
|
|
43041
43074
|
const cloud = authedCloudClient(merged);
|
|
43042
43075
|
let webUiUrl = "";
|
|
@@ -43801,6 +43834,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
43801
43834
|
initialCfg.accessToken = null;
|
|
43802
43835
|
initialCfg.refreshToken = null;
|
|
43803
43836
|
initialCfg.tokenEndpoint = null;
|
|
43837
|
+
initialCfg.oauthClientId = null;
|
|
43804
43838
|
}
|
|
43805
43839
|
const cloud = authedCloudClient(initialCfg, { timeoutMs: CLOUD_TIMEOUT_MS });
|
|
43806
43840
|
const cloudNow = () => {
|
|
@@ -43812,6 +43846,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
43812
43846
|
current.accessToken = null;
|
|
43813
43847
|
current.refreshToken = null;
|
|
43814
43848
|
current.tokenEndpoint = null;
|
|
43849
|
+
current.oauthClientId = null;
|
|
43815
43850
|
}
|
|
43816
43851
|
return authedCloudClient(current, { timeoutMs: CLOUD_TIMEOUT_MS });
|
|
43817
43852
|
};
|
|
@@ -44424,6 +44459,7 @@ init_cloud_endpoint_policy();
|
|
|
44424
44459
|
init_src6();
|
|
44425
44460
|
init_cloud_auth();
|
|
44426
44461
|
import { createServer } from "node:http";
|
|
44462
|
+
var DEFAULT_OAUTH_SCOPE = "openid profile graph:read graph:write mcp:tools";
|
|
44427
44463
|
var strip = (u) => u.replace(/\/+$/, "");
|
|
44428
44464
|
async function discoverEndpoints(cloudUrl, fetchFn = fetch) {
|
|
44429
44465
|
let consoleUrl = cloudUrl;
|
|
@@ -44440,7 +44476,11 @@ async function discoverEndpoints(cloudUrl, fetchFn = fetch) {
|
|
|
44440
44476
|
if (asm.ok) {
|
|
44441
44477
|
const j = await asm.json();
|
|
44442
44478
|
if (j.authorization_endpoint && j.token_endpoint) {
|
|
44443
|
-
return {
|
|
44479
|
+
return {
|
|
44480
|
+
authorizationEndpoint: j.authorization_endpoint,
|
|
44481
|
+
tokenEndpoint: j.token_endpoint,
|
|
44482
|
+
...j.registration_endpoint ? { registrationEndpoint: j.registration_endpoint } : {}
|
|
44483
|
+
};
|
|
44444
44484
|
}
|
|
44445
44485
|
}
|
|
44446
44486
|
} catch {
|
|
@@ -44467,8 +44507,8 @@ async function loginOAuthLoopback(opts) {
|
|
|
44467
44507
|
const endpoints = await discoverEndpoints(opts.cloudUrl, fetchFn);
|
|
44468
44508
|
const pkce = generatePkce();
|
|
44469
44509
|
const state = randomState();
|
|
44470
|
-
const
|
|
44471
|
-
const { code, redirectUri } = await new Promise(
|
|
44510
|
+
const scope = opts.scope ?? DEFAULT_OAUTH_SCOPE;
|
|
44511
|
+
const { code, redirectUri, clientId } = await new Promise(
|
|
44472
44512
|
(resolve5, reject) => {
|
|
44473
44513
|
const server = createServer((req, res) => {
|
|
44474
44514
|
const u = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
@@ -44492,24 +44532,40 @@ async function loginOAuthLoopback(opts) {
|
|
|
44492
44532
|
res.writeHead(200, { "content-type": "text/html" });
|
|
44493
44533
|
res.end("<html><body>inErrata: you're logged in. You can close this tab.</body></html>");
|
|
44494
44534
|
server.close();
|
|
44495
|
-
resolve5({ code: code2, redirectUri: `http://127.0.0.1:${port}/callback
|
|
44535
|
+
resolve5({ code: code2, redirectUri: `http://127.0.0.1:${port}/callback`, clientId: activeClientId });
|
|
44496
44536
|
});
|
|
44537
|
+
let activeClientId = oauthClientId();
|
|
44497
44538
|
server.on("error", reject);
|
|
44498
44539
|
server.listen(0, "127.0.0.1", () => {
|
|
44499
|
-
|
|
44500
|
-
|
|
44501
|
-
|
|
44502
|
-
|
|
44503
|
-
|
|
44504
|
-
|
|
44505
|
-
|
|
44506
|
-
|
|
44507
|
-
|
|
44508
|
-
|
|
44509
|
-
|
|
44510
|
-
|
|
44511
|
-
|
|
44540
|
+
void (async () => {
|
|
44541
|
+
try {
|
|
44542
|
+
const addr2 = server.address();
|
|
44543
|
+
const port = typeof addr2 === "object" && addr2 ? addr2.port : 0;
|
|
44544
|
+
const redirectUri2 = `http://127.0.0.1:${port}/callback`;
|
|
44545
|
+
if (endpoints.registrationEndpoint) {
|
|
44546
|
+
const registered = await registerOAuthClient(fetchFn, endpoints.registrationEndpoint, {
|
|
44547
|
+
redirectUri: redirectUri2,
|
|
44548
|
+
scope,
|
|
44549
|
+
clientName: "errata daemon"
|
|
44550
|
+
});
|
|
44551
|
+
activeClientId = registered.clientId;
|
|
44552
|
+
}
|
|
44553
|
+
const url2 = buildAuthorizeUrl(endpoints.authorizationEndpoint, {
|
|
44554
|
+
clientId: activeClientId,
|
|
44555
|
+
redirectUri: redirectUri2,
|
|
44556
|
+
scope,
|
|
44557
|
+
state,
|
|
44558
|
+
challenge: pkce.challenge,
|
|
44559
|
+
method: pkce.method
|
|
44560
|
+
});
|
|
44561
|
+
if (opts.open) opts.open(url2);
|
|
44562
|
+
else console.log(`approve this login in your browser:
|
|
44512
44563
|
${url2}`);
|
|
44564
|
+
} catch (err2) {
|
|
44565
|
+
server.close();
|
|
44566
|
+
reject(err2);
|
|
44567
|
+
}
|
|
44568
|
+
})();
|
|
44513
44569
|
});
|
|
44514
44570
|
if (opts.timeoutMs) {
|
|
44515
44571
|
setTimeout(() => {
|
|
@@ -44525,7 +44581,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
44525
44581
|
redirectUri,
|
|
44526
44582
|
clientId
|
|
44527
44583
|
});
|
|
44528
|
-
return { tokens, tokenEndpoint: endpoints.tokenEndpoint };
|
|
44584
|
+
return { tokens, tokenEndpoint: endpoints.tokenEndpoint, clientId };
|
|
44529
44585
|
}
|
|
44530
44586
|
|
|
44531
44587
|
// src/update.ts
|
|
@@ -44617,6 +44673,15 @@ function parseBurstArgs(args2) {
|
|
|
44617
44673
|
};
|
|
44618
44674
|
}
|
|
44619
44675
|
|
|
44676
|
+
// src/login-mode.ts
|
|
44677
|
+
var OAUTH_DEFAULT_ENV = "ERRATA_DAEMON_OAUTH_DEFAULT";
|
|
44678
|
+
function isDaemonOAuthDefaultEnabled(env2 = process.env) {
|
|
44679
|
+
return env2[OAUTH_DEFAULT_ENV] === "1";
|
|
44680
|
+
}
|
|
44681
|
+
function shouldUseOAuthLogin(flags2, env2 = process.env) {
|
|
44682
|
+
return Boolean(flags2.oauth || !flags2.device && isDaemonOAuthDefaultEnabled(env2));
|
|
44683
|
+
}
|
|
44684
|
+
|
|
44620
44685
|
// src/consolidation-trigger.ts
|
|
44621
44686
|
var DEFAULT_CONSOLIDATION_POLICY = {
|
|
44622
44687
|
baseFloorMs: 6e4,
|
|
@@ -44793,7 +44858,7 @@ Commands:
|
|
|
44793
44858
|
Flags: --port N (default 7891)
|
|
44794
44859
|
mcp Run the MCP stdio server \u2014 the agent's full errata tool
|
|
44795
44860
|
surface (navigation, problems, claims, burst, health)
|
|
44796
|
-
login Sign in with the cloud (
|
|
44861
|
+
login Sign in with the cloud (device-code by default; --oauth for OAuth)
|
|
44797
44862
|
logout Clear local cloud credentials
|
|
44798
44863
|
sync now Flush outbox to the cloud once
|
|
44799
44864
|
privacy Show what is collected/scrubbed + your consent state
|
|
@@ -44808,6 +44873,7 @@ Commands:
|
|
|
44808
44873
|
Environment:
|
|
44809
44874
|
ERRATA_CLOUD_URL Cloud base URL (default ${DEFAULT_CLOUD_URL})
|
|
44810
44875
|
ERRATA_ALLOW_DIRECT_V1_CLOUD=1 Allow non-local legacy v1 cloud testing
|
|
44876
|
+
${OAUTH_DEFAULT_ENV}=1 Internal dogfood: plain \`errata login\` uses OAuth
|
|
44811
44877
|
`);
|
|
44812
44878
|
}
|
|
44813
44879
|
function resolveHookPort(explicit) {
|
|
@@ -45117,6 +45183,7 @@ async function applyToken(cfg, token) {
|
|
|
45117
45183
|
cfg.accessToken = null;
|
|
45118
45184
|
cfg.refreshToken = null;
|
|
45119
45185
|
cfg.tokenEndpoint = null;
|
|
45186
|
+
cfg.oauthClientId = null;
|
|
45120
45187
|
cfg.userId = me.agentId;
|
|
45121
45188
|
cfg.email = me.handle;
|
|
45122
45189
|
saveConfig(cfg);
|
|
@@ -45158,19 +45225,24 @@ async function cmdLoginOAuth(cfg) {
|
|
|
45158
45225
|
process.exitCode = 1;
|
|
45159
45226
|
return;
|
|
45160
45227
|
}
|
|
45161
|
-
|
|
45162
|
-
|
|
45163
|
-
|
|
45164
|
-
|
|
45165
|
-
|
|
45228
|
+
const nextCfg = {
|
|
45229
|
+
...cfg,
|
|
45230
|
+
accessToken: result.tokens.accessToken,
|
|
45231
|
+
refreshToken: result.tokens.refreshToken ?? null,
|
|
45232
|
+
tokenEndpoint: result.tokenEndpoint,
|
|
45233
|
+
oauthClientId: result.clientId,
|
|
45234
|
+
apiKey: null
|
|
45235
|
+
};
|
|
45166
45236
|
try {
|
|
45167
|
-
const me = await authedCloudClient(
|
|
45168
|
-
|
|
45169
|
-
|
|
45170
|
-
saveConfig(
|
|
45237
|
+
const me = await authedCloudClient(nextCfg).me();
|
|
45238
|
+
nextCfg.userId = me.agentId;
|
|
45239
|
+
nextCfg.email = me.handle;
|
|
45240
|
+
saveConfig(nextCfg);
|
|
45171
45241
|
console.log(`logged in as ${me.handle} (${me.tier}) \u2014 tokens stored at ${globalConfigPath()}`);
|
|
45172
45242
|
} catch (err2) {
|
|
45173
|
-
console.
|
|
45243
|
+
console.error(`signed in, but identity check failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
45244
|
+
console.error(` credentials were not stored; try again or paste a key: errata login --token <key>`);
|
|
45245
|
+
process.exitCode = 1;
|
|
45174
45246
|
}
|
|
45175
45247
|
}
|
|
45176
45248
|
async function cmdLogin() {
|
|
@@ -45181,7 +45253,7 @@ async function cmdLogin() {
|
|
|
45181
45253
|
await applyToken(cfg, flags2.token);
|
|
45182
45254
|
return;
|
|
45183
45255
|
}
|
|
45184
|
-
if (flags2
|
|
45256
|
+
if (shouldUseOAuthLogin(flags2)) {
|
|
45185
45257
|
await cmdLoginOAuth(cfg);
|
|
45186
45258
|
return;
|
|
45187
45259
|
}
|
|
@@ -45232,6 +45304,7 @@ async function cmdLogin() {
|
|
|
45232
45304
|
cfg.accessToken = null;
|
|
45233
45305
|
cfg.refreshToken = null;
|
|
45234
45306
|
cfg.tokenEndpoint = null;
|
|
45307
|
+
cfg.oauthClientId = null;
|
|
45235
45308
|
cfg.userId = poll.agentId ?? null;
|
|
45236
45309
|
cfg.email = poll.handle ?? handle2;
|
|
45237
45310
|
saveConfig(cfg);
|
|
@@ -45259,6 +45332,7 @@ async function cmdLogout() {
|
|
|
45259
45332
|
cfg.accessToken = null;
|
|
45260
45333
|
cfg.refreshToken = null;
|
|
45261
45334
|
cfg.tokenEndpoint = null;
|
|
45335
|
+
cfg.oauthClientId = null;
|
|
45262
45336
|
cfg.userId = null;
|
|
45263
45337
|
cfg.email = null;
|
|
45264
45338
|
saveConfig(cfg);
|