@glasstrace/sdk 1.4.0 → 1.5.1

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 (43) hide show
  1. package/README.md +56 -0
  2. package/dist/{chunk-JZ475QRH.js → chunk-D3QXU2VM.js} +22 -191
  3. package/dist/chunk-D3QXU2VM.js.map +1 -0
  4. package/dist/{chunk-VQDYXXVS.js → chunk-MLRQTCCK.js} +154 -8
  5. package/dist/chunk-MLRQTCCK.js.map +1 -0
  6. package/dist/{chunk-VJQIFY33.js → chunk-YLY7AGLC.js} +7 -4
  7. package/dist/chunk-YLY7AGLC.js.map +1 -0
  8. package/dist/chunk-ZBQQXVHD.js +208 -0
  9. package/dist/chunk-ZBQQXVHD.js.map +1 -0
  10. package/dist/cli/init.cjs +206 -34
  11. package/dist/cli/init.cjs.map +1 -1
  12. package/dist/cli/init.js +65 -8
  13. package/dist/cli/init.js.map +1 -1
  14. package/dist/cli/mcp-add.cjs +45 -25
  15. package/dist/cli/mcp-add.cjs.map +1 -1
  16. package/dist/cli/mcp-add.js +10 -7
  17. package/dist/cli/mcp-add.js.map +1 -1
  18. package/dist/cli/status.cjs +33 -3
  19. package/dist/cli/status.cjs.map +1 -1
  20. package/dist/cli/status.js +12 -3
  21. package/dist/cli/status.js.map +1 -1
  22. package/dist/cli/uninit.cjs +27 -3
  23. package/dist/cli/uninit.cjs.map +1 -1
  24. package/dist/cli/uninit.d.cts +10 -2
  25. package/dist/cli/uninit.d.ts +10 -2
  26. package/dist/cli/uninit.js +2 -1
  27. package/dist/cli/upgrade-instructions.cjs +440 -0
  28. package/dist/cli/upgrade-instructions.cjs.map +1 -0
  29. package/dist/cli/upgrade-instructions.d.cts +48 -0
  30. package/dist/cli/upgrade-instructions.d.ts +48 -0
  31. package/dist/cli/upgrade-instructions.js +80 -0
  32. package/dist/cli/upgrade-instructions.js.map +1 -0
  33. package/dist/index.cjs +229 -60
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.js +2 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/node-entry.cjs +237 -68
  38. package/dist/node-entry.cjs.map +1 -1
  39. package/dist/node-entry.js +2 -1
  40. package/package.json +3 -2
  41. package/dist/chunk-JZ475QRH.js.map +0 -1
  42. package/dist/chunk-VJQIFY33.js.map +0 -1
  43. package/dist/chunk-VQDYXXVS.js.map +0 -1
