@glasstrace/sdk 1.10.2 → 1.11.0

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 (38) hide show
  1. package/README.md +43 -5
  2. package/dist/{chunk-QS5RZ2TC.js → chunk-DQFGNX3H.js} +13 -8
  3. package/dist/{chunk-QS5RZ2TC.js.map → chunk-DQFGNX3H.js.map} +1 -1
  4. package/dist/{chunk-UMGZJYC4.js → chunk-FQ4SEG6Y.js} +8 -3
  5. package/dist/chunk-FQ4SEG6Y.js.map +1 -0
  6. package/dist/{chunk-CIKPFJOM.js → chunk-KOYZJN6G.js} +310 -20
  7. package/dist/chunk-KOYZJN6G.js.map +1 -0
  8. package/dist/{chunk-ZBQQXVHD.js → chunk-YIEXKQYP.js} +2 -67
  9. package/dist/chunk-YIEXKQYP.js.map +1 -0
  10. package/dist/cli/init.cjs +453 -126
  11. package/dist/cli/init.cjs.map +1 -1
  12. package/dist/cli/init.js +29 -16
  13. package/dist/cli/init.js.map +1 -1
  14. package/dist/cli/mcp-add.cjs +339 -97
  15. package/dist/cli/mcp-add.cjs.map +1 -1
  16. package/dist/cli/mcp-add.js +32 -14
  17. package/dist/cli/mcp-add.js.map +1 -1
  18. package/dist/cli/status.cjs +6 -1
  19. package/dist/cli/status.cjs.map +1 -1
  20. package/dist/cli/status.js +7 -2
  21. package/dist/cli/status.js.map +1 -1
  22. package/dist/cli/uninit.cjs +6 -1
  23. package/dist/cli/uninit.cjs.map +1 -1
  24. package/dist/cli/uninit.js +2 -2
  25. package/dist/cli/upgrade-instructions.cjs +383 -112
  26. package/dist/cli/upgrade-instructions.cjs.map +1 -1
  27. package/dist/cli/upgrade-instructions.js +70 -18
  28. package/dist/cli/upgrade-instructions.js.map +1 -1
  29. package/dist/index.cjs +11 -6
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.js +2 -2
  32. package/dist/node-entry.cjs +11 -6
  33. package/dist/node-entry.cjs.map +1 -1
  34. package/dist/node-entry.js +2 -2
  35. package/package.json +1 -1
  36. package/dist/chunk-CIKPFJOM.js.map +0 -1
  37. package/dist/chunk-UMGZJYC4.js.map +0 -1
  38. package/dist/chunk-ZBQQXVHD.js.map +0 -1
package/dist/cli/init.cjs CHANGED
@@ -15226,10 +15226,7 @@ async function detectAgents(projectRoot) {
15226
15226
  continue;
15227
15227
  }
15228
15228
  seenAgents.add(rule.name);
15229
- let infoFilePath = rule.infoFilePath(foundDir);
15230
- if (infoFilePath !== null && !await pathExists(infoFilePath)) {
15231
- infoFilePath = null;
15232
- }
15229
+ const infoFilePath = rule.infoFilePath(foundDir);
15233
15230
  const cliAvailable = rule.cliBinary ? await isCliAvailable(rule.cliBinary) : false;
