@inerrata-corporation/errata 2.0.0-dev.56 → 2.0.0-dev.58

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 +48 -8
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -21216,6 +21216,16 @@ var init_client = __esm({
21216
21216
  * resolvable member ids. AUTHED. Always HTTP 200 — the `status` field
21217
21217
  * discriminates outcomes (incl. the autophagy-floor refusal, which is a
21218
21218
  * normal "not enough collective grounding yet" result, not an error). */
21219
+ /** Durable skills pinned to this workspace's cloud project (bodies included).
21220
+ * The daemon claims these on its skill-sync tick and installs them into
21221
+ * `.errata/skills/`, unioned into the collective set (never pruned). Returns
21222
+ * an empty set when nothing is pinned or the project isn't linked. */
21223
+ async getSkillPins(projectId) {
21224
+ return this.json(
21225
+ "GET",
21226
+ `/v2/skill-pins?projectId=${encodeURIComponent(projectId)}`
21227
+ );
21228
+ }
21219
21229
  async induceSkill(body2) {
21220
21230
  return this.json("POST", "/v2/skills/induce", body2);
21221
21231
  }
@@ -21507,13 +21517,21 @@ function loadConfig() {
21507
21517
  const raw2 = readFileSync3(p, "utf8").replace(/^\uFEFF/, "");
21508
21518
  const parsed = JSON.parse(raw2);
21509
21519
  const base = defaultConfig();
21510
- return {
21520
+ const envCloudUrl = process.env["ERRATA_CLOUD_URL"];
21521
+ const migrateLegacyDefault = parsed.cloudUrl === LEGACY_CLOUD_URL;
21522
+ const resolved = {
21511
21523
  ...base,
21512
21524
  ...parsed,
21525
+ // An explicit environment override always wins, including when a persisted
21526
+ // config already exists. Existing installs on the retired official Render
21527
+ // default migrate to the endpoint baked into their installed dist-tag.
21528
+ cloudUrl: envCloudUrl ?? (migrateLegacyDefault ? DEFAULT_CLOUD_URL : parsed.cloudUrl ?? base.cloudUrl),
21513
21529
  // Deep-merge consent so an old/partial config keeps the opt-in defaults
21514
21530
  // for any channel it doesn't mention.
21515
21531
  consent: { ...base.consent, ...parsed.consent ?? {} }
21516
21532
  };
21533
+ if (migrateLegacyDefault && !envCloudUrl) saveConfig(resolved);
21534
+ return resolved;
21517
21535
  }
21518
21536
  function saveConfig(cfg) {
21519
21537
  ensureDir(globalDir());
@@ -21541,12 +21559,13 @@ function clearActiveAgent(cfg = loadConfig()) {
21541
21559
  saveConfig(next);
21542
21560
  return next;
21543
21561
  }
21544
- var DEFAULT_CLOUD_URL;
21562
+ var LEGACY_CLOUD_URL, DEFAULT_CLOUD_URL;
21545
21563
  var init_config = __esm({
21546
21564
  "src/config.ts"() {
21547
21565
  "use strict";
21548
21566
  init_paths();
21549
- DEFAULT_CLOUD_URL = "https://inerrata-gateway.onrender.com";
21567
+ LEGACY_CLOUD_URL = "https://inerrata-gateway.onrender.com";
21568
+ DEFAULT_CLOUD_URL = true ? "https://dev.inerrata.dev" : DEV_CLOUD_URL;
21550
21569
  }
21551
21570
  });
21552
21571
 
@@ -21566,10 +21585,13 @@ function isLocalCloudUrl(url2) {
21566
21585
  return false;
21567
21586
  }
21568
21587
  }
21588
+ function isMachinePlaneGatewayHost(host) {
21589
+ return host === "inerrata.dev" || host === "dev.inerrata.dev";
21590
+ }
21569
21591
  function looksLikeGatewayCloudUrl(url2) {
21570
21592
  try {
21571
21593
  const host = new URL(url2).hostname.toLowerCase();
21572
- return host.includes("gateway") || host.startsWith("gw.") || host.includes("-gw.");
21594
+ return host.includes("gateway") || host.startsWith("gw.") || host.includes("-gw.") || isMachinePlaneGatewayHost(host);
21573
21595
  } catch {
21574
21596
  return false;
21575
21597
  }
@@ -42362,11 +42384,11 @@ function readSkillManifest(manifestPath) {
42362
42384
  return [];
42363
42385
  }
42364
42386
  }
42365
- async function syncSkills(paths, client, seed) {
42387
+ async function syncSkills(paths, client, seed, pins = []) {
42366
42388
  const res = await client.getSkills(void 0, seed);
42367
42389
  const staleDaemon = res.staleDaemon && res.latestDaemonVersion ? { latest: res.latestDaemonVersion } : void 0;
42368
42390
  mkdirSync5(paths.skillsDir, { recursive: true });
42369
- if (res.skills.length === 0) {
42391
+ if (res.skills.length === 0 && pins.length === 0) {
42370
42392
  const existing = readdirSync6(paths.skillsDir).filter((f) => f.endsWith(".md"));
42371
42393
  if (existing.length > 0) return { written: 0, pruned: 0, ...staleDaemon ? { staleDaemon } : {} };
42372
42394
  }
@@ -42384,6 +42406,19 @@ async function syncSkills(paths, client, seed) {
42384
42406
  file: `skills/${fileName}`
42385
42407
  });
42386
42408
  }
42409
+ for (const p of pins) {
42410
+ const fileName = skillFileName(p.id);
42411
+ if (keep.has(fileName)) continue;
42412
+ keep.add(fileName);
42413
+ writeFileSync10(join18(paths.skillsDir, fileName), p.markdown, "utf8");
42414
+ rows.push({
42415
+ id: p.id,
42416
+ title: p.title,
42417
+ layer: p.layer,
42418
+ confidence: p.confidence,
42419
+ file: `skills/${fileName}`
42420
+ });
42421
+ }
42387
42422
  let pruned = 0;
42388
42423
  for (const f of readdirSync6(paths.skillsDir)) {
42389
42424
  if (!f.endsWith(".md")) continue;
@@ -42820,7 +42855,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
42820
42855
  }
42821
42856
 
42822
42857
  // src/engine.ts
42823
- var DAEMON_VERSION = true ? "2.0.0-dev.56" : "2.0.0-alpha.0";
42858
+ var DAEMON_VERSION = true ? "2.0.0-dev.58" : "2.0.0-alpha.0";
42824
42859
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
42825
42860
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
42826
42861
  var GIT_OP_MUTE_MS = 4e3;
@@ -43802,7 +43837,8 @@ function createWorkspaceEngine(opts) {
43802
43837
  const cloudId = p.attrs["cloudNodeId"];
43803
43838
  return typeof cloudId === "string" && cloudId !== p.id ? [p.id, cloudId] : [p.id];
43804
43839
  });
43805
- return syncSkills(paths, cloud, skillSeed);
43840
+ const pins = profile?.projectId ? await cloud.getSkillPins(profile.projectId).then((r) => r.pins).catch(() => []) : [];
43841
+ return syncSkills(paths, cloud, skillSeed, pins);
43806
43842
  };
43807
43843
  return {
43808
43844
  profile,
@@ -46032,6 +46068,10 @@ var cmd = argv[0] ?? "help";
46032
46068
  var rest = argv.slice(1);
46033
46069
  var NIGHTLY_INTERVAL_MS = 10 * 6e4;
46034
46070
  async function main() {
46071
+ if (cmd === "--version" || cmd === "-V" || cmd === "version") {
46072
+ console.log(DAEMON_VERSION);
46073
+ return;
46074
+ }
46035
46075
  if (cmd !== "help" && cmd !== "--help" && cmd !== "-h" && (rest.includes("--help") || rest.includes("-h"))) {
46036
46076
  return printHelp();
46037
46077
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.56",
3
+ "version": "2.0.0-dev.58",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {