@glasstrace/sdk 0.7.2 → 0.8.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/dist/{chunk-CNNEPHWN.js → chunk-UGHMMOM4.js} +89 -16
- package/dist/chunk-UGHMMOM4.js.map +1 -0
- package/dist/cli/init.cjs +230 -103
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +6 -1
- package/dist/cli/init.d.ts +6 -1
- package/dist/cli/init.js +97 -90
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/mcp-add.cjs +5 -2
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CNNEPHWN.js.map +0 -1
package/dist/cli/init.cjs
CHANGED
|
@@ -35,12 +35,68 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
35
35
|
function identityFingerprint(token) {
|
|
36
36
|
return `sha256:${(0, import_node_crypto.createHash)("sha256").update(token).digest("hex")}`;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return
|
|
38
|
+
function hasRegisterGlasstraceCall(content) {
|
|
39
|
+
return content.split("\n").some((line) => {
|
|
40
|
+
const uncommented = line.replace(/\/\/.*$/, "");
|
|
41
|
+
return /\bregisterGlasstrace\s*\(/.test(uncommented);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function injectRegisterGlasstrace(content) {
|
|
45
|
+
if (hasRegisterGlasstraceCall(content)) {
|
|
46
|
+
return { injected: false, content };
|
|
47
|
+
}
|
|
48
|
+
const registerFnRegex = /export\s+(?:async\s+)?function\s+register\s*\([^)]*\)\s*\{/;
|
|
49
|
+
const match = registerFnRegex.exec(content);
|
|
50
|
+
if (!match) {
|
|
51
|
+
return { injected: false, content };
|
|
52
|
+
}
|
|
53
|
+
const afterBrace = content.slice(match.index + match[0].length);
|
|
54
|
+
const indentMatch = /\n([ \t]+)/.exec(afterBrace);
|
|
55
|
+
const indent = indentMatch ? indentMatch[1] : " ";
|
|
56
|
+
const importLine = 'import { registerGlasstrace } from "@glasstrace/sdk";\n';
|
|
57
|
+
const hasGlasstraceImport = content.includes("@glasstrace/sdk");
|
|
58
|
+
const insertPoint = match.index + match[0].length;
|
|
59
|
+
const callInjection = `
|
|
60
|
+
${indent}// Glasstrace must be registered before other instrumentation
|
|
61
|
+
${indent}registerGlasstrace();
|
|
62
|
+
`;
|
|
63
|
+
let modified;
|
|
64
|
+
if (hasGlasstraceImport) {
|
|
65
|
+
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@glasstrace\/sdk["']/;
|
|
66
|
+
const importMatch = importRegex.exec(content);
|
|
67
|
+
if (importMatch) {
|
|
68
|
+
const specifiers = importMatch[1];
|
|
69
|
+
const alreadyImported = specifiers.split(",").some((s) => s.trim() === "registerGlasstrace");
|
|
70
|
+
if (alreadyImported) {
|
|
71
|
+
modified = content.slice(0, insertPoint) + callInjection + content.slice(insertPoint);
|
|
72
|
+
} else {
|
|
73
|
+
const existingImports = specifiers.trimEnd();
|
|
74
|
+
const separator = existingImports.endsWith(",") ? " " : ", ";
|
|
75
|
+
const updatedImport = `import {${existingImports}${separator}registerGlasstrace} from "@glasstrace/sdk"`;
|
|
76
|
+
modified = content.replace(importMatch[0], updatedImport);
|
|
77
|
+
const newMatch = registerFnRegex.exec(modified);
|
|
78
|
+
if (newMatch) {
|
|
79
|
+
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
80
|
+
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
modified = importLine + content;
|
|
85
|
+
const newMatch = registerFnRegex.exec(modified);
|
|
86
|
+
if (newMatch) {
|
|
87
|
+
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
88
|
+
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
modified = importLine + content.slice(0, insertPoint) + callInjection + content.slice(insertPoint);
|
|
42
93
|
}
|
|
43
|
-
|
|
94
|
+
return { injected: true, content: modified };
|
|
95
|
+
}
|
|
96
|
+
async function scaffoldInstrumentation(projectRoot) {
|
|
97
|
+
const filePath = path.join(projectRoot, "instrumentation.ts");
|
|
98
|
+
if (!fs.existsSync(filePath)) {
|
|
99
|
+
const content = `import { registerGlasstrace } from "@glasstrace/sdk";
|
|
44
100
|
|
|
45
101
|
export async function register() {
|
|
46
102
|
// Glasstrace must be registered before Prisma instrumentation
|
|
@@ -49,8 +105,19 @@ export async function register() {
|
|
|
49
105
|
registerGlasstrace();
|
|
50
106
|
}
|
|
51
107
|
`;
|
|
52
|
-
|
|
53
|
-
|
|
108
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
109
|
+
return { action: "created" };
|
|
110
|
+
}
|
|
111
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
112
|
+
if (hasRegisterGlasstraceCall(existing)) {
|
|
113
|
+
return { action: "already-registered" };
|
|
114
|
+
}
|
|
115
|
+
const result = injectRegisterGlasstrace(existing);
|
|
116
|
+
if (result.injected) {
|
|
117
|
+
fs.writeFileSync(filePath, result.content, "utf-8");
|
|
118
|
+
return { action: "injected" };
|
|
119
|
+
}
|
|
120
|
+
return { action: "unrecognized" };
|
|
54
121
|
}
|
|
55
122
|
async function scaffoldNextConfig(projectRoot) {
|
|
56
123
|
let configPath;
|
|
@@ -64,31 +131,34 @@ async function scaffoldNextConfig(projectRoot) {
|
|
|
64
131
|
}
|
|
65
132
|
}
|
|
66
133
|
if (configPath === void 0 || configName === void 0) {
|
|
67
|
-
return
|
|
134
|
+
return null;
|
|
68
135
|
}
|
|
69
136
|
const existing = fs.readFileSync(configPath, "utf-8");
|
|
137
|
+
if (existing.trim().length === 0) {
|
|
138
|
+
return { modified: false, reason: "empty-file" };
|
|
139
|
+
}
|
|
70
140
|
if (existing.includes("withGlasstraceConfig")) {
|
|
71
|
-
return false;
|
|
141
|
+
return { modified: false, reason: "already-wrapped" };
|
|
72
142
|
}
|
|
73
143
|
const isESM = configName.endsWith(".ts") || configName.endsWith(".mjs");
|
|
74
144
|
if (isESM) {
|
|
75
145
|
const importLine = 'import { withGlasstraceConfig } from "@glasstrace/sdk";\n';
|
|
76
146
|
const wrapResult2 = wrapExport(existing);
|
|
77
147
|
if (!wrapResult2.wrapped) {
|
|
78
|
-
return false;
|
|
148
|
+
return { modified: false, reason: "no-export" };
|
|
79
149
|
}
|
|
80
150
|
const modified2 = importLine + "\n" + wrapResult2.content;
|
|
81
151
|
fs.writeFileSync(configPath, modified2, "utf-8");
|
|
82
|
-
return true;
|
|
152
|
+
return { modified: true };
|
|
83
153
|
}
|
|
84
154
|
const requireLine = 'const { withGlasstraceConfig } = require("@glasstrace/sdk");\n';
|
|
85
155
|
const wrapResult = wrapCJSExport(existing);
|
|
86
156
|
if (!wrapResult.wrapped) {
|
|
87
|
-
return false;
|
|
157
|
+
return { modified: false, reason: "no-export" };
|
|
88
158
|
}
|
|
89
159
|
const modified = requireLine + "\n" + wrapResult.content;
|
|
90
160
|
fs.writeFileSync(configPath, modified, "utf-8");
|
|
91
|
-
return true;
|
|
161
|
+
return { modified: true };
|
|
92
162
|
}
|
|
93
163
|
function wrapExport(content) {
|
|
94
164
|
const marker = "export default";
|
|
@@ -14608,6 +14678,14 @@ var init_zod = __esm({
|
|
|
14608
14678
|
});
|
|
14609
14679
|
|
|
14610
14680
|
// ../protocol/dist/index.js
|
|
14681
|
+
function randomHex(byteCount) {
|
|
14682
|
+
const bytes = new Uint8Array(byteCount);
|
|
14683
|
+
crypto.getRandomValues(bytes);
|
|
14684
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
14685
|
+
}
|
|
14686
|
+
function createAnonApiKey() {
|
|
14687
|
+
return AnonApiKeySchema.parse(`gt_anon_${randomHex(24)}`);
|
|
14688
|
+
}
|
|
14611
14689
|
function createBuildHash(hash2) {
|
|
14612
14690
|
return BuildHashSchema.parse(hash2);
|
|
14613
14691
|
}
|
|
@@ -14761,6 +14839,44 @@ async function readAnonKey(projectRoot) {
|
|
|
14761
14839
|
}
|
|
14762
14840
|
return null;
|
|
14763
14841
|
}
|
|
14842
|
+
async function getOrCreateAnonKey(projectRoot) {
|
|
14843
|
+
const root = projectRoot ?? process.cwd();
|
|
14844
|
+
const dirPath = (0, import_node_path.join)(root, GLASSTRACE_DIR);
|
|
14845
|
+
const keyPath = (0, import_node_path.join)(dirPath, ANON_KEY_FILE);
|
|
14846
|
+
const existingKey = await readAnonKey(root);
|
|
14847
|
+
if (existingKey !== null) {
|
|
14848
|
+
return existingKey;
|
|
14849
|
+
}
|
|
14850
|
+
const cached2 = ephemeralKeyCache.get(root);
|
|
14851
|
+
if (cached2 !== void 0) {
|
|
14852
|
+
return cached2;
|
|
14853
|
+
}
|
|
14854
|
+
const newKey = createAnonApiKey();
|
|
14855
|
+
try {
|
|
14856
|
+
await (0, import_promises.mkdir)(dirPath, { recursive: true, mode: 448 });
|
|
14857
|
+
await (0, import_promises.writeFile)(keyPath, newKey, { flag: "wx", mode: 384 });
|
|
14858
|
+
return newKey;
|
|
14859
|
+
} catch (err) {
|
|
14860
|
+
const code = err.code;
|
|
14861
|
+
if (code === "EEXIST") {
|
|
14862
|
+
const winnerKey = await readAnonKey(root);
|
|
14863
|
+
if (winnerKey !== null) {
|
|
14864
|
+
return winnerKey;
|
|
14865
|
+
}
|
|
14866
|
+
try {
|
|
14867
|
+
await (0, import_promises.writeFile)(keyPath, newKey, { mode: 384 });
|
|
14868
|
+
await (0, import_promises.chmod)(keyPath, 384);
|
|
14869
|
+
return newKey;
|
|
14870
|
+
} catch {
|
|
14871
|
+
}
|
|
14872
|
+
}
|
|
14873
|
+
ephemeralKeyCache.set(root, newKey);
|
|
14874
|
+
console.warn(
|
|
14875
|
+
`[glasstrace] Failed to persist anonymous key to ${keyPath}: ${err instanceof Error ? err.message : String(err)}. Using ephemeral key.`
|
|
14876
|
+
);
|
|
14877
|
+
return newKey;
|
|
14878
|
+
}
|
|
14879
|
+
}
|
|
14764
14880
|
var import_promises, import_node_path, GLASSTRACE_DIR, ANON_KEY_FILE, ephemeralKeyCache;
|
|
14765
14881
|
var init_anon_key = __esm({
|
|
14766
14882
|
"src/anon-key.ts"() {
|
|
@@ -15052,8 +15168,11 @@ function generateInfoSection(agent, endpoint) {
|
|
|
15052
15168
|
`Glasstrace is configured as an MCP server at: ${endpoint}`,
|
|
15053
15169
|
"",
|
|
15054
15170
|
"Available tools:",
|
|
15055
|
-
"- `
|
|
15056
|
-
"- `
|
|
15171
|
+
"- `get_latest_error` - Get the most recent error trace from the current session",
|
|
15172
|
+
"- `get_trace` - Get a specific trace by ID or URL pattern",
|
|
15173
|
+
"- `get_root_cause` - Get the full span tree and root cause analysis for an error",
|
|
15174
|
+
"- `get_test_suggestions` - Get test suggestions based on recent errors",
|
|
15175
|
+
"- `get_session_timeline` - Get the timeline of all traces in the current session",
|
|
15057
15176
|
"",
|
|
15058
15177
|
"To reconfigure, run: `npx glasstrace mcp add`",
|
|
15059
15178
|
""
|
|
@@ -15525,6 +15644,7 @@ var init_mcp_add = __esm({
|
|
|
15525
15644
|
// src/cli/init.ts
|
|
15526
15645
|
var init_exports = {};
|
|
15527
15646
|
__export(init_exports, {
|
|
15647
|
+
meetsNodeVersion: () => meetsNodeVersion,
|
|
15528
15648
|
runInit: () => runInit
|
|
15529
15649
|
});
|
|
15530
15650
|
module.exports = __toCommonJS(init_exports);
|
|
@@ -15708,6 +15828,10 @@ init_detect();
|
|
|
15708
15828
|
init_configs();
|
|
15709
15829
|
init_inject();
|
|
15710
15830
|
init_constants();
|
|
15831
|
+
function meetsNodeVersion(minMajor) {
|
|
15832
|
+
const [major] = process.versions.node.split(".").map(Number);
|
|
15833
|
+
return major >= minMajor;
|
|
15834
|
+
}
|
|
15711
15835
|
async function promptYesNo(question, defaultValue) {
|
|
15712
15836
|
if (!process.stdin.isTTY) {
|
|
15713
15837
|
return defaultValue;
|
|
@@ -15739,41 +15863,40 @@ async function runInit(options) {
|
|
|
15739
15863
|
errors.push("No package.json found. Run this command from a Node.js project root.");
|
|
15740
15864
|
return { exitCode: 1, summary, warnings, errors };
|
|
15741
15865
|
}
|
|
15742
|
-
const instrumentationPath = path4.join(projectRoot, "instrumentation.ts");
|
|
15743
|
-
const instrumentationExists = fs4.existsSync(instrumentationPath);
|
|
15744
|
-
let shouldWriteInstrumentation = true;
|
|
15745
|
-
if (instrumentationExists && !yes) {
|
|
15746
|
-
shouldWriteInstrumentation = await promptYesNo(
|
|
15747
|
-
"instrumentation.ts already exists. Overwrite?",
|
|
15748
|
-
false
|
|
15749
|
-
);
|
|
15750
|
-
} else if (instrumentationExists && yes) {
|
|
15751
|
-
shouldWriteInstrumentation = false;
|
|
15752
|
-
}
|
|
15753
15866
|
try {
|
|
15754
|
-
const
|
|
15755
|
-
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15867
|
+
const instrResult = await scaffoldInstrumentation(projectRoot);
|
|
15868
|
+
switch (instrResult.action) {
|
|
15869
|
+
case "created":
|
|
15870
|
+
summary.push("Created instrumentation.ts");
|
|
15871
|
+
break;
|
|
15872
|
+
case "injected":
|
|
15873
|
+
summary.push("Added registerGlasstrace() to existing instrumentation.ts");
|
|
15874
|
+
break;
|
|
15875
|
+
case "already-registered":
|
|
15876
|
+
summary.push("Skipped instrumentation.ts (registerGlasstrace already present)");
|
|
15877
|
+
break;
|
|
15878
|
+
case "unrecognized":
|
|
15879
|
+
warnings.push(
|
|
15880
|
+
'instrumentation.ts exists but has no recognizable register() function.\nAdd this import at the top of your file:\n\n import { registerGlasstrace } from "@glasstrace/sdk";\n\nThen add this as the first statement in your register() function:\n\n registerGlasstrace();\n'
|
|
15881
|
+
);
|
|
15882
|
+
break;
|
|
15759
15883
|
}
|
|
15760
15884
|
} catch (err) {
|
|
15761
15885
|
errors.push(`Failed to write instrumentation.ts: ${err instanceof Error ? err.message : String(err)}`);
|
|
15762
15886
|
return { exitCode: 1, summary, warnings, errors };
|
|
15763
15887
|
}
|
|
15764
15888
|
try {
|
|
15765
|
-
const
|
|
15766
|
-
if (
|
|
15889
|
+
const configResult = await scaffoldNextConfig(projectRoot);
|
|
15890
|
+
if (configResult?.modified) {
|
|
15767
15891
|
summary.push("Wrapped next.config with withGlasstraceConfig()");
|
|
15892
|
+
} else if (configResult === null) {
|
|
15893
|
+
warnings.push("No next.config.* found. You may need to create one for Next.js projects.");
|
|
15894
|
+
} else if (configResult.reason === "already-wrapped") {
|
|
15895
|
+
summary.push("Skipped next.config (already contains withGlasstraceConfig)");
|
|
15896
|
+
} else if (configResult.reason === "empty-file") {
|
|
15897
|
+
warnings.push("next.config is empty \u2014 add a Next.js configuration export to enable wrapping");
|
|
15768
15898
|
} else {
|
|
15769
|
-
|
|
15770
|
-
(name) => fs4.existsSync(path4.join(projectRoot, name))
|
|
15771
|
-
);
|
|
15772
|
-
if (hasNextConfig) {
|
|
15773
|
-
summary.push("Skipped next.config (already contains withGlasstraceConfig)");
|
|
15774
|
-
} else {
|
|
15775
|
-
warnings.push("No next.config.* found. You may need to create one for Next.js projects.");
|
|
15776
|
-
}
|
|
15899
|
+
warnings.push("next.config has no recognizable export pattern \u2014 add withGlasstraceConfig() manually");
|
|
15777
15900
|
}
|
|
15778
15901
|
} catch (err) {
|
|
15779
15902
|
errors.push(`Failed to modify next.config: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -15804,10 +15927,30 @@ async function runInit(options) {
|
|
|
15804
15927
|
const ciEnv = process.env["CI"];
|
|
15805
15928
|
const isCI = typeof ciEnv === "string" && ciEnv.trim() !== "" && ciEnv.toLowerCase() !== "false" && ciEnv.trim() !== "0" || process.env["GITHUB_ACTIONS"] === "true";
|
|
15806
15929
|
try {
|
|
15807
|
-
const anonKey = await
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15930
|
+
const anonKey = await getOrCreateAnonKey(projectRoot);
|
|
15931
|
+
let anyConfigWritten = false;
|
|
15932
|
+
if (isCI) {
|
|
15933
|
+
const genericAgent = {
|
|
15934
|
+
name: "generic",
|
|
15935
|
+
mcpConfigPath: path4.join(projectRoot, ".glasstrace", "mcp.json"),
|
|
15936
|
+
infoFilePath: null,
|
|
15937
|
+
cliAvailable: false,
|
|
15938
|
+
registrationCommand: null
|
|
15939
|
+
};
|
|
15940
|
+
const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT, anonKey);
|
|
15941
|
+
await writeMcpConfig(genericAgent, genericConfig, projectRoot);
|
|
15942
|
+
if (genericAgent.mcpConfigPath !== null && fs4.existsSync(genericAgent.mcpConfigPath)) {
|
|
15943
|
+
anyConfigWritten = true;
|
|
15944
|
+
summary.push("Created .glasstrace/mcp.json (CI mode)");
|
|
15945
|
+
}
|
|
15946
|
+
} else {
|
|
15947
|
+
let agents;
|
|
15948
|
+
try {
|
|
15949
|
+
agents = await detectAgents(projectRoot);
|
|
15950
|
+
} catch (detectErr) {
|
|
15951
|
+
warnings.push(
|
|
15952
|
+
`Agent detection failed: ${detectErr instanceof Error ? detectErr.message : String(detectErr)}. Writing generic config only.`
|
|
15953
|
+
);
|
|
15811
15954
|
const genericAgent = {
|
|
15812
15955
|
name: "generic",
|
|
15813
15956
|
mcpConfigPath: path4.join(projectRoot, ".glasstrace", "mcp.json"),
|
|
@@ -15819,71 +15962,47 @@ async function runInit(options) {
|
|
|
15819
15962
|
await writeMcpConfig(genericAgent, genericConfig, projectRoot);
|
|
15820
15963
|
if (genericAgent.mcpConfigPath !== null && fs4.existsSync(genericAgent.mcpConfigPath)) {
|
|
15821
15964
|
anyConfigWritten = true;
|
|
15822
|
-
summary.push("Created .glasstrace/mcp.json (CI mode)");
|
|
15823
15965
|
}
|
|
15824
|
-
|
|
15825
|
-
|
|
15966
|
+
agents = [];
|
|
15967
|
+
}
|
|
15968
|
+
const configuredNames = [];
|
|
15969
|
+
for (const agent of agents) {
|
|
15826
15970
|
try {
|
|
15827
|
-
|
|
15828
|
-
|
|
15971
|
+
const configContent = generateMcpConfig(agent, MCP_ENDPOINT, anonKey);
|
|
15972
|
+
await writeMcpConfig(agent, configContent, projectRoot);
|
|
15973
|
+
const configExists = agent.mcpConfigPath !== null && fs4.existsSync(agent.mcpConfigPath);
|
|
15974
|
+
if (!configExists) {
|
|
15975
|
+
continue;
|
|
15976
|
+
}
|
|
15977
|
+
anyConfigWritten = true;
|
|
15978
|
+
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
15979
|
+
if (infoContent !== "") {
|
|
15980
|
+
await injectInfoSection(agent, infoContent, projectRoot);
|
|
15981
|
+
}
|
|
15982
|
+
if (agent.name !== "generic") {
|
|
15983
|
+
configuredNames.push(formatAgentName(agent.name));
|
|
15984
|
+
}
|
|
15985
|
+
} catch (agentErr) {
|
|
15829
15986
|
warnings.push(
|
|
15830
|
-
`
|
|
15987
|
+
`Failed to configure MCP for ${agent.name}: ${agentErr instanceof Error ? agentErr.message : String(agentErr)}`
|
|
15831
15988
|
);
|
|
15832
|
-
const genericAgent = {
|
|
15833
|
-
name: "generic",
|
|
15834
|
-
mcpConfigPath: path4.join(projectRoot, ".glasstrace", "mcp.json"),
|
|
15835
|
-
infoFilePath: null,
|
|
15836
|
-
cliAvailable: false,
|
|
15837
|
-
registrationCommand: null
|
|
15838
|
-
};
|
|
15839
|
-
const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT, anonKey);
|
|
15840
|
-
await writeMcpConfig(genericAgent, genericConfig, projectRoot);
|
|
15841
|
-
if (genericAgent.mcpConfigPath !== null && fs4.existsSync(genericAgent.mcpConfigPath)) {
|
|
15842
|
-
anyConfigWritten = true;
|
|
15843
|
-
}
|
|
15844
|
-
agents = [];
|
|
15845
|
-
}
|
|
15846
|
-
const configuredNames = [];
|
|
15847
|
-
for (const agent of agents) {
|
|
15848
|
-
try {
|
|
15849
|
-
const configContent = generateMcpConfig(agent, MCP_ENDPOINT, anonKey);
|
|
15850
|
-
await writeMcpConfig(agent, configContent, projectRoot);
|
|
15851
|
-
const configExists = agent.mcpConfigPath !== null && fs4.existsSync(agent.mcpConfigPath);
|
|
15852
|
-
if (!configExists) {
|
|
15853
|
-
continue;
|
|
15854
|
-
}
|
|
15855
|
-
anyConfigWritten = true;
|
|
15856
|
-
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
15857
|
-
if (infoContent !== "") {
|
|
15858
|
-
await injectInfoSection(agent, infoContent, projectRoot);
|
|
15859
|
-
}
|
|
15860
|
-
if (agent.name !== "generic") {
|
|
15861
|
-
configuredNames.push(formatAgentName(agent.name));
|
|
15862
|
-
}
|
|
15863
|
-
} catch (agentErr) {
|
|
15864
|
-
warnings.push(
|
|
15865
|
-
`Failed to configure MCP for ${agent.name}: ${agentErr instanceof Error ? agentErr.message : String(agentErr)}`
|
|
15866
|
-
);
|
|
15867
|
-
}
|
|
15868
|
-
}
|
|
15869
|
-
if (configuredNames.length > 0) {
|
|
15870
|
-
summary.push(`Configured MCP for: ${configuredNames.join(", ")}`);
|
|
15871
|
-
} else if (anyConfigWritten) {
|
|
15872
|
-
summary.push("Created .glasstrace/mcp.json (generic config)");
|
|
15873
15989
|
}
|
|
15874
15990
|
}
|
|
15875
|
-
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
|
|
15879
|
-
|
|
15880
|
-
|
|
15881
|
-
|
|
15882
|
-
|
|
15883
|
-
|
|
15991
|
+
if (configuredNames.length > 0) {
|
|
15992
|
+
summary.push(`Configured MCP for: ${configuredNames.join(", ")}`);
|
|
15993
|
+
} else if (anyConfigWritten) {
|
|
15994
|
+
summary.push("Created .glasstrace/mcp.json (generic config)");
|
|
15995
|
+
}
|
|
15996
|
+
}
|
|
15997
|
+
await updateGitignore(
|
|
15998
|
+
[".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".codex/config.toml"],
|
|
15999
|
+
projectRoot
|
|
16000
|
+
);
|
|
16001
|
+
if (anyConfigWritten) {
|
|
16002
|
+
const markerCreated = await scaffoldMcpMarker(projectRoot, anonKey);
|
|
16003
|
+
if (markerCreated) {
|
|
16004
|
+
summary.push("Created .glasstrace/mcp-connected marker");
|
|
15884
16005
|
}
|
|
15885
|
-
} else {
|
|
15886
|
-
warnings.push("No anonymous key found. Skipping MCP auto-configuration. Run init again after the SDK has generated a key.");
|
|
15887
16006
|
}
|
|
15888
16007
|
} catch (mcpErr) {
|
|
15889
16008
|
warnings.push(
|
|
@@ -15941,6 +16060,13 @@ var scriptPath = typeof process !== "undefined" && process.argv[1] !== void 0 ?
|
|
|
15941
16060
|
var scriptBasename = scriptPath !== void 0 ? path4.basename(scriptPath) : void 0;
|
|
15942
16061
|
var isDirectExecution = scriptPath !== void 0 && (scriptPath.endsWith("/cli/init.js") || scriptPath.endsWith("/cli/init.ts") || scriptBasename === "glasstrace");
|
|
15943
16062
|
if (isDirectExecution) {
|
|
16063
|
+
if (!meetsNodeVersion(20)) {
|
|
16064
|
+
process.stderr.write(
|
|
16065
|
+
`Error: @glasstrace/sdk requires Node.js >= 20. Current version: ${process.version}
|
|
16066
|
+
`
|
|
16067
|
+
);
|
|
16068
|
+
process.exit(1);
|
|
16069
|
+
}
|
|
15944
16070
|
const subcommand = process.argv[2];
|
|
15945
16071
|
if (subcommand === "mcp") {
|
|
15946
16072
|
if (process.argv[3] === "add") {
|
|
@@ -16020,6 +16146,7 @@ Usage:
|
|
|
16020
16146
|
}
|
|
16021
16147
|
// Annotate the CommonJS export names for ESM import in node:
|
|
16022
16148
|
0 && (module.exports = {
|
|
16149
|
+
meetsNodeVersion,
|
|
16023
16150
|
runInit
|
|
16024
16151
|
});
|
|
16025
16152
|
//# sourceMappingURL=init.cjs.map
|