15234
15231
  detected.push({
15235
15232
  name: rule.name,
@@ -15242,7 +15239,7 @@ async function detectAgents(projectRoot) {
15242
15239
  detected.push({
15243
15240
  name: "generic",
15244
15241
  mcpConfigPath: (0, import_node_path.join)(resolvedRoot, ".glasstrace", "mcp.json"),
15245
- infoFilePath: null,
15242
+ infoFilePath: (0, import_node_path.join)(resolvedRoot, "AGENTS.md"),
15246
15243
  cliAvailable: false,
15247
15244
  registrationCommand: null
15248
15245
  });
@@ -15268,33 +15265,61 @@ var init_detect = __esm({
15268
15265
  },
15269
15266
  {
15270
15267
  name: "codex",
15268
+ // Codex 2026 default discovery is `AGENTS.override.md` → `AGENTS.md` →
15269
+ // opt-in `project_doc_fallback_filenames`; `codex.md` is NOT in the
15270
+ // default fallback list. Detection requires Codex-specific markers
15271
+ // (`codex.md` legacy, `.codex/` config dir) — `AGENTS.md` is NOT
15272
+ // included as a marker because the SDK now writes `AGENTS.md`
15273
+ // broadly via the multi-target dispatcher's companion writes; if
15274
+ // `AGENTS.md` were a Codex marker, every project with the SDK's
15275
+ // own companion AGENTS.md would re-classify as Codex on subsequent
15276
+ // detect runs and trigger unintended `.codex/config.toml` writes
15277
+ // (Codex P1 + Copilot P1 review of Wave 18 PR #274). The canonical
15278
+ // write destination remains AGENTS.md regardless of which marker
15279
+ // classified the project.
15271
15280
  markers: ["codex.md", ".codex"],
15272
15281
  mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".codex", "config.toml"),
15273
- infoFilePath: (dir) => (0, import_node_path.join)(dir, "codex.md"),
15282
+ infoFilePath: (dir) => (0, import_node_path.join)(dir, "AGENTS.md"),
15274
15283
  cliBinary: "codex",
15275
15284
  registrationCommand: "npx glasstrace mcp add --agent codex"
15276
15285
  },
15277
15286
  {
15278
15287
  name: "gemini",
15279
- markers: [".gemini"],
15288
+ markers: [".gemini", "GEMINI.md"],
15280
15289
  mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".gemini", "settings.json"),
15281
- infoFilePath: () => null,
15290
+ infoFilePath: (dir) => (0, import_node_path.join)(dir, "GEMINI.md"),
15282
15291
  cliBinary: "gemini",
15283
15292
  registrationCommand: "npx glasstrace mcp add --agent gemini"
15284
15293
  },
15285
15294
  {
15286
15295
  name: "cursor",
15296
+ // `.cursor/rules/*.mdc` is the current canonical format per Cursor's
15297
+ // 2026 docs. `.cursorrules` (single file) is supported-but-deprecated
15298
+ // and stays as a transitional fallback that the multi-target write
15299
+ // helper writes unconditionally alongside the .mdc canonical.
15287
15300
  markers: [".cursor", ".cursorrules"],
15288
15301
  mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".cursor", "mcp.json"),
15289
- infoFilePath: (dir) => (0, import_node_path.join)(dir, ".cursorrules"),
15302
+ infoFilePath: (dir) => (0, import_node_path.join)(dir, ".cursor", "rules", "glasstrace.mdc"),
15290
15303
  cliBinary: null,
15291
15304
  registrationCommand: "npx glasstrace mcp add --agent cursor"
15292
15305
  },
15293
15306
  {
15294
15307
  name: "windsurf",
15295
- markers: [".windsurfrules", ".windsurf"],
15308
+ // Windsurf's current canonical workspace-rules format is
15309
+ // `.windsurf/rules/*.md`. AGENTS.md is a parallel cross-tool
15310
+ // mechanism Windsurf also reads BUT is NOT included as a Windsurf
15311
+ // detection marker — the SDK writes `AGENTS.md` broadly via the
15312
+ // multi-target dispatcher's companion writes, so treating
15313
+ // `AGENTS.md` as a Windsurf marker would re-classify every
15314
+ // SDK-managed project as Windsurf and cause `glasstrace uninit`
15315
+ // to mutate the global `~/.codeium/windsurf/mcp_config.json` for
15316
+ // non-Windsurf projects (Codex P1 + Copilot P1 review of Wave 18
15317
+ // PR #274). The single-file `.windsurfrules` is the deprecated
15318
+ // legacy form — recognized as a marker so legacy projects classify
15319
+ // correctly, but the SDK no longer writes to it.
15320
+ markers: [".windsurf", ".windsurfrules"],
15296
15321
  mcpConfigPath: () => (0, import_node_path.join)((0, import_node_os.homedir)(), ".codeium", "windsurf", "mcp_config.json"),
15297
- infoFilePath: (dir) => (0, import_node_path.join)(dir, ".windsurfrules"),
15322
+ infoFilePath: (dir) => (0, import_node_path.join)(dir, ".windsurf", "rules", "glasstrace.md"),
15298
15323
  cliBinary: null,
15299
15324
  registrationCommand: "npx glasstrace mcp add --agent windsurf"
15300
15325
  }
@@ -15479,34 +15504,71 @@ function generateInfoSection(agent, endpoint, sdkVersion) {
15479
15504
  }
15480
15505
  const content = buildAgentInstructionBody();
15481
15506
  switch (agent.name) {
15482
- case "claude": {
15483
- const m = htmlMarkers(sdkVersion);
15484
- return `${m.start}
15485
- ${content}${m.end}
15486
- `;
15487
- }
15488
- case "codex": {
15507
+ case "claude":
15508
+ case "codex":
15509
+ case "gemini":
15510
+ case "windsurf":
15511
+ case "generic": {
15489
15512
  const m = htmlMarkers(sdkVersion);
15490
15513
  return `${m.start}
15491
15514
  ${content}${m.end}
15492
15515
  `;
15493
15516
  }
15494
15517
  case "cursor": {
15495
- const m = hashMarkers(sdkVersion);
15518
+ const m = htmlMarkers(sdkVersion);
15496
15519
  return `${m.start}
15497
15520
  ${content}${m.end}
15498
15521
  `;
15499
15522
  }
15500
- case "gemini":
15501
- case "windsurf":
15502
- case "generic":
15503
- return "";
15504
15523
  default: {
15505
15524
  const _exhaustive = agent.name;
15506
15525
  throw new Error(`Unknown agent: ${_exhaustive}`);
15507
15526
  }
15508
15527
  }
15509
15528
  }
15529
+ function generateInfoSectionForCursorrulesLegacy(endpoint, sdkVersion) {
15530
+ if (!endpoint || endpoint.trim() === "") {
15531
+ throw new Error("endpoint must not be empty");
15532
+ }
15533
+ if (!sdkVersion || sdkVersion.trim() === "") {
15534
+ throw new Error("sdkVersion must not be empty");
15535
+ }
15536
+ if (!SDK_VERSION_STAMP_PATTERN.test(sdkVersion)) {
15537
+ throw new Error(
15538
+ "sdkVersion must match [A-Za-z0-9.+\\-]+ (semver-shaped, no whitespace, no angle brackets)"
15539
+ );
15540
+ }
15541
+ const content = buildAgentInstructionBody();
15542
+ const m = hashMarkers(sdkVersion);
15543
+ return `${m.start}
15544
+ ${content}${m.end}
15545
+ `;
15546
+ }
15547
+ function generateInfoSectionForCursorMdc(endpoint, sdkVersion) {
15548
+ if (!endpoint || endpoint.trim() === "") {
15549
+ throw new Error("endpoint must not be empty");
15550
+ }
15551
+ if (!sdkVersion || sdkVersion.trim() === "") {
15552
+ throw new Error("sdkVersion must not be empty");
15553
+ }
15554
+ if (!SDK_VERSION_STAMP_PATTERN.test(sdkVersion)) {
15555
+ throw new Error(
15556
+ "sdkVersion must match [A-Za-z0-9.+\\-]+ (semver-shaped, no whitespace, no angle brackets)"
15557
+ );
15558
+ }
15559
+ const content = buildAgentInstructionBody();
15560
+ const m = htmlMarkers(sdkVersion);
15561
+ return [
15562
+ "---",
15563
+ "description: Glasstrace MCP runtime debugging tools \u2014 runtime evidence the agent reads when source alone cannot resolve a bug",
15564
+ "alwaysApply: true",
15565
+ "---",
15566
+ "",
15567
+ `${m.start}
15568
+ ${content}${m.end}
15569
+ `
15570
+ ].join("\n");
15571
+ }
15510
15572
  var SDK_VERSION_STAMP_PATTERN;
15511
15573
  var init_configs = __esm({
15512
15574
  "src/agent-detection/configs.ts"() {
@@ -15586,71 +15648,6 @@ function findMarkerBoundaries(lines) {
15586
15648
  }
15587
15649
  return null;
15588
15650
  }
15589
- async function injectInfoSection(agent, content, projectRoot) {
15590
- if (agent.infoFilePath === null) {
15591
- return;
15592
- }
15593
- if (content === "") {
15594
- return;
15595
- }
15596
- const filePath = agent.infoFilePath;
15597
- let existingContent = null;
15598
- try {
15599
- existingContent = await (0, import_promises2.readFile)(filePath, "utf-8");
15600
- } catch (err) {
15601
- const code = err.code;
15602
- if (code !== "ENOENT") {
15603
- if (isPermissionError(err)) {
15604
- process.stderr.write(
15605
- `Warning: cannot read info file ${filePath}: permission denied
15606
- `
15607
- );
15608
- return;
15609
- }
15610
- throw err;
15611
- }
15612
- }
15613
- if (existingContent === null) {
15614
- try {
15615
- await (0, import_promises2.mkdir)((0, import_node_path2.dirname)(filePath), { recursive: true });
15616
- await (0, import_promises2.writeFile)(filePath, content, "utf-8");
15617
- } catch (err) {
15618
- if (isPermissionError(err)) {
15619
- process.stderr.write(
15620
- `Warning: cannot write info file ${filePath}: permission denied
15621
- `
15622
- );
15623
- return;
15624
- }
15625
- throw err;
15626
- }
15627
- return;
15628
- }
15629
- const lines = existingContent.split("\n");
15630
- const boundaries = findMarkerBoundaries(lines);
15631
- let newContent;
15632
- if (boundaries !== null) {
15633
- const before = lines.slice(0, boundaries.startIdx);
15634
- const after = lines.slice(boundaries.endIdx + 1);
15635
- const contentWithoutTrailingNewline = content.endsWith("\n") ? content.slice(0, -1) : content;
15636
- newContent = [...before, contentWithoutTrailingNewline, ...after].join("\n");
15637
- } else {
15638
- const separator = existingContent.endsWith("\n") ? "\n" : "\n\n";
15639
- newContent = existingContent + separator + content;
15640
- }
15641
- try {
15642
- await (0, import_promises2.writeFile)(filePath, newContent, "utf-8");
15643
- } catch (err) {
15644
- if (isPermissionError(err)) {
15645
- process.stderr.write(
15646
- `Warning: cannot write info file ${filePath}: permission denied
15647
- `
15648
- );
15649
- return;
15650
- }
15651
- throw err;
15652
- }
15653
- }
15654
15651
  async function hasManagedSection(filePath) {
15655
15652
  let content;
15656
15653
  try {
@@ -15721,6 +15718,238 @@ var init_inject = __esm({
15721
15718
  }
15722
15719
  });
15723
15720
 
15721
+ // src/agent-detection/inject-all-targets.ts
15722
+ async function injectAllTargets(agents, endpoint, sdkVersion, projectRoot) {
15723
+ const writtenAgentsMd = /* @__PURE__ */ new Set();
15724
+ for (const agent of agents) {
15725
+ const targets = computeTargets(agent, projectRoot);
15726
+ for (const target of targets) {
15727
+ if (target.isAgentsMdCompanion) {
15728
+ if (writtenAgentsMd.has(target.path)) {
15729
+ continue;
15730
+ }
15731
+ writtenAgentsMd.add(target.path);
15732
+ }
15733
+ let createContent;
15734
+ let managedSectionOnly;
15735
+ if (target.kind === "cursor-mdc") {
15736
+ createContent = generateInfoSectionForCursorMdc(endpoint, sdkVersion);
15737
+ managedSectionOnly = generateInfoSection(agent, endpoint, sdkVersion);
15738
+ } else if (target.kind === "cursorrules-legacy") {
15739
+ createContent = generateInfoSectionForCursorrulesLegacy(
15740
+ endpoint,
15741
+ sdkVersion
15742
+ );
15743
+ managedSectionOnly = createContent;
15744
+ } else {
15745
+ createContent = generateInfoSection(agent, endpoint, sdkVersion);
15746
+ managedSectionOnly = createContent;
15747
+ }
15748
+ if (managedSectionOnly === "") continue;
15749
+ await writeManagedSectionToTarget(
15750
+ target.path,
15751
+ createContent,
15752
+ managedSectionOnly
15753
+ );
15754
+ }
15755
+ }
15756
+ }
15757
+ function foundDirFromAgent(agent) {
15758
+ if (agent.infoFilePath === null) return null;
15759
+ switch (agent.name) {
15760
+ case "claude":
15761
+ case "codex":
15762
+ case "gemini":
15763
+ case "generic":
15764
+ return (0, import_node_path3.dirname)(agent.infoFilePath);
15765
+ case "cursor":
15766
+ return (0, import_node_path3.dirname)((0, import_node_path3.dirname)((0, import_node_path3.dirname)(agent.infoFilePath)));
15767
+ case "windsurf":
15768
+ return (0, import_node_path3.dirname)((0, import_node_path3.dirname)((0, import_node_path3.dirname)(agent.infoFilePath)));
15769
+ }
15770
+ }
15771
+ function computeTargets(agent, projectRoot) {
15772
+ const targets = [];
15773
+ const foundDir = foundDirFromAgent(agent) ?? projectRoot;
15774
+ switch (agent.name) {
15775
+ case "claude": {
15776
+ if (agent.infoFilePath) {
15777
+ targets.push({
15778
+ path: agent.infoFilePath,
15779
+ kind: "primary",
15780
+ isAgentsMdCompanion: false
15781
+ });
15782
+ }
15783
+ targets.push({
15784
+ path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
15785
+ kind: "agents-md-companion",
15786
+ isAgentsMdCompanion: true
15787
+ });
15788
+ return targets;
15789
+ }
15790
+ case "codex": {
15791
+ if (agent.infoFilePath) {
15792
+ targets.push({
15793
+ path: agent.infoFilePath,
15794
+ kind: "primary",
15795
+ isAgentsMdCompanion: true
15796
+ });
15797
+ }
15798
+ return targets;
15799
+ }
15800
+ case "gemini": {
15801
+ if (agent.infoFilePath) {
15802
+ targets.push({
15803
+ path: agent.infoFilePath,
15804
+ kind: "primary",
15805
+ isAgentsMdCompanion: false
15806
+ });
15807
+ }
15808
+ targets.push({
15809
+ path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
15810
+ kind: "agents-md-companion",
15811
+ isAgentsMdCompanion: true
15812
+ });
15813
+ return targets;
15814
+ }
15815
+ case "cursor": {
15816
+ if (agent.infoFilePath) {
15817
+ targets.push({
15818
+ path: agent.infoFilePath,
15819
+ kind: "cursor-mdc",
15820
+ isAgentsMdCompanion: false
15821
+ });
15822
+ targets.push({
15823
+ path: (0, import_node_path3.join)(foundDir, ".cursorrules"),
15824
+ kind: "cursorrules-legacy",
15825
+ isAgentsMdCompanion: false
15826
+ });
15827
+ }
15828
+ targets.push({
15829
+ path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
15830
+ kind: "agents-md-companion",
15831
+ isAgentsMdCompanion: true
15832
+ });
15833
+ return targets;
15834
+ }
15835
+ case "windsurf": {
15836
+ if (agent.infoFilePath) {
15837
+ targets.push({
15838
+ path: agent.infoFilePath,
15839
+ kind: "primary",
15840
+ isAgentsMdCompanion: false
15841
+ });
15842
+ }
15843
+ targets.push({
15844
+ path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
15845
+ kind: "agents-md-companion",
15846
+ isAgentsMdCompanion: true
15847
+ });
15848
+ return targets;
15849
+ }
15850
+ case "generic": {
15851
+ if (agent.infoFilePath) {
15852
+ targets.push({
15853
+ path: agent.infoFilePath,
15854
+ kind: "primary",
15855
+ isAgentsMdCompanion: true
15856
+ });
15857
+ }
15858
+ return targets;
15859
+ }
15860
+ default: {
15861
+ const _exhaustive = agent.name;
15862
+ throw new Error(`Unknown agent: ${_exhaustive}`);
15863
+ }
15864
+ }
15865
+ }
15866
+ async function writeManagedSectionToTarget(filePath, createContent, managedSectionOnly) {
15867
+ let existingContent = null;
15868
+ try {
15869
+ existingContent = await (0, import_promises3.readFile)(filePath, "utf-8");
15870
+ } catch (err) {
15871
+ const code = err.code;
15872
+ if (code !== "ENOENT") {
15873
+ emitTargetWarning(filePath, "read", err);
15874
+ return;
15875
+ }
15876
+ }
15877
+ if (existingContent === null) {
15878
+ try {
15879
+ await (0, import_promises3.mkdir)((0, import_node_path3.dirname)(filePath), { recursive: true });
15880
+ await (0, import_promises3.writeFile)(filePath, createContent, "utf-8");
15881
+ } catch (err) {
15882
+ emitTargetWarning(filePath, "write", err);
15883
+ return;
15884
+ }
15885
+ return;
15886
+ }
15887
+ const lines = existingContent.split("\n");
15888
+ const boundaries = findMarkerBoundaries(lines);
15889
+ let newContent;
15890
+ if (boundaries !== null) {
15891
+ const before = lines.slice(0, boundaries.startIdx);
15892
+ const after = lines.slice(boundaries.endIdx + 1);
15893
+ const contentWithoutTrailingNewline = managedSectionOnly.endsWith("\n") ? managedSectionOnly.slice(0, -1) : managedSectionOnly;
15894
+ newContent = [...before, contentWithoutTrailingNewline, ...after].join(
15895
+ "\n"
15896
+ );
15897
+ } else {
15898
+ const separator = existingContent.endsWith("\n") ? "\n" : "\n\n";
15899
+ newContent = existingContent + separator + managedSectionOnly;
15900
+ }
15901
+ try {
15902
+ await (0, import_promises3.writeFile)(filePath, newContent, "utf-8");
15903
+ } catch (err) {
15904
+ emitTargetWarning(filePath, "write", err);
15905
+ }
15906
+ }
15907
+ function emitTargetWarning(filePath, op, err) {
15908
+ const code = err.code;
15909
+ let qualifier;
15910
+ switch (code) {
15911
+ case "EACCES":
15912
+ case "EPERM":
15913
+ qualifier = "permission denied";
15914
+ break;
15915
+ case "EROFS":
15916
+ qualifier = "filesystem read-only";
15917
+ break;
15918
+ case "ENOSPC":
15919
+ qualifier = "disk full";
15920
+ break;
15921
+ case "ENAMETOOLONG":
15922
+ qualifier = "path too long";
15923
+ break;
15924
+ case "ENOTDIR":
15925
+ qualifier = "not a directory";
15926
+ break;
15927
+ case "EISDIR":
15928
+ qualifier = "is a directory";
15929
+ break;
15930
+ default:
15931
+ qualifier = "I/O error";
15932
+ break;
15933
+ }
15934
+ try {
15935
+ process.stderr.write(
15936
+ `Warning: cannot ${op} info file ${filePath}: ${qualifier}
15937
+ `
15938
+ );
15939
+ } catch {
15940
+ }
15941
+ }
15942
+ var import_promises3, import_node_path3;
15943
+ var init_inject_all_targets = __esm({
15944
+ "src/agent-detection/inject-all-targets.ts"() {
15945
+ "use strict";
15946
+ import_promises3 = require("node:fs/promises");
15947
+ import_node_path3 = require("node:path");
15948
+ init_configs();
15949
+ init_inject();
15950
+ }
15951
+ });
15952
+
15724
15953
  // src/cli/monorepo.ts
15725
15954
  var monorepo_exports = {};
15726
15955
  __export(monorepo_exports, {
@@ -16873,9 +17102,14 @@ var init_uninit = __esm({
16873
17102
  init_inject();
16874
17103
  MCP_CONFIG_FILES = [".mcp.json", ".cursor/mcp.json", ".gemini/settings.json"];
16875
17104
  AGENT_INFO_FILES = [
17105
+ "AGENTS.md",
16876
17106
  "CLAUDE.md",
17107
+ "GEMINI.md",
17108
+ ".cursor/rules/glasstrace.mdc",
17109
+ ".windsurf/rules/glasstrace.md",
17110
+ ".cursorrules",
16877
17111
  "codex.md",
16878
- ".cursorrules"
17112
+ ".windsurfrules"
16879
17113
  ];
16880
17114
  }
16881
17115
  });
@@ -17026,14 +17260,9 @@ async function mcpAdd(options) {
17026
17260
  const bearer = resolved.effective.key;
17027
17261
  for (const agent of targetAgents) {
17028
17262
  const name = formatAgentName(agent.name);
17029
- const sdkVersion = true ? "1.10.2" : "0.0.0-dev";
17030
17263
  if (agent.name !== "generic") {
17031
17264
  const cliSuccess = await registerViaCli(agent, bearer);
17032
17265
  if (cliSuccess) {
17033
- const infoContent = generateInfoSection(agent, MCP_ENDPOINT, sdkVersion);
17034
- if (infoContent !== "") {
17035
- await injectInfoSection(agent, infoContent, projectRoot);
17036
- }
17037
17266
  results.push({
17038
17267
  agent: agent.name,
17039
17268
  success: true,
@@ -17048,10 +17277,6 @@ async function mcpAdd(options) {
17048
17277
  const configContent = generateMcpConfig(agent, MCP_ENDPOINT, bearer);
17049
17278
  await writeMcpConfig(agent, configContent, projectRoot);
17050
17279
  if (fs6.existsSync(agent.mcpConfigPath)) {
17051
- const infoContent = generateInfoSection(agent, MCP_ENDPOINT, sdkVersion);
17052
- if (infoContent !== "") {
17053
- await injectInfoSection(agent, infoContent, projectRoot);
17054
- }
17055
17280
  results.push({
17056
17281
  agent: agent.name,
17057
17282
  success: true,
@@ -17084,6 +17309,34 @@ async function mcpAdd(options) {
17084
17309
  message: `${name}: No registration method available`
17085
17310
  });
17086
17311
  }
17312
+ const successfulAgentNames = new Set(
17313
+ results.filter((r) => r.success).map((r) => r.agent)
17314
+ );
17315
+ const agentsWithMcpReady = targetAgents.filter(
17316
+ (a) => successfulAgentNames.has(a.name)
17317
+ );
17318
+ const detectedNonGenericMcpAdd = targetAgents.filter(
17319
+ (a) => a.name !== "generic"
17320
+ );
17321
+ const nonGenericReadyMcpAdd = agentsWithMcpReady.filter(
17322
+ (a) => a.name !== "generic"
17323
+ );
17324
+ const dispatchSetMcpAdd = detectedNonGenericMcpAdd.length === 0 ? agentsWithMcpReady : nonGenericReadyMcpAdd;
17325
+ if (dispatchSetMcpAdd.length > 0) {
17326
+ const sdkVersion = true ? "1.11.0" : "0.0.0-dev";
17327
+ try {
17328
+ await injectAllTargets(
17329
+ dispatchSetMcpAdd,
17330
+ MCP_ENDPOINT,
17331
+ sdkVersion,
17332
+ projectRoot
17333
+ );
17334
+ } catch (injectErr) {
17335
+ messages.push(
17336
+ `Warning: Failed to write some agent-instruction files: ${injectErr instanceof Error ? injectErr.message : String(injectErr)}`
17337
+ );
17338
+ }
17339
+ }
17087
17340
  await updateGitignore(
17088
17341
  [".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".codex/config.toml"],
17089
17342
  projectRoot
@@ -17139,6 +17392,7 @@ var init_mcp_add = __esm({
17139
17392
  init_mcp_runtime();
17140
17393
  init_detect();
17141
17394
  init_configs();
17395
+ init_inject_all_targets();
17142
17396
  init_inject();
17143
17397
  init_constants();
17144
17398
  execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
@@ -17273,9 +17527,41 @@ var upgrade_instructions_exports = {};
17273
17527
  __export(upgrade_instructions_exports, {
17274
17528
  runUpgradeInstructions: () => runUpgradeInstructions
17275
17529
  });
17530
+ function legacyDestinationsForAgent(agent) {
17531
+ if (agent.infoFilePath === null) {
17532
+ return [];
17533
+ }
17534
+ switch (agent.name) {
17535
+ case "codex":
17536
+ return [(0, import_node_path4.join)((0, import_node_path4.dirname)(agent.infoFilePath), "codex.md")];
17537
+ case "cursor":
17538
+ return [
17539
+ (0, import_node_path4.join)((0, import_node_path4.dirname)((0, import_node_path4.dirname)((0, import_node_path4.dirname)(agent.infoFilePath))), ".cursorrules")
17540
+ ];
17541
+ case "windsurf":
17542
+ return [
17543
+ (0, import_node_path4.join)(
17544
+ (0, import_node_path4.dirname)((0, import_node_path4.dirname)((0, import_node_path4.dirname)(agent.infoFilePath))),
17545
+ ".windsurfrules"
17546
+ )
17547
+ ];
17548
+ case "claude":
17549
+ case "gemini":
17550
+ case "generic":
17551
+ return [];
17552
+ }
17553
+ }
17554
+ async function anyHasManagedSection(paths) {
17555
+ for (const p of paths) {
17556
+ if (await hasManagedSection(p)) {
17557
+ return true;
17558
+ }
17559
+ }
17560
+ return false;
17561
+ }
17276
17562
  function formatPathForOutput(filePath, projectRoot) {
17277
- const rel = (0, import_node_path3.relative)(projectRoot, filePath);
17278
- if (rel === "" || rel.startsWith("..") || (0, import_node_path3.isAbsolute)(rel)) {
17563
+ const rel = (0, import_node_path4.relative)(projectRoot, filePath);
17564
+ if (rel === "" || rel.startsWith("..") || (0, import_node_path4.isAbsolute)(rel)) {
17279
17565
  return filePath;
17280
17566
  }
17281
17567
  return rel;
@@ -17294,7 +17580,8 @@ async function runUpgradeInstructions(options) {
17294
17580
  );
17295
17581
  return { exitCode: 1, refreshed, skipped, warnings, errors };
17296
17582
  }
17297
- const sdkVersion = true ? "1.10.2" : "0.0.0-dev";
17583
+ const sdkVersion = true ? "1.11.0" : "0.0.0-dev";
17584
+ const optedInAgents = [];
17298
17585
  for (const agent of agents) {
17299
17586
  if (agent.infoFilePath === null) {
17300
17587
  continue;
@@ -17303,44 +17590,64 @@ async function runUpgradeInstructions(options) {
17303
17590
  agent.infoFilePath,
17304
17591
  options.projectRoot
17305
17592
  );
17306
- let containsSection;
17593
+ const legacyDestinations = legacyDestinationsForAgent(agent);
17594
+ let optedIn;
17307
17595
  try {
17308
- containsSection = await hasManagedSection(agent.infoFilePath);
17596
+ optedIn = await anyHasManagedSection([
17597
+ agent.infoFilePath,
17598
+ ...legacyDestinations
17599
+ ]);
17309
17600
  } catch (err) {
17310
17601
  warnings.push(
17311
17602
  `Could not inspect ${displayPath}: ${err instanceof Error ? err.message : String(err)}`
17312
17603
  );
17313
17604
  continue;
17314
17605
  }
17315
- if (!containsSection) {
17606
+ if (!optedIn) {
17316
17607
  skipped.push(displayPath);
17317
17608
  continue;
17318
17609
  }
17319
- const content = generateInfoSection(agent, MCP_ENDPOINT, sdkVersion);
17320
- if (content === "") {
17321
- continue;
17322
- }
17610
+ optedInAgents.push(agent);
17611
+ }
17612
+ if (optedInAgents.length > 0) {
17323
17613
  try {
17324
- await injectInfoSection(agent, content, options.projectRoot);
17325
- refreshed.push(displayPath);
17614
+ await injectAllTargets(
17615
+ optedInAgents,
17616
+ MCP_ENDPOINT,
17617
+ sdkVersion,
17618
+ options.projectRoot
17619
+ );
17620
+ for (const a of optedInAgents) {
17621
+ if (a.infoFilePath !== null) {
17622
+ refreshed.push(formatPathForOutput(a.infoFilePath, options.projectRoot));
17623
+ }
17624
+ }
17326
17625
  } catch (err) {
17327
17626
  errors.push(
17328
- `Failed to refresh ${displayPath}: ${err instanceof Error ? err.message : String(err)}`
17627
+ `Failed to refresh agent-instruction files: ${err instanceof Error ? err.message : String(err)}`
17329
17628
  );
17330
17629
  }
17331
17630
  }
17631
+ const refreshedSet = new Set(refreshed);
17632
+ const dedupedSkipped = skipped.filter((p) => !refreshedSet.has(p));
17332
17633
  const exitCode = errors.length === 0 ? 0 : 1;
17333
- return { exitCode, refreshed, skipped, warnings, errors };
17634
+ return {
17635
+ exitCode,
17636
+ refreshed,
17637
+ skipped: dedupedSkipped,
17638
+ warnings,
17639
+ errors
17640
+ };
17334
17641
  }
17335
- var import_node_path3;
17642
+ var import_node_path4;
17336
17643
  var init_upgrade_instructions = __esm({
17337
17644
  "src/cli/upgrade-instructions.ts"() {
17338
17645
  "use strict";
17339
- import_node_path3 = require("node:path");
17646
+ import_node_path4 = require("node:path");
17340
17647
  init_mcp_runtime();
17341
17648
  init_detect();
17342
- init_configs();
17343
17649
  init_inject();
17650
+ init_inject_all_targets();
17344
17651
  }
17345
17652
  });
17346
17653
 
@@ -17528,9 +17835,14 @@ var init_status = __esm({
17528
17835
  MCP_JSON_FILES = [".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".glasstrace/mcp.json"];
17529
17836
  MCP_TOML_FILES = [".codex/config.toml"];
17530
17837
  AGENT_INFO_FILES2 = [
17838
+ "AGENTS.md",
17531
17839
  "CLAUDE.md",
17840
+ "GEMINI.md",
17841
+ ".cursor/rules/glasstrace.mdc",
17842
+ ".windsurf/rules/glasstrace.md",
17843
+ ".cursorrules",
17532
17844
  "codex.md",
17533
- ".cursorrules"
17845
+ ".windsurfrules"
17534
17846
  ];
17535
17847
  INSTRUMENTATION_FILES = [
17536
17848
  "instrumentation.ts",
@@ -18112,6 +18424,7 @@ async function buildImportGraph(projectRoot) {
18112
18424
  init_anon_key();
18113
18425
  init_detect();
18114
18426
  init_configs();
18427
+ init_inject_all_targets();
18115
18428
  init_inject();
18116
18429
  init_constants();
18117
18430
  init_monorepo();
@@ -18910,6 +19223,7 @@ Then add this as the first statement in your register() function:
18910
19223
  agents = [];
18911
19224
  }
18912
19225
  const configuredNames = [];
19226
+ const agentsWithMcpReady = [];
18913
19227
  for (const agent of agents) {
18914
19228
  try {
18915
19229
  const configContent = generateMcpConfig(agent, MCP_ENDPOINT, bearer);
@@ -18924,6 +19238,7 @@ Then add this as the first statement in your register() function:
18924
19238
  );
18925
19239
  if (agent.mcpConfigPath !== null && fs9.existsSync(agent.mcpConfigPath)) {
18926
19240
  anyConfigWritten = true;
19241
+ agentsWithMcpReady.push(agent);
18927
19242
  }
18928
19243
  continue;
18929
19244
  }
@@ -18934,15 +19249,7 @@ Then add this as the first statement in your register() function:
18934
19249
  }
18935
19250
  anyConfigWritten = true;
18936
19251
  anyConfigRewrittenWithBearer = true;
18937
- const sdkVersionForInject = true ? "1.10.2" : "0.0.0-dev";
18938
- const infoContent = generateInfoSection(
18939
- agent,
18940
- MCP_ENDPOINT,
18941
- sdkVersionForInject
18942
- );
18943
- if (infoContent !== "") {
18944
- await injectInfoSection(agent, infoContent, projectRoot);
18945
- }
19252
+ agentsWithMcpReady.push(agent);
18946
19253
  if (agent.name !== "generic") {
18947
19254
  configuredNames.push(formatAgentName(agent.name));
18948
19255
  }
@@ -18952,6 +19259,26 @@ Then add this as the first statement in your register() function:
18952
19259
  );
18953
19260
  }
18954
19261
  }
19262
+ const detectedNonGeneric = agents.filter((a) => a.name !== "generic");
19263
+ const nonGenericReady = agentsWithMcpReady.filter(
19264
+ (a) => a.name !== "generic"
19265
+ );
19266
+ const dispatchSet = detectedNonGeneric.length === 0 ? agentsWithMcpReady : nonGenericReady;
19267
+ if (dispatchSet.length > 0) {
19268
+ const sdkVersionForInject = true ? "1.11.0" : "0.0.0-dev";
19269
+ try {
19270
+ await injectAllTargets(
19271
+ dispatchSet,
19272
+ MCP_ENDPOINT,
19273
+ sdkVersionForInject,
19274
+ projectRoot
19275
+ );
19276
+ } catch (injectErr) {
19277
+ warnings.push(
19278
+ `Failed to write agent-instruction files: ${injectErr instanceof Error ? injectErr.message : String(injectErr)}`
19279
+ );
19280
+ }
19281
+ }
18955
19282
  if (configuredNames.length > 0) {
18956
19283
  summary.push(`Configured MCP for: ${configuredNames.join(", ")}`);
18957
19284
  } else if (anyConfigWritten) {
@@ -19040,7 +19367,7 @@ async function verifyAnonKeyRegistration(projectRoot) {
19040
19367
  }
19041
19368
  const baseConfig = resolveConfig({ apiKey: devKey });
19042
19369
  const config2 = { ...baseConfig, apiKey: devKey };
19043
- const sdkVersion = true ? "1.10.2" : "0.0.0-dev";
19370
+ const sdkVersion = true ? "1.11.0" : "0.0.0-dev";
19044
19371
  const result = await verifyInitReachable(config2, anonKey, sdkVersion);
19045
19372
  if (result.ok) {
19046
19373
  return { outcome: "verified" };