@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.
- package/README.md +43 -5
- package/dist/{chunk-QS5RZ2TC.js → chunk-DQFGNX3H.js} +13 -8
- package/dist/{chunk-QS5RZ2TC.js.map → chunk-DQFGNX3H.js.map} +1 -1
- package/dist/{chunk-UMGZJYC4.js → chunk-FQ4SEG6Y.js} +8 -3
- package/dist/chunk-FQ4SEG6Y.js.map +1 -0
- package/dist/{chunk-CIKPFJOM.js → chunk-KOYZJN6G.js} +310 -20
- package/dist/chunk-KOYZJN6G.js.map +1 -0
- package/dist/{chunk-ZBQQXVHD.js → chunk-YIEXKQYP.js} +2 -67
- package/dist/chunk-YIEXKQYP.js.map +1 -0
- package/dist/cli/init.cjs +453 -126
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.js +29 -16
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/mcp-add.cjs +339 -97
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +32 -14
- package/dist/cli/mcp-add.js.map +1 -1
- package/dist/cli/status.cjs +6 -1
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.js +7 -2
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/uninit.cjs +6 -1
- package/dist/cli/uninit.cjs.map +1 -1
- package/dist/cli/uninit.js +2 -2
- package/dist/cli/upgrade-instructions.cjs +383 -112
- package/dist/cli/upgrade-instructions.cjs.map +1 -1
- package/dist/cli/upgrade-instructions.js +70 -18
- package/dist/cli/upgrade-instructions.js.map +1 -1
- package/dist/index.cjs +11 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/node-entry.cjs +11 -6
- package/dist/node-entry.cjs.map +1 -1
- package/dist/node-entry.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-CIKPFJOM.js.map +0 -1
- package/dist/chunk-UMGZJYC4.js.map +0 -1
- package/dist/chunk-ZBQQXVHD.js.map +0 -1
package/dist/cli/mcp-add.cjs
CHANGED
|
@@ -14277,33 +14277,61 @@ var AGENT_RULES = [
|
|
|
14277
14277
|
},
|
|
14278
14278
|
{
|
|
14279
14279
|
name: "codex",
|
|
14280
|
+
// Codex 2026 default discovery is `AGENTS.override.md` → `AGENTS.md` →
|
|
14281
|
+
// opt-in `project_doc_fallback_filenames`; `codex.md` is NOT in the
|
|
14282
|
+
// default fallback list. Detection requires Codex-specific markers
|
|
14283
|
+
// (`codex.md` legacy, `.codex/` config dir) — `AGENTS.md` is NOT
|
|
14284
|
+
// included as a marker because the SDK now writes `AGENTS.md`
|
|
14285
|
+
// broadly via the multi-target dispatcher's companion writes; if
|
|
14286
|
+
// `AGENTS.md` were a Codex marker, every project with the SDK's
|
|
14287
|
+
// own companion AGENTS.md would re-classify as Codex on subsequent
|
|
14288
|
+
// detect runs and trigger unintended `.codex/config.toml` writes
|
|
14289
|
+
// (Codex P1 + Copilot P1 review of Wave 18 PR #274). The canonical
|
|
14290
|
+
// write destination remains AGENTS.md regardless of which marker
|
|
14291
|
+
// classified the project.
|
|
14280
14292
|
markers: ["codex.md", ".codex"],
|
|
14281
14293
|
mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".codex", "config.toml"),
|
|
14282
|
-
infoFilePath: (dir) => (0, import_node_path.join)(dir, "
|
|
14294
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, "AGENTS.md"),
|
|
14283
14295
|
cliBinary: "codex",
|
|
14284
14296
|
registrationCommand: "npx glasstrace mcp add --agent codex"
|
|
14285
14297
|
},
|
|
14286
14298
|
{
|
|
14287
14299
|
name: "gemini",
|
|
14288
|
-
markers: [".gemini"],
|
|
14300
|
+
markers: [".gemini", "GEMINI.md"],
|
|
14289
14301
|
mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".gemini", "settings.json"),
|
|
14290
|
-
infoFilePath: () =>
|
|
14302
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, "GEMINI.md"),
|
|
14291
14303
|
cliBinary: "gemini",
|
|
14292
14304
|
registrationCommand: "npx glasstrace mcp add --agent gemini"
|
|
14293
14305
|
},
|
|
14294
14306
|
{
|
|
14295
14307
|
name: "cursor",
|
|
14308
|
+
// `.cursor/rules/*.mdc` is the current canonical format per Cursor's
|
|
14309
|
+
// 2026 docs. `.cursorrules` (single file) is supported-but-deprecated
|
|
14310
|
+
// and stays as a transitional fallback that the multi-target write
|
|
14311
|
+
// helper writes unconditionally alongside the .mdc canonical.
|
|
14296
14312
|
markers: [".cursor", ".cursorrules"],
|
|
14297
14313
|
mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".cursor", "mcp.json"),
|
|
14298
|
-
infoFilePath: (dir) => (0, import_node_path.join)(dir, ".
|
|
14314
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, ".cursor", "rules", "glasstrace.mdc"),
|
|
14299
14315
|
cliBinary: null,
|
|
14300
14316
|
registrationCommand: "npx glasstrace mcp add --agent cursor"
|
|
14301
14317
|
},
|
|
14302
14318
|
{
|
|
14303
14319
|
name: "windsurf",
|
|
14304
|
-
|
|
14320
|
+
// Windsurf's current canonical workspace-rules format is
|
|
14321
|
+
// `.windsurf/rules/*.md`. AGENTS.md is a parallel cross-tool
|
|
14322
|
+
// mechanism Windsurf also reads BUT is NOT included as a Windsurf
|
|
14323
|
+
// detection marker — the SDK writes `AGENTS.md` broadly via the
|
|
14324
|
+
// multi-target dispatcher's companion writes, so treating
|
|
14325
|
+
// `AGENTS.md` as a Windsurf marker would re-classify every
|
|
14326
|
+
// SDK-managed project as Windsurf and cause `glasstrace uninit`
|
|
14327
|
+
// to mutate the global `~/.codeium/windsurf/mcp_config.json` for
|
|
14328
|
+
// non-Windsurf projects (Codex P1 + Copilot P1 review of Wave 18
|
|
14329
|
+
// PR #274). The single-file `.windsurfrules` is the deprecated
|
|
14330
|
+
// legacy form — recognized as a marker so legacy projects classify
|
|
14331
|
+
// correctly, but the SDK no longer writes to it.
|
|
14332
|
+
markers: [".windsurf", ".windsurfrules"],
|
|
14305
14333
|
mcpConfigPath: () => (0, import_node_path.join)((0, import_node_os.homedir)(), ".codeium", "windsurf", "mcp_config.json"),
|
|
14306
|
-
infoFilePath: (dir) => (0, import_node_path.join)(dir, ".
|
|
14334
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, ".windsurf", "rules", "glasstrace.md"),
|
|
14307
14335
|
cliBinary: null,
|
|
14308
14336
|
registrationCommand: "npx glasstrace mcp add --agent windsurf"
|
|
14309
14337
|
}
|
|
@@ -14390,10 +14418,7 @@ async function detectAgents(projectRoot) {
|
|
|
14390
14418
|
continue;
|
|
14391
14419
|
}
|
|
14392
14420
|
seenAgents.add(rule.name);
|
|
14393
|
-
|
|
14394
|
-
if (infoFilePath !== null && !await pathExists(infoFilePath)) {
|
|
14395
|
-
infoFilePath = null;
|
|
14396
|
-
}
|
|
14421
|
+
const infoFilePath = rule.infoFilePath(foundDir);
|
|
14397
14422
|
const cliAvailable = rule.cliBinary ? await isCliAvailable(rule.cliBinary) : false;
|
|
14398
14423
|
detected.push({
|
|
14399
14424
|
name: rule.name,
|
|
@@ -14406,7 +14431,7 @@ async function detectAgents(projectRoot) {
|
|
|
14406
14431
|
detected.push({
|
|
14407
14432
|
name: "generic",
|
|
14408
14433
|
mcpConfigPath: (0, import_node_path.join)(resolvedRoot, ".glasstrace", "mcp.json"),
|
|
14409
|
-
infoFilePath:
|
|
14434
|
+
infoFilePath: (0, import_node_path.join)(resolvedRoot, "AGENTS.md"),
|
|
14410
14435
|
cliAvailable: false,
|
|
14411
14436
|
registrationCommand: null
|
|
14412
14437
|
});
|
|
@@ -14586,34 +14611,75 @@ function generateInfoSection(agent, endpoint, sdkVersion) {
|
|
|
14586
14611
|
}
|
|
14587
14612
|
const content = buildAgentInstructionBody();
|
|
14588
14613
|
switch (agent.name) {
|
|
14589
|
-
case "claude":
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
}
|
|
14595
|
-
case "codex": {
|
|
14614
|
+
case "claude":
|
|
14615
|
+
case "codex":
|
|
14616
|
+
case "gemini":
|
|
14617
|
+
case "windsurf":
|
|
14618
|
+
case "generic": {
|
|
14596
14619
|
const m = htmlMarkers(sdkVersion);
|
|
14597
14620
|
return `${m.start}
|
|
14598
14621
|
${content}${m.end}
|
|
14599
14622
|
`;
|
|
14600
14623
|
}
|
|
14601
14624
|
case "cursor": {
|
|
14602
|
-
const m =
|
|
14625
|
+
const m = htmlMarkers(sdkVersion);
|
|
14603
14626
|
return `${m.start}
|
|
14604
14627
|
${content}${m.end}
|
|
14605
14628
|
`;
|
|
14606
14629
|
}
|
|
14607
|
-
case "gemini":
|
|
14608
|
-
case "windsurf":
|
|
14609
|
-
case "generic":
|
|
14610
|
-
return "";
|
|
14611
14630
|
default: {
|
|
14612
14631
|
const _exhaustive = agent.name;
|
|
14613
14632
|
throw new Error(`Unknown agent: ${_exhaustive}`);
|
|
14614
14633
|
}
|
|
14615
14634
|
}
|
|
14616
14635
|
}
|
|
14636
|
+
function generateInfoSectionForCursorrulesLegacy(endpoint, sdkVersion) {
|
|
14637
|
+
if (!endpoint || endpoint.trim() === "") {
|
|
14638
|
+
throw new Error("endpoint must not be empty");
|
|
14639
|
+
}
|
|
14640
|
+
if (!sdkVersion || sdkVersion.trim() === "") {
|
|
14641
|
+
throw new Error("sdkVersion must not be empty");
|
|
14642
|
+
}
|
|
14643
|
+
if (!SDK_VERSION_STAMP_PATTERN.test(sdkVersion)) {
|
|
14644
|
+
throw new Error(
|
|
14645
|
+
"sdkVersion must match [A-Za-z0-9.+\\-]+ (semver-shaped, no whitespace, no angle brackets)"
|
|
14646
|
+
);
|
|
14647
|
+
}
|
|
14648
|
+
const content = buildAgentInstructionBody();
|
|
14649
|
+
const m = hashMarkers(sdkVersion);
|
|
14650
|
+
return `${m.start}
|
|
14651
|
+
${content}${m.end}
|
|
14652
|
+
`;
|
|
14653
|
+
}
|
|
14654
|
+
function generateInfoSectionForCursorMdc(endpoint, sdkVersion) {
|
|
14655
|
+
if (!endpoint || endpoint.trim() === "") {
|
|
14656
|
+
throw new Error("endpoint must not be empty");
|
|
14657
|
+
}
|
|
14658
|
+
if (!sdkVersion || sdkVersion.trim() === "") {
|
|
14659
|
+
throw new Error("sdkVersion must not be empty");
|
|
14660
|
+
}
|
|
14661
|
+
if (!SDK_VERSION_STAMP_PATTERN.test(sdkVersion)) {
|
|
14662
|
+
throw new Error(
|
|
14663
|
+
"sdkVersion must match [A-Za-z0-9.+\\-]+ (semver-shaped, no whitespace, no angle brackets)"
|
|
14664
|
+
);
|
|
14665
|
+
}
|
|
14666
|
+
const content = buildAgentInstructionBody();
|
|
14667
|
+
const m = htmlMarkers(sdkVersion);
|
|
14668
|
+
return [
|
|
14669
|
+
"---",
|
|
14670
|
+
"description: Glasstrace MCP runtime debugging tools \u2014 runtime evidence the agent reads when source alone cannot resolve a bug",
|
|
14671
|
+
"alwaysApply: true",
|
|
14672
|
+
"---",
|
|
14673
|
+
"",
|
|
14674
|
+
`${m.start}
|
|
14675
|
+
${content}${m.end}
|
|
14676
|
+
`
|
|
14677
|
+
].join("\n");
|
|
14678
|
+
}
|
|
14679
|
+
|
|
14680
|
+
// src/agent-detection/inject-all-targets.ts
|
|
14681
|
+
var import_promises3 = require("node:fs/promises");
|
|
14682
|
+
var import_node_path3 = require("node:path");
|
|
14617
14683
|
|
|
14618
14684
|
// src/agent-detection/inject.ts
|
|
14619
14685
|
var import_promises2 = require("node:fs/promises");
|
|
@@ -14688,71 +14754,6 @@ function findMarkerBoundaries(lines) {
|
|
|
14688
14754
|
}
|
|
14689
14755
|
return null;
|
|
14690
14756
|
}
|
|
14691
|
-
async function injectInfoSection(agent, content, projectRoot) {
|
|
14692
|
-
if (agent.infoFilePath === null) {
|
|
14693
|
-
return;
|
|
14694
|
-
}
|
|
14695
|
-
if (content === "") {
|
|
14696
|
-
return;
|
|
14697
|
-
}
|
|
14698
|
-
const filePath = agent.infoFilePath;
|
|
14699
|
-
let existingContent = null;
|
|
14700
|
-
try {
|
|
14701
|
-
existingContent = await (0, import_promises2.readFile)(filePath, "utf-8");
|
|
14702
|
-
} catch (err) {
|
|
14703
|
-
const code = err.code;
|
|
14704
|
-
if (code !== "ENOENT") {
|
|
14705
|
-
if (isPermissionError(err)) {
|
|
14706
|
-
process.stderr.write(
|
|
14707
|
-
`Warning: cannot read info file ${filePath}: permission denied
|
|
14708
|
-
`
|
|
14709
|
-
);
|
|
14710
|
-
return;
|
|
14711
|
-
}
|
|
14712
|
-
throw err;
|
|
14713
|
-
}
|
|
14714
|
-
}
|
|
14715
|
-
if (existingContent === null) {
|
|
14716
|
-
try {
|
|
14717
|
-
await (0, import_promises2.mkdir)((0, import_node_path2.dirname)(filePath), { recursive: true });
|
|
14718
|
-
await (0, import_promises2.writeFile)(filePath, content, "utf-8");
|
|
14719
|
-
} catch (err) {
|
|
14720
|
-
if (isPermissionError(err)) {
|
|
14721
|
-
process.stderr.write(
|
|
14722
|
-
`Warning: cannot write info file ${filePath}: permission denied
|
|
14723
|
-
`
|
|
14724
|
-
);
|
|
14725
|
-
return;
|
|
14726
|
-
}
|
|
14727
|
-
throw err;
|
|
14728
|
-
}
|
|
14729
|
-
return;
|
|
14730
|
-
}
|
|
14731
|
-
const lines = existingContent.split("\n");
|
|
14732
|
-
const boundaries = findMarkerBoundaries(lines);
|
|
14733
|
-
let newContent;
|
|
14734
|
-
if (boundaries !== null) {
|
|
14735
|
-
const before = lines.slice(0, boundaries.startIdx);
|
|
14736
|
-
const after = lines.slice(boundaries.endIdx + 1);
|
|
14737
|
-
const contentWithoutTrailingNewline = content.endsWith("\n") ? content.slice(0, -1) : content;
|
|
14738
|
-
newContent = [...before, contentWithoutTrailingNewline, ...after].join("\n");
|
|
14739
|
-
} else {
|
|
14740
|
-
const separator = existingContent.endsWith("\n") ? "\n" : "\n\n";
|
|
14741
|
-
newContent = existingContent + separator + content;
|
|
14742
|
-
}
|
|
14743
|
-
try {
|
|
14744
|
-
await (0, import_promises2.writeFile)(filePath, newContent, "utf-8");
|
|
14745
|
-
} catch (err) {
|
|
14746
|
-
if (isPermissionError(err)) {
|
|
14747
|
-
process.stderr.write(
|
|
14748
|
-
`Warning: cannot write info file ${filePath}: permission denied
|
|
14749
|
-
`
|
|
14750
|
-
);
|
|
14751
|
-
return;
|
|
14752
|
-
}
|
|
14753
|
-
throw err;
|
|
14754
|
-
}
|
|
14755
|
-
}
|
|
14756
14757
|
async function updateGitignore(paths, projectRoot) {
|
|
14757
14758
|
const gitignorePath = (0, import_node_path2.join)(projectRoot, ".gitignore");
|
|
14758
14759
|
const relativePaths = paths.filter((p) => !(0, import_node_path2.isAbsolute)(p));
|
|
@@ -14800,6 +14801,228 @@ async function updateGitignore(paths, projectRoot) {
|
|
|
14800
14801
|
}
|
|
14801
14802
|
}
|
|
14802
14803
|
|
|
14804
|
+
// src/agent-detection/inject-all-targets.ts
|
|
14805
|
+
async function injectAllTargets(agents, endpoint, sdkVersion, projectRoot) {
|
|
14806
|
+
const writtenAgentsMd = /* @__PURE__ */ new Set();
|
|
14807
|
+
for (const agent of agents) {
|
|
14808
|
+
const targets = computeTargets(agent, projectRoot);
|
|
14809
|
+
for (const target of targets) {
|
|
14810
|
+
if (target.isAgentsMdCompanion) {
|
|
14811
|
+
if (writtenAgentsMd.has(target.path)) {
|
|
14812
|
+
continue;
|
|
14813
|
+
}
|
|
14814
|
+
writtenAgentsMd.add(target.path);
|
|
14815
|
+
}
|
|
14816
|
+
let createContent;
|
|
14817
|
+
let managedSectionOnly;
|
|
14818
|
+
if (target.kind === "cursor-mdc") {
|
|
14819
|
+
createContent = generateInfoSectionForCursorMdc(endpoint, sdkVersion);
|
|
14820
|
+
managedSectionOnly = generateInfoSection(agent, endpoint, sdkVersion);
|
|
14821
|
+
} else if (target.kind === "cursorrules-legacy") {
|
|
14822
|
+
createContent = generateInfoSectionForCursorrulesLegacy(
|
|
14823
|
+
endpoint,
|
|
14824
|
+
sdkVersion
|
|
14825
|
+
);
|
|
14826
|
+
managedSectionOnly = createContent;
|
|
14827
|
+
} else {
|
|
14828
|
+
createContent = generateInfoSection(agent, endpoint, sdkVersion);
|
|
14829
|
+
managedSectionOnly = createContent;
|
|
14830
|
+
}
|
|
14831
|
+
if (managedSectionOnly === "") continue;
|
|
14832
|
+
await writeManagedSectionToTarget(
|
|
14833
|
+
target.path,
|
|
14834
|
+
createContent,
|
|
14835
|
+
managedSectionOnly
|
|
14836
|
+
);
|
|
14837
|
+
}
|
|
14838
|
+
}
|
|
14839
|
+
}
|
|
14840
|
+
function foundDirFromAgent(agent) {
|
|
14841
|
+
if (agent.infoFilePath === null) return null;
|
|
14842
|
+
switch (agent.name) {
|
|
14843
|
+
case "claude":
|
|
14844
|
+
case "codex":
|
|
14845
|
+
case "gemini":
|
|
14846
|
+
case "generic":
|
|
14847
|
+
return (0, import_node_path3.dirname)(agent.infoFilePath);
|
|
14848
|
+
case "cursor":
|
|
14849
|
+
return (0, import_node_path3.dirname)((0, import_node_path3.dirname)((0, import_node_path3.dirname)(agent.infoFilePath)));
|
|
14850
|
+
case "windsurf":
|
|
14851
|
+
return (0, import_node_path3.dirname)((0, import_node_path3.dirname)((0, import_node_path3.dirname)(agent.infoFilePath)));
|
|
14852
|
+
}
|
|
14853
|
+
}
|
|
14854
|
+
function computeTargets(agent, projectRoot) {
|
|
14855
|
+
const targets = [];
|
|
14856
|
+
const foundDir = foundDirFromAgent(agent) ?? projectRoot;
|
|
14857
|
+
switch (agent.name) {
|
|
14858
|
+
case "claude": {
|
|
14859
|
+
if (agent.infoFilePath) {
|
|
14860
|
+
targets.push({
|
|
14861
|
+
path: agent.infoFilePath,
|
|
14862
|
+
kind: "primary",
|
|
14863
|
+
isAgentsMdCompanion: false
|
|
14864
|
+
});
|
|
14865
|
+
}
|
|
14866
|
+
targets.push({
|
|
14867
|
+
path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
|
|
14868
|
+
kind: "agents-md-companion",
|
|
14869
|
+
isAgentsMdCompanion: true
|
|
14870
|
+
});
|
|
14871
|
+
return targets;
|
|
14872
|
+
}
|
|
14873
|
+
case "codex": {
|
|
14874
|
+
if (agent.infoFilePath) {
|
|
14875
|
+
targets.push({
|
|
14876
|
+
path: agent.infoFilePath,
|
|
14877
|
+
kind: "primary",
|
|
14878
|
+
isAgentsMdCompanion: true
|
|
14879
|
+
});
|
|
14880
|
+
}
|
|
14881
|
+
return targets;
|
|
14882
|
+
}
|
|
14883
|
+
case "gemini": {
|
|
14884
|
+
if (agent.infoFilePath) {
|
|
14885
|
+
targets.push({
|
|
14886
|
+
path: agent.infoFilePath,
|
|
14887
|
+
kind: "primary",
|
|
14888
|
+
isAgentsMdCompanion: false
|
|
14889
|
+
});
|
|
14890
|
+
}
|
|
14891
|
+
targets.push({
|
|
14892
|
+
path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
|
|
14893
|
+
kind: "agents-md-companion",
|
|
14894
|
+
isAgentsMdCompanion: true
|
|
14895
|
+
});
|
|
14896
|
+
return targets;
|
|
14897
|
+
}
|
|
14898
|
+
case "cursor": {
|
|
14899
|
+
if (agent.infoFilePath) {
|
|
14900
|
+
targets.push({
|
|
14901
|
+
path: agent.infoFilePath,
|
|
14902
|
+
kind: "cursor-mdc",
|
|
14903
|
+
isAgentsMdCompanion: false
|
|
14904
|
+
});
|
|
14905
|
+
targets.push({
|
|
14906
|
+
path: (0, import_node_path3.join)(foundDir, ".cursorrules"),
|
|
14907
|
+
kind: "cursorrules-legacy",
|
|
14908
|
+
isAgentsMdCompanion: false
|
|
14909
|
+
});
|
|
14910
|
+
}
|
|
14911
|
+
targets.push({
|
|
14912
|
+
path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
|
|
14913
|
+
kind: "agents-md-companion",
|
|
14914
|
+
isAgentsMdCompanion: true
|
|
14915
|
+
});
|
|
14916
|
+
return targets;
|
|
14917
|
+
}
|
|
14918
|
+
case "windsurf": {
|
|
14919
|
+
if (agent.infoFilePath) {
|
|
14920
|
+
targets.push({
|
|
14921
|
+
path: agent.infoFilePath,
|
|
14922
|
+
kind: "primary",
|
|
14923
|
+
isAgentsMdCompanion: false
|
|
14924
|
+
});
|
|
14925
|
+
}
|
|
14926
|
+
targets.push({
|
|
14927
|
+
path: (0, import_node_path3.join)(foundDir, "AGENTS.md"),
|
|
14928
|
+
kind: "agents-md-companion",
|
|
14929
|
+
isAgentsMdCompanion: true
|
|
14930
|
+
});
|
|
14931
|
+
return targets;
|
|
14932
|
+
}
|
|
14933
|
+
case "generic": {
|
|
14934
|
+
if (agent.infoFilePath) {
|
|
14935
|
+
targets.push({
|
|
14936
|
+
path: agent.infoFilePath,
|
|
14937
|
+
kind: "primary",
|
|
14938
|
+
isAgentsMdCompanion: true
|
|
14939
|
+
});
|
|
14940
|
+
}
|
|
14941
|
+
return targets;
|
|
14942
|
+
}
|
|
14943
|
+
default: {
|
|
14944
|
+
const _exhaustive = agent.name;
|
|
14945
|
+
throw new Error(`Unknown agent: ${_exhaustive}`);
|
|
14946
|
+
}
|
|
14947
|
+
}
|
|
14948
|
+
}
|
|
14949
|
+
async function writeManagedSectionToTarget(filePath, createContent, managedSectionOnly) {
|
|
14950
|
+
let existingContent = null;
|
|
14951
|
+
try {
|
|
14952
|
+
existingContent = await (0, import_promises3.readFile)(filePath, "utf-8");
|
|
14953
|
+
} catch (err) {
|
|
14954
|
+
const code = err.code;
|
|
14955
|
+
if (code !== "ENOENT") {
|
|
14956
|
+
emitTargetWarning(filePath, "read", err);
|
|
14957
|
+
return;
|
|
14958
|
+
}
|
|
14959
|
+
}
|
|
14960
|
+
if (existingContent === null) {
|
|
14961
|
+
try {
|
|
14962
|
+
await (0, import_promises3.mkdir)((0, import_node_path3.dirname)(filePath), { recursive: true });
|
|
14963
|
+
await (0, import_promises3.writeFile)(filePath, createContent, "utf-8");
|
|
14964
|
+
} catch (err) {
|
|
14965
|
+
emitTargetWarning(filePath, "write", err);
|
|
14966
|
+
return;
|
|
14967
|
+
}
|
|
14968
|
+
return;
|
|
14969
|
+
}
|
|
14970
|
+
const lines = existingContent.split("\n");
|
|
14971
|
+
const boundaries = findMarkerBoundaries(lines);
|
|
14972
|
+
let newContent;
|
|
14973
|
+
if (boundaries !== null) {
|
|
14974
|
+
const before = lines.slice(0, boundaries.startIdx);
|
|
14975
|
+
const after = lines.slice(boundaries.endIdx + 1);
|
|
14976
|
+
const contentWithoutTrailingNewline = managedSectionOnly.endsWith("\n") ? managedSectionOnly.slice(0, -1) : managedSectionOnly;
|
|
14977
|
+
newContent = [...before, contentWithoutTrailingNewline, ...after].join(
|
|
14978
|
+
"\n"
|
|
14979
|
+
);
|
|
14980
|
+
} else {
|
|
14981
|
+
const separator = existingContent.endsWith("\n") ? "\n" : "\n\n";
|
|
14982
|
+
newContent = existingContent + separator + managedSectionOnly;
|
|
14983
|
+
}
|
|
14984
|
+
try {
|
|
14985
|
+
await (0, import_promises3.writeFile)(filePath, newContent, "utf-8");
|
|
14986
|
+
} catch (err) {
|
|
14987
|
+
emitTargetWarning(filePath, "write", err);
|
|
14988
|
+
}
|
|
14989
|
+
}
|
|
14990
|
+
function emitTargetWarning(filePath, op, err) {
|
|
14991
|
+
const code = err.code;
|
|
14992
|
+
let qualifier;
|
|
14993
|
+
switch (code) {
|
|
14994
|
+
case "EACCES":
|
|
14995
|
+
case "EPERM":
|
|
14996
|
+
qualifier = "permission denied";
|
|
14997
|
+
break;
|
|
14998
|
+
case "EROFS":
|
|
14999
|
+
qualifier = "filesystem read-only";
|
|
15000
|
+
break;
|
|
15001
|
+
case "ENOSPC":
|
|
15002
|
+
qualifier = "disk full";
|
|
15003
|
+
break;
|
|
15004
|
+
case "ENAMETOOLONG":
|
|
15005
|
+
qualifier = "path too long";
|
|
15006
|
+
break;
|
|
15007
|
+
case "ENOTDIR":
|
|
15008
|
+
qualifier = "not a directory";
|
|
15009
|
+
break;
|
|
15010
|
+
case "EISDIR":
|
|
15011
|
+
qualifier = "is a directory";
|
|
15012
|
+
break;
|
|
15013
|
+
default:
|
|
15014
|
+
qualifier = "I/O error";
|
|
15015
|
+
break;
|
|
15016
|
+
}
|
|
15017
|
+
try {
|
|
15018
|
+
process.stderr.write(
|
|
15019
|
+
`Warning: cannot ${op} info file ${filePath}: ${qualifier}
|
|
15020
|
+
`
|
|
15021
|
+
);
|
|
15022
|
+
} catch {
|
|
15023
|
+
}
|
|
15024
|
+
}
|
|
15025
|
+
|
|
14803
15026
|
// src/cli/constants.ts
|
|
14804
15027
|
function formatAgentName(name) {
|
|
14805
15028
|
const displayNames = {
|
|
@@ -14955,14 +15178,9 @@ async function mcpAdd(options) {
|
|
|
14955
15178
|
const bearer = resolved.effective.key;
|
|
14956
15179
|
for (const agent of targetAgents) {
|
|
14957
15180
|
const name = formatAgentName(agent.name);
|
|
14958
|
-
const sdkVersion = true ? "1.10.2" : "0.0.0-dev";
|
|
14959
15181
|
if (agent.name !== "generic") {
|
|
14960
15182
|
const cliSuccess = await registerViaCli(agent, bearer);
|
|
14961
15183
|
if (cliSuccess) {
|
|
14962
|
-
const infoContent = generateInfoSection(agent, MCP_ENDPOINT, sdkVersion);
|
|
14963
|
-
if (infoContent !== "") {
|
|
14964
|
-
await injectInfoSection(agent, infoContent, projectRoot);
|
|
14965
|
-
}
|
|
14966
15184
|
results.push({
|
|
14967
15185
|
agent: agent.name,
|
|
14968
15186
|
success: true,
|
|
@@ -14977,10 +15195,6 @@ async function mcpAdd(options) {
|
|
|
14977
15195
|
const configContent = generateMcpConfig(agent, MCP_ENDPOINT, bearer);
|
|
14978
15196
|
await writeMcpConfig(agent, configContent, projectRoot);
|
|
14979
15197
|
if (fs.existsSync(agent.mcpConfigPath)) {
|
|
14980
|
-
const infoContent = generateInfoSection(agent, MCP_ENDPOINT, sdkVersion);
|
|
14981
|
-
if (infoContent !== "") {
|
|
14982
|
-
await injectInfoSection(agent, infoContent, projectRoot);
|
|
14983
|
-
}
|
|
14984
15198
|
results.push({
|
|
14985
15199
|
agent: agent.name,
|
|
14986
15200
|
success: true,
|
|
@@ -15013,6 +15227,34 @@ async function mcpAdd(options) {
|
|
|
15013
15227
|
message: `${name}: No registration method available`
|
|
15014
15228
|
});
|
|
15015
15229
|
}
|
|
15230
|
+
const successfulAgentNames = new Set(
|
|
15231
|
+
results.filter((r) => r.success).map((r) => r.agent)
|
|
15232
|
+
);
|
|
15233
|
+
const agentsWithMcpReady = targetAgents.filter(
|
|
15234
|
+
(a) => successfulAgentNames.has(a.name)
|
|
15235
|
+
);
|
|
15236
|
+
const detectedNonGenericMcpAdd = targetAgents.filter(
|
|
15237
|
+
(a) => a.name !== "generic"
|
|
15238
|
+
);
|
|
15239
|
+
const nonGenericReadyMcpAdd = agentsWithMcpReady.filter(
|
|
15240
|
+
(a) => a.name !== "generic"
|
|
15241
|
+
);
|
|
15242
|
+
const dispatchSetMcpAdd = detectedNonGenericMcpAdd.length === 0 ? agentsWithMcpReady : nonGenericReadyMcpAdd;
|
|
15243
|
+
if (dispatchSetMcpAdd.length > 0) {
|
|
15244
|
+
const sdkVersion = true ? "1.11.0" : "0.0.0-dev";
|
|
15245
|
+
try {
|
|
15246
|
+
await injectAllTargets(
|
|
15247
|
+
dispatchSetMcpAdd,
|
|
15248
|
+
MCP_ENDPOINT,
|
|
15249
|
+
sdkVersion,
|
|
15250
|
+
projectRoot
|
|
15251
|
+
);
|
|
15252
|
+
} catch (injectErr) {
|
|
15253
|
+
messages.push(
|
|
15254
|
+
`Warning: Failed to write some agent-instruction files: ${injectErr instanceof Error ? injectErr.message : String(injectErr)}`
|
|
15255
|
+
);
|
|
15256
|
+
}
|
|
15257
|
+
}
|
|
15016
15258
|
await updateGitignore(
|
|
15017
15259
|
[".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".codex/config.toml"],
|
|
15018
15260
|
projectRoot
|