@inerrata-corporation/errata 2.0.0-dev.36 → 2.0.0-dev.38
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 +278 -16
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -20608,6 +20608,24 @@ var init_oauth = __esm({
|
|
|
20608
20608
|
|
|
20609
20609
|
// ../../packages/cloud-client/src/client.ts
|
|
20610
20610
|
import { randomUUID } from "node:crypto";
|
|
20611
|
+
function wirePerContext(value) {
|
|
20612
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
20613
|
+
const out2 = {};
|
|
20614
|
+
for (const [bucket, entry] of Object.entries(value)) {
|
|
20615
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
20616
|
+
const e = entry;
|
|
20617
|
+
const confirmed = asWireCount(e["confirmed"]);
|
|
20618
|
+
if (confirmed === null) continue;
|
|
20619
|
+
const independent = asWireCount(e["independent"]);
|
|
20620
|
+
const inferredIndependent = asWireCount(e["inferredIndependent"]);
|
|
20621
|
+
out2[bucket] = {
|
|
20622
|
+
confirmed,
|
|
20623
|
+
...independent !== null ? { independent } : {},
|
|
20624
|
+
...inferredIndependent !== null ? { inferredIndependent } : {}
|
|
20625
|
+
};
|
|
20626
|
+
}
|
|
20627
|
+
return Object.keys(out2).length > 0 ? out2 : null;
|
|
20628
|
+
}
|
|
20611
20629
|
function sidecarForNodes(sidecar, nodes) {
|
|
20612
20630
|
if (!sidecar) return void 0;
|
|
20613
20631
|
const present = /* @__PURE__ */ new Set();
|
|
@@ -20632,32 +20650,152 @@ function toWirePayload(batch, runId) {
|
|
|
20632
20650
|
attrs: n.attrs ?? {},
|
|
20633
20651
|
extractionSource: n.extractionSource
|
|
20634
20652
|
}));
|
|
20635
|
-
const edges = batch.edges.map((e) =>
|
|
20636
|
-
|
|
20637
|
-
|
|
20638
|
-
|
|
20639
|
-
|
|
20640
|
-
|
|
20641
|
-
|
|
20642
|
-
|
|
20653
|
+
const edges = batch.edges.map((e) => {
|
|
20654
|
+
const perContext = wirePerContext(e.attrs?.["perContext"]);
|
|
20655
|
+
return {
|
|
20656
|
+
fromCanonicalId: e.from,
|
|
20657
|
+
toCanonicalId: e.to,
|
|
20658
|
+
type: e.type,
|
|
20659
|
+
attrs: {
|
|
20660
|
+
...typeof e.confidence === "number" ? { confidence: clamp012(e.confidence) } : {},
|
|
20661
|
+
...perContext ? { perContext } : {}
|
|
20662
|
+
}
|
|
20663
|
+
};
|
|
20664
|
+
});
|
|
20643
20665
|
const symbolSummaries = sidecarForNodes(batch.symbolSummaries, nodes);
|
|
20644
20666
|
return { runId, source: "daemon", nodes, edges, ...symbolSummaries ? { symbolSummaries } : {} };
|
|
20645
20667
|
}
|
|
20646
20668
|
function clamp012(x) {
|
|
20647
20669
|
return Math.max(0, Math.min(1, x));
|
|
20648
20670
|
}
|
|
20671
|
+
function compactAttrs(input) {
|
|
20672
|
+
const out2 = {};
|
|
20673
|
+
for (const [key, value] of Object.entries(input)) {
|
|
20674
|
+
if (value !== void 0) out2[key] = value;
|
|
20675
|
+
}
|
|
20676
|
+
return out2;
|
|
20677
|
+
}
|
|
20678
|
+
function textOrThrow(value, field) {
|
|
20679
|
+
const text = value.trim();
|
|
20680
|
+
if (!text) throw new TypeError(`${field} must be a non-empty string`);
|
|
20681
|
+
return text;
|
|
20682
|
+
}
|
|
20683
|
+
function optionalEdgeAttrs(confidence) {
|
|
20684
|
+
return typeof confidence === "number" ? { confidence: clamp012(confidence) } : void 0;
|
|
20685
|
+
}
|
|
20686
|
+
function makeEdge(fromCanonicalId, type, toCanonicalId, confidence) {
|
|
20687
|
+
const attrs = optionalEdgeAttrs(confidence);
|
|
20688
|
+
return {
|
|
20689
|
+
fromCanonicalId,
|
|
20690
|
+
toCanonicalId,
|
|
20691
|
+
type,
|
|
20692
|
+
...attrs ? { attrs } : {}
|
|
20693
|
+
};
|
|
20694
|
+
}
|
|
20695
|
+
function makeNode(args2) {
|
|
20696
|
+
return {
|
|
20697
|
+
canonicalId: args2.canonicalId,
|
|
20698
|
+
label: args2.label,
|
|
20699
|
+
description: args2.description,
|
|
20700
|
+
attrs: compactAttrs(args2.attrs),
|
|
20701
|
+
extractionSource: "agent-observed",
|
|
20702
|
+
...args2.validationSource ? { validationSource: args2.validationSource } : {}
|
|
20703
|
+
};
|
|
20704
|
+
}
|
|
20705
|
+
function normalizeProblem(input, opts) {
|
|
20706
|
+
if (typeof input === "string") {
|
|
20707
|
+
return {
|
|
20708
|
+
id: void 0,
|
|
20709
|
+
description: textOrThrow(input, "problem"),
|
|
20710
|
+
kind: opts.problemKind,
|
|
20711
|
+
error: opts.errorMessage?.trim() || void 0,
|
|
20712
|
+
attrs: opts.attrs,
|
|
20713
|
+
confidence: void 0,
|
|
20714
|
+
validationSource: opts.validationSource
|
|
20715
|
+
};
|
|
20716
|
+
}
|
|
20717
|
+
return {
|
|
20718
|
+
id: input.id,
|
|
20719
|
+
description: textOrThrow(input.description, "problem.description"),
|
|
20720
|
+
kind: input.kind,
|
|
20721
|
+
error: input.error?.trim() || void 0,
|
|
20722
|
+
attrs: input.attrs,
|
|
20723
|
+
confidence: input.confidence,
|
|
20724
|
+
validationSource: input.validationSource ?? opts.validationSource
|
|
20725
|
+
};
|
|
20726
|
+
}
|
|
20727
|
+
function normalizeTriage(input) {
|
|
20728
|
+
if (input === void 0) return null;
|
|
20729
|
+
if (typeof input === "string") {
|
|
20730
|
+
return {
|
|
20731
|
+
id: void 0,
|
|
20732
|
+
statement: textOrThrow(input, "triage"),
|
|
20733
|
+
route: void 0,
|
|
20734
|
+
attrs: void 0,
|
|
20735
|
+
confidence: void 0,
|
|
20736
|
+
validationSource: void 0
|
|
20737
|
+
};
|
|
20738
|
+
}
|
|
20739
|
+
return {
|
|
20740
|
+
id: input.id,
|
|
20741
|
+
statement: textOrThrow(input.statement, "triage.statement"),
|
|
20742
|
+
route: input.route,
|
|
20743
|
+
attrs: input.attrs,
|
|
20744
|
+
confidence: input.confidence,
|
|
20745
|
+
validationSource: input.validationSource
|
|
20746
|
+
};
|
|
20747
|
+
}
|
|
20748
|
+
function normalizeRootCause(input) {
|
|
20749
|
+
if (input === void 0) return null;
|
|
20750
|
+
if (typeof input === "string") {
|
|
20751
|
+
return {
|
|
20752
|
+
id: void 0,
|
|
20753
|
+
description: textOrThrow(input, "rootCause"),
|
|
20754
|
+
attrs: void 0,
|
|
20755
|
+
confidence: void 0,
|
|
20756
|
+
validationSource: void 0
|
|
20757
|
+
};
|
|
20758
|
+
}
|
|
20759
|
+
return {
|
|
20760
|
+
id: input.id,
|
|
20761
|
+
description: textOrThrow(input.description, "rootCause.description"),
|
|
20762
|
+
attrs: input.attrs,
|
|
20763
|
+
confidence: input.confidence,
|
|
20764
|
+
validationSource: input.validationSource
|
|
20765
|
+
};
|
|
20766
|
+
}
|
|
20767
|
+
function normalizeSolution(input) {
|
|
20768
|
+
if (input === void 0) return null;
|
|
20769
|
+
if (typeof input === "string") {
|
|
20770
|
+
return {
|
|
20771
|
+
id: void 0,
|
|
20772
|
+
description: textOrThrow(input, "solution"),
|
|
20773
|
+
attrs: void 0,
|
|
20774
|
+
confidence: void 0,
|
|
20775
|
+
validationSource: void 0
|
|
20776
|
+
};
|
|
20777
|
+
}
|
|
20778
|
+
return {
|
|
20779
|
+
id: input.id,
|
|
20780
|
+
description: textOrThrow(input.description, "solution.description"),
|
|
20781
|
+
attrs: input.attrs,
|
|
20782
|
+
confidence: input.confidence,
|
|
20783
|
+
validationSource: input.validationSource
|
|
20784
|
+
};
|
|
20785
|
+
}
|
|
20649
20786
|
function chunkArray(items, size) {
|
|
20650
20787
|
if (items.length <= size) return items.length ? [[...items]] : [];
|
|
20651
20788
|
const out2 = [];
|
|
20652
20789
|
for (let i2 = 0; i2 < items.length; i2 += size) out2.push(items.slice(i2, i2 + size));
|
|
20653
20790
|
return out2;
|
|
20654
20791
|
}
|
|
20655
|
-
var INGEST_NODE_CHUNK, CloudClient, CloudError;
|
|
20792
|
+
var asWireCount, INGEST_NODE_CHUNK, CloudClient, CloudError;
|
|
20656
20793
|
var init_client = __esm({
|
|
20657
20794
|
"../../packages/cloud-client/src/client.ts"() {
|
|
20658
20795
|
"use strict";
|
|
20659
20796
|
init_oauth();
|
|
20660
20797
|
init_src();
|
|
20798
|
+
asWireCount = (n) => typeof n === "number" && Number.isFinite(n) && n >= 0 ? Math.floor(n) : null;
|
|
20661
20799
|
INGEST_NODE_CHUNK = 25;
|
|
20662
20800
|
CloudClient = class {
|
|
20663
20801
|
baseUrl;
|
|
@@ -20762,6 +20900,122 @@ var init_client = __esm({
|
|
|
20762
20900
|
async ingestWire(payload) {
|
|
20763
20901
|
return this.json("POST", "/v2/ingest", payload);
|
|
20764
20902
|
}
|
|
20903
|
+
/**
|
|
20904
|
+
* SDK v2 graph-native write. It remembers a typed diagnostic spine through
|
|
20905
|
+
* `/v2/ingest` instead of the legacy forum question/answer routes:
|
|
20906
|
+
*
|
|
20907
|
+
* Problem --TRIAGED_BY--> Triage --INDICATES/CONFIRMS--> RootCause
|
|
20908
|
+
* RootCause --FIXED_BY--> Solution
|
|
20909
|
+
*
|
|
20910
|
+
* Shorthand inputs are accepted for low-friction use, but object inputs keep
|
|
20911
|
+
* the graph labels explicit for adapters and agents that already know their
|
|
20912
|
+
* node types.
|
|
20913
|
+
*/
|
|
20914
|
+
async remember(problemInput, opts = {}) {
|
|
20915
|
+
const runId = opts.runId ?? randomUUID();
|
|
20916
|
+
const problem = normalizeProblem(problemInput, opts);
|
|
20917
|
+
const triage = normalizeTriage(opts.triage);
|
|
20918
|
+
const rootCause = normalizeRootCause(opts.rootCause);
|
|
20919
|
+
const solution = normalizeSolution(opts.solution);
|
|
20920
|
+
const languageInput = opts.language ?? opts.lang;
|
|
20921
|
+
const language = languageInput ? textOrThrow(languageInput, "language") : void 0;
|
|
20922
|
+
const hasLanguage = language !== void 0;
|
|
20923
|
+
const commonAttrs = compactAttrs({
|
|
20924
|
+
sdk: "cloud-client",
|
|
20925
|
+
sdkVersion: "v2",
|
|
20926
|
+
tags: opts.tags && opts.tags.length > 0 ? [...opts.tags] : void 0,
|
|
20927
|
+
lang: language,
|
|
20928
|
+
model: opts.model,
|
|
20929
|
+
context: opts.context
|
|
20930
|
+
});
|
|
20931
|
+
const problemId = problem.id ?? (problem.kind === "runtime" || problem.error ? identityId({ kind: "RuntimeProblem", error: problem.error ?? problem.description }) : identityId({ kind: "DesignProblem", statement: problem.description }));
|
|
20932
|
+
const nodes = [
|
|
20933
|
+
makeNode({
|
|
20934
|
+
canonicalId: problemId,
|
|
20935
|
+
label: "Problem",
|
|
20936
|
+
description: problem.description,
|
|
20937
|
+
attrs: { ...problem.attrs ?? {}, ...commonAttrs },
|
|
20938
|
+
validationSource: problem.validationSource
|
|
20939
|
+
})
|
|
20940
|
+
];
|
|
20941
|
+
const edges = [];
|
|
20942
|
+
let triageId;
|
|
20943
|
+
if (triage) {
|
|
20944
|
+
triageId = triage.id ?? identityId({ kind: "Triage", statement: triage.statement });
|
|
20945
|
+
nodes.push(
|
|
20946
|
+
makeNode({
|
|
20947
|
+
canonicalId: triageId,
|
|
20948
|
+
label: "Triage",
|
|
20949
|
+
description: triage.statement,
|
|
20950
|
+
attrs: { ...triage.attrs ?? {}, ...commonAttrs },
|
|
20951
|
+
validationSource: triage.validationSource ?? opts.validationSource
|
|
20952
|
+
})
|
|
20953
|
+
);
|
|
20954
|
+
edges.push(makeEdge(problemId, "TRIAGED_BY", triageId, triage.confidence));
|
|
20955
|
+
}
|
|
20956
|
+
let rootCauseId;
|
|
20957
|
+
if (rootCause) {
|
|
20958
|
+
rootCauseId = rootCause.id ?? genericCanonicalId("dcause", { statement: rootCause.description });
|
|
20959
|
+
nodes.push(
|
|
20960
|
+
makeNode({
|
|
20961
|
+
canonicalId: rootCauseId,
|
|
20962
|
+
label: "RootCause",
|
|
20963
|
+
description: rootCause.description,
|
|
20964
|
+
attrs: { ...rootCause.attrs ?? {}, ...commonAttrs },
|
|
20965
|
+
validationSource: rootCause.validationSource ?? opts.validationSource
|
|
20966
|
+
})
|
|
20967
|
+
);
|
|
20968
|
+
if (triageId) {
|
|
20969
|
+
const routeType = triage?.route === "confirms" ? "CONFIRMS" : "INDICATES";
|
|
20970
|
+
edges.push(makeEdge(triageId, routeType, rootCauseId, rootCause.confidence));
|
|
20971
|
+
} else {
|
|
20972
|
+
edges.push(makeEdge(problemId, "CAUSED_BY", rootCauseId, rootCause.confidence));
|
|
20973
|
+
}
|
|
20974
|
+
}
|
|
20975
|
+
let solutionId;
|
|
20976
|
+
if (solution) {
|
|
20977
|
+
solutionId = solution.id ?? genericCanonicalId("dfix", { problemId: rootCauseId ?? problemId, fix: solution.description });
|
|
20978
|
+
nodes.push(
|
|
20979
|
+
makeNode({
|
|
20980
|
+
canonicalId: solutionId,
|
|
20981
|
+
label: "Solution",
|
|
20982
|
+
description: solution.description,
|
|
20983
|
+
attrs: { ...solution.attrs ?? {}, ...commonAttrs },
|
|
20984
|
+
validationSource: solution.validationSource ?? opts.validationSource
|
|
20985
|
+
})
|
|
20986
|
+
);
|
|
20987
|
+
edges.push(
|
|
20988
|
+
makeEdge(rootCauseId ?? problemId, rootCauseId ? "FIXED_BY" : "SOLVED_BY", solutionId, solution.confidence)
|
|
20989
|
+
);
|
|
20990
|
+
}
|
|
20991
|
+
let languageId;
|
|
20992
|
+
if (hasLanguage) {
|
|
20993
|
+
languageId = languageCanonicalId(language);
|
|
20994
|
+
nodes.push(
|
|
20995
|
+
makeNode({
|
|
20996
|
+
canonicalId: languageId,
|
|
20997
|
+
label: "Language",
|
|
20998
|
+
description: language,
|
|
20999
|
+
attrs: { sdk: "cloud-client", sdkVersion: "v2" },
|
|
21000
|
+
validationSource: opts.validationSource
|
|
21001
|
+
})
|
|
21002
|
+
);
|
|
21003
|
+
edges.push(makeEdge(problemId, "OCCURS_IN", languageId));
|
|
21004
|
+
}
|
|
21005
|
+
const payload = { runId, source: "agent", nodes, edges };
|
|
21006
|
+
const result = await this.ingestWire(payload);
|
|
21007
|
+
return {
|
|
21008
|
+
runId,
|
|
21009
|
+
problemId,
|
|
21010
|
+
...triageId ? { triageId } : {},
|
|
21011
|
+
...rootCauseId ? { rootCauseId } : {},
|
|
21012
|
+
...solutionId ? { solutionId } : {},
|
|
21013
|
+
...languageId ? { languageId } : {},
|
|
21014
|
+
nodes,
|
|
21015
|
+
edges,
|
|
21016
|
+
result
|
|
21017
|
+
};
|
|
21018
|
+
}
|
|
20765
21019
|
// ─── reads ─────────────────────────────────────────────────────────
|
|
20766
21020
|
/** Daemon pull/merge search (`?shape=castalia`): graph nodes reconstructed
|
|
20767
21021
|
* into local-mergeable CastaliaNodes, marked `attrs.source: 'cloud'` so the
|
|
@@ -41397,13 +41651,21 @@ function isSyncableRoute(edge2, shared, triage, ignorePatterns = []) {
|
|
|
41397
41651
|
function generalizeRouteForSync(edge2, level) {
|
|
41398
41652
|
const disc = edge2.attrs["discriminator"];
|
|
41399
41653
|
const local = edge2.attrs["perContext"] ?? {};
|
|
41400
|
-
const
|
|
41401
|
-
for (const [b, c] of Object.entries(local))
|
|
41654
|
+
const perContext = {};
|
|
41655
|
+
for (const [b, c] of Object.entries(local)) {
|
|
41656
|
+
const independent = c.independent ?? c.contributors?.length;
|
|
41657
|
+
const inferredIndependent = c.inferredIndependent ?? c.inferredContributors?.length;
|
|
41658
|
+
perContext[b] = {
|
|
41659
|
+
confirmed: c.confirmed,
|
|
41660
|
+
...typeof independent === "number" && independent > 0 ? { independent } : {},
|
|
41661
|
+
...typeof inferredIndependent === "number" && inferredIndependent > 0 ? { inferredIndependent } : {}
|
|
41662
|
+
};
|
|
41663
|
+
}
|
|
41402
41664
|
return {
|
|
41403
41665
|
...edge2,
|
|
41404
41666
|
attrs: {
|
|
41405
41667
|
driftKind: edge2.attrs["driftKind"],
|
|
41406
|
-
perContext
|
|
41668
|
+
perContext,
|
|
41407
41669
|
provisional: false,
|
|
41408
41670
|
...typeof disc === "string" && disc.trim() ? { discriminator: generalize(disc, { level }).text } : {}
|
|
41409
41671
|
},
|
|
@@ -42216,7 +42478,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
42216
42478
|
}
|
|
42217
42479
|
|
|
42218
42480
|
// src/engine.ts
|
|
42219
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
42481
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.38" : "2.0.0-alpha.0";
|
|
42220
42482
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
42221
42483
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
42222
42484
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -45124,7 +45386,7 @@ function parseBurstArgs(args2) {
|
|
|
45124
45386
|
// src/login-mode.ts
|
|
45125
45387
|
var OAUTH_DEFAULT_ENV = "ERRATA_DAEMON_OAUTH_DEFAULT";
|
|
45126
45388
|
function isDaemonOAuthDefaultEnabled(env2 = process.env) {
|
|
45127
|
-
return env2[OAUTH_DEFAULT_ENV]
|
|
45389
|
+
return env2[OAUTH_DEFAULT_ENV] !== "0";
|
|
45128
45390
|
}
|
|
45129
45391
|
function shouldUseOAuthLogin(flags2, env2 = process.env) {
|
|
45130
45392
|
return Boolean(flags2.oauth || !flags2.device && isDaemonOAuthDefaultEnabled(env2));
|
|
@@ -45306,7 +45568,7 @@ Commands:
|
|
|
45306
45568
|
Flags: --port N (default 7891)
|
|
45307
45569
|
mcp Run the MCP stdio server \u2014 the agent's full errata tool
|
|
45308
45570
|
surface (navigation, problems, claims, burst, health)
|
|
45309
|
-
login Sign in with the cloud (
|
|
45571
|
+
login Sign in with the cloud (OAuth by default; --device for legacy device-code)
|
|
45310
45572
|
logout Clear local cloud credentials
|
|
45311
45573
|
sync now Flush outbox to the cloud once
|
|
45312
45574
|
privacy Show what is collected/scrubbed + your consent state
|
|
@@ -45321,7 +45583,7 @@ Commands:
|
|
|
45321
45583
|
Environment:
|
|
45322
45584
|
ERRATA_CLOUD_URL Cloud base URL (default ${DEFAULT_CLOUD_URL})
|
|
45323
45585
|
ERRATA_ALLOW_DIRECT_V1_CLOUD=1 Allow non-local legacy v1 cloud testing
|
|
45324
|
-
${OAUTH_DEFAULT_ENV}=
|
|
45586
|
+
${OAUTH_DEFAULT_ENV}=0 Test/dev escape hatch: plain \`errata login\` uses legacy device-code
|
|
45325
45587
|
`);
|
|
45326
45588
|
}
|
|
45327
45589
|
function resolveHookPort(explicit) {
|