@inerrata-corporation/errata 2.0.0-dev.51 → 2.0.0-dev.53

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.
Files changed (2) hide show
  1. package/errata.mjs +84 -4
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -20934,6 +20934,11 @@ var init_client = __esm({
20934
20934
  async me() {
20935
20935
  return this.json("GET", "/v2/me");
20936
20936
  }
20937
+ /** Current plan/quota/cost status through the gateway. The gateway flushes
20938
+ * this replica's ≤2s usage batch before reading the canonical Hono ledger. */
20939
+ async usage() {
20940
+ return this.json("GET", "/v2/usage");
20941
+ }
20937
20942
  // ─── acting-agent switching (gateway control plane, #898) ───────────
20938
20943
  /** Agents the authenticated user may act as, plus their default agent.
20939
20944
  * Authenticated with the caller's console-signed gateway JWT. */
@@ -24526,7 +24531,7 @@ var init_generalize_graph = __esm({
24526
24531
 
24527
24532
  // src/dual-burst.ts
24528
24533
  function collectiveScore(hit, cap) {
24529
- if (hit.cloudScore != null) return Math.min(cap, Math.max(0, hit.cloudScore));
24534
+ if (hit.cloudScore != null) return cap * Math.max(0, Math.min(1, hit.cloudScore));
24530
24535
  const u = hit.usageCount ?? 0;
24531
24536
  return Math.min(cap, Math.log10(u + 1) / 3);
24532
24537
  }
@@ -24597,20 +24602,26 @@ function dedupCloudHits(hits) {
24597
24602
  }
24598
24603
  function searchResultToCloudHits(result) {
24599
24604
  const n = result.nodes.length;
24605
+ const scores = result.nodes.map((nd) => typeof nd.attrs?.["score"] === "number" ? nd.attrs["score"] : NaN);
24606
+ const maxScore = Math.max(0, ...scores.filter((s) => !Number.isNaN(s)));
24600
24607
  return result.nodes.map((node2, i2) => {
24601
24608
  const usage = node2.attrs?.["usageCount"];
24609
+ const s = scores[i2];
24610
+ const cloudScore = !Number.isNaN(s) && maxScore > 0 ? s / maxScore : n > 0 ? (n - i2) / n : 0;
24602
24611
  return {
24603
24612
  id: node2.id,
24604
24613
  label: node2.label,
24605
24614
  description: node2.description,
24606
- cloudScore: n > 0 ? (n - i2) / n : 0,
24615
+ cloudScore,
24607
24616
  ...typeof usage === "number" ? { usageCount: usage } : {}
24608
24617
  };
24609
24618
  });
24610
24619
  }
24620
+ var DUAL_BURST_SEMANTIC_NEUTRAL;
24611
24621
  var init_dual_burst = __esm({
24612
24622
  "src/dual-burst.ts"() {
24613
24623
  "use strict";
24624
+ DUAL_BURST_SEMANTIC_NEUTRAL = 0.3;
24614
24625
  }
24615
24626
  });
24616
24627
 
@@ -24705,7 +24716,7 @@ import { homedir as homedir2 } from "node:os";
24705
24716
  import { dirname as dirname3, join as join4 } from "node:path";
24706
24717
  import { createRequire } from "node:module";
24707
24718
  function semanticFloorFor(version2) {
24708
- if (version2 === EMBEDDING_VERSION) return 0.25;
24719
+ if (version2 === EMBEDDING_VERSION || version2 === MODEL_EMBEDDING_VERSION) return 0.25;
24709
24720
  return 0.5;
24710
24721
  }
24711
24722
  function noteHashFallback() {
@@ -26249,6 +26260,30 @@ function embedCodeNodes(store, opts = {}) {
26249
26260
  function embedSemanticNodes(store, opts = {}) {
26250
26261
  return embedNodesByLabels(store, SEMANTIC_LABELS, opts);
26251
26262
  }
26263
+ async function ensureNodeEmbedded(store, nodeId, opts = {}) {
26264
+ const node2 = store.getNode(nodeId);
26265
+ if (!node2 || node2.embedding.length > 0) return false;
26266
+ const text = buildText(store, node2);
26267
+ if (!text) return false;
26268
+ let result;
26269
+ try {
26270
+ if (opts.mode === "hash") {
26271
+ const v = embed(text);
26272
+ result = { vector: v, version: EMBEDDING_VERSION, dim: v.length };
26273
+ } else {
26274
+ const r = (await embedBatchWithModelOrHash([text]))[0];
26275
+ if (!r) return false;
26276
+ result = r;
26277
+ }
26278
+ } catch {
26279
+ return false;
26280
+ }
26281
+ store.updateNode(nodeId, {
26282
+ embedding: result.vector,
26283
+ attrs: { ...node2.attrs, embeddingVersion: result.version }
26284
+ });
26285
+ return true;
26286
+ }
26252
26287
  async function embedNodesByLabels(store, labels, opts = {}) {
26253
26288
  const started2 = Date.now();
26254
26289
  const report = {
@@ -26455,6 +26490,7 @@ __export(src_exports4, {
26455
26490
  commandSignature: () => commandSignature,
26456
26491
  embedCodeNodes: () => embedCodeNodes,
26457
26492
  embedSemanticNodes: () => embedSemanticNodes,
26493
+ ensureNodeEmbedded: () => ensureNodeEmbedded,
26458
26494
  evaluateForReview: () => evaluateForReview,
26459
26495
  extractDiagnostics: () => extractDiagnostics,
26460
26496
  extractErrorSignature: () => extractErrorSignature,
@@ -35728,6 +35764,7 @@ var init_mcp = __esm({
35728
35764
  init_src4();
35729
35765
  init_src2();
35730
35766
  init_src10();
35767
+ init_dual_burst();
35731
35768
  init_paths();
35732
35769
  init_symbol_summaries();
35733
35770
  init_webui();
@@ -35955,7 +35992,15 @@ var init_mcp = __esm({
35955
35992
  }
35956
35993
  return unresolved(args2);
35957
35994
  }
35995
+ const seedForBurst = store.getNode(id);
35996
+ if (seedForBurst && seedForBurst.embedding.length === 0) {
35997
+ await ensureNodeEmbedded(store, id);
35998
+ }
35958
35999
  const ranked = localBurst(store, id, {
36000
+ // Hold an embeddingless candidate's neutral semantic under the dual-burst
36001
+ // cloud cap so unknown local code can't outrank the capped collective (see
36002
+ // DUAL_BURST_SEMANTIC_NEUTRAL). No-op for local-only bursts.
36003
+ weights: { semanticNeutral: DUAL_BURST_SEMANTIC_NEUTRAL },
35959
36004
  ...args2["maxHops"] != null ? { maxHops: Number(args2["maxHops"]) } : {},
35960
36005
  ...args2["limit"] != null ? { limit: Number(args2["limit"]) } : {}
35961
36006
  });
@@ -42754,7 +42799,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
42754
42799
  }
42755
42800
 
42756
42801
  // src/engine.ts
42757
- var DAEMON_VERSION = true ? "2.0.0-dev.51" : "2.0.0-alpha.0";
42802
+ var DAEMON_VERSION = true ? "2.0.0-dev.53" : "2.0.0-alpha.0";
42758
42803
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
42759
42804
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
42760
42805
  var GIT_OP_MUTE_MS = 4e3;
@@ -45967,6 +46012,8 @@ async function main() {
45967
46012
  return cmdStop();
45968
46013
  case "status":
45969
46014
  return cmdStatus();
46015
+ case "usage":
46016
+ return cmdUsage();
45970
46017
  case "login":
45971
46018
  return cmdLogin();
45972
46019
  case "logout":
@@ -46053,6 +46100,8 @@ Commands:
46053
46100
  start Run the daemon (FS watchers + hook receiver + tick loop)
46054
46101
  stop Stop a running daemon (reads .errata/daemon.lock for the pid)
46055
46102
  status Print workspace + cloud status (incl. version + pending update)
46103
+ usage Show current cloud plan, units remaining, estimated cost,
46104
+ and per-tool usage (reads the gateway's batched Hono ledger)
46056
46105
  update [--channel dev|latest] [--check]
46057
46106
  Pull the newest build on this machine's channel via npm.
46058
46107
  --check only reports; --channel switches + persists channel.
@@ -46458,6 +46507,37 @@ function applyCloudUrl(cfg, url2) {
46458
46507
  function cloudPolicyMessage(cfg, inspection) {
46459
46508
  return formatCloudEndpointBlock(cfg.cloudUrl, evaluateCloudEndpoint(cfg.cloudUrl, inspection));
46460
46509
  }
46510
+ async function cmdUsage() {
46511
+ const cfg = loadConfig();
46512
+ if (!hasCloudCredential(cfg)) {
46513
+ console.error("not logged in \u2014 run `errata login` first");
46514
+ process.exitCode = 1;
46515
+ return;
46516
+ }
46517
+ try {
46518
+ const status = await authedCloudClient(cfg).usage();
46519
+ const quota = status.quota.unlimited ? `${status.quota.units_used.toLocaleString()} used \xB7 unlimited` : `${status.quota.units_used.toLocaleString()} / ${status.quota.effective_unit_limit?.toLocaleString()} used \xB7 ${status.quota.units_remaining?.toLocaleString()} remaining`;
46520
+ console.log(`inErrata usage \u2014 ${status.plan}`);
46521
+ console.log(` period: ${status.period_start.slice(0, 10)} \u2192 ${status.period_end.slice(0, 10)}`);
46522
+ console.log(` units: ${quota}`);
46523
+ console.log(` calls: ${status.totals.event_count.toLocaleString()}`);
46524
+ if (status.quota.units_reserved > 0) {
46525
+ console.log(` held: ${status.quota.units_reserved.toLocaleString()} units reserved by in-flight calls`);
46526
+ }
46527
+ console.log(` cost: $${(status.quota.estimated_cents_current / 100).toFixed(2)} estimated`);
46528
+ console.log(` rate: $${(status.pricing.cents_per_1000_units / 100).toFixed(2)} / 1,000 units${status.pricing.estimate_only ? " (estimate, not an invoice)" : ""}`);
46529
+ if (status.by_tool.length > 0) {
46530
+ console.log(" tools:");
46531
+ for (const row of [...status.by_tool].sort((a, b) => b.units - a.units).slice(0, 10)) {
46532
+ console.log(` ${row.tool.padEnd(24)} ${row.units.toLocaleString().padStart(8)} units ${row.event_count.toLocaleString().padStart(6)} calls`);
46533
+ }
46534
+ }
46535
+ console.log(` as of: ${status.as_of} (ledger + live reservations; poll again after ${Math.ceil(status.poll_after_ms / 1e3)}s)`);
46536
+ } catch (err2) {
46537
+ console.error(`usage unavailable: ${err2 instanceof Error ? err2.message : err2}`);
46538
+ process.exitCode = 1;
46539
+ }
46540
+ }
46461
46541
  async function applyToken(cfg, token) {
46462
46542
  const inspection = await inspectCloudEndpoint(cfg.cloudUrl);
46463
46543
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.51",
3
+ "version": "2.0.0-dev.53",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {