@glasstrace/sdk 0.12.5 → 0.13.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.
package/dist/cli/init.cjs CHANGED
@@ -560,10 +560,10 @@ function mergeDefs(...defs) {
560
560
  function cloneDef(schema) {
561
561
  return mergeDefs(schema._zod.def);
562
562
  }
563
- function getElementAtPath(obj, path7) {
564
- if (!path7)
563
+ function getElementAtPath(obj, path8) {
564
+ if (!path8)
565
565
  return obj;
566
- return path7.reduce((acc, key) => acc?.[key], obj);
566
+ return path8.reduce((acc, key) => acc?.[key], obj);
567
567
  }
568
568
  function promiseAllObject(promisesObj) {
569
569
  const keys = Object.keys(promisesObj);
@@ -875,11 +875,11 @@ function aborted(x, startIndex = 0) {
875
875
  }
876
876
  return false;
877
877
  }
878
- function prefixIssues(path7, issues) {
878
+ function prefixIssues(path8, issues) {
879
879
  return issues.map((iss) => {
880
880
  var _a2;
881
881
  (_a2 = iss).path ?? (_a2.path = []);
882
- iss.path.unshift(path7);
882
+ iss.path.unshift(path8);
883
883
  return iss;
884
884
  });
885
885
  }
@@ -1122,7 +1122,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
1122
1122
  }
1123
1123
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
1124
1124
  const result = { errors: [] };
1125
- const processError = (error49, path7 = []) => {
1125
+ const processError = (error49, path8 = []) => {
1126
1126
  var _a2, _b;
1127
1127
  for (const issue2 of error49.issues) {
1128
1128
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -1132,7 +1132,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
1132
1132
  } else if (issue2.code === "invalid_element") {
1133
1133
  processError({ issues: issue2.issues }, issue2.path);
1134
1134
  } else {
1135
- const fullpath = [...path7, ...issue2.path];
1135
+ const fullpath = [...path8, ...issue2.path];
1136
1136
  if (fullpath.length === 0) {
1137
1137
  result.errors.push(mapper(issue2));
1138
1138
  continue;
@@ -1164,8 +1164,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
1164
1164
  }
1165
1165
  function toDotPath(_path) {
1166
1166
  const segs = [];
1167
- const path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1168
- for (const seg of path7) {
1167
+ const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1168
+ for (const seg of path8) {
1169
1169
  if (typeof seg === "number")
1170
1170
  segs.push(`[${seg}]`);
1171
1171
  else if (typeof seg === "symbol")
@@ -13929,13 +13929,13 @@ function resolveRef(ref, ctx) {
13929
13929
  if (!ref.startsWith("#")) {
13930
13930
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
13931
13931
  }
13932
- const path7 = ref.slice(1).split("/").filter(Boolean);
13933
- if (path7.length === 0) {
13932
+ const path8 = ref.slice(1).split("/").filter(Boolean);
13933
+ if (path8.length === 0) {
13934
13934
  return ctx.rootSchema;
13935
13935
  }
13936
13936
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
13937
- if (path7[0] === defsKey) {
13938
- const key = path7[1];
13937
+ if (path8[0] === defsKey) {
13938
+ const key = path8[1];
13939
13939
  if (!key || !ctx.defs[key]) {
13940
13940
  throw new Error(`Reference not found: ${ref}`);
13941
13941
  }
@@ -14848,11 +14848,11 @@ var init_dist = __esm({
14848
14848
  async function loadFsPath() {
14849
14849
  if (fsPathCache !== void 0) return fsPathCache;
14850
14850
  try {
14851
- const [fs7, path7] = await Promise.all([
14851
+ const [fs8, path8] = await Promise.all([
14852
14852
  import("fs/promises"),
14853
14853
  import("path")
14854
14854
  ]);
14855
- fsPathCache = { fs: fs7, path: path7 };
14855
+ fsPathCache = { fs: fs8, path: path8 };
14856
14856
  return fsPathCache;
14857
14857
  } catch {
14858
14858
  fsPathCache = null;
@@ -14939,9 +14939,9 @@ var init_anon_key = __esm({
14939
14939
  });
14940
14940
 
14941
14941
  // src/agent-detection/detect.ts
14942
- async function pathExists(path7, mode = import_node_fs.constants.R_OK) {
14942
+ async function pathExists(path8, mode = import_node_fs.constants.R_OK) {
14943
14943
  try {
14944
- await (0, import_promises.access)(path7, mode);
14944
+ await (0, import_promises.access)(path8, mode);
14945
14945
  return true;
14946
14946
  } catch {
14947
14947
  return false;
@@ -15447,6 +15447,251 @@ var init_inject = __esm({
15447
15447
  }
15448
15448
  });
15449
15449
 
15450
+ // src/cli/monorepo.ts
15451
+ var monorepo_exports = {};
15452
+ __export(monorepo_exports, {
15453
+ findNextJsApps: () => findNextJsApps,
15454
+ isMonorepoRoot: () => isMonorepoRoot,
15455
+ parsePnpmWorkspaceYaml: () => parsePnpmWorkspaceYaml,
15456
+ resolveProjectRoot: () => resolveProjectRoot
15457
+ });
15458
+ function resolveProjectRoot(cwd) {
15459
+ if (hasNextConfig(cwd)) {
15460
+ return { projectRoot: cwd, isMonorepo: false };
15461
+ }
15462
+ if (hasNextDependency(cwd)) {
15463
+ return { projectRoot: cwd, isMonorepo: false };
15464
+ }
15465
+ if (isMonorepoRoot(cwd)) {
15466
+ const apps = findNextJsApps(cwd);
15467
+ if (apps.length === 0) {
15468
+ throw new Error(
15469
+ "This is a monorepo but no Next.js apps were found in workspace packages."
15470
+ );
15471
+ }
15472
+ if (apps.length === 1) {
15473
+ const appDir = apps[0];
15474
+ const relativePath = path3.relative(cwd, appDir);
15475
+ return {
15476
+ projectRoot: appDir,
15477
+ isMonorepo: true,
15478
+ appRelativePath: relativePath
15479
+ };
15480
+ }
15481
+ const appList = apps.map((app) => ` - ${path3.relative(cwd, app)}`).join("\n");
15482
+ throw new Error(
15483
+ `Found multiple Next.js apps:
15484
+ ${appList}
15485
+ Run init from the specific app directory you want to instrument.`
15486
+ );
15487
+ }
15488
+ throw new Error(
15489
+ "No Next.js project found in the current directory.\nRun this command from your Next.js app directory, or from a monorepo root."
15490
+ );
15491
+ }
15492
+ function hasNextConfig(dir) {
15493
+ return NEXT_CONFIG_NAMES.some(
15494
+ (name) => fs3.existsSync(path3.join(dir, name))
15495
+ );
15496
+ }
15497
+ function hasNextDependency(dir) {
15498
+ const packageJsonPath = path3.join(dir, "package.json");
15499
+ if (!fs3.existsSync(packageJsonPath)) return false;
15500
+ try {
15501
+ const content = fs3.readFileSync(packageJsonPath, "utf-8");
15502
+ const pkg = JSON.parse(content);
15503
+ const deps = pkg["dependencies"];
15504
+ const devDeps = pkg["devDependencies"];
15505
+ if (typeof deps === "object" && deps !== null && "next" in deps) return true;
15506
+ if (typeof devDeps === "object" && devDeps !== null && "next" in devDeps) return true;
15507
+ } catch {
15508
+ }
15509
+ return false;
15510
+ }
15511
+ function isMonorepoRoot(dir) {
15512
+ if (fs3.existsSync(path3.join(dir, "pnpm-workspace.yaml"))) return true;
15513
+ if (fs3.existsSync(path3.join(dir, "turbo.json"))) return true;
15514
+ if (fs3.existsSync(path3.join(dir, "lerna.json"))) return true;
15515
+ const packageJsonPath = path3.join(dir, "package.json");
15516
+ if (fs3.existsSync(packageJsonPath)) {
15517
+ try {
15518
+ const content = fs3.readFileSync(packageJsonPath, "utf-8");
15519
+ const pkg = JSON.parse(content);
15520
+ if (pkg["workspaces"] !== void 0) return true;
15521
+ } catch {
15522
+ }
15523
+ }
15524
+ return false;
15525
+ }
15526
+ function findNextJsApps(monorepoRoot) {
15527
+ const { includeGlobs, negationPatterns } = collectWorkspaceGlobs(monorepoRoot);
15528
+ if (includeGlobs.length === 0) {
15529
+ throw new Error(
15530
+ 'Monorepo detected but no workspace configuration found.\nAdd a "workspaces" field to package.json or create pnpm-workspace.yaml.'
15531
+ );
15532
+ }
15533
+ const workspaceDirs = expandGlobs(monorepoRoot, includeGlobs);
15534
+ const excludedDirs = expandGlobs(monorepoRoot, negationPatterns);
15535
+ const excludedSet = new Set(excludedDirs);
15536
+ const seen = /* @__PURE__ */ new Set();
15537
+ const nextApps = [];
15538
+ for (const dir of workspaceDirs) {
15539
+ if (seen.has(dir)) continue;
15540
+ seen.add(dir);
15541
+ if (excludedSet.has(dir)) continue;
15542
+ if (hasNextConfig(dir) || hasNextDependency(dir)) {
15543
+ nextApps.push(dir);
15544
+ }
15545
+ }
15546
+ return nextApps.sort();
15547
+ }
15548
+ function collectWorkspaceGlobs(root) {
15549
+ const globs = [];
15550
+ const negations = [];
15551
+ const pnpmPath = path3.join(root, "pnpm-workspace.yaml");
15552
+ if (fs3.existsSync(pnpmPath)) {
15553
+ const content = fs3.readFileSync(pnpmPath, "utf-8");
15554
+ const parsed = parsePnpmWorkspaceYaml(content);
15555
+ globs.push(...parsed.includeGlobs);
15556
+ negations.push(...parsed.negationPatterns);
15557
+ }
15558
+ const packageJsonPath = path3.join(root, "package.json");
15559
+ if (fs3.existsSync(packageJsonPath)) {
15560
+ try {
15561
+ const content = fs3.readFileSync(packageJsonPath, "utf-8");
15562
+ const pkg = JSON.parse(content);
15563
+ globs.push(...parsePackageJsonWorkspaces(pkg));
15564
+ } catch {
15565
+ }
15566
+ }
15567
+ const lernaPath = path3.join(root, "lerna.json");
15568
+ if (fs3.existsSync(lernaPath)) {
15569
+ try {
15570
+ const content = fs3.readFileSync(lernaPath, "utf-8");
15571
+ const lerna = JSON.parse(content);
15572
+ const packages = lerna["packages"];
15573
+ if (Array.isArray(packages)) {
15574
+ for (const pkg of packages) {
15575
+ if (typeof pkg === "string") {
15576
+ globs.push(pkg);
15577
+ }
15578
+ }
15579
+ }
15580
+ } catch {
15581
+ }
15582
+ }
15583
+ return {
15584
+ includeGlobs: [...new Set(globs)],
15585
+ negationPatterns: [...new Set(negations)]
15586
+ };
15587
+ }
15588
+ function parsePnpmWorkspaceYaml(content) {
15589
+ const lines = content.split("\n");
15590
+ const includeGlobs = [];
15591
+ const negationPatterns = [];
15592
+ let inPackages = false;
15593
+ for (const rawLine of lines) {
15594
+ const trimmed = rawLine.trim();
15595
+ if (/^packages\s*:/.test(trimmed)) {
15596
+ inPackages = true;
15597
+ continue;
15598
+ }
15599
+ if (inPackages && trimmed.length > 0 && !trimmed.startsWith("-") && !rawLine.startsWith(" ") && !rawLine.startsWith(" ")) {
15600
+ inPackages = false;
15601
+ continue;
15602
+ }
15603
+ if (!inPackages) continue;
15604
+ const itemMatch = /^\s*-\s+(.+)$/.exec(rawLine);
15605
+ if (!itemMatch) continue;
15606
+ const value = itemMatch[1].trim().replace(/^["']|["']$/g, "");
15607
+ if (value.length === 0) continue;
15608
+ if (value.startsWith("!")) {
15609
+ negationPatterns.push(value.slice(1));
15610
+ continue;
15611
+ }
15612
+ includeGlobs.push(value);
15613
+ }
15614
+ return { includeGlobs, negationPatterns };
15615
+ }
15616
+ function parsePackageJsonWorkspaces(pkg) {
15617
+ const workspaces = pkg["workspaces"];
15618
+ if (workspaces === void 0 || workspaces === null) return [];
15619
+ if (Array.isArray(workspaces)) {
15620
+ return workspaces.filter((w) => typeof w === "string");
15621
+ }
15622
+ if (typeof workspaces === "object") {
15623
+ const obj = workspaces;
15624
+ const packages = obj["packages"];
15625
+ if (Array.isArray(packages)) {
15626
+ return packages.filter((p) => typeof p === "string");
15627
+ }
15628
+ }
15629
+ return [];
15630
+ }
15631
+ function expandGlobs(root, globs) {
15632
+ const dirs = [];
15633
+ for (const glob of globs) {
15634
+ const cleanGlob = glob.replace(/\/+$/, "");
15635
+ if (cleanGlob.includes("**")) {
15636
+ const prefix = cleanGlob.split("**")[0].replace(/\/+$/, "");
15637
+ const baseDir = path3.join(root, prefix);
15638
+ if (fs3.existsSync(baseDir)) {
15639
+ dirs.push(...walkDirectories(baseDir));
15640
+ }
15641
+ } else if (cleanGlob.includes("*")) {
15642
+ const parts = cleanGlob.split("*");
15643
+ const baseDir = path3.join(root, parts[0].replace(/\/+$/, ""));
15644
+ const suffix = parts.slice(1).join("*");
15645
+ if (!fs3.existsSync(baseDir)) continue;
15646
+ let entries;
15647
+ try {
15648
+ entries = fs3.readdirSync(baseDir, { withFileTypes: true });
15649
+ } catch {
15650
+ continue;
15651
+ }
15652
+ for (const entry of entries) {
15653
+ if (!entry.isDirectory()) continue;
15654
+ if (suffix && !entry.name.endsWith(suffix)) continue;
15655
+ dirs.push(path3.join(baseDir, entry.name));
15656
+ }
15657
+ } else {
15658
+ const targetDir = path3.join(root, cleanGlob);
15659
+ if (fs3.existsSync(targetDir) && fs3.statSync(targetDir).isDirectory()) {
15660
+ dirs.push(targetDir);
15661
+ }
15662
+ }
15663
+ }
15664
+ return dirs;
15665
+ }
15666
+ function walkDirectories(baseDir) {
15667
+ const result = [];
15668
+ let entries;
15669
+ try {
15670
+ entries = fs3.readdirSync(baseDir, { withFileTypes: true });
15671
+ } catch {
15672
+ return result;
15673
+ }
15674
+ for (const entry of entries) {
15675
+ if (!entry.isDirectory()) continue;
15676
+ if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
15677
+ const fullPath = path3.join(baseDir, entry.name);
15678
+ if (fs3.existsSync(path3.join(fullPath, "package.json"))) {
15679
+ result.push(fullPath);
15680
+ }
15681
+ result.push(...walkDirectories(fullPath));
15682
+ }
15683
+ return result;
15684
+ }
15685
+ var fs3, path3;
15686
+ var init_monorepo = __esm({
15687
+ "src/cli/monorepo.ts"() {
15688
+ "use strict";
15689
+ fs3 = __toESM(require("fs"), 1);
15690
+ path3 = __toESM(require("path"), 1);
15691
+ init_constants();
15692
+ }
15693
+ });
15694
+
15450
15695
  // src/cli/uninit.ts
15451
15696
  var uninit_exports = {};
15452
15697
  __export(uninit_exports, {
@@ -16260,31 +16505,161 @@ var init_mcp_add = __esm({
16260
16505
  }
16261
16506
  });
16262
16507
 
16263
- // src/cli/init.ts
16264
- var init_exports = {};
16265
- __export(init_exports, {
16266
- meetsNodeVersion: () => meetsNodeVersion,
16267
- rollbackSteps: () => rollbackSteps,
16268
- runInit: () => runInit
16508
+ // src/cli/status.ts
16509
+ var status_exports = {};
16510
+ __export(status_exports, {
16511
+ runStatus: () => runStatus
16269
16512
  });
16270
- module.exports = __toCommonJS(init_exports);
16271
- var fs6 = __toESM(require("fs"), 1);
16272
- var path6 = __toESM(require("path"), 1);
16273
- var readline = __toESM(require("readline"), 1);
16274
- init_scaffolder();
16275
-
16276
- // src/import-graph.ts
16277
- var fs2 = __toESM(require("fs/promises"), 1);
16278
- var fsSync = __toESM(require("fs"), 1);
16279
- var path2 = __toESM(require("path"), 1);
16280
- var crypto2 = __toESM(require("crypto"), 1);
16281
- init_dist();
16282
- var MAX_TEST_FILES = 5e3;
16283
- var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", ".next", ".git", "dist", ".turbo"]);
16284
- var DEFAULT_TEST_PATTERNS = [
16285
- /\.test\.tsx?$/,
16286
- /\.spec\.tsx?$/
16287
- ];
16513
+ function runStatus(options) {
16514
+ const root = options.projectRoot;
16515
+ return {
16516
+ installed: checkInstalled(root),
16517
+ initialized: checkInitialized(root),
16518
+ instrumentation: checkInstrumentation(root),
16519
+ configWrapped: checkConfigWrapped(root),
16520
+ anonKey: checkAnonKey(root),
16521
+ mcpConfigured: checkMcpConfigured(root),
16522
+ agents: checkAgents(root)
16523
+ };
16524
+ }
16525
+ function checkInstalled(root) {
16526
+ try {
16527
+ const pkgPath = path6.join(root, "package.json");
16528
+ const content = fs6.readFileSync(pkgPath, "utf-8");
16529
+ const pkg = JSON.parse(content);
16530
+ const deps = pkg["dependencies"];
16531
+ const devDeps = pkg["devDependencies"];
16532
+ return deps != null && "@glasstrace/sdk" in deps || devDeps != null && "@glasstrace/sdk" in devDeps;
16533
+ } catch {
16534
+ return false;
16535
+ }
16536
+ }
16537
+ function checkInitialized(root) {
16538
+ try {
16539
+ return fs6.statSync(path6.join(root, ".glasstrace")).isDirectory();
16540
+ } catch {
16541
+ return false;
16542
+ }
16543
+ }
16544
+ function checkInstrumentation(root) {
16545
+ for (const name of INSTRUMENTATION_FILES) {
16546
+ try {
16547
+ const content = fs6.readFileSync(path6.join(root, name), "utf-8");
16548
+ if (content.includes("registerGlasstrace")) {
16549
+ return true;
16550
+ }
16551
+ } catch {
16552
+ }
16553
+ }
16554
+ return false;
16555
+ }
16556
+ function checkConfigWrapped(root) {
16557
+ for (const name of NEXT_CONFIG_NAMES) {
16558
+ try {
16559
+ const content = fs6.readFileSync(path6.join(root, name), "utf-8");
16560
+ if (content.includes("withGlasstraceConfig")) {
16561
+ return true;
16562
+ }
16563
+ } catch {
16564
+ }
16565
+ }
16566
+ return false;
16567
+ }
16568
+ function checkAnonKey(root) {
16569
+ try {
16570
+ return fs6.statSync(path6.join(root, ".glasstrace", "anon_key")).isFile();
16571
+ } catch {
16572
+ return false;
16573
+ }
16574
+ }
16575
+ function checkMcpConfigured(root) {
16576
+ for (const name of MCP_JSON_FILES) {
16577
+ try {
16578
+ const content = fs6.readFileSync(path6.join(root, name), "utf-8");
16579
+ const parsed = JSON.parse(content);
16580
+ const mcpServers = parsed["mcpServers"];
16581
+ if (mcpServers && typeof mcpServers === "object" && "glasstrace" in mcpServers) {
16582
+ return true;
16583
+ }
16584
+ } catch {
16585
+ }
16586
+ }
16587
+ for (const name of MCP_TOML_FILES) {
16588
+ try {
16589
+ const content = fs6.readFileSync(path6.join(root, name), "utf-8");
16590
+ if (content.includes("[mcp_servers.glasstrace]")) {
16591
+ return true;
16592
+ }
16593
+ } catch {
16594
+ }
16595
+ }
16596
+ return false;
16597
+ }
16598
+ function checkAgents(root) {
16599
+ const found = [];
16600
+ for (const name of AGENT_INFO_FILES2) {
16601
+ try {
16602
+ const content = fs6.readFileSync(path6.join(root, name), "utf-8");
16603
+ const hasHtmlMarkers = content.includes("<!-- glasstrace:mcp:start -->") && content.includes("<!-- glasstrace:mcp:end -->");
16604
+ const hasHashMarkers = content.includes("# glasstrace:mcp:start") && content.includes("# glasstrace:mcp:end");
16605
+ if (hasHtmlMarkers || hasHashMarkers) {
16606
+ found.push(name);
16607
+ }
16608
+ } catch {
16609
+ }
16610
+ }
16611
+ return found;
16612
+ }
16613
+ var fs6, path6, MCP_JSON_FILES, MCP_TOML_FILES, AGENT_INFO_FILES2, INSTRUMENTATION_FILES;
16614
+ var init_status = __esm({
16615
+ "src/cli/status.ts"() {
16616
+ "use strict";
16617
+ fs6 = __toESM(require("fs"), 1);
16618
+ path6 = __toESM(require("path"), 1);
16619
+ init_constants();
16620
+ MCP_JSON_FILES = [".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".glasstrace/mcp.json"];
16621
+ MCP_TOML_FILES = [".codex/config.toml"];
16622
+ AGENT_INFO_FILES2 = [
16623
+ "CLAUDE.md",
16624
+ "codex.md",
16625
+ ".cursorrules"
16626
+ ];
16627
+ INSTRUMENTATION_FILES = [
16628
+ "instrumentation.ts",
16629
+ "instrumentation.js",
16630
+ "instrumentation.mjs",
16631
+ "src/instrumentation.ts",
16632
+ "src/instrumentation.js",
16633
+ "src/instrumentation.mjs"
16634
+ ];
16635
+ }
16636
+ });
16637
+
16638
+ // src/cli/init.ts
16639
+ var init_exports = {};
16640
+ __export(init_exports, {
16641
+ meetsNodeVersion: () => meetsNodeVersion,
16642
+ rollbackSteps: () => rollbackSteps,
16643
+ runInit: () => runInit
16644
+ });
16645
+ module.exports = __toCommonJS(init_exports);
16646
+ var fs7 = __toESM(require("fs"), 1);
16647
+ var path7 = __toESM(require("path"), 1);
16648
+ var readline = __toESM(require("readline"), 1);
16649
+ init_scaffolder();
16650
+
16651
+ // src/import-graph.ts
16652
+ var fs2 = __toESM(require("fs/promises"), 1);
16653
+ var fsSync = __toESM(require("fs"), 1);
16654
+ var path2 = __toESM(require("path"), 1);
16655
+ var crypto2 = __toESM(require("crypto"), 1);
16656
+ init_dist();
16657
+ var MAX_TEST_FILES = 5e3;
16658
+ var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", ".next", ".git", "dist", ".turbo"]);
16659
+ var DEFAULT_TEST_PATTERNS = [
16660
+ /\.test\.tsx?$/,
16661
+ /\.spec\.tsx?$/
16662
+ ];
16288
16663
  function globToRegExp(glob) {
16289
16664
  const DOUBLE_STAR_PLACEHOLDER = "\0DSTAR\0";
16290
16665
  const regexStr = glob.replace(/\*\*\//g, DOUBLE_STAR_PLACEHOLDER).replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]+").replace(new RegExp(DOUBLE_STAR_PLACEHOLDER.replace(/\0/g, "\\0"), "g"), "(?:.+/)?");
@@ -16448,240 +16823,7 @@ init_detect();
16448
16823
  init_configs();
16449
16824
  init_inject();
16450
16825
  init_constants();
16451
-
16452
- // src/cli/monorepo.ts
16453
- var fs3 = __toESM(require("fs"), 1);
16454
- var path3 = __toESM(require("path"), 1);
16455
- init_constants();
16456
- function resolveProjectRoot(cwd) {
16457
- if (hasNextConfig(cwd)) {
16458
- return { projectRoot: cwd, isMonorepo: false };
16459
- }
16460
- if (hasNextDependency(cwd)) {
16461
- return { projectRoot: cwd, isMonorepo: false };
16462
- }
16463
- if (isMonorepoRoot(cwd)) {
16464
- const apps = findNextJsApps(cwd);
16465
- if (apps.length === 0) {
16466
- throw new Error(
16467
- "This is a monorepo but no Next.js apps were found in workspace packages."
16468
- );
16469
- }
16470
- if (apps.length === 1) {
16471
- const appDir = apps[0];
16472
- const relativePath = path3.relative(cwd, appDir);
16473
- return {
16474
- projectRoot: appDir,
16475
- isMonorepo: true,
16476
- appRelativePath: relativePath
16477
- };
16478
- }
16479
- const appList = apps.map((app) => ` - ${path3.relative(cwd, app)}`).join("\n");
16480
- throw new Error(
16481
- `Found multiple Next.js apps:
16482
- ${appList}
16483
- Run init from the specific app directory you want to instrument.`
16484
- );
16485
- }
16486
- throw new Error(
16487
- "No Next.js project found in the current directory.\nRun this command from your Next.js app directory, or from a monorepo root."
16488
- );
16489
- }
16490
- function hasNextConfig(dir) {
16491
- return NEXT_CONFIG_NAMES.some(
16492
- (name) => fs3.existsSync(path3.join(dir, name))
16493
- );
16494
- }
16495
- function hasNextDependency(dir) {
16496
- const packageJsonPath = path3.join(dir, "package.json");
16497
- if (!fs3.existsSync(packageJsonPath)) return false;
16498
- try {
16499
- const content = fs3.readFileSync(packageJsonPath, "utf-8");
16500
- const pkg = JSON.parse(content);
16501
- const deps = pkg["dependencies"];
16502
- const devDeps = pkg["devDependencies"];
16503
- if (typeof deps === "object" && deps !== null && "next" in deps) return true;
16504
- if (typeof devDeps === "object" && devDeps !== null && "next" in devDeps) return true;
16505
- } catch {
16506
- }
16507
- return false;
16508
- }
16509
- function isMonorepoRoot(dir) {
16510
- if (fs3.existsSync(path3.join(dir, "pnpm-workspace.yaml"))) return true;
16511
- if (fs3.existsSync(path3.join(dir, "turbo.json"))) return true;
16512
- if (fs3.existsSync(path3.join(dir, "lerna.json"))) return true;
16513
- const packageJsonPath = path3.join(dir, "package.json");
16514
- if (fs3.existsSync(packageJsonPath)) {
16515
- try {
16516
- const content = fs3.readFileSync(packageJsonPath, "utf-8");
16517
- const pkg = JSON.parse(content);
16518
- if (pkg["workspaces"] !== void 0) return true;
16519
- } catch {
16520
- }
16521
- }
16522
- return false;
16523
- }
16524
- function findNextJsApps(monorepoRoot) {
16525
- const { includeGlobs, negationPatterns } = collectWorkspaceGlobs(monorepoRoot);
16526
- if (includeGlobs.length === 0) {
16527
- throw new Error(
16528
- 'Monorepo detected but no workspace configuration found.\nAdd a "workspaces" field to package.json or create pnpm-workspace.yaml.'
16529
- );
16530
- }
16531
- const workspaceDirs = expandGlobs(monorepoRoot, includeGlobs);
16532
- const excludedDirs = expandGlobs(monorepoRoot, negationPatterns);
16533
- const excludedSet = new Set(excludedDirs);
16534
- const seen = /* @__PURE__ */ new Set();
16535
- const nextApps = [];
16536
- for (const dir of workspaceDirs) {
16537
- if (seen.has(dir)) continue;
16538
- seen.add(dir);
16539
- if (excludedSet.has(dir)) continue;
16540
- if (hasNextConfig(dir) || hasNextDependency(dir)) {
16541
- nextApps.push(dir);
16542
- }
16543
- }
16544
- return nextApps.sort();
16545
- }
16546
- function collectWorkspaceGlobs(root) {
16547
- const globs = [];
16548
- const negations = [];
16549
- const pnpmPath = path3.join(root, "pnpm-workspace.yaml");
16550
- if (fs3.existsSync(pnpmPath)) {
16551
- const content = fs3.readFileSync(pnpmPath, "utf-8");
16552
- const parsed = parsePnpmWorkspaceYaml(content);
16553
- globs.push(...parsed.includeGlobs);
16554
- negations.push(...parsed.negationPatterns);
16555
- }
16556
- const packageJsonPath = path3.join(root, "package.json");
16557
- if (fs3.existsSync(packageJsonPath)) {
16558
- try {
16559
- const content = fs3.readFileSync(packageJsonPath, "utf-8");
16560
- const pkg = JSON.parse(content);
16561
- globs.push(...parsePackageJsonWorkspaces(pkg));
16562
- } catch {
16563
- }
16564
- }
16565
- const lernaPath = path3.join(root, "lerna.json");
16566
- if (fs3.existsSync(lernaPath)) {
16567
- try {
16568
- const content = fs3.readFileSync(lernaPath, "utf-8");
16569
- const lerna = JSON.parse(content);
16570
- const packages = lerna["packages"];
16571
- if (Array.isArray(packages)) {
16572
- for (const pkg of packages) {
16573
- if (typeof pkg === "string") {
16574
- globs.push(pkg);
16575
- }
16576
- }
16577
- }
16578
- } catch {
16579
- }
16580
- }
16581
- return {
16582
- includeGlobs: [...new Set(globs)],
16583
- negationPatterns: [...new Set(negations)]
16584
- };
16585
- }
16586
- function parsePnpmWorkspaceYaml(content) {
16587
- const lines = content.split("\n");
16588
- const includeGlobs = [];
16589
- const negationPatterns = [];
16590
- let inPackages = false;
16591
- for (const rawLine of lines) {
16592
- const trimmed = rawLine.trim();
16593
- if (/^packages\s*:/.test(trimmed)) {
16594
- inPackages = true;
16595
- continue;
16596
- }
16597
- if (inPackages && trimmed.length > 0 && !trimmed.startsWith("-") && !rawLine.startsWith(" ") && !rawLine.startsWith(" ")) {
16598
- inPackages = false;
16599
- continue;
16600
- }
16601
- if (!inPackages) continue;
16602
- const itemMatch = /^\s*-\s+(.+)$/.exec(rawLine);
16603
- if (!itemMatch) continue;
16604
- const value = itemMatch[1].trim().replace(/^["']|["']$/g, "");
16605
- if (value.length === 0) continue;
16606
- if (value.startsWith("!")) {
16607
- negationPatterns.push(value.slice(1));
16608
- continue;
16609
- }
16610
- includeGlobs.push(value);
16611
- }
16612
- return { includeGlobs, negationPatterns };
16613
- }
16614
- function parsePackageJsonWorkspaces(pkg) {
16615
- const workspaces = pkg["workspaces"];
16616
- if (workspaces === void 0 || workspaces === null) return [];
16617
- if (Array.isArray(workspaces)) {
16618
- return workspaces.filter((w) => typeof w === "string");
16619
- }
16620
- if (typeof workspaces === "object") {
16621
- const obj = workspaces;
16622
- const packages = obj["packages"];
16623
- if (Array.isArray(packages)) {
16624
- return packages.filter((p) => typeof p === "string");
16625
- }
16626
- }
16627
- return [];
16628
- }
16629
- function expandGlobs(root, globs) {
16630
- const dirs = [];
16631
- for (const glob of globs) {
16632
- const cleanGlob = glob.replace(/\/+$/, "");
16633
- if (cleanGlob.includes("**")) {
16634
- const prefix = cleanGlob.split("**")[0].replace(/\/+$/, "");
16635
- const baseDir = path3.join(root, prefix);
16636
- if (fs3.existsSync(baseDir)) {
16637
- dirs.push(...walkDirectories(baseDir));
16638
- }
16639
- } else if (cleanGlob.includes("*")) {
16640
- const parts = cleanGlob.split("*");
16641
- const baseDir = path3.join(root, parts[0].replace(/\/+$/, ""));
16642
- const suffix = parts.slice(1).join("*");
16643
- if (!fs3.existsSync(baseDir)) continue;
16644
- let entries;
16645
- try {
16646
- entries = fs3.readdirSync(baseDir, { withFileTypes: true });
16647
- } catch {
16648
- continue;
16649
- }
16650
- for (const entry of entries) {
16651
- if (!entry.isDirectory()) continue;
16652
- if (suffix && !entry.name.endsWith(suffix)) continue;
16653
- dirs.push(path3.join(baseDir, entry.name));
16654
- }
16655
- } else {
16656
- const targetDir = path3.join(root, cleanGlob);
16657
- if (fs3.existsSync(targetDir) && fs3.statSync(targetDir).isDirectory()) {
16658
- dirs.push(targetDir);
16659
- }
16660
- }
16661
- }
16662
- return dirs;
16663
- }
16664
- function walkDirectories(baseDir) {
16665
- const result = [];
16666
- let entries;
16667
- try {
16668
- entries = fs3.readdirSync(baseDir, { withFileTypes: true });
16669
- } catch {
16670
- return result;
16671
- }
16672
- for (const entry of entries) {
16673
- if (!entry.isDirectory()) continue;
16674
- if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
16675
- const fullPath = path3.join(baseDir, entry.name);
16676
- if (fs3.existsSync(path3.join(fullPath, "package.json"))) {
16677
- result.push(fullPath);
16678
- }
16679
- result.push(...walkDirectories(fullPath));
16680
- }
16681
- return result;
16682
- }
16683
-
16684
- // src/cli/init.ts
16826
+ init_monorepo();
16685
16827
  init_uninit();
16686
16828
  function meetsNodeVersion(minMajor) {
16687
16829
  const [major] = process.versions.node.split(".").map(Number);
@@ -16716,17 +16858,17 @@ async function rollbackSteps(steps, projectRoot, state) {
16716
16858
  try {
16717
16859
  switch (step) {
16718
16860
  case "instrumentation": {
16719
- const instrPath = path6.join(projectRoot, "instrumentation.ts");
16720
- if (fs6.existsSync(instrPath)) {
16721
- const content = fs6.readFileSync(instrPath, "utf-8");
16861
+ const instrPath = path7.join(projectRoot, "instrumentation.ts");
16862
+ if (fs7.existsSync(instrPath)) {
16863
+ const content = fs7.readFileSync(instrPath, "utf-8");
16722
16864
  if (isInitCreatedInstrumentation(content)) {
16723
- fs6.unlinkSync(instrPath);
16865
+ fs7.unlinkSync(instrPath);
16724
16866
  } else if (state?.originalInstrumentationContent !== void 0) {
16725
- fs6.writeFileSync(instrPath, state.originalInstrumentationContent, "utf-8");
16867
+ fs7.writeFileSync(instrPath, state.originalInstrumentationContent, "utf-8");
16726
16868
  } else {
16727
16869
  const cleaned = removeRegisterGlasstrace(content);
16728
16870
  if (cleaned !== content) {
16729
- fs6.writeFileSync(instrPath, cleaned, "utf-8");
16871
+ fs7.writeFileSync(instrPath, cleaned, "utf-8");
16730
16872
  }
16731
16873
  }
16732
16874
  }
@@ -16734,11 +16876,11 @@ async function rollbackSteps(steps, projectRoot, state) {
16734
16876
  }
16735
16877
  case "next-config": {
16736
16878
  for (const name of NEXT_CONFIG_NAMES) {
16737
- const configPath = path6.join(projectRoot, name);
16738
- if (!fs6.existsSync(configPath)) {
16879
+ const configPath = path7.join(projectRoot, name);
16880
+ if (!fs7.existsSync(configPath)) {
16739
16881
  continue;
16740
16882
  }
16741
- const content = fs6.readFileSync(configPath, "utf-8");
16883
+ const content = fs7.readFileSync(configPath, "utf-8");
16742
16884
  if (!content.includes("withGlasstraceConfig")) {
16743
16885
  continue;
16744
16886
  }
@@ -16746,16 +16888,16 @@ async function rollbackSteps(steps, projectRoot, state) {
16746
16888
  const unwrapResult = isESM ? unwrapExport(content) : unwrapCJSExport(content);
16747
16889
  if (unwrapResult.unwrapped) {
16748
16890
  const cleaned = removeGlasstraceConfigImport(unwrapResult.content);
16749
- fs6.writeFileSync(configPath, cleanLeadingBlankLines2(cleaned), "utf-8");
16891
+ fs7.writeFileSync(configPath, cleanLeadingBlankLines2(cleaned), "utf-8");
16750
16892
  }
16751
16893
  break;
16752
16894
  }
16753
16895
  break;
16754
16896
  }
16755
16897
  case "env-local": {
16756
- const envPath = path6.join(projectRoot, ".env.local");
16757
- if (fs6.existsSync(envPath)) {
16758
- const content = fs6.readFileSync(envPath, "utf-8");
16898
+ const envPath = path7.join(projectRoot, ".env.local");
16899
+ if (fs7.existsSync(envPath)) {
16900
+ const content = fs7.readFileSync(envPath, "utf-8");
16759
16901
  const lines = content.split("\n");
16760
16902
  const filtered = lines.filter((line) => {
16761
16903
  const trimmed = line.trim();
@@ -16764,18 +16906,18 @@ async function rollbackSteps(steps, projectRoot, state) {
16764
16906
  if (filtered.length !== lines.length) {
16765
16907
  const result = filtered.join("\n");
16766
16908
  if (result.trim().length === 0) {
16767
- fs6.unlinkSync(envPath);
16909
+ fs7.unlinkSync(envPath);
16768
16910
  } else {
16769
- fs6.writeFileSync(envPath, result, "utf-8");
16911
+ fs7.writeFileSync(envPath, result, "utf-8");
16770
16912
  }
16771
16913
  }
16772
16914
  }
16773
16915
  break;
16774
16916
  }
16775
16917
  case "gitignore": {
16776
- const gitignorePath = path6.join(projectRoot, ".gitignore");
16777
- if (fs6.existsSync(gitignorePath)) {
16778
- const content = fs6.readFileSync(gitignorePath, "utf-8");
16918
+ const gitignorePath = path7.join(projectRoot, ".gitignore");
16919
+ if (fs7.existsSync(gitignorePath)) {
16920
+ const content = fs7.readFileSync(gitignorePath, "utf-8");
16779
16921
  const lines = content.split("\n");
16780
16922
  const filtered = lines.filter(
16781
16923
  (line) => line.trim() !== ".glasstrace/"
@@ -16783,9 +16925,9 @@ async function rollbackSteps(steps, projectRoot, state) {
16783
16925
  if (filtered.length !== lines.length) {
16784
16926
  const result = filtered.join("\n");
16785
16927
  if (result.trim().length === 0) {
16786
- fs6.unlinkSync(gitignorePath);
16928
+ fs7.unlinkSync(gitignorePath);
16787
16929
  } else {
16788
- fs6.writeFileSync(gitignorePath, result, "utf-8");
16930
+ fs7.writeFileSync(gitignorePath, result, "utf-8");
16789
16931
  }
16790
16932
  }
16791
16933
  }
@@ -16812,16 +16954,16 @@ async function runInit(options) {
16812
16954
  errors.push(err instanceof Error ? err.message : String(err));
16813
16955
  return { exitCode: 1, summary, warnings, errors };
16814
16956
  }
16815
- const packageJsonPath = path6.join(projectRoot, "package.json");
16816
- if (!fs6.existsSync(packageJsonPath)) {
16957
+ const packageJsonPath = path7.join(projectRoot, "package.json");
16958
+ if (!fs7.existsSync(packageJsonPath)) {
16817
16959
  errors.push("No package.json found. Run this command from a Node.js project root.");
16818
16960
  return { exitCode: 1, summary, warnings, errors };
16819
16961
  }
16820
16962
  const rollbackState = { steps: [] };
16821
16963
  try {
16822
- const instrPath = path6.join(projectRoot, "instrumentation.ts");
16823
- if (fs6.existsSync(instrPath)) {
16824
- rollbackState.originalInstrumentationContent = fs6.readFileSync(instrPath, "utf-8");
16964
+ const instrPath = path7.join(projectRoot, "instrumentation.ts");
16965
+ if (fs7.existsSync(instrPath)) {
16966
+ rollbackState.originalInstrumentationContent = fs7.readFileSync(instrPath, "utf-8");
16825
16967
  }
16826
16968
  const instrResult = await scaffoldInstrumentation(projectRoot);
16827
16969
  switch (instrResult.action) {
@@ -16900,14 +17042,14 @@ async function runInit(options) {
16900
17042
  if (isCI) {
16901
17043
  const genericAgent = {
16902
17044
  name: "generic",
16903
- mcpConfigPath: path6.join(projectRoot, ".glasstrace", "mcp.json"),
17045
+ mcpConfigPath: path7.join(projectRoot, ".glasstrace", "mcp.json"),
16904
17046
  infoFilePath: null,
16905
17047
  cliAvailable: false,
16906
17048
  registrationCommand: null
16907
17049
  };
16908
17050
  const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT, anonKey);
16909
17051
  await writeMcpConfig(genericAgent, genericConfig, projectRoot);
16910
- if (genericAgent.mcpConfigPath !== null && fs6.existsSync(genericAgent.mcpConfigPath)) {
17052
+ if (genericAgent.mcpConfigPath !== null && fs7.existsSync(genericAgent.mcpConfigPath)) {
16911
17053
  anyConfigWritten = true;
16912
17054
  summary.push("Created .glasstrace/mcp.json (CI mode)");
16913
17055
  }
@@ -16921,14 +17063,14 @@ async function runInit(options) {
16921
17063
  );
16922
17064
  const genericAgent = {
16923
17065
  name: "generic",
16924
- mcpConfigPath: path6.join(projectRoot, ".glasstrace", "mcp.json"),
17066
+ mcpConfigPath: path7.join(projectRoot, ".glasstrace", "mcp.json"),
16925
17067
  infoFilePath: null,
16926
17068
  cliAvailable: false,
16927
17069
  registrationCommand: null
16928
17070
  };
16929
17071
  const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT, anonKey);
16930
17072
  await writeMcpConfig(genericAgent, genericConfig, projectRoot);
16931
- if (genericAgent.mcpConfigPath !== null && fs6.existsSync(genericAgent.mcpConfigPath)) {
17073
+ if (genericAgent.mcpConfigPath !== null && fs7.existsSync(genericAgent.mcpConfigPath)) {
16932
17074
  anyConfigWritten = true;
16933
17075
  }
16934
17076
  agents = [];
@@ -16938,7 +17080,7 @@ async function runInit(options) {
16938
17080
  try {
16939
17081
  const configContent = generateMcpConfig(agent, MCP_ENDPOINT, anonKey);
16940
17082
  await writeMcpConfig(agent, configContent, projectRoot);
16941
- const configExists = agent.mcpConfigPath !== null && fs6.existsSync(agent.mcpConfigPath);
17083
+ const configExists = agent.mcpConfigPath !== null && fs7.existsSync(agent.mcpConfigPath);
16942
17084
  if (!configExists) {
16943
17085
  continue;
16944
17086
  }
@@ -17025,7 +17167,7 @@ function parseArgs(argv) {
17025
17167
  };
17026
17168
  }
17027
17169
  var scriptPath = typeof process !== "undefined" && process.argv[1] !== void 0 ? process.argv[1].replace(/\\/g, "/") : void 0;
17028
- var scriptBasename = scriptPath !== void 0 ? path6.basename(scriptPath) : void 0;
17170
+ var scriptBasename = scriptPath !== void 0 ? path7.basename(scriptPath) : void 0;
17029
17171
  var isDirectExecution = scriptPath !== void 0 && (scriptPath.endsWith("/cli/init.js") || scriptPath.endsWith("/cli/init.ts") || scriptBasename === "glasstrace");
17030
17172
  if (isDirectExecution) {
17031
17173
  if (!meetsNodeVersion(20)) {
@@ -17128,6 +17270,46 @@ Usage: glasstrace mcp add [--force] [--dry-run]
17128
17270
  }).catch((err) => {
17129
17271
  process.stderr.write(
17130
17272
  `Fatal error: ${err instanceof Error ? err.message : String(err)}
17273
+ `
17274
+ );
17275
+ process.exit(1);
17276
+ });
17277
+ } else if (subcommand === "status") {
17278
+ const remainingArgs = process.argv.slice(3);
17279
+ const json2 = remainingArgs.includes("--json");
17280
+ Promise.all([Promise.resolve().then(() => (init_status(), status_exports)), Promise.resolve().then(() => (init_monorepo(), monorepo_exports))]).then(([{ runStatus: runStatus2 }, { resolveProjectRoot: resolve2 }]) => {
17281
+ let projectRoot = process.cwd();
17282
+ try {
17283
+ projectRoot = resolve2(projectRoot).projectRoot;
17284
+ } catch {
17285
+ }
17286
+ const result = runStatus2({ projectRoot });
17287
+ if (json2) {
17288
+ process.stdout.write(JSON.stringify(result) + "\n");
17289
+ } else {
17290
+ const checks = [
17291
+ ["Installed", result.installed],
17292
+ ["Initialized", result.initialized],
17293
+ ["Instrumentation", result.instrumentation],
17294
+ ["Config wrapped", result.configWrapped],
17295
+ ["Anon key", result.anonKey],
17296
+ ["MCP configured", result.mcpConfigured]
17297
+ ];
17298
+ for (const [label, ok] of checks) {
17299
+ process.stderr.write(` ${ok ? "+" : "-"} ${label}
17300
+ `);
17301
+ }
17302
+ if (result.agents.length > 0) {
17303
+ process.stderr.write(` + Agents: ${result.agents.join(", ")}
17304
+ `);
17305
+ } else {
17306
+ process.stderr.write(" - Agents\n");
17307
+ }
17308
+ }
17309
+ process.exit(0);
17310
+ }).catch((err) => {
17311
+ process.stderr.write(
17312
+ `Fatal error: ${err instanceof Error ? err.message : String(err)}
17131
17313
  `
17132
17314
  );
17133
17315
  process.exit(1);
@@ -17139,6 +17321,7 @@ Usage: glasstrace mcp add [--force] [--dry-run]
17139
17321
  Usage:
17140
17322
  glasstrace init [--yes] [--coverage-map]
17141
17323
  glasstrace uninit [--dry-run]
17324
+ glasstrace status [--json]
17142
17325
  glasstrace mcp add [--force] [--dry-run]
17143
17326
  `
17144
17327
  );