@inerrata-corporation/errata 2.0.0-dev.25 → 2.0.0-dev.27
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 +117 -37
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -18827,7 +18827,41 @@ function communitySeeds(store, opts = {}) {
|
|
|
18827
18827
|
}
|
|
18828
18828
|
return seeds;
|
|
18829
18829
|
}
|
|
18830
|
-
|
|
18830
|
+
function communityInductionRequests(store, opts = {}) {
|
|
18831
|
+
const maxCommunities = opts.maxCommunities ?? 2;
|
|
18832
|
+
const byCommunity = /* @__PURE__ */ new Map();
|
|
18833
|
+
for (const label of JOINT_COMMUNITY_LABELS) {
|
|
18834
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
18835
|
+
const cid = n.attrs["localCommunity"];
|
|
18836
|
+
if (typeof cid !== "string") continue;
|
|
18837
|
+
const cloudId = n.attrs["cloudNodeId"];
|
|
18838
|
+
const l = byCommunity.get(cid) ?? [];
|
|
18839
|
+
l.push({
|
|
18840
|
+
id: n.id,
|
|
18841
|
+
pulled: n.attrs["source"] === "cloud",
|
|
18842
|
+
cloudId: typeof cloudId === "string" && cloudId !== n.id ? cloudId : null,
|
|
18843
|
+
ts: n.lastUpdatedAt,
|
|
18844
|
+
description: n.description
|
|
18845
|
+
});
|
|
18846
|
+
byCommunity.set(cid, l);
|
|
18847
|
+
}
|
|
18848
|
+
}
|
|
18849
|
+
if (byCommunity.size === 0) return [];
|
|
18850
|
+
return [...byCommunity.entries()].map(([cid, mem]) => ({ cid, mem, fresh: Math.max(...mem.map((m) => m.ts)) })).sort((a, b) => b.fresh - a.fresh).map(({ cid, mem }) => {
|
|
18851
|
+
const ids = /* @__PURE__ */ new Set();
|
|
18852
|
+
for (const m of mem) {
|
|
18853
|
+
ids.add(m.id);
|
|
18854
|
+
if (m.cloudId) ids.add(m.cloudId);
|
|
18855
|
+
}
|
|
18856
|
+
const freshestLocal = [...mem].filter((m) => !m.pulled).sort((a, b) => b.ts - a.ts)[0];
|
|
18857
|
+
return {
|
|
18858
|
+
communityId: cid,
|
|
18859
|
+
members: [...ids].slice(0, 64),
|
|
18860
|
+
context: (freshestLocal?.description ?? "recurring workspace problem cluster").slice(0, 200)
|
|
18861
|
+
};
|
|
18862
|
+
}).filter((r) => r.members.length >= MIN_INDUCTION_MEMBERS).slice(0, maxCommunities);
|
|
18863
|
+
}
|
|
18864
|
+
var JOINT_COMMUNITY_LABELS, JOINT_COMMUNITY_EDGES, DEFAULT_MIN_COMMUNITY_SIZE, MIN_INDUCTION_MEMBERS;
|
|
18831
18865
|
var init_community2 = __esm({
|
|
18832
18866
|
"../../packages/local-graph/src/community.ts"() {
|
|
18833
18867
|
"use strict";
|
|
@@ -18853,6 +18887,7 @@ var init_community2 = __esm({
|
|
|
18853
18887
|
"RELATES_TO"
|
|
18854
18888
|
];
|
|
18855
18889
|
DEFAULT_MIN_COMMUNITY_SIZE = 2;
|
|
18890
|
+
MIN_INDUCTION_MEMBERS = 3;
|
|
18856
18891
|
}
|
|
18857
18892
|
});
|
|
18858
18893
|
|
|
@@ -19496,6 +19531,7 @@ __export(src_exports, {
|
|
|
19496
19531
|
causalChain: () => causalChain,
|
|
19497
19532
|
claimId: () => claimId,
|
|
19498
19533
|
clearRevisit: () => clearRevisit,
|
|
19534
|
+
communityInductionRequests: () => communityInductionRequests,
|
|
19499
19535
|
communitySeeds: () => communitySeeds,
|
|
19500
19536
|
compareSemver: () => compareSemver,
|
|
19501
19537
|
corroborateClaim: () => corroborateClaim,
|
|
@@ -20344,6 +20380,13 @@ var init_client = __esm({
|
|
|
20344
20380
|
if (seed && seed.length > 0) qs.set("seed", seed.join(","));
|
|
20345
20381
|
return this.json("GET", `/v2/skills?${qs.toString()}`);
|
|
20346
20382
|
}
|
|
20383
|
+
/** CL-induce: request a skill for a locally-detected community's cloud-
|
|
20384
|
+
* resolvable member ids. AUTHED. Always HTTP 200 — the `status` field
|
|
20385
|
+
* discriminates outcomes (incl. the autophagy-floor refusal, which is a
|
|
20386
|
+
* normal "not enough collective grounding yet" result, not an error). */
|
|
20387
|
+
async induceSkill(body2) {
|
|
20388
|
+
return this.json("POST", "/v2/skills/induce", body2);
|
|
20389
|
+
}
|
|
20347
20390
|
/** Dependency-spine neighborhood. Accepts purls (Package canonicalId = purl)
|
|
20348
20391
|
* or bare name@version slugs. A miss 404s AND registers demand (Stream B). */
|
|
20349
20392
|
async packages(purlOrSlug, limit) {
|
|
@@ -20585,7 +20628,7 @@ import { randomUUID as randomUUID2 } from "node:crypto";
|
|
|
20585
20628
|
function defaultConfig() {
|
|
20586
20629
|
return {
|
|
20587
20630
|
version: 1,
|
|
20588
|
-
cloudUrl: process.env["ERRATA_CLOUD_URL"] ??
|
|
20631
|
+
cloudUrl: process.env["ERRATA_CLOUD_URL"] ?? DEFAULT_CLOUD_URL,
|
|
20589
20632
|
apiKey: null,
|
|
20590
20633
|
accessToken: null,
|
|
20591
20634
|
refreshToken: null,
|
|
@@ -20631,10 +20674,12 @@ function machineId() {
|
|
|
20631
20674
|
saveConfig({ ...cfg, machineId: id });
|
|
20632
20675
|
return id;
|
|
20633
20676
|
}
|
|
20677
|
+
var DEFAULT_CLOUD_URL;
|
|
20634
20678
|
var init_config = __esm({
|
|
20635
20679
|
"src/config.ts"() {
|
|
20636
20680
|
"use strict";
|
|
20637
20681
|
init_paths();
|
|
20682
|
+
DEFAULT_CLOUD_URL = "https://inerrata-gateway.onrender.com";
|
|
20638
20683
|
}
|
|
20639
20684
|
});
|
|
20640
20685
|
|
|
@@ -20708,7 +20753,7 @@ function assertDeviceCodeEndpointAllowed(url2, inspection) {
|
|
|
20708
20753
|
allowed: false,
|
|
20709
20754
|
label: "gateway device-code blocked",
|
|
20710
20755
|
reason: "device-code login mints legacy v1 keys, while gateway launch uses console-issued keys/JWTs",
|
|
20711
|
-
guidance: "Use `errata login
|
|
20756
|
+
guidance: "Use `errata login` for OAuth or `errata login --token <console errk_...>`."
|
|
20712
20757
|
};
|
|
20713
20758
|
throw new CloudEndpointPolicyError(formatCloudEndpointBlock(url2, decision), decision);
|
|
20714
20759
|
}
|
|
@@ -20852,6 +20897,7 @@ function authedCloudClient(cfg, opts = {}) {
|
|
|
20852
20897
|
accessToken: cfg.accessToken,
|
|
20853
20898
|
...cfg.refreshToken ? { refreshToken: cfg.refreshToken } : {},
|
|
20854
20899
|
fetchFn,
|
|
20900
|
+
...opts.timeoutMs ? { timeoutMs: opts.timeoutMs } : {},
|
|
20855
20901
|
...tokenEndpoint && cfg.refreshToken ? {
|
|
20856
20902
|
refreshFn: (rt) => refreshAccessToken(opts.fetchFn ?? fetch, tokenEndpoint, {
|
|
20857
20903
|
refreshToken: rt,
|
|
@@ -20870,9 +20916,13 @@ function authedCloudClient(cfg, opts = {}) {
|
|
|
20870
20916
|
return new CloudClient({
|
|
20871
20917
|
baseUrl,
|
|
20872
20918
|
...cfg.apiKey ? { apiKey: cfg.apiKey } : {},
|
|
20873
|
-
fetchFn
|
|
20919
|
+
fetchFn,
|
|
20920
|
+
...opts.timeoutMs ? { timeoutMs: opts.timeoutMs } : {}
|
|
20874
20921
|
});
|
|
20875
20922
|
}
|
|
20923
|
+
function hasCloudCredential(cfg) {
|
|
20924
|
+
return Boolean(cfg.accessToken || cfg.apiKey);
|
|
20925
|
+
}
|
|
20876
20926
|
var init_cloud_auth = __esm({
|
|
20877
20927
|
"src/cloud-auth.ts"() {
|
|
20878
20928
|
"use strict";
|
|
@@ -34439,7 +34489,7 @@ function createMcpHandler(store, ctx = {}) {
|
|
|
34439
34489
|
function buildToolContext() {
|
|
34440
34490
|
try {
|
|
34441
34491
|
const cfg = loadConfig();
|
|
34442
|
-
if (cfg.consent.sync && cfg
|
|
34492
|
+
if (cfg.consent.sync && hasCloudCredential(cfg) && cfg.cloudUrl) {
|
|
34443
34493
|
return { cloud: authedCloudClient(cfg) };
|
|
34444
34494
|
}
|
|
34445
34495
|
} catch {
|
|
@@ -40815,11 +40865,11 @@ var TelemetryRecorder = class {
|
|
|
40815
40865
|
return out2;
|
|
40816
40866
|
}
|
|
40817
40867
|
/**
|
|
40818
|
-
* Flush to the cloud iff consent +
|
|
40868
|
+
* Flush to the cloud iff consent + a cloud credential are present. Returns how many were
|
|
40819
40869
|
* accepted (0 when skipped). On network failure the batch is re-queued.
|
|
40820
40870
|
*/
|
|
40821
40871
|
async flush(cloud, opts) {
|
|
40822
|
-
if (!opts.consent || !opts.
|
|
40872
|
+
if (!opts.consent || !opts.credentialPresent) {
|
|
40823
40873
|
this.drain();
|
|
40824
40874
|
return { sent: 0, skipped: true };
|
|
40825
40875
|
}
|
|
@@ -41113,6 +41163,7 @@ function autodetectProfile(root) {
|
|
|
41113
41163
|
|
|
41114
41164
|
// src/engine.ts
|
|
41115
41165
|
init_config();
|
|
41166
|
+
init_cloud_auth();
|
|
41116
41167
|
|
|
41117
41168
|
// src/notify.ts
|
|
41118
41169
|
init_config();
|
|
@@ -41231,7 +41282,7 @@ function maybeFlushDigests() {
|
|
|
41231
41282
|
}
|
|
41232
41283
|
|
|
41233
41284
|
// src/engine.ts
|
|
41234
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
41285
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.27" : "2.0.0-alpha.0";
|
|
41235
41286
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
41236
41287
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
41237
41288
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -42036,7 +42087,19 @@ function createWorkspaceEngine(opts) {
|
|
|
42036
42087
|
}
|
|
42037
42088
|
});
|
|
42038
42089
|
}
|
|
42039
|
-
const pullSkills = () => {
|
|
42090
|
+
const pullSkills = async () => {
|
|
42091
|
+
if ((opts.syncConsent ?? loadConfig().consent.sync) === true) {
|
|
42092
|
+
for (const req of communityInductionRequests(store)) {
|
|
42093
|
+
try {
|
|
42094
|
+
const r = await cloud.induceSkill({ members: req.members, context: req.context });
|
|
42095
|
+
if (r.status === "induced" || r.status === "refreshed") {
|
|
42096
|
+
console.log(`[errata] skill ${r.status} for community ${req.communityId}: ${r.title ?? r.skillId}`);
|
|
42097
|
+
}
|
|
42098
|
+
} catch {
|
|
42099
|
+
break;
|
|
42100
|
+
}
|
|
42101
|
+
}
|
|
42102
|
+
}
|
|
42040
42103
|
const communitySeed = communitySeeds(store);
|
|
42041
42104
|
const skillSeed = communitySeed.length > 0 ? communitySeed : store.findNodesByLabel("Problem").sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 6).flatMap((p) => {
|
|
42042
42105
|
const cloudId = p.attrs["cloudNodeId"];
|
|
@@ -42222,7 +42285,7 @@ function createWorkspaceEngine(opts) {
|
|
|
42222
42285
|
}
|
|
42223
42286
|
const t = await telemetry.flush(cloud, {
|
|
42224
42287
|
consent: freshCfg.consent.telemetry,
|
|
42225
|
-
|
|
42288
|
+
credentialPresent: Boolean(opts.apiKey) || hasCloudCredential(freshCfg)
|
|
42226
42289
|
});
|
|
42227
42290
|
if (t.sent > 0) {
|
|
42228
42291
|
console.log(`[errata] telemetry: ${t.sent} events sent`);
|
|
@@ -42259,6 +42322,8 @@ async function startDaemon(opts) {
|
|
|
42259
42322
|
if (opts.apiKey) {
|
|
42260
42323
|
merged.apiKey = opts.apiKey;
|
|
42261
42324
|
merged.accessToken = null;
|
|
42325
|
+
merged.refreshToken = null;
|
|
42326
|
+
merged.tokenEndpoint = null;
|
|
42262
42327
|
}
|
|
42263
42328
|
const cloud = authedCloudClient(merged);
|
|
42264
42329
|
let webUiUrl = "";
|
|
@@ -42408,7 +42473,6 @@ function pidAlive(pid) {
|
|
|
42408
42473
|
|
|
42409
42474
|
// src/multi.ts
|
|
42410
42475
|
init_dist();
|
|
42411
|
-
init_src6();
|
|
42412
42476
|
init_src4();
|
|
42413
42477
|
import { readFileSync as readFileSync17, unlinkSync as unlinkSync3, writeFileSync as writeFileSync14 } from "node:fs";
|
|
42414
42478
|
|
|
@@ -43009,6 +43073,7 @@ function isDaemonAlive(lockPath) {
|
|
|
43009
43073
|
// src/multi.ts
|
|
43010
43074
|
init_config();
|
|
43011
43075
|
init_cloud_endpoint_policy();
|
|
43076
|
+
init_cloud_auth();
|
|
43012
43077
|
function normPath(p) {
|
|
43013
43078
|
return p.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
43014
43079
|
}
|
|
@@ -43043,21 +43108,25 @@ async function startMultiDaemon(opts = {}) {
|
|
|
43043
43108
|
const cfg = loadConfig();
|
|
43044
43109
|
const CLOUD_TIMEOUT_MS = 12e4;
|
|
43045
43110
|
const initialCloudUrl = normalizeCloudUrl(opts.cloudUrl ?? cfg.cloudUrl);
|
|
43046
|
-
const
|
|
43047
|
-
|
|
43048
|
-
|
|
43049
|
-
|
|
43050
|
-
|
|
43051
|
-
|
|
43111
|
+
const initialCfg = { ...cfg, cloudUrl: initialCloudUrl };
|
|
43112
|
+
if (opts.apiKey) {
|
|
43113
|
+
initialCfg.apiKey = opts.apiKey;
|
|
43114
|
+
initialCfg.accessToken = null;
|
|
43115
|
+
initialCfg.refreshToken = null;
|
|
43116
|
+
initialCfg.tokenEndpoint = null;
|
|
43117
|
+
}
|
|
43118
|
+
const cloud = authedCloudClient(initialCfg, { timeoutMs: CLOUD_TIMEOUT_MS });
|
|
43052
43119
|
const cloudNow = () => {
|
|
43053
43120
|
const c = loadConfig();
|
|
43054
43121
|
const baseUrl2 = normalizeCloudUrl(opts.cloudUrl ?? c.cloudUrl);
|
|
43055
|
-
|
|
43056
|
-
|
|
43057
|
-
|
|
43058
|
-
|
|
43059
|
-
|
|
43060
|
-
|
|
43122
|
+
const current = { ...c, cloudUrl: baseUrl2 };
|
|
43123
|
+
if (opts.apiKey) {
|
|
43124
|
+
current.apiKey = opts.apiKey;
|
|
43125
|
+
current.accessToken = null;
|
|
43126
|
+
current.refreshToken = null;
|
|
43127
|
+
current.tokenEndpoint = null;
|
|
43128
|
+
}
|
|
43129
|
+
return authedCloudClient(current, { timeoutMs: CLOUD_TIMEOUT_MS });
|
|
43061
43130
|
};
|
|
43062
43131
|
const sharedDbPath = sharedStorePath();
|
|
43063
43132
|
ensureParent(sharedDbPath);
|
|
@@ -43758,7 +43827,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
43758
43827
|
if (opts.timeoutMs) {
|
|
43759
43828
|
setTimeout(() => {
|
|
43760
43829
|
server.close();
|
|
43761
|
-
reject(new Error("login timed out \u2014 run `errata login
|
|
43830
|
+
reject(new Error("login timed out \u2014 run `errata login` again"));
|
|
43762
43831
|
}, opts.timeoutMs).unref?.();
|
|
43763
43832
|
}
|
|
43764
43833
|
}
|
|
@@ -44032,8 +44101,8 @@ Commands:
|
|
|
44032
44101
|
Flags: --port N (default 7891)
|
|
44033
44102
|
mcp Run the MCP stdio server \u2014 the agent's full errata tool
|
|
44034
44103
|
surface (navigation, problems, claims, burst, health)
|
|
44035
|
-
login
|
|
44036
|
-
logout Clear local
|
|
44104
|
+
login Sign in with the cloud (OAuth by default; --device for legacy)
|
|
44105
|
+
logout Clear local cloud credentials
|
|
44037
44106
|
sync now Flush outbox to the cloud once
|
|
44038
44107
|
privacy Show what is collected/scrubbed + your consent state
|
|
44039
44108
|
consent <channel> <on|off>
|
|
@@ -44045,7 +44114,7 @@ Commands:
|
|
|
44045
44114
|
Desktop toasts on problem open/resolve + review ready
|
|
44046
44115
|
|
|
44047
44116
|
Environment:
|
|
44048
|
-
ERRATA_CLOUD_URL Cloud base URL (default
|
|
44117
|
+
ERRATA_CLOUD_URL Cloud base URL (default ${DEFAULT_CLOUD_URL})
|
|
44049
44118
|
ERRATA_ALLOW_DIRECT_V1_CLOUD=1 Allow non-local legacy v1 cloud testing
|
|
44050
44119
|
`);
|
|
44051
44120
|
}
|
|
@@ -44133,7 +44202,7 @@ async function cmdInit() {
|
|
|
44133
44202
|
console.log("");
|
|
44134
44203
|
console.log("Next:");
|
|
44135
44204
|
console.log(" errata start # observe this repo");
|
|
44136
|
-
if (!cfgNow
|
|
44205
|
+
if (!hasCloudCredential(cfgNow)) {
|
|
44137
44206
|
console.log(" errata login # connect a cloud account (or: --token <key>)");
|
|
44138
44207
|
}
|
|
44139
44208
|
if (!cfgNow.consent.sync) {
|
|
@@ -44233,7 +44302,7 @@ async function cmdStatus() {
|
|
|
44233
44302
|
);
|
|
44234
44303
|
console.log(` cloud:`);
|
|
44235
44304
|
console.log(` url: ${cfg.cloudUrl}`);
|
|
44236
|
-
console.log(` logged in: ${cfg
|
|
44305
|
+
console.log(` logged in: ${hasCloudCredential(cfg) ? `yes (${cfg.email})` : "no"}`);
|
|
44237
44306
|
const inspection = await inspectCloudEndpoint(cfg.cloudUrl);
|
|
44238
44307
|
const decision = evaluateCloudEndpoint(cfg.cloudUrl, inspection);
|
|
44239
44308
|
const service = inspection.service ? ` \xB7 service ${inspection.service}` : "";
|
|
@@ -44242,7 +44311,7 @@ async function cmdStatus() {
|
|
|
44242
44311
|
console.log(` policy: blocked - ${decision.reason}`);
|
|
44243
44312
|
if (decision.guidance) console.log(` ${decision.guidance}`);
|
|
44244
44313
|
}
|
|
44245
|
-
if (cfg
|
|
44314
|
+
if (hasCloudCredential(cfg)) {
|
|
44246
44315
|
if (!decision.allowed) {
|
|
44247
44316
|
console.log(
|
|
44248
44317
|
` reachable: ${inspection.reachable ? `yes (${inspection.probe})` : `no (${inspection.error ?? "unreachable"})`}`
|
|
@@ -44326,6 +44395,7 @@ function parseFlags(args2) {
|
|
|
44326
44395
|
else if (a === "--token") out2.token = args2[++i2];
|
|
44327
44396
|
else if (a.startsWith("--token=")) out2.token = a.slice("--token=".length);
|
|
44328
44397
|
else if (a === "--oauth") out2.oauth = true;
|
|
44398
|
+
else if (a === "--device") out2.device = true;
|
|
44329
44399
|
else if (!a.startsWith("--")) out2._.push(a);
|
|
44330
44400
|
}
|
|
44331
44401
|
return out2;
|
|
@@ -44351,6 +44421,9 @@ async function applyToken(cfg, token) {
|
|
|
44351
44421
|
try {
|
|
44352
44422
|
const me = await c.me();
|
|
44353
44423
|
cfg.apiKey = token;
|
|
44424
|
+
cfg.accessToken = null;
|
|
44425
|
+
cfg.refreshToken = null;
|
|
44426
|
+
cfg.tokenEndpoint = null;
|
|
44354
44427
|
cfg.userId = me.agentId;
|
|
44355
44428
|
cfg.email = me.handle;
|
|
44356
44429
|
saveConfig(cfg);
|
|
@@ -44387,7 +44460,7 @@ async function cmdLoginOAuth(cfg) {
|
|
|
44387
44460
|
result = await loginOAuthLoopback({ cloudUrl: cfg.cloudUrl, timeoutMs: 5 * 6e4 });
|
|
44388
44461
|
} catch (err2) {
|
|
44389
44462
|
console.error(`oauth login failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
44390
|
-
console.error(` fall back to device code: errata login`);
|
|
44463
|
+
console.error(` fall back to device code: errata login --device`);
|
|
44391
44464
|
console.error(` or paste a key: errata login --token <key>`);
|
|
44392
44465
|
process.exitCode = 1;
|
|
44393
44466
|
return;
|
|
@@ -44395,6 +44468,7 @@ async function cmdLoginOAuth(cfg) {
|
|
|
44395
44468
|
cfg.accessToken = result.tokens.accessToken;
|
|
44396
44469
|
cfg.refreshToken = result.tokens.refreshToken ?? null;
|
|
44397
44470
|
cfg.tokenEndpoint = result.tokenEndpoint;
|
|
44471
|
+
cfg.apiKey = null;
|
|
44398
44472
|
saveConfig(cfg);
|
|
44399
44473
|
try {
|
|
44400
44474
|
const me = await authedCloudClient(cfg).me();
|
|
@@ -44414,7 +44488,7 @@ async function cmdLogin() {
|
|
|
44414
44488
|
await applyToken(cfg, flags2.token);
|
|
44415
44489
|
return;
|
|
44416
44490
|
}
|
|
44417
|
-
if (flags2.oauth) {
|
|
44491
|
+
if (flags2.oauth || !flags2.device) {
|
|
44418
44492
|
await cmdLoginOAuth(cfg);
|
|
44419
44493
|
return;
|
|
44420
44494
|
}
|
|
@@ -44462,6 +44536,9 @@ async function cmdLogin() {
|
|
|
44462
44536
|
if (poll.status === "pending") continue;
|
|
44463
44537
|
if (poll.status === "authorized" && poll.apiKey) {
|
|
44464
44538
|
cfg.apiKey = poll.apiKey;
|
|
44539
|
+
cfg.accessToken = null;
|
|
44540
|
+
cfg.refreshToken = null;
|
|
44541
|
+
cfg.tokenEndpoint = null;
|
|
44465
44542
|
cfg.userId = poll.agentId ?? null;
|
|
44466
44543
|
cfg.email = poll.handle ?? handle2;
|
|
44467
44544
|
saveConfig(cfg);
|
|
@@ -44486,6 +44563,9 @@ async function cmdLogin() {
|
|
|
44486
44563
|
async function cmdLogout() {
|
|
44487
44564
|
const cfg = loadConfig();
|
|
44488
44565
|
cfg.apiKey = null;
|
|
44566
|
+
cfg.accessToken = null;
|
|
44567
|
+
cfg.refreshToken = null;
|
|
44568
|
+
cfg.tokenEndpoint = null;
|
|
44489
44569
|
cfg.userId = null;
|
|
44490
44570
|
cfg.email = null;
|
|
44491
44571
|
saveConfig(cfg);
|
|
@@ -44849,7 +44929,7 @@ async function cmdBurst(args2) {
|
|
|
44849
44929
|
let ctx = {};
|
|
44850
44930
|
if (!local) {
|
|
44851
44931
|
const cfg = loadConfig();
|
|
44852
|
-
if (cfg
|
|
44932
|
+
if (hasCloudCredential(cfg)) ctx = { cloud: authedCloudClient(cfg) };
|
|
44853
44933
|
}
|
|
44854
44934
|
await withStore(async (store) => {
|
|
44855
44935
|
const result = await runTool2(
|
|
@@ -45441,7 +45521,7 @@ async function cmdPrivacy() {
|
|
|
45441
45521
|
sync: ${onoff(cfg.consent.sync)}
|
|
45442
45522
|
telemetry: ${onoff(cfg.consent.telemetry)}
|
|
45443
45523
|
packages: ${onoff(cfg.consent.contributePackages)}
|
|
45444
|
-
logged in: ${cfg
|
|
45524
|
+
logged in: ${hasCloudCredential(cfg) ? `yes (${cfg.email})` : "no"}
|
|
45445
45525
|
|
|
45446
45526
|
Change it: errata consent sync on | errata consent telemetry off
|
|
45447
45527
|
Kill switch: errata consent all off (or errata logout to drop your key)
|
|
@@ -45464,8 +45544,8 @@ async function cmdConsent(args2) {
|
|
|
45464
45544
|
console.log(
|
|
45465
45545
|
`consent updated \u2192 sync=${cfg.consent.sync ? "on" : "off"} telemetry=${cfg.consent.telemetry ? "on" : "off"} packages=${cfg.consent.contributePackages ? "on" : "off"}`
|
|
45466
45546
|
);
|
|
45467
|
-
if ((channel === "sync" || channel === "all") && value && !cfg
|
|
45468
|
-
console.log(" note: run `errata login` to actually upload (no
|
|
45547
|
+
if ((channel === "sync" || channel === "all") && value && !hasCloudCredential(cfg)) {
|
|
45548
|
+
console.log(" note: run `errata login` to actually upload (no cloud credential yet).");
|
|
45469
45549
|
}
|
|
45470
45550
|
}
|
|
45471
45551
|
async function cmdDash(args2) {
|
|
@@ -45757,7 +45837,7 @@ async function cmdNotifications(state) {
|
|
|
45757
45837
|
}
|
|
45758
45838
|
async function cmdFeedback(args2) {
|
|
45759
45839
|
const cfg = loadConfig();
|
|
45760
|
-
if (!cfg
|
|
45840
|
+
if (!hasCloudCredential(cfg)) {
|
|
45761
45841
|
console.error("not logged in \u2014 run `errata login` first.");
|
|
45762
45842
|
process.exit(2);
|
|
45763
45843
|
}
|