@inerrata-corporation/errata 2.0.22-dev.4660 → 2.0.22-dev.4665

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.
@@ -17575,7 +17575,13 @@ var DEMAND_HOT = Math.log1p(10);
17575
17575
  var DEMAND_WARM = Math.log1p(5);
17576
17576
 
17577
17577
  // ../../packages/local-graph/src/node-select.ts
17578
- var SELECT_INDEXES = ["nodes_live_local_community", "nodes_live_fold_candidate"];
17578
+ var SELECT_INDEXES = [
17579
+ "nodes_live_local_community",
17580
+ "nodes_live_fold_candidate",
17581
+ "nodes_live_resolved",
17582
+ "nodes_live_fix_candidate",
17583
+ "nodes_live_anchor_hint"
17584
+ ];
17579
17585
  var EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
17580
17586
  var KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
17581
17587
  var COLUMNS = /* @__PURE__ */ new Set([
@@ -17602,7 +17608,7 @@ function column(c) {
17602
17608
  function compileNodeWhere(q) {
17603
17609
  if (q.labels.length === 0) throw new Error("selectNodes: no labels");
17604
17610
  const params = [...q.labels];
17605
- const byId = (q.where ?? []).some((w) => "idIn" in w);
17611
+ const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
17606
17612
  const unindexed = byId ? "+" : "";
17607
17613
  const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
17608
17614
  if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
@@ -17612,6 +17618,11 @@ function compileNodeWhere(q) {
17612
17618
  } else if ("idPrefix" in w) {
17613
17619
  conds.push("substr(id, 1, ?) = ?");
17614
17620
  params.push(w.idPrefix.length, w.idPrefix);
17621
+ if (w.idPrefix.length > 0) {
17622
+ const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
17623
+ conds.push("id >= ? AND id < ?");
17624
+ params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
17625
+ }
17615
17626
  } else if ("idIn" in w) {
17616
17627
  if (w.idIn.length === 0) conds.push("0");
17617
17628
  else {
@@ -17893,6 +17904,12 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
17893
17904
  -- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
17894
17905
  -- Problems; without it every live Problem was read to find them (56 MB).
17895
17906
  CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
17907
+ -- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
17908
+ -- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
17909
+ -- several times a run, and a run follows most writes (2026-10-20).
17910
+ CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
17911
+ CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
17912
+ CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
17896
17913
  CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
17897
17914
  CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
17898
17915
  -- Covering + partial index for labelFingerprint over the instance labels: the
package/errata.mjs CHANGED
@@ -20398,7 +20398,7 @@ function column(c) {
20398
20398
  function compileNodeWhere(q) {
20399
20399
  if (q.labels.length === 0) throw new Error("selectNodes: no labels");
20400
20400
  const params = [...q.labels];
20401
- const byId = (q.where ?? []).some((w) => "idIn" in w);
20401
+ const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
20402
20402
  const unindexed = byId ? "+" : "";
20403
20403
  const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
20404
20404
  if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
@@ -20408,6 +20408,11 @@ function compileNodeWhere(q) {
20408
20408
  } else if ("idPrefix" in w) {
20409
20409
  conds.push("substr(id, 1, ?) = ?");
20410
20410
  params.push(w.idPrefix.length, w.idPrefix);
20411
+ if (w.idPrefix.length > 0) {
20412
+ const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
20413
+ conds.push("id >= ? AND id < ?");
20414
+ params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
20415
+ }
20411
20416
  } else if ("idIn" in w) {
20412
20417
  if (w.idIn.length === 0) conds.push("0");
20413
20418
  else {
@@ -20530,7 +20535,13 @@ var SELECT_INDEXES, EMBEDDING_DIM_SQL, KEY, COLUMNS;
20530
20535
  var init_node_select = __esm({
20531
20536
  "../../packages/local-graph/src/node-select.ts"() {
20532
20537
  "use strict";
20533
- SELECT_INDEXES = ["nodes_live_local_community", "nodes_live_fold_candidate"];
20538
+ SELECT_INDEXES = [
20539
+ "nodes_live_local_community",
20540
+ "nodes_live_fold_candidate",
20541
+ "nodes_live_resolved",
20542
+ "nodes_live_fix_candidate",
20543
+ "nodes_live_anchor_hint"
20544
+ ];
20534
20545
  EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
20535
20546
  KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
20536
20547
  COLUMNS = /* @__PURE__ */ new Set([
@@ -20801,6 +20812,12 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
20801
20812
  -- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
20802
20813
  -- Problems; without it every live Problem was read to find them (56 MB).
20803
20814
  CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
20815
+ -- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
20816
+ -- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
20817
+ -- several times a run, and a run follows most writes (2026-10-20).
20818
+ CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
20819
+ CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
20820
+ CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
20804
20821
  CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
20805
20822
  CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
20806
20823
  -- Covering + partial index for labelFingerprint over the instance labels: the
@@ -24534,7 +24551,8 @@ function upgradeAnchorHints(store, workspaceId2, ts) {
24534
24551
  const hinted = store.selectNodes({
24535
24552
  labels: ["Problem"],
24536
24553
  attrs: ["resolvedAt", "anchorHint"],
24537
- where: [{ attr: "anchorHint", notNullish: true }]
24554
+ where: [{ attr: "anchorHint", notNullish: true }],
24555
+ indexedBy: "nodes_live_anchor_hint"
24538
24556
  });
24539
24557
  for (const row of hinted) {
24540
24558
  if (row.attrs["resolvedAt"]) continue;
@@ -24617,7 +24635,8 @@ function reopenAutoClosedProblems(store, t) {
24617
24635
  const closed = store.selectNodes({
24618
24636
  labels: ["Problem"],
24619
24637
  attrs: ["resolvedAt", "resolvedAs", "mergedInto", "resolutionWitnessed", "retiredEditPlaceholder", "resolutionSuspect"],
24620
- where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }]
24638
+ where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }],
24639
+ indexedBy: "nodes_live_resolved"
24621
24640
  });
24622
24641
  for (const p of closed) {
24623
24642
  if (p.attrs["resolvedAt"] == null) continue;
@@ -24735,7 +24754,7 @@ function markFixCandidates(store, t) {
24735
24754
  }
24736
24755
  function clearSettledFixCandidates(store, t) {
24737
24756
  const report = { answered: 0, ignored: 0, unsubstantiated: 0, standing: 0 };
24738
- const asked = store.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }] });
24757
+ const asked = store.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }], indexedBy: "nodes_live_fix_candidate" });
24739
24758
  for (const row of asked) {
24740
24759
  const p = store.getNode(row.id);
24741
24760
  if (!p) continue;
@@ -87030,7 +87049,7 @@ function createWatchBreaker(deps) {
87030
87049
  }
87031
87050
 
87032
87051
  // src/engine.ts
87033
- var DAEMON_VERSION = true ? "2.0.22-dev.4660" : "2.0.0-alpha.0";
87052
+ var DAEMON_VERSION = true ? "2.0.22-dev.4665" : "2.0.0-alpha.0";
87034
87053
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
87035
87054
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
87036
87055
  var GIT_OP_MUTE_MS = 4e3;
@@ -15972,7 +15972,13 @@ var DEMAND_HOT = Math.log1p(10);
15972
15972
  var DEMAND_WARM = Math.log1p(5);
15973
15973
 
15974
15974
  // ../../packages/local-graph/src/node-select.ts
15975
- var SELECT_INDEXES = ["nodes_live_local_community", "nodes_live_fold_candidate"];
15975
+ var SELECT_INDEXES = [
15976
+ "nodes_live_local_community",
15977
+ "nodes_live_fold_candidate",
15978
+ "nodes_live_resolved",
15979
+ "nodes_live_fix_candidate",
15980
+ "nodes_live_anchor_hint"
15981
+ ];
15976
15982
  var EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
15977
15983
  var KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
15978
15984
  var COLUMNS = /* @__PURE__ */ new Set([
@@ -15999,7 +16005,7 @@ function column(c) {
15999
16005
  function compileNodeWhere(q) {
16000
16006
  if (q.labels.length === 0) throw new Error("selectNodes: no labels");
16001
16007
  const params = [...q.labels];
16002
- const byId = (q.where ?? []).some((w) => "idIn" in w);
16008
+ const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
16003
16009
  const unindexed = byId ? "+" : "";
16004
16010
  const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
16005
16011
  if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
@@ -16009,6 +16015,11 @@ function compileNodeWhere(q) {
16009
16015
  } else if ("idPrefix" in w) {
16010
16016
  conds.push("substr(id, 1, ?) = ?");
16011
16017
  params.push(w.idPrefix.length, w.idPrefix);
16018
+ if (w.idPrefix.length > 0) {
16019
+ const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
16020
+ conds.push("id >= ? AND id < ?");
16021
+ params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
16022
+ }
16012
16023
  } else if ("idIn" in w) {
16013
16024
  if (w.idIn.length === 0) conds.push("0");
16014
16025
  else {
@@ -16290,6 +16301,12 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
16290
16301
  -- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
16291
16302
  -- Problems; without it every live Problem was read to find them (56 MB).
16292
16303
  CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
16304
+ -- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
16305
+ -- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
16306
+ -- several times a run, and a run follows most writes (2026-10-20).
16307
+ CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
16308
+ CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
16309
+ CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
16293
16310
  CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
16294
16311
  CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
16295
16312
  -- Covering + partial index for labelFingerprint over the instance labels: the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.22-dev.4660",
3
+ "version": "2.0.22-dev.4665",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -26851,7 +26851,13 @@ function pagerankLocal(input) {
26851
26851
  }
26852
26852
 
26853
26853
  // ../../packages/local-graph/src/node-select.ts
26854
- var SELECT_INDEXES = ["nodes_live_local_community", "nodes_live_fold_candidate"];
26854
+ var SELECT_INDEXES = [
26855
+ "nodes_live_local_community",
26856
+ "nodes_live_fold_candidate",
26857
+ "nodes_live_resolved",
26858
+ "nodes_live_fix_candidate",
26859
+ "nodes_live_anchor_hint"
26860
+ ];
26855
26861
  var EMBEDDING_DIM_SQL = "(CASE WHEN length(embedding_blob) >= 4 THEN length(embedding_blob) / 4 ELSE COALESCE(json_array_length(embedding_json), 0) END)";
26856
26862
  var KEY = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
26857
26863
  var COLUMNS = /* @__PURE__ */ new Set([
@@ -26878,7 +26884,7 @@ function column(c) {
26878
26884
  function compileNodeWhere(q) {
26879
26885
  if (q.labels.length === 0) throw new Error("selectNodes: no labels");
26880
26886
  const params = [...q.labels];
26881
- const byId = (q.where ?? []).some((w) => "idIn" in w);
26887
+ const byId = (q.where ?? []).some((w) => "idIn" in w || "idPrefix" in w && w.idPrefix.length > 0);
26882
26888
  const unindexed = byId ? "+" : "";
26883
26889
  const conds = [`${unindexed}label IN (${q.labels.map(() => "?").join(", ")})`];
26884
26890
  if (!q.includeClosed) conds.push(`${unindexed}valid_to IS NULL`);
@@ -26888,6 +26894,11 @@ function compileNodeWhere(q) {
26888
26894
  } else if ("idPrefix" in w) {
26889
26895
  conds.push("substr(id, 1, ?) = ?");
26890
26896
  params.push(w.idPrefix.length, w.idPrefix);
26897
+ if (w.idPrefix.length > 0) {
26898
+ const last = w.idPrefix.charCodeAt(w.idPrefix.length - 1);
26899
+ conds.push("id >= ? AND id < ?");
26900
+ params.push(w.idPrefix, w.idPrefix.slice(0, -1) + String.fromCharCode(last + 1));
26901
+ }
26891
26902
  } else if ("idIn" in w) {
26892
26903
  if (w.idIn.length === 0) conds.push("0");
26893
26904
  else {
@@ -27169,6 +27180,12 @@ CREATE INDEX IF NOT EXISTS nodes_live_local_community ON nodes(label, valid_to,
27169
27180
  -- Problems parked for the fold judge (read every settle boundary): ~1 in 5 open
27170
27181
  -- Problems; without it every live Problem was read to find them (56 MB).
27171
27182
  CREATE INDEX IF NOT EXISTS nodes_live_fold_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.foldCandidate') IS NOT NULL;
27183
+ -- The semantic-maintenance sweeps' own filters (closed, asked, hinted): each read
27184
+ -- every Problem row (~30 MB on a 1.1 GB store) for the few hundred that match,
27185
+ -- several times a run, and a run follows most writes (2026-10-20).
27186
+ CREATE INDEX IF NOT EXISTS nodes_live_resolved ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.resolvedAt') IS NOT NULL;
27187
+ CREATE INDEX IF NOT EXISTS nodes_live_fix_candidate ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_type(attrs_json, '$.fixCandidateAt') IS NOT NULL;
27188
+ CREATE INDEX IF NOT EXISTS nodes_live_anchor_hint ON nodes(label, valid_to) WHERE valid_to IS NULL AND json_extract(attrs_json, '$.anchorHint') IS NOT NULL;
27172
27189
  CREATE INDEX IF NOT EXISTS nodes_session_evidence ON nodes(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
27173
27190
  CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_EVIDENCE_PREDICATE};
27174
27191
  -- Covering + partial index for labelFingerprint over the instance labels: the
@@ -29387,7 +29404,8 @@ function upgradeAnchorHints(store2, workspaceId, ts) {
29387
29404
  const hinted = store2.selectNodes({
29388
29405
  labels: ["Problem"],
29389
29406
  attrs: ["resolvedAt", "anchorHint"],
29390
- where: [{ attr: "anchorHint", notNullish: true }]
29407
+ where: [{ attr: "anchorHint", notNullish: true }],
29408
+ indexedBy: "nodes_live_anchor_hint"
29391
29409
  });
29392
29410
  for (const row of hinted) {
29393
29411
  if (row.attrs["resolvedAt"]) continue;
@@ -29418,7 +29436,8 @@ function reopenAutoClosedProblems(store2, t) {
29418
29436
  const closed = store2.selectNodes({
29419
29437
  labels: ["Problem"],
29420
29438
  attrs: ["resolvedAt", "resolvedAs", "mergedInto", "resolutionWitnessed", "retiredEditPlaceholder", "resolutionSuspect"],
29421
- where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }]
29439
+ where: [{ attr: "resolvedAt", notNullish: true }, { attr: "resolvedAs", nullish: true }, { attr: "mergedInto", absent: true }],
29440
+ indexedBy: "nodes_live_resolved"
29422
29441
  });
29423
29442
  for (const p of closed) {
29424
29443
  if (p.attrs["resolvedAt"] == null) continue;
@@ -29507,7 +29526,7 @@ function markFixCandidates(store2, t) {
29507
29526
  var FIX_CANDIDATE_ASK_LIMIT = 5;
29508
29527
  function clearSettledFixCandidates(store2, t) {
29509
29528
  const report = { answered: 0, ignored: 0, unsubstantiated: 0, standing: 0 };
29510
- const asked = store2.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }] });
29529
+ const asked = store2.selectNodes({ labels: ["Problem"], where: [{ attr: "fixCandidateAt", present: true }], indexedBy: "nodes_live_fix_candidate" });
29511
29530
  for (const row of asked) {
29512
29531
  const p = store2.getNode(row.id);
29513
29532
  if (!p) continue;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "errata-context",
3
- "version": "2.0.22-dev.4660",
3
+ "version": "2.0.22-dev.4665",
4
4
  "description": "A minimal 3D view of loaded Errata priors and recent graph bursts.",
5
5
  "author": {
6
6
  "name": "inErrata"
@@ -1,4 +1,4 @@
1
- 3bcb422706463f9d29ee3751dd1036046ce56211386ec8d38b1cbe53b26ac809 .codex-plugin/plugin.json
1
+ f1e400bb7113a7620b6d9642dba999330a5888059992763fc34dd7c802ff0843 .codex-plugin/plugin.json
2
2
  a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
3
3
  fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
4
4
  73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js