@@ -339,10 +339,10 @@ function mergeDefs(...defs) {
339
339
  function cloneDef(schema) {
340
340
  return mergeDefs(schema._zod.def);
341
341
  }
342
- function getElementAtPath(obj, path4) {
343
- if (!path4)
342
+ function getElementAtPath(obj, path5) {
343
+ if (!path5)
344
344
  return obj;
345
- return path4.reduce((acc, key) => acc?.[key], obj);
345
+ return path5.reduce((acc, key) => acc?.[key], obj);
346
346
  }
347
347
  function promiseAllObject(promisesObj) {
348
348
  const keys = Object.keys(promisesObj);
@@ -654,11 +654,11 @@ function aborted(x, startIndex = 0) {
654
654
  }
655
655
  return false;
656
656
  }
657
- function prefixIssues(path4, issues) {
657
+ function prefixIssues(path5, issues) {
658
658
  return issues.map((iss) => {
659
659
  var _a2;
660
660
  (_a2 = iss).path ?? (_a2.path = []);
661
- iss.path.unshift(path4);
661
+ iss.path.unshift(path5);
662
662
  return iss;
663
663
  });
664
664
  }
@@ -901,7 +901,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
901
901
  }
902
902
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
903
903
  const result = { errors: [] };
904
- const processError = (error49, path4 = []) => {
904
+ const processError = (error49, path5 = []) => {
905
905
  var _a2, _b;
906
906
  for (const issue2 of error49.issues) {
907
907
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -911,7 +911,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
911
911
  } else if (issue2.code === "invalid_element") {
912
912
  processError({ issues: issue2.issues }, issue2.path);
913
913
  } else {
914
- const fullpath = [...path4, ...issue2.path];
914
+ const fullpath = [...path5, ...issue2.path];
915
915
  if (fullpath.length === 0) {
916
916
  result.errors.push(mapper(issue2));
917
917
  continue;
@@ -943,8 +943,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
943
943
  }
944
944
  function toDotPath(_path) {
945
945
  const segs = [];
946
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
947
- for (const seg of path4) {
946
+ const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
947
+ for (const seg of path5) {
948
948
  if (typeof seg === "number")
949
949
  segs.push(`[${seg}]`);
950
950
  else if (typeof seg === "symbol")
@@ -13708,13 +13708,13 @@ function resolveRef(ref, ctx) {
13708
13708
  if (!ref.startsWith("#")) {
13709
13709
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
13710
13710
  }
13711
- const path4 = ref.slice(1).split("/").filter(Boolean);
13712
- if (path4.length === 0) {
13711
+ const path5 = ref.slice(1).split("/").filter(Boolean);
13712
+ if (path5.length === 0) {
13713
13713
  return ctx.rootSchema;
13714
13714
  }
13715
13715
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
13716
- if (path4[0] === defsKey) {
13717
- const key = path4[1];
13716
+ if (path5[0] === defsKey) {
13717
+ const key = path5[1];
13718
13718
  if (!key || !ctx.defs[key]) {
13719
13719
  throw new Error(`Reference not found: ${ref}`);
13720
13720
  }
@@ -16485,10 +16485,10 @@ function sanitize(input) {
16485
16485
  }
16486
16486
  function markerFileExists() {
16487
16487
  try {
16488
- const fs4 = require("node:fs");
16489
- const path4 = require("node:path");
16490
- const markerPath = path4.join(process.cwd(), ".glasstrace", "mcp-connected");
16491
- return fs4.existsSync(markerPath);
16488
+ const fs5 = require("node:fs");
16489
+ const path5 = require("node:path");
16490
+ const markerPath = path5.join(process.cwd(), ".glasstrace", "mcp-connected");
16491
+ return fs5.existsSync(markerPath);
16492
16492
  } catch {
16493
16493
  return false;
16494
16494
  }
@@ -16637,7 +16637,7 @@ __export(source_map_uploader_exports, {
16637
16637
  uploadToBlob: () => uploadToBlob
16638
16638
  });
16639
16639
  async function discoverSourceMapFiles(buildDir) {
16640
- const resolvedDir = path2.resolve(buildDir);
16640
+ const resolvedDir = path3.resolve(buildDir);
16641
16641
  const results = [];
16642
16642
  try {
16643
16643
  await walkDirMetadata(resolvedDir, resolvedDir, results);
@@ -16658,18 +16658,18 @@ async function discoverSourceMapFiles(buildDir) {
16658
16658
  async function walkDirMetadata(baseDir, currentDir, results) {
16659
16659
  let entries;
16660
16660
  try {
16661
- entries = await fs2.readdir(currentDir, { withFileTypes: true });
16661
+ entries = await fs3.readdir(currentDir, { withFileTypes: true });
16662
16662
  } catch {
16663
16663
  return;
16664
16664
  }
16665
16665
  for (const entry of entries) {
16666
- const fullPath = path2.join(currentDir, entry.name);
16666
+ const fullPath = path3.join(currentDir, entry.name);
16667
16667
  if (entry.isDirectory()) {
16668
16668
  await walkDirMetadata(baseDir, fullPath, results);
16669
16669
  } else if (entry.isFile() && entry.name.endsWith(".map")) {
16670
16670
  try {
16671
- const stat2 = await fs2.stat(fullPath);
16672
- const relativePath = path2.relative(baseDir, fullPath).replace(/\\/g, "/");
16671
+ const stat2 = await fs3.stat(fullPath);
16672
+ const relativePath = path3.relative(baseDir, fullPath).replace(/\\/g, "/");
16673
16673
  const compiledPath = relativePath.replace(/\.map$/, "");
16674
16674
  results.push({
16675
16675
  filePath: compiledPath,
@@ -16682,7 +16682,7 @@ async function walkDirMetadata(baseDir, currentDir, results) {
16682
16682
  }
16683
16683
  }
16684
16684
  async function readSourceMapContent(absolutePath) {
16685
- return fs2.readFile(absolutePath, "utf-8");
16685
+ return fs3.readFile(absolutePath, "utf-8");
16686
16686
  }
16687
16687
  async function collectSourceMaps(buildDir) {
16688
16688
  const fileInfos = await discoverSourceMapFiles(buildDir);
@@ -16937,12 +16937,12 @@ async function uploadSourceMapsAuto(apiKey, endpoint, buildHash, maps, options)
16937
16937
  );
16938
16938
  return uploadSourceMaps(apiKey, endpoint, buildHash, maps);
16939
16939
  }
16940
- var fs2, path2, crypto2, import_node_child_process, LARGE_FILE_WARNING_BYTES, PRESIGNED_THRESHOLD_BYTES, _blobClientLoader;
16940
+ var fs3, path3, crypto2, import_node_child_process, LARGE_FILE_WARNING_BYTES, PRESIGNED_THRESHOLD_BYTES, _blobClientLoader;
16941
16941
  var init_source_map_uploader = __esm({
16942
16942
  "src/source-map-uploader.ts"() {
16943
16943
  "use strict";
16944
- fs2 = __toESM(require("node:fs/promises"), 1);
16945
- path2 = __toESM(require("node:path"), 1);
16944
+ fs3 = __toESM(require("node:fs/promises"), 1);
16945
+ path3 = __toESM(require("node:path"), 1);
16946
16946
  crypto2 = __toESM(require("node:crypto"), 1);
16947
16947
  import_node_child_process = require("node:child_process");
16948
16948
  init_console_capture();
@@ -17191,11 +17191,11 @@ var fsPathCache;
17191
17191
  async function loadFsPath() {
17192
17192
  if (fsPathCache !== void 0) return fsPathCache;
17193
17193
  try {
17194
- const [fs4, path4] = await Promise.all([
17194
+ const [fs5, path5] = await Promise.all([
17195
17195
  import("node:fs/promises"),
17196
17196
  import("node:path")
17197
17197
  ]);
17198
- fsPathCache = { fs: fs4, path: path4 };
17198
+ fsPathCache = { fs: fs5, path: path5 };
17199
17199
  return fsPathCache;
17200
17200
  } catch {
17201
17201
  fsPathCache = null;
@@ -17716,35 +17716,35 @@ function atomicWriteFileSync(targetPath, payload, options = {}) {
17716
17716
  function atomicWriteFileSyncWithTmp(targetPath, tmpPath, payload, options = {}) {
17717
17717
  const mode = options.mode ?? 384;
17718
17718
  const encoding = options.encoding ?? "utf-8";
17719
- const fs4 = loadFsSync();
17719
+ const fs5 = loadFsSync();
17720
17720
  let fd = null;
17721
17721
  try {
17722
17722
  if (typeof payload === "string") {
17723
- fs4.writeFileSync(tmpPath, payload, { encoding, mode });
17723
+ fs5.writeFileSync(tmpPath, payload, { encoding, mode });
17724
17724
  } else {
17725
- fs4.writeFileSync(tmpPath, payload, { mode });
17725
+ fs5.writeFileSync(tmpPath, payload, { mode });
17726
17726
  }
17727
- fs4.chmodSync(tmpPath, mode);
17728
- fd = fs4.openSync(tmpPath, "r");
17729
- fs4.fsyncSync(fd);
17730
- fs4.closeSync(fd);
17727
+ fs5.chmodSync(tmpPath, mode);
17728
+ fd = fs5.openSync(tmpPath, "r");
17729
+ fs5.fsyncSync(fd);
17730
+ fs5.closeSync(fd);
17731
17731
  fd = null;
17732
- fs4.renameSync(tmpPath, targetPath);
17732
+ fs5.renameSync(tmpPath, targetPath);
17733
17733
  } catch (err) {
17734
17734
  if (fd !== null) {
17735
17735
  try {
17736
- fs4.closeSync(fd);
17736
+ fs5.closeSync(fd);
17737
17737
  } catch {
17738
17738
  }
17739
17739
  }
17740
- removeTmpResidueSync(fs4, tmpPath);
17740
+ removeTmpResidueSync(fs5, tmpPath);
17741
17741
  throw err;
17742
17742
  }
17743
- fsyncParentDirSyncWithFs(targetPath, fs4);
17743
+ fsyncParentDirSyncWithFs(targetPath, fs5);
17744
17744
  }
17745
- function removeTmpResidueSync(fs4, tmpPath) {
17745
+ function removeTmpResidueSync(fs5, tmpPath) {
17746
17746
  try {
17747
- fs4.unlinkSync(tmpPath);
17747
+ fs5.unlinkSync(tmpPath);
17748
17748
  return;
17749
17749
  } catch (err) {
17750
17750
  const code = errnoCodeOf(err);
@@ -17753,16 +17753,16 @@ function removeTmpResidueSync(fs4, tmpPath) {
17753
17753
  }
17754
17754
  }
17755
17755
  try {
17756
- fs4.rmdirSync(tmpPath);
17756
+ fs5.rmdirSync(tmpPath);
17757
17757
  } catch {
17758
17758
  }
17759
17759
  }
17760
- function fsyncParentDirSyncWithFs(targetPath, fs4) {
17760
+ function fsyncParentDirSyncWithFs(targetPath, fs5) {
17761
17761
  const parent = parentDir(targetPath);
17762
17762
  let fd = null;
17763
17763
  try {
17764
- fd = fs4.openSync(parent, "r");
17765
- fs4.fsyncSync(fd);
17764
+ fd = fs5.openSync(parent, "r");
17765
+ fs5.fsyncSync(fd);
17766
17766
  } catch (err) {
17767
17767
  const code = errnoCodeOf(err);
17768
17768
  if (code !== void 0 && PARENT_FSYNC_SWALLOWED_CODES.has(code)) {
@@ -17772,7 +17772,7 @@ function fsyncParentDirSyncWithFs(targetPath, fs4) {
17772
17772
  } finally {
17773
17773
  if (fd !== null) {
17774
17774
  try {
17775
- fs4.closeSync(fd);
17775
+ fs5.closeSync(fd);
17776
17776
  } catch {
17777
17777
  }
17778
17778
  }
@@ -17793,11 +17793,11 @@ var fsPathCache2;
17793
17793
  async function loadFsPath2() {
17794
17794
  if (fsPathCache2 !== void 0) return fsPathCache2;
17795
17795
  try {
17796
- const [fs4, path4] = await Promise.all([
17796
+ const [fs5, path5] = await Promise.all([
17797
17797
  import("node:fs/promises"),
17798
17798
  import("node:path")
17799
17799
  ]);
17800
- fsPathCache2 = { fs: fs4, path: path4 };
17800
+ fsPathCache2 = { fs: fs5, path: path5 };
17801
17801
  return fsPathCache2;
17802
17802
  } catch {
17803
17803
  fsPathCache2 = null;
@@ -18083,11 +18083,11 @@ var fsPathAsyncCache;
18083
18083
  async function loadFsPathAsync() {
18084
18084
  if (fsPathAsyncCache !== void 0) return fsPathAsyncCache;
18085
18085
  try {
18086
- const [fs4, path4] = await Promise.all([
18086
+ const [fs5, path5] = await Promise.all([
18087
18087
  import("node:fs/promises"),
18088
18088
  import("node:path")
18089
18089
  ]);
18090
- fsPathAsyncCache = { fs: fs4, path: path4 };
18090
+ fsPathAsyncCache = { fs: fs5, path: path5 };
18091
18091
  return fsPathAsyncCache;
18092
18092
  } catch {
18093
18093
  fsPathAsyncCache = null;
@@ -18096,9 +18096,9 @@ async function loadFsPathAsync() {
18096
18096
  }
18097
18097
  function loadFsSyncOrNull() {
18098
18098
  try {
18099
- const fs4 = require("node:fs");
18100
- const path4 = require("node:path");
18101
- return { readFileSync: fs4.readFileSync, join: path4.join };
18099
+ const fs5 = require("node:fs");
18100
+ const path5 = require("node:path");
18101
+ return { readFileSync: fs5.readFileSync, join: path5.join };
18102
18102
  } catch {
18103
18103
  return null;
18104
18104
  }
@@ -20545,7 +20545,7 @@ function appendRootPathToUrlIfNeeded(url2) {
20545
20545
  return void 0;
20546
20546
  }
20547
20547
  }
20548
- function appendResourcePathToUrl(url2, path4) {
20548
+ function appendResourcePathToUrl(url2, path5) {
20549
20549
  try {
20550
20550
  new URL(url2);
20551
20551
  } catch {
@@ -20555,11 +20555,11 @@ function appendResourcePathToUrl(url2, path4) {
20555
20555
  if (!url2.endsWith("/")) {
20556
20556
  url2 = url2 + "/";
20557
20557
  }
20558
- url2 += path4;
20558
+ url2 += path5;
20559
20559
  try {
20560
20560
  new URL(url2);
20561
20561
  } catch {
20562
- diag2.warn(`Configuration: Provided URL appended with '${path4}' is not a valid URL, using 'undefined' instead of '${url2}'`);
20562
+ diag2.warn(`Configuration: Provided URL appended with '${path5}' is not a valid URL, using 'undefined' instead of '${url2}'`);
20563
20563
  return void 0;
20564
20564
  }
20565
20565
  return url2;
@@ -22765,6 +22765,171 @@ function writeStateNow() {
22765
22765
  }
22766
22766
  }
22767
22767
 
22768
+ // src/agent-detection/upgrade-notice.ts
22769
+ var fs2 = __toESM(require("node:fs"), 1);
22770
+ var path2 = __toESM(require("node:path"), 1);
22771
+
22772
+ // src/agent-detection/inject.ts
22773
+ var HTML_START_RE = /^<!--\s*glasstrace:mcp:start(?:\s+v=([^\s>]+))?\s*-->$/;
22774
+ var HTML_END = "<!-- glasstrace:mcp:end -->";
22775
+ var HASH_START_RE = /^#\s*glasstrace:mcp:start(?:\s+v=(\S+))?$/;
22776
+ var HASH_END = "# glasstrace:mcp:end";
22777
+ function parseStartMarkerLine(line) {
22778
+ const trimmed = line.trim();
22779
+ const html = HTML_START_RE.exec(trimmed);
22780
+ if (html !== null) {
22781
+ return { kind: "html", stamp: html[1] ?? null };
22782
+ }
22783
+ const hash2 = HASH_START_RE.exec(trimmed);
22784
+ if (hash2 !== null) {
22785
+ return { kind: "hash", stamp: hash2[1] ?? null };
22786
+ }
22787
+ return null;
22788
+ }
22789
+ function isEndMarker(line) {
22790
+ const trimmed = line.trim();
22791
+ return trimmed === HTML_END || trimmed === HASH_END;
22792
+ }
22793
+ function isEndMarkerLine(line) {
22794
+ return isEndMarker(line);
22795
+ }
22796
+
22797
+ // src/agent-detection/upgrade-notice.ts
22798
+ var warningEmitted = false;
22799
+ var AGENT_INSTRUCTION_FILES = [
22800
+ "CLAUDE.md",
22801
+ "codex.md",
22802
+ ".cursorrules"
22803
+ ];
22804
+ function parseSemver(input) {
22805
+ const plusIdx = input.indexOf("+");
22806
+ const core = plusIdx === -1 ? input : input.slice(0, plusIdx);
22807
+ const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(core);
22808
+ if (m === null) return null;
22809
+ return {
22810
+ major: Number(m[1]),
22811
+ minor: Number(m[2]),
22812
+ patch: Number(m[3]),
22813
+ prerelease: m[4] ?? null
22814
+ };
22815
+ }
22816
+ function comparePrerelease(a, b) {
22817
+ const ap = a.split(".");
22818
+ const bp = b.split(".");
22819
+ const len = Math.min(ap.length, bp.length);
22820
+ for (let i = 0; i < len; i++) {
22821
+ const x = ap[i];
22822
+ const y = bp[i];
22823
+ const xNumeric = /^\d+$/.test(x);
22824
+ const yNumeric = /^\d+$/.test(y);
22825
+ if (xNumeric && yNumeric) {
22826
+ const xv = Number(x);
22827
+ const yv = Number(y);
22828
+ if (xv !== yv) return xv < yv ? -1 : 1;
22829
+ } else if (xNumeric) {
22830
+ return -1;
22831
+ } else if (yNumeric) {
22832
+ return 1;
22833
+ } else if (x !== y) {
22834
+ return x < y ? -1 : 1;
22835
+ }
22836
+ }
22837
+ return ap.length - bp.length;
22838
+ }
22839
+ function compareSemver(a, b) {
22840
+ const pa = parseSemver(a);
22841
+ const pb = parseSemver(b);
22842
+ if (pa === null || pb === null) return null;
22843
+ if (pa.major !== pb.major) return pa.major - pb.major;
22844
+ if (pa.minor !== pb.minor) return pa.minor - pb.minor;
22845
+ if (pa.patch !== pb.patch) return pa.patch - pb.patch;
22846
+ if (pa.prerelease === null && pb.prerelease === null) return 0;
22847
+ if (pa.prerelease === null) return 1;
22848
+ if (pb.prerelease === null) return -1;
22849
+ return comparePrerelease(pa.prerelease, pb.prerelease);
22850
+ }
22851
+ function isOptedOut() {
22852
+ const raw = process.env.GLASSTRACE_DISABLE_UPGRADE_NOTICE;
22853
+ if (typeof raw !== "string") return false;
22854
+ const trimmed = raw.trim().toLowerCase();
22855
+ return trimmed === "1" || trimmed === "true" || trimmed === "yes";
22856
+ }
22857
+ function isQuietCiContext() {
22858
+ const stderrIsTty = process.stderr.isTTY === true;
22859
+ if (stderrIsTty) return false;
22860
+ return process.env.CI === "true";
22861
+ }
22862
+ var MAX_AGENT_FILE_BYTES = 5 * 1024 * 1024;
22863
+ function inspectFile(filePath, runningSdkVersion) {
22864
+ let content;
22865
+ try {
22866
+ const stat2 = fs2.statSync(filePath);
22867
+ if (!stat2.isFile()) return "absent";
22868
+ if (stat2.size > MAX_AGENT_FILE_BYTES) return "absent";
22869
+ content = fs2.readFileSync(filePath, "utf-8");
22870
+ } catch {
22871
+ return "absent";
22872
+ }
22873
+ const lines = content.split("\n");
22874
+ let lastStart = null;
22875
+ let foundEnd = false;
22876
+ for (const line of lines) {
22877
+ const parsed = parseStartMarkerLine(line);
22878
+ if (parsed !== null) {
22879
+ lastStart = parsed;
22880
+ continue;
22881
+ }
22882
+ if (lastStart !== null && isEndMarkerLine(line)) {
22883
+ foundEnd = true;
22884
+ break;
22885
+ }
22886
+ }
22887
+ if (lastStart === null || !foundEnd) {
22888
+ return "no-section";
22889
+ }
22890
+ if (lastStart.stamp === null) {
22891
+ return "no-stamp";
22892
+ }
22893
+ const cmp = compareSemver(lastStart.stamp, runningSdkVersion);
22894
+ if (cmp === null) {
22895
+ return "unknown-stamp";
22896
+ }
22897
+ return cmp < 0 ? "stale" : "current";
22898
+ }
22899
+ function maybeWarnStaleAgentInstructions(options) {
22900
+ try {
22901
+ if (warningEmitted) return;
22902
+ if (typeof process === "undefined" || typeof process.versions?.node !== "string" || typeof process.env !== "object" || process.env === null) {
22903
+ return;
22904
+ }
22905
+ if (isOptedOut()) return;
22906
+ if (isQuietCiContext()) return;
22907
+ if (parseSemver(options.sdkVersion) === null) return;
22908
+ const staleFiles = [];
22909
+ for (const fileName of AGENT_INSTRUCTION_FILES) {
22910
+ const fullPath = path2.join(options.projectRoot, fileName);
22911
+ const state = inspectFile(fullPath, options.sdkVersion);
22912
+ if (state === "stale") {
22913
+ staleFiles.push(fileName);
22914
+ }
22915
+ }
22916
+ if (staleFiles.length === 0) return;
22917
+ const fileList = staleFiles.join(", ");
22918
+ const message = `[glasstrace] Glasstrace managed MCP section in ${fileList} was rendered by an older @glasstrace/sdk; run \`npx glasstrace upgrade-instructions\` to refresh (silence with GLASSTRACE_DISABLE_UPGRADE_NOTICE=1).
22919
+ `;
22920
+ warningEmitted = true;
22921
+ if (options.stderrWrite !== void 0) {
22922
+ options.stderrWrite(message);
22923
+ return;
22924
+ }
22925
+ try {
22926
+ process.stderr.write(message);
22927
+ } catch {
22928
+ }
22929
+ } catch {
22930
+ }
22931
+ }
22932
+
22768
22933
  // src/register.ts
22769
22934
  function maskKey(key) {
22770
22935
  if (key.length <= 12) return key.slice(0, 4) + "...";
@@ -22793,9 +22958,13 @@ function registerGlasstrace(options) {
22793
22958
  return;
22794
22959
  }
22795
22960
  setCoreState(CoreState.REGISTERING);
22961
+ maybeWarnStaleAgentInstructions({
22962
+ projectRoot: process.cwd(),
22963
+ sdkVersion: "1.5.1"
22964
+ });
22796
22965
  startRuntimeStateWriter({
22797
22966
  projectRoot: process.cwd(),
22798
- sdkVersion: "1.4.0"
22967
+ sdkVersion: "1.5.1"
22799
22968
  });
22800
22969
  const config2 = resolveConfig(options);
22801
22970
  if (config2.verbose) {
@@ -22962,8 +23131,8 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22962
23131
  if (config2.verbose) {
22963
23132
  console.info("[glasstrace] Background init firing.");
22964
23133
  }
22965
- const healthReport = collectHealthReport("1.4.0");
22966
- const initResult = await performInit(config2, anonKeyForInit, "1.4.0", healthReport);
23134
+ const healthReport = collectHealthReport("1.5.1");
23135
+ const initResult = await performInit(config2, anonKeyForInit, "1.5.1", healthReport);
22967
23136
  if (generation !== registrationGeneration) return;
22968
23137
  const currentState = getCoreState();
22969
23138
  if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
@@ -22986,7 +23155,7 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22986
23155
  }
22987
23156
  maybeInstallConsoleCapture();
22988
23157
  if (didLastInitSucceed()) {
22989
- startHeartbeat(config2, anonKeyForInit, "1.4.0", generation, (newApiKey, accountId) => {
23158
+ startHeartbeat(config2, anonKeyForInit, "1.5.1", generation, (newApiKey, accountId) => {
22990
23159
  setAuthState(AuthState.CLAIMING);
22991
23160
  emitLifecycleEvent("auth:claim_started", { accountId });
22992
23161
  setResolvedApiKey(newApiKey);
@@ -23220,9 +23389,9 @@ function captureError(error48) {
23220
23389
  init_source_map_uploader();
23221
23390
 
23222
23391
  // src/import-graph.ts
23223
- var fs3 = __toESM(require("node:fs/promises"), 1);
23392
+ var fs4 = __toESM(require("node:fs/promises"), 1);
23224
23393
  var fsSync2 = __toESM(require("node:fs"), 1);
23225
- var path3 = __toESM(require("node:path"), 1);
23394
+ var path4 = __toESM(require("node:path"), 1);
23226
23395
  var crypto3 = __toESM(require("node:crypto"), 1);
23227
23396
  init_dist();
23228
23397
  var MAX_TEST_FILES = 5e3;
@@ -23252,7 +23421,7 @@ function loadCustomTestPatterns(projectRoot) {
23252
23421
  "jest.config.mjs"
23253
23422
  ];
23254
23423
  for (const name of configNames) {
23255
- const configPath = path3.join(projectRoot, name);
23424
+ const configPath = path4.join(projectRoot, name);
23256
23425
  let content;
23257
23426
  try {
23258
23427
  content = fsSync2.readFileSync(configPath, "utf-8");
@@ -23309,7 +23478,7 @@ async function walkForTests(baseDir, currentDir, results, testPatterns) {
23309
23478
  }
23310
23479
  let entries;
23311
23480
  try {
23312
- entries = await fs3.readdir(currentDir, { withFileTypes: true });
23481
+ entries = await fs4.readdir(currentDir, { withFileTypes: true });
23313
23482
  } catch {
23314
23483
  return;
23315
23484
  }
@@ -23317,14 +23486,14 @@ async function walkForTests(baseDir, currentDir, results, testPatterns) {
23317
23486
  if (results.length >= MAX_TEST_FILES) {
23318
23487
  return;
23319
23488
  }
23320
- const fullPath = path3.join(currentDir, entry.name);
23489
+ const fullPath = path4.join(currentDir, entry.name);
23321
23490
  if (entry.isDirectory()) {
23322
23491
  if (EXCLUDED_DIRS.has(entry.name)) {
23323
23492
  continue;
23324
23493
  }
23325
23494
  await walkForTests(baseDir, fullPath, results, testPatterns);
23326
23495
  } else if (entry.isFile()) {
23327
- const relativePath = path3.relative(baseDir, fullPath).replace(/\\/g, "/");
23496
+ const relativePath = path4.relative(baseDir, fullPath).replace(/\\/g, "/");
23328
23497
  const isTestFile = testPatterns.some((p) => p.test(entry.name) || p.test(relativePath)) || relativePath.includes("__tests__");
23329
23498
  if (isTestFile && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx"))) {
23330
23499
  results.push(relativePath);
@@ -23372,9 +23541,9 @@ async function buildImportGraph(projectRoot) {
23372
23541
  const testFiles = await discoverTestFiles(projectRoot);
23373
23542
  const graph = {};
23374
23543
  for (const testFile of testFiles) {
23375
- const fullPath = path3.join(projectRoot, testFile);
23544
+ const fullPath = path4.join(projectRoot, testFile);
23376
23545
  try {
23377
- const content = await fs3.readFile(fullPath, "utf-8");
23546
+ const content = await fs4.readFile(fullPath, "utf-8");
23378
23547
  const imports = extractImports(content);
23379
23548
  graph[testFile] = imports;
23380
23549
  } catch {