@glasstrace/sdk 1.1.0 → 1.1.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/{chunk-KE7MCPO5.js → chunk-4EZ6JTDG.js} +2 -2
- package/dist/{chunk-67RIOAXV.js → chunk-6RNBUUBR.js} +2 -2
- package/dist/{chunk-DXRZKKSO.js → chunk-7SZQN6IU.js} +1 -3
- package/dist/chunk-7SZQN6IU.js.map +1 -0
- package/dist/{chunk-55FBXXER.js → chunk-DIM4JRXM.js} +2 -2
- package/dist/{chunk-UGJ3X4CT.js → chunk-DST4UBXU.js} +2 -2
- package/dist/{chunk-DO2YPMQ5.js → chunk-MXDZHFJQ.js} +23 -5
- package/dist/chunk-MXDZHFJQ.js.map +1 -0
- package/dist/chunk-P22UQ2OJ.js +384 -0
- package/dist/chunk-P22UQ2OJ.js.map +1 -0
- package/dist/{chunk-HAU66QBQ.js → chunk-P4OYPFQ5.js} +9 -9
- package/dist/chunk-P4OYPFQ5.js.map +1 -0
- package/dist/{chunk-TQ54WLCZ.js → chunk-X5MAXP5T.js} +2 -1
- package/dist/{chunk-ZBTC5QIQ.js → chunk-Y26HJUPD.js} +9 -9
- package/dist/{chunk-LU3PPAOQ.js → chunk-ZRDQ6ZKI.js} +474 -93
- package/dist/chunk-ZRDQ6ZKI.js.map +1 -0
- package/dist/cli/init.cjs +1118 -946
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.js +42 -29
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/mcp-add.cjs +243 -83
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.d.cts +35 -4
- package/dist/cli/mcp-add.d.ts +35 -4
- package/dist/cli/mcp-add.js +48 -24
- package/dist/cli/mcp-add.js.map +1 -1
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.js +3 -1
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/uninit.cjs +4 -4
- package/dist/cli/uninit.cjs.map +1 -1
- package/dist/cli/uninit.js +4 -4
- package/dist/edge-entry.js +2 -2
- package/dist/index.cjs +293 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -5
- package/dist/{monorepo-N5Z63XP7.js → monorepo-GSL6JD3G.js} +5 -3
- package/dist/node-entry.cjs +293 -11
- package/dist/node-entry.cjs.map +1 -1
- package/dist/node-entry.js +7 -7
- package/dist/node-subpath.js +3 -3
- package/dist/{source-map-uploader-BJIXRLJ6.js → source-map-uploader-DPUUCLNW.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-DO2YPMQ5.js.map +0 -1
- package/dist/chunk-DXRZKKSO.js.map +0 -1
- package/dist/chunk-HAU66QBQ.js.map +0 -1
- package/dist/chunk-IP4NMDJK.js +0 -98
- package/dist/chunk-IP4NMDJK.js.map +0 -1
- package/dist/chunk-LU3PPAOQ.js.map +0 -1
- package/dist/chunk-O63DJKIJ.js +0 -460
- package/dist/chunk-O63DJKIJ.js.map +0 -1
- /package/dist/{chunk-KE7MCPO5.js.map → chunk-4EZ6JTDG.js.map} +0 -0
- /package/dist/{chunk-67RIOAXV.js.map → chunk-6RNBUUBR.js.map} +0 -0
- /package/dist/{chunk-55FBXXER.js.map → chunk-DIM4JRXM.js.map} +0 -0
- /package/dist/{chunk-UGJ3X4CT.js.map → chunk-DST4UBXU.js.map} +0 -0
- /package/dist/{chunk-TQ54WLCZ.js.map → chunk-X5MAXP5T.js.map} +0 -0
- /package/dist/{chunk-ZBTC5QIQ.js.map → chunk-Y26HJUPD.js.map} +0 -0
- /package/dist/{monorepo-N5Z63XP7.js.map → monorepo-GSL6JD3G.js.map} +0 -0
- /package/dist/{source-map-uploader-BJIXRLJ6.js.map → source-map-uploader-DPUUCLNW.js.map} +0 -0
package/dist/cli/init.cjs
CHANGED
|
@@ -31,889 +31,418 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
));
|
|
32
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
33
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
var init_constants = __esm({
|
|
48
|
-
"src/cli/constants.ts"() {
|
|
49
|
-
"use strict";
|
|
50
|
-
MCP_ENDPOINT = "https://api.glasstrace.dev/mcp";
|
|
51
|
-
NEXT_CONFIG_NAMES = ["next.config.ts", "next.config.js", "next.config.mjs"];
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// src/cli/scaffolder.ts
|
|
56
|
-
function identityFingerprint(token) {
|
|
57
|
-
return `sha256:${(0, import_node_crypto.createHash)("sha256").update(token).digest("hex")}`;
|
|
58
|
-
}
|
|
59
|
-
function hasRegisterGlasstraceCall(content) {
|
|
60
|
-
return content.split("\n").some((line) => {
|
|
61
|
-
const uncommented = line.replace(/\/\/.*$/, "");
|
|
62
|
-
return /\bregisterGlasstrace\s*\(/.test(uncommented);
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
function injectRegisterGlasstrace(content) {
|
|
66
|
-
if (hasRegisterGlasstraceCall(content)) {
|
|
67
|
-
return { injected: false, content };
|
|
68
|
-
}
|
|
69
|
-
const registerFnRegex = /export\s+(?:async\s+)?function\s+register\s*\([^)]*\)\s*\{/;
|
|
70
|
-
const match = registerFnRegex.exec(content);
|
|
71
|
-
if (!match) {
|
|
72
|
-
return { injected: false, content };
|
|
73
|
-
}
|
|
74
|
-
const afterBrace = content.slice(match.index + match[0].length);
|
|
75
|
-
const indentMatch = /\n([ \t]+)/.exec(afterBrace);
|
|
76
|
-
const indent = indentMatch ? indentMatch[1] : " ";
|
|
77
|
-
const importLine = 'import { registerGlasstrace } from "@glasstrace/sdk";\n';
|
|
78
|
-
const hasGlasstraceImport2 = content.includes("@glasstrace/sdk");
|
|
79
|
-
const insertPoint = match.index + match[0].length;
|
|
80
|
-
const callInjection = `
|
|
81
|
-
${indent}// Glasstrace must be registered before other instrumentation
|
|
82
|
-
${indent}registerGlasstrace();
|
|
83
|
-
`;
|
|
84
|
-
let modified;
|
|
85
|
-
if (hasGlasstraceImport2) {
|
|
86
|
-
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@glasstrace\/sdk["']/;
|
|
87
|
-
const importMatch = importRegex.exec(content);
|
|
88
|
-
if (importMatch) {
|
|
89
|
-
const specifiers = importMatch[1];
|
|
90
|
-
const alreadyImported = specifiers.split(",").some((s) => s.trim() === "registerGlasstrace");
|
|
91
|
-
if (alreadyImported) {
|
|
92
|
-
modified = content.slice(0, insertPoint) + callInjection + content.slice(insertPoint);
|
|
93
|
-
} else {
|
|
94
|
-
const existingImports = specifiers.trimEnd();
|
|
95
|
-
const separator = existingImports.endsWith(",") ? " " : ", ";
|
|
96
|
-
const updatedImport = `import { ${existingImports.trim()}${separator}registerGlasstrace } from "@glasstrace/sdk"`;
|
|
97
|
-
modified = content.replace(importMatch[0], updatedImport);
|
|
98
|
-
const newMatch = registerFnRegex.exec(modified);
|
|
99
|
-
if (newMatch) {
|
|
100
|
-
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
101
|
-
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
} else {
|
|
105
|
-
modified = importLine + content;
|
|
106
|
-
const newMatch = registerFnRegex.exec(modified);
|
|
107
|
-
if (newMatch) {
|
|
108
|
-
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
109
|
-
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
110
|
-
}
|
|
34
|
+
// ../../node_modules/zod/v4/core/core.js
|
|
35
|
+
// @__NO_SIDE_EFFECTS__
|
|
36
|
+
function $constructor(name, initializer3, params) {
|
|
37
|
+
function init(inst, def) {
|
|
38
|
+
if (!inst._zod) {
|
|
39
|
+
Object.defineProperty(inst, "_zod", {
|
|
40
|
+
value: {
|
|
41
|
+
def,
|
|
42
|
+
constr: _,
|
|
43
|
+
traits: /* @__PURE__ */ new Set()
|
|
44
|
+
},
|
|
45
|
+
enumerable: false
|
|
46
|
+
});
|
|
111
47
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
return { injected: true, content: modified };
|
|
116
|
-
}
|
|
117
|
-
function resolveInstrumentationTarget(projectRoot) {
|
|
118
|
-
const rootExisting = [];
|
|
119
|
-
const srcExisting = [];
|
|
120
|
-
for (const name of INSTRUMENTATION_FILENAMES) {
|
|
121
|
-
const rootPath = path.join(projectRoot, name);
|
|
122
|
-
if (isRegularFile(rootPath)) {
|
|
123
|
-
rootExisting.push(rootPath);
|
|
48
|
+
if (inst._zod.traits.has(name)) {
|
|
49
|
+
return;
|
|
124
50
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
51
|
+
inst._zod.traits.add(name);
|
|
52
|
+
initializer3(inst, def);
|
|
53
|
+
const proto = _.prototype;
|
|
54
|
+
const keys = Object.keys(proto);
|
|
55
|
+
for (let i = 0; i < keys.length; i++) {
|
|
56
|
+
const k = keys[i];
|
|
57
|
+
if (!(k in inst)) {
|
|
58
|
+
inst[k] = proto[k].bind(inst);
|
|
59
|
+
}
|
|
128
60
|
}
|
|
129
61
|
}
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
target: null,
|
|
134
|
-
layout: null,
|
|
135
|
-
existing,
|
|
136
|
-
rootExisting,
|
|
137
|
-
srcExisting,
|
|
138
|
-
conflict: true
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
if (srcExisting.length > 0) {
|
|
142
|
-
return {
|
|
143
|
-
target: srcExisting[0],
|
|
144
|
-
layout: "src",
|
|
145
|
-
existing,
|
|
146
|
-
rootExisting,
|
|
147
|
-
srcExisting,
|
|
148
|
-
conflict: false
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (rootExisting.length > 0) {
|
|
152
|
-
return {
|
|
153
|
-
target: rootExisting[0],
|
|
154
|
-
layout: "root",
|
|
155
|
-
existing,
|
|
156
|
-
rootExisting,
|
|
157
|
-
srcExisting,
|
|
158
|
-
conflict: false
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
const srcDir = path.join(projectRoot, "src");
|
|
162
|
-
const layout = isDirectory(srcDir) ? "src" : "root";
|
|
163
|
-
const target = layout === "src" ? path.join(projectRoot, "src", "instrumentation.ts") : path.join(projectRoot, "instrumentation.ts");
|
|
164
|
-
return {
|
|
165
|
-
target,
|
|
166
|
-
layout,
|
|
167
|
-
existing,
|
|
168
|
-
rootExisting,
|
|
169
|
-
srcExisting,
|
|
170
|
-
conflict: false
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
function isDirectory(p) {
|
|
174
|
-
try {
|
|
175
|
-
return fs.statSync(p).isDirectory();
|
|
176
|
-
} catch {
|
|
177
|
-
return false;
|
|
62
|
+
const Parent = params?.Parent ?? Object;
|
|
63
|
+
class Definition extends Parent {
|
|
178
64
|
}
|
|
179
|
-
}
|
|
180
|
-
function
|
|
181
|
-
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
65
|
+
Object.defineProperty(Definition, "name", { value: name });
|
|
66
|
+
function _(def) {
|
|
67
|
+
var _a2;
|
|
68
|
+
const inst = params?.Parent ? new Definition() : this;
|
|
69
|
+
init(inst, def);
|
|
70
|
+
(_a2 = inst._zod).deferred ?? (_a2.deferred = []);
|
|
71
|
+
for (const fn of inst._zod.deferred) {
|
|
72
|
+
fn();
|
|
185
73
|
}
|
|
186
|
-
return
|
|
187
|
-
} catch {
|
|
188
|
-
return false;
|
|
74
|
+
return inst;
|
|
189
75
|
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (!hasGlasstraceImport2) {
|
|
197
|
-
withImport = importLine + content;
|
|
198
|
-
} else {
|
|
199
|
-
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@glasstrace\/sdk["']/;
|
|
200
|
-
const importMatch = importRegex.exec(content);
|
|
201
|
-
if (importMatch) {
|
|
202
|
-
const specifiers = importMatch[1];
|
|
203
|
-
const alreadyImported = specifiers.split(",").some((s) => s.trim() === "registerGlasstrace");
|
|
204
|
-
if (!alreadyImported) {
|
|
205
|
-
const existingImports = specifiers.trimEnd();
|
|
206
|
-
const separator = existingImports.endsWith(",") ? " " : ", ";
|
|
207
|
-
const updatedImport = `import { ${existingImports.trim()}${separator}registerGlasstrace } from "@glasstrace/sdk"`;
|
|
208
|
-
withImport = content.replace(importMatch[0], updatedImport);
|
|
209
|
-
}
|
|
210
|
-
} else {
|
|
211
|
-
withImport = importLine + content;
|
|
76
|
+
Object.defineProperty(_, "init", { value: init });
|
|
77
|
+
Object.defineProperty(_, Symbol.hasInstance, {
|
|
78
|
+
value: (inst) => {
|
|
79
|
+
if (params?.Parent && inst instanceof params.Parent)
|
|
80
|
+
return true;
|
|
81
|
+
return inst?._zod?.traits?.has(name);
|
|
212
82
|
}
|
|
213
|
-
}
|
|
214
|
-
const trailingNewline = withImport.endsWith("\n") ? "" : "\n";
|
|
215
|
-
return withImport + trailingNewline + functionBlock;
|
|
216
|
-
}
|
|
217
|
-
async function defaultInstrumentationPrompt(question, defaultValue) {
|
|
218
|
-
if (!process.stdin.isTTY) return defaultValue;
|
|
219
|
-
const readline2 = await import("node:readline");
|
|
220
|
-
const rl = readline2.createInterface({
|
|
221
|
-
input: process.stdin,
|
|
222
|
-
output: process.stdout
|
|
223
|
-
});
|
|
224
|
-
return new Promise((resolve2) => {
|
|
225
|
-
const suffix = defaultValue ? " [Y/n] " : " [y/N] ";
|
|
226
|
-
rl.question(question + suffix, (answer) => {
|
|
227
|
-
rl.close();
|
|
228
|
-
const trimmed = answer.trim().toLowerCase();
|
|
229
|
-
if (trimmed === "") {
|
|
230
|
-
resolve2(defaultValue);
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
resolve2(trimmed === "y" || trimmed === "yes");
|
|
234
|
-
});
|
|
235
83
|
});
|
|
84
|
+
Object.defineProperty(_, "name", { value: name });
|
|
85
|
+
return _;
|
|
236
86
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
action: "conflict",
|
|
242
|
-
// Point the user at the `src/` variant — modern Next.js apps with a
|
|
243
|
-
// `src/` directory load from there, so that's the merge target. The
|
|
244
|
-
// competing path is reported separately for the error message.
|
|
245
|
-
filePath: target.srcExisting[0],
|
|
246
|
-
conflictingPath: target.rootExisting[0]
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
const filePath = target.target;
|
|
250
|
-
const layout = target.layout;
|
|
251
|
-
if (filePath === null || layout === null) {
|
|
252
|
-
return { action: "unrecognized" };
|
|
253
|
-
}
|
|
254
|
-
const force = options.force === true;
|
|
255
|
-
const prompt = options.prompt ?? defaultInstrumentationPrompt;
|
|
256
|
-
if (!fs.existsSync(filePath)) {
|
|
257
|
-
const content = `import { registerGlasstrace } from "@glasstrace/sdk";
|
|
258
|
-
|
|
259
|
-
export async function register() {
|
|
260
|
-
// Glasstrace must be registered before Prisma instrumentation
|
|
261
|
-
// to ensure all ORM spans are captured correctly.
|
|
262
|
-
// If you use @prisma/instrumentation, import it after this call.
|
|
263
|
-
registerGlasstrace();
|
|
87
|
+
function config(newConfig) {
|
|
88
|
+
if (newConfig)
|
|
89
|
+
Object.assign(globalConfig, newConfig);
|
|
90
|
+
return globalConfig;
|
|
264
91
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
fs.writeFileSync(filePath, injectResult.content, "utf-8");
|
|
286
|
-
return { action: "injected", filePath, layout };
|
|
92
|
+
var NEVER, $brand, $ZodAsyncError, $ZodEncodeError, globalConfig;
|
|
93
|
+
var init_core = __esm({
|
|
94
|
+
"../../node_modules/zod/v4/core/core.js"() {
|
|
95
|
+
"use strict";
|
|
96
|
+
NEVER = Object.freeze({
|
|
97
|
+
status: "aborted"
|
|
98
|
+
});
|
|
99
|
+
$brand = /* @__PURE__ */ Symbol("zod_brand");
|
|
100
|
+
$ZodAsyncError = class extends Error {
|
|
101
|
+
constructor() {
|
|
102
|
+
super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
$ZodEncodeError = class extends Error {
|
|
106
|
+
constructor(name) {
|
|
107
|
+
super(`Encountered unidirectional transform during encode: ${name}`);
|
|
108
|
+
this.name = "ZodEncodeError";
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
globalConfig = {};
|
|
287
112
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// ../../node_modules/zod/v4/core/util.js
|
|
116
|
+
var util_exports = {};
|
|
117
|
+
__export(util_exports, {
|
|
118
|
+
BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
|
|
119
|
+
Class: () => Class,
|
|
120
|
+
NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
|
|
121
|
+
aborted: () => aborted,
|
|
122
|
+
allowsEval: () => allowsEval,
|
|
123
|
+
assert: () => assert,
|
|
124
|
+
assertEqual: () => assertEqual,
|
|
125
|
+
assertIs: () => assertIs,
|
|
126
|
+
assertNever: () => assertNever,
|
|
127
|
+
assertNotEqual: () => assertNotEqual,
|
|
128
|
+
assignProp: () => assignProp,
|
|
129
|
+
base64ToUint8Array: () => base64ToUint8Array,
|
|
130
|
+
base64urlToUint8Array: () => base64urlToUint8Array,
|
|
131
|
+
cached: () => cached,
|
|
132
|
+
captureStackTrace: () => captureStackTrace,
|
|
133
|
+
cleanEnum: () => cleanEnum,
|
|
134
|
+
cleanRegex: () => cleanRegex,
|
|
135
|
+
clone: () => clone,
|
|
136
|
+
cloneDef: () => cloneDef,
|
|
137
|
+
createTransparentProxy: () => createTransparentProxy,
|
|
138
|
+
defineLazy: () => defineLazy,
|
|
139
|
+
esc: () => esc,
|
|
140
|
+
escapeRegex: () => escapeRegex,
|
|
141
|
+
extend: () => extend,
|
|
142
|
+
finalizeIssue: () => finalizeIssue,
|
|
143
|
+
floatSafeRemainder: () => floatSafeRemainder,
|
|
144
|
+
getElementAtPath: () => getElementAtPath,
|
|
145
|
+
getEnumValues: () => getEnumValues,
|
|
146
|
+
getLengthableOrigin: () => getLengthableOrigin,
|
|
147
|
+
getParsedType: () => getParsedType,
|
|
148
|
+
getSizableOrigin: () => getSizableOrigin,
|
|
149
|
+
hexToUint8Array: () => hexToUint8Array,
|
|
150
|
+
isObject: () => isObject,
|
|
151
|
+
isPlainObject: () => isPlainObject,
|
|
152
|
+
issue: () => issue,
|
|
153
|
+
joinValues: () => joinValues,
|
|
154
|
+
jsonStringifyReplacer: () => jsonStringifyReplacer,
|
|
155
|
+
merge: () => merge,
|
|
156
|
+
mergeDefs: () => mergeDefs,
|
|
157
|
+
normalizeParams: () => normalizeParams,
|
|
158
|
+
nullish: () => nullish,
|
|
159
|
+
numKeys: () => numKeys,
|
|
160
|
+
objectClone: () => objectClone,
|
|
161
|
+
omit: () => omit,
|
|
162
|
+
optionalKeys: () => optionalKeys,
|
|
163
|
+
parsedType: () => parsedType,
|
|
164
|
+
partial: () => partial,
|
|
165
|
+
pick: () => pick,
|
|
166
|
+
prefixIssues: () => prefixIssues,
|
|
167
|
+
primitiveTypes: () => primitiveTypes,
|
|
168
|
+
promiseAllObject: () => promiseAllObject,
|
|
169
|
+
propertyKeyTypes: () => propertyKeyTypes,
|
|
170
|
+
randomString: () => randomString,
|
|
171
|
+
required: () => required,
|
|
172
|
+
safeExtend: () => safeExtend,
|
|
173
|
+
shallowClone: () => shallowClone,
|
|
174
|
+
slugify: () => slugify,
|
|
175
|
+
stringifyPrimitive: () => stringifyPrimitive,
|
|
176
|
+
uint8ArrayToBase64: () => uint8ArrayToBase64,
|
|
177
|
+
uint8ArrayToBase64url: () => uint8ArrayToBase64url,
|
|
178
|
+
uint8ArrayToHex: () => uint8ArrayToHex,
|
|
179
|
+
unwrapMessage: () => unwrapMessage
|
|
180
|
+
});
|
|
181
|
+
function assertEqual(val) {
|
|
182
|
+
return val;
|
|
291
183
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
let configName;
|
|
295
|
-
for (const name of NEXT_CONFIG_NAMES) {
|
|
296
|
-
const candidate = path.join(projectRoot, name);
|
|
297
|
-
if (fs.existsSync(candidate)) {
|
|
298
|
-
configPath = candidate;
|
|
299
|
-
configName = name;
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
if (configPath === void 0 || configName === void 0) {
|
|
304
|
-
return null;
|
|
305
|
-
}
|
|
306
|
-
const existing = fs.readFileSync(configPath, "utf-8");
|
|
307
|
-
if (existing.trim().length === 0) {
|
|
308
|
-
return { modified: false, reason: "empty-file" };
|
|
309
|
-
}
|
|
310
|
-
if (existing.includes("withGlasstraceConfig")) {
|
|
311
|
-
return { modified: false, reason: "already-wrapped" };
|
|
312
|
-
}
|
|
313
|
-
const isESM = configName.endsWith(".ts") || configName.endsWith(".mjs");
|
|
314
|
-
if (isESM) {
|
|
315
|
-
const importLine = 'import { withGlasstraceConfig } from "@glasstrace/sdk";\n';
|
|
316
|
-
const wrapResult2 = wrapExport(existing);
|
|
317
|
-
if (!wrapResult2.wrapped) {
|
|
318
|
-
return { modified: false, reason: "no-export" };
|
|
319
|
-
}
|
|
320
|
-
const modified2 = importLine + "\n" + wrapResult2.content;
|
|
321
|
-
fs.writeFileSync(configPath, modified2, "utf-8");
|
|
322
|
-
return { modified: true };
|
|
323
|
-
}
|
|
324
|
-
const requireLine = 'const { withGlasstraceConfig } = require("@glasstrace/sdk");\n';
|
|
325
|
-
const wrapResult = wrapCJSExport(existing);
|
|
326
|
-
if (!wrapResult.wrapped) {
|
|
327
|
-
return { modified: false, reason: "no-export" };
|
|
328
|
-
}
|
|
329
|
-
const modified = requireLine + "\n" + wrapResult.content;
|
|
330
|
-
fs.writeFileSync(configPath, modified, "utf-8");
|
|
331
|
-
return { modified: true };
|
|
184
|
+
function assertNotEqual(val) {
|
|
185
|
+
return val;
|
|
332
186
|
}
|
|
333
|
-
function
|
|
334
|
-
const marker = "export default";
|
|
335
|
-
const idx = content.lastIndexOf(marker);
|
|
336
|
-
if (idx === -1) {
|
|
337
|
-
return { content, wrapped: false };
|
|
338
|
-
}
|
|
339
|
-
const preamble = content.slice(0, idx);
|
|
340
|
-
const exprRaw = content.slice(idx + marker.length);
|
|
341
|
-
const expr = exprRaw.trim().replace(/;?\s*$/, "");
|
|
342
|
-
if (expr.length === 0) {
|
|
343
|
-
return { content, wrapped: false };
|
|
344
|
-
}
|
|
345
|
-
return {
|
|
346
|
-
content: preamble + `export default withGlasstraceConfig(${expr});
|
|
347
|
-
`,
|
|
348
|
-
wrapped: true
|
|
349
|
-
};
|
|
187
|
+
function assertIs(_arg) {
|
|
350
188
|
}
|
|
351
|
-
function
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
if (
|
|
366
|
-
return
|
|
367
|
-
|
|
189
|
+
function assertNever(_x) {
|
|
190
|
+
throw new Error("Unexpected value in exhaustive check");
|
|
191
|
+
}
|
|
192
|
+
function assert(_) {
|
|
193
|
+
}
|
|
194
|
+
function getEnumValues(entries) {
|
|
195
|
+
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
196
|
+
const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
|
|
197
|
+
return values;
|
|
198
|
+
}
|
|
199
|
+
function joinValues(array2, separator = "|") {
|
|
200
|
+
return array2.map((val) => stringifyPrimitive(val)).join(separator);
|
|
201
|
+
}
|
|
202
|
+
function jsonStringifyReplacer(_, value) {
|
|
203
|
+
if (typeof value === "bigint")
|
|
204
|
+
return value.toString();
|
|
205
|
+
return value;
|
|
206
|
+
}
|
|
207
|
+
function cached(getter) {
|
|
208
|
+
const set2 = false;
|
|
368
209
|
return {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
210
|
+
get value() {
|
|
211
|
+
if (!set2) {
|
|
212
|
+
const value = getter();
|
|
213
|
+
Object.defineProperty(this, "value", { value });
|
|
214
|
+
return value;
|
|
215
|
+
}
|
|
216
|
+
throw new Error("cached value already set");
|
|
217
|
+
}
|
|
372
218
|
};
|
|
373
219
|
}
|
|
374
|
-
function
|
|
375
|
-
|
|
376
|
-
const regex = /^\s*GLASSTRACE_API_KEY\s*=\s*(.*)$/gm;
|
|
377
|
-
let match;
|
|
378
|
-
while ((match = regex.exec(content)) !== null) {
|
|
379
|
-
const raw = match[1].trim();
|
|
380
|
-
if (raw === "") continue;
|
|
381
|
-
const unquoted = raw.replace(/^(['"])(.*)\1$/, "$2");
|
|
382
|
-
if (unquoted === "" || unquoted === "your_key_here") continue;
|
|
383
|
-
last = unquoted;
|
|
384
|
-
}
|
|
385
|
-
return last;
|
|
220
|
+
function nullish(input) {
|
|
221
|
+
return input === null || input === void 0;
|
|
386
222
|
}
|
|
387
|
-
function
|
|
388
|
-
|
|
389
|
-
|
|
223
|
+
function cleanRegex(source) {
|
|
224
|
+
const start = source.startsWith("^") ? 1 : 0;
|
|
225
|
+
const end = source.endsWith("$") ? source.length - 1 : source.length;
|
|
226
|
+
return source.slice(start, end);
|
|
390
227
|
}
|
|
391
|
-
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
228
|
+
function floatSafeRemainder(val, step) {
|
|
229
|
+
const valDecCount = (val.toString().split(".")[1] || "").length;
|
|
230
|
+
const stepString = step.toString();
|
|
231
|
+
let stepDecCount = (stepString.split(".")[1] || "").length;
|
|
232
|
+
if (stepDecCount === 0 && /\d?e-\d?/.test(stepString)) {
|
|
233
|
+
const match = stepString.match(/\d?e-(\d?)/);
|
|
234
|
+
if (match?.[1]) {
|
|
235
|
+
stepDecCount = Number.parseInt(match[1]);
|
|
397
236
|
}
|
|
398
|
-
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
399
|
-
fs.writeFileSync(filePath, existing + separator + "# GLASSTRACE_API_KEY=your_key_here\n", "utf-8");
|
|
400
|
-
return true;
|
|
401
237
|
}
|
|
402
|
-
|
|
403
|
-
|
|
238
|
+
const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
|
|
239
|
+
const valInt = Number.parseInt(val.toFixed(decCount).replace(".", ""));
|
|
240
|
+
const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", ""));
|
|
241
|
+
return valInt % stepInt / 10 ** decCount;
|
|
404
242
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
243
|
+
function defineLazy(object2, key, getter) {
|
|
244
|
+
let value = void 0;
|
|
245
|
+
Object.defineProperty(object2, key, {
|
|
246
|
+
get() {
|
|
247
|
+
if (value === EVALUATING) {
|
|
248
|
+
return void 0;
|
|
249
|
+
}
|
|
250
|
+
if (value === void 0) {
|
|
251
|
+
value = EVALUATING;
|
|
252
|
+
value = getter();
|
|
253
|
+
}
|
|
254
|
+
return value;
|
|
255
|
+
},
|
|
256
|
+
set(v) {
|
|
257
|
+
Object.defineProperty(object2, key, {
|
|
258
|
+
value: v
|
|
259
|
+
// configurable: true,
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
configurable: true
|
|
263
|
+
});
|
|
426
264
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
if (fs.existsSync(filePath)) {
|
|
430
|
-
const existing = fs.readFileSync(filePath, "utf-8");
|
|
431
|
-
const lines = existing.split("\n").map((l) => l.trim());
|
|
432
|
-
if (lines.includes(".glasstrace/")) {
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
436
|
-
fs.writeFileSync(filePath, existing + separator + ".glasstrace/\n", "utf-8");
|
|
437
|
-
return true;
|
|
438
|
-
}
|
|
439
|
-
fs.writeFileSync(filePath, ".glasstrace/\n", "utf-8");
|
|
440
|
-
return true;
|
|
265
|
+
function objectClone(obj) {
|
|
266
|
+
return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
|
|
441
267
|
}
|
|
442
|
-
function
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
return existingContent.trim() === trimmedExpected;
|
|
268
|
+
function assignProp(target, prop, value) {
|
|
269
|
+
Object.defineProperty(target, prop, {
|
|
270
|
+
value,
|
|
271
|
+
writable: true,
|
|
272
|
+
enumerable: true,
|
|
273
|
+
configurable: true
|
|
274
|
+
});
|
|
451
275
|
}
|
|
452
|
-
function
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const obj = value;
|
|
458
|
-
const sorted = {};
|
|
459
|
-
for (const key of Object.keys(obj).sort()) {
|
|
460
|
-
sorted[key] = canonicalize(obj[key]);
|
|
461
|
-
}
|
|
462
|
-
return sorted;
|
|
276
|
+
function mergeDefs(...defs) {
|
|
277
|
+
const mergedDescriptors = {};
|
|
278
|
+
for (const def of defs) {
|
|
279
|
+
const descriptors = Object.getOwnPropertyDescriptors(def);
|
|
280
|
+
Object.assign(mergedDescriptors, descriptors);
|
|
463
281
|
}
|
|
464
|
-
return
|
|
282
|
+
return Object.defineProperties({}, mergedDescriptors);
|
|
465
283
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
const markerPath = path.join(dirPath, "mcp-connected");
|
|
469
|
-
const keyHash = identityFingerprint(anonKey);
|
|
470
|
-
if (fs.existsSync(markerPath)) {
|
|
471
|
-
try {
|
|
472
|
-
const existing = JSON.parse(fs.readFileSync(markerPath, "utf-8"));
|
|
473
|
-
if (existing.keyHash === keyHash) {
|
|
474
|
-
return false;
|
|
475
|
-
}
|
|
476
|
-
} catch {
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
fs.mkdirSync(dirPath, { recursive: true, mode: 448 });
|
|
480
|
-
const marker = JSON.stringify(
|
|
481
|
-
{ keyHash, configuredAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
482
|
-
null,
|
|
483
|
-
2
|
|
484
|
-
);
|
|
485
|
-
fs.writeFileSync(markerPath, marker, { mode: 384 });
|
|
486
|
-
fs.chmodSync(markerPath, 384);
|
|
487
|
-
return true;
|
|
284
|
+
function cloneDef(schema) {
|
|
285
|
+
return mergeDefs(schema._zod.def);
|
|
488
286
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
"instrumentation.js",
|
|
500
|
-
"instrumentation.mjs"
|
|
501
|
-
];
|
|
502
|
-
}
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
// ../../node_modules/zod/v4/core/core.js
|
|
506
|
-
// @__NO_SIDE_EFFECTS__
|
|
507
|
-
function $constructor(name, initializer3, params) {
|
|
508
|
-
function init(inst, def) {
|
|
509
|
-
if (!inst._zod) {
|
|
510
|
-
Object.defineProperty(inst, "_zod", {
|
|
511
|
-
value: {
|
|
512
|
-
def,
|
|
513
|
-
constr: _,
|
|
514
|
-
traits: /* @__PURE__ */ new Set()
|
|
515
|
-
},
|
|
516
|
-
enumerable: false
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
if (inst._zod.traits.has(name)) {
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
inst._zod.traits.add(name);
|
|
523
|
-
initializer3(inst, def);
|
|
524
|
-
const proto = _.prototype;
|
|
525
|
-
const keys = Object.keys(proto);
|
|
287
|
+
function getElementAtPath(obj, path10) {
|
|
288
|
+
if (!path10)
|
|
289
|
+
return obj;
|
|
290
|
+
return path10.reduce((acc, key) => acc?.[key], obj);
|
|
291
|
+
}
|
|
292
|
+
function promiseAllObject(promisesObj) {
|
|
293
|
+
const keys = Object.keys(promisesObj);
|
|
294
|
+
const promises = keys.map((key) => promisesObj[key]);
|
|
295
|
+
return Promise.all(promises).then((results) => {
|
|
296
|
+
const resolvedObj = {};
|
|
526
297
|
for (let i = 0; i < keys.length; i++) {
|
|
527
|
-
|
|
528
|
-
if (!(k in inst)) {
|
|
529
|
-
inst[k] = proto[k].bind(inst);
|
|
530
|
-
}
|
|
298
|
+
resolvedObj[keys[i]] = results[i];
|
|
531
299
|
}
|
|
300
|
+
return resolvedObj;
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
function randomString(length = 10) {
|
|
304
|
+
const chars = "abcdefghijklmnopqrstuvwxyz";
|
|
305
|
+
let str = "";
|
|
306
|
+
for (let i = 0; i < length; i++) {
|
|
307
|
+
str += chars[Math.floor(Math.random() * chars.length)];
|
|
532
308
|
}
|
|
533
|
-
|
|
534
|
-
|
|
309
|
+
return str;
|
|
310
|
+
}
|
|
311
|
+
function esc(str) {
|
|
312
|
+
return JSON.stringify(str);
|
|
313
|
+
}
|
|
314
|
+
function slugify(input) {
|
|
315
|
+
return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
316
|
+
}
|
|
317
|
+
function isObject(data) {
|
|
318
|
+
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
319
|
+
}
|
|
320
|
+
function isPlainObject(o) {
|
|
321
|
+
if (isObject(o) === false)
|
|
322
|
+
return false;
|
|
323
|
+
const ctor = o.constructor;
|
|
324
|
+
if (ctor === void 0)
|
|
325
|
+
return true;
|
|
326
|
+
if (typeof ctor !== "function")
|
|
327
|
+
return true;
|
|
328
|
+
const prot = ctor.prototype;
|
|
329
|
+
if (isObject(prot) === false)
|
|
330
|
+
return false;
|
|
331
|
+
if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
|
|
332
|
+
return false;
|
|
535
333
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
function shallowClone(o) {
|
|
337
|
+
if (isPlainObject(o))
|
|
338
|
+
return { ...o };
|
|
339
|
+
if (Array.isArray(o))
|
|
340
|
+
return [...o];
|
|
341
|
+
return o;
|
|
342
|
+
}
|
|
343
|
+
function numKeys(data) {
|
|
344
|
+
let keyCount = 0;
|
|
345
|
+
for (const key in data) {
|
|
346
|
+
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
347
|
+
keyCount++;
|
|
544
348
|
}
|
|
545
|
-
return inst;
|
|
546
349
|
}
|
|
547
|
-
|
|
548
|
-
Object.defineProperty(_, Symbol.hasInstance, {
|
|
549
|
-
value: (inst) => {
|
|
550
|
-
if (params?.Parent && inst instanceof params.Parent)
|
|
551
|
-
return true;
|
|
552
|
-
return inst?._zod?.traits?.has(name);
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
Object.defineProperty(_, "name", { value: name });
|
|
556
|
-
return _;
|
|
350
|
+
return keyCount;
|
|
557
351
|
}
|
|
558
|
-
function
|
|
559
|
-
|
|
560
|
-
Object.assign(globalConfig, newConfig);
|
|
561
|
-
return globalConfig;
|
|
352
|
+
function escapeRegex(str) {
|
|
353
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
562
354
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
status: "aborted"
|
|
569
|
-
});
|
|
570
|
-
$brand = /* @__PURE__ */ Symbol("zod_brand");
|
|
571
|
-
$ZodAsyncError = class extends Error {
|
|
572
|
-
constructor() {
|
|
573
|
-
super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
$ZodEncodeError = class extends Error {
|
|
577
|
-
constructor(name) {
|
|
578
|
-
super(`Encountered unidirectional transform during encode: ${name}`);
|
|
579
|
-
this.name = "ZodEncodeError";
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
globalConfig = {};
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
// ../../node_modules/zod/v4/core/util.js
|
|
587
|
-
var util_exports = {};
|
|
588
|
-
__export(util_exports, {
|
|
589
|
-
BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
|
|
590
|
-
Class: () => Class,
|
|
591
|
-
NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
|
|
592
|
-
aborted: () => aborted,
|
|
593
|
-
allowsEval: () => allowsEval,
|
|
594
|
-
assert: () => assert,
|
|
595
|
-
assertEqual: () => assertEqual,
|
|
596
|
-
assertIs: () => assertIs,
|
|
597
|
-
assertNever: () => assertNever,
|
|
598
|
-
assertNotEqual: () => assertNotEqual,
|
|
599
|
-
assignProp: () => assignProp,
|
|
600
|
-
base64ToUint8Array: () => base64ToUint8Array,
|
|
601
|
-
base64urlToUint8Array: () => base64urlToUint8Array,
|
|
602
|
-
cached: () => cached,
|
|
603
|
-
captureStackTrace: () => captureStackTrace,
|
|
604
|
-
cleanEnum: () => cleanEnum,
|
|
605
|
-
cleanRegex: () => cleanRegex,
|
|
606
|
-
clone: () => clone,
|
|
607
|
-
cloneDef: () => cloneDef,
|
|
608
|
-
createTransparentProxy: () => createTransparentProxy,
|
|
609
|
-
defineLazy: () => defineLazy,
|
|
610
|
-
esc: () => esc,
|
|
611
|
-
escapeRegex: () => escapeRegex,
|
|
612
|
-
extend: () => extend,
|
|
613
|
-
finalizeIssue: () => finalizeIssue,
|
|
614
|
-
floatSafeRemainder: () => floatSafeRemainder,
|
|
615
|
-
getElementAtPath: () => getElementAtPath,
|
|
616
|
-
getEnumValues: () => getEnumValues,
|
|
617
|
-
getLengthableOrigin: () => getLengthableOrigin,
|
|
618
|
-
getParsedType: () => getParsedType,
|
|
619
|
-
getSizableOrigin: () => getSizableOrigin,
|
|
620
|
-
hexToUint8Array: () => hexToUint8Array,
|
|
621
|
-
isObject: () => isObject,
|
|
622
|
-
isPlainObject: () => isPlainObject,
|
|
623
|
-
issue: () => issue,
|
|
624
|
-
joinValues: () => joinValues,
|
|
625
|
-
jsonStringifyReplacer: () => jsonStringifyReplacer,
|
|
626
|
-
merge: () => merge,
|
|
627
|
-
mergeDefs: () => mergeDefs,
|
|
628
|
-
normalizeParams: () => normalizeParams,
|
|
629
|
-
nullish: () => nullish,
|
|
630
|
-
numKeys: () => numKeys,
|
|
631
|
-
objectClone: () => objectClone,
|
|
632
|
-
omit: () => omit,
|
|
633
|
-
optionalKeys: () => optionalKeys,
|
|
634
|
-
parsedType: () => parsedType,
|
|
635
|
-
partial: () => partial,
|
|
636
|
-
pick: () => pick,
|
|
637
|
-
prefixIssues: () => prefixIssues,
|
|
638
|
-
primitiveTypes: () => primitiveTypes,
|
|
639
|
-
promiseAllObject: () => promiseAllObject,
|
|
640
|
-
propertyKeyTypes: () => propertyKeyTypes,
|
|
641
|
-
randomString: () => randomString,
|
|
642
|
-
required: () => required,
|
|
643
|
-
safeExtend: () => safeExtend,
|
|
644
|
-
shallowClone: () => shallowClone,
|
|
645
|
-
slugify: () => slugify,
|
|
646
|
-
stringifyPrimitive: () => stringifyPrimitive,
|
|
647
|
-
uint8ArrayToBase64: () => uint8ArrayToBase64,
|
|
648
|
-
uint8ArrayToBase64url: () => uint8ArrayToBase64url,
|
|
649
|
-
uint8ArrayToHex: () => uint8ArrayToHex,
|
|
650
|
-
unwrapMessage: () => unwrapMessage
|
|
651
|
-
});
|
|
652
|
-
function assertEqual(val) {
|
|
653
|
-
return val;
|
|
654
|
-
}
|
|
655
|
-
function assertNotEqual(val) {
|
|
656
|
-
return val;
|
|
657
|
-
}
|
|
658
|
-
function assertIs(_arg) {
|
|
659
|
-
}
|
|
660
|
-
function assertNever(_x) {
|
|
661
|
-
throw new Error("Unexpected value in exhaustive check");
|
|
662
|
-
}
|
|
663
|
-
function assert(_) {
|
|
664
|
-
}
|
|
665
|
-
function getEnumValues(entries) {
|
|
666
|
-
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
667
|
-
const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
|
|
668
|
-
return values;
|
|
669
|
-
}
|
|
670
|
-
function joinValues(array2, separator = "|") {
|
|
671
|
-
return array2.map((val) => stringifyPrimitive(val)).join(separator);
|
|
672
|
-
}
|
|
673
|
-
function jsonStringifyReplacer(_, value) {
|
|
674
|
-
if (typeof value === "bigint")
|
|
675
|
-
return value.toString();
|
|
676
|
-
return value;
|
|
677
|
-
}
|
|
678
|
-
function cached(getter) {
|
|
679
|
-
const set2 = false;
|
|
680
|
-
return {
|
|
681
|
-
get value() {
|
|
682
|
-
if (!set2) {
|
|
683
|
-
const value = getter();
|
|
684
|
-
Object.defineProperty(this, "value", { value });
|
|
685
|
-
return value;
|
|
686
|
-
}
|
|
687
|
-
throw new Error("cached value already set");
|
|
688
|
-
}
|
|
689
|
-
};
|
|
690
|
-
}
|
|
691
|
-
function nullish(input) {
|
|
692
|
-
return input === null || input === void 0;
|
|
693
|
-
}
|
|
694
|
-
function cleanRegex(source) {
|
|
695
|
-
const start = source.startsWith("^") ? 1 : 0;
|
|
696
|
-
const end = source.endsWith("$") ? source.length - 1 : source.length;
|
|
697
|
-
return source.slice(start, end);
|
|
355
|
+
function clone(inst, def, params) {
|
|
356
|
+
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
357
|
+
if (!def || params?.parent)
|
|
358
|
+
cl._zod.parent = inst;
|
|
359
|
+
return cl;
|
|
698
360
|
}
|
|
699
|
-
function
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
if (
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
361
|
+
function normalizeParams(_params) {
|
|
362
|
+
const params = _params;
|
|
363
|
+
if (!params)
|
|
364
|
+
return {};
|
|
365
|
+
if (typeof params === "string")
|
|
366
|
+
return { error: () => params };
|
|
367
|
+
if (params?.message !== void 0) {
|
|
368
|
+
if (params?.error !== void 0)
|
|
369
|
+
throw new Error("Cannot specify both `message` and `error` params");
|
|
370
|
+
params.error = params.message;
|
|
708
371
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
return
|
|
372
|
+
delete params.message;
|
|
373
|
+
if (typeof params.error === "string")
|
|
374
|
+
return { ...params, error: () => params.error };
|
|
375
|
+
return params;
|
|
713
376
|
}
|
|
714
|
-
function
|
|
715
|
-
let
|
|
716
|
-
|
|
717
|
-
get() {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}
|
|
721
|
-
if (value === void 0) {
|
|
722
|
-
value = EVALUATING;
|
|
723
|
-
value = getter();
|
|
724
|
-
}
|
|
725
|
-
return value;
|
|
377
|
+
function createTransparentProxy(getter) {
|
|
378
|
+
let target;
|
|
379
|
+
return new Proxy({}, {
|
|
380
|
+
get(_, prop, receiver) {
|
|
381
|
+
target ?? (target = getter());
|
|
382
|
+
return Reflect.get(target, prop, receiver);
|
|
726
383
|
},
|
|
727
|
-
set(
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
// configurable: true,
|
|
731
|
-
});
|
|
384
|
+
set(_, prop, value, receiver) {
|
|
385
|
+
target ?? (target = getter());
|
|
386
|
+
return Reflect.set(target, prop, value, receiver);
|
|
732
387
|
},
|
|
733
|
-
|
|
388
|
+
has(_, prop) {
|
|
389
|
+
target ?? (target = getter());
|
|
390
|
+
return Reflect.has(target, prop);
|
|
391
|
+
},
|
|
392
|
+
deleteProperty(_, prop) {
|
|
393
|
+
target ?? (target = getter());
|
|
394
|
+
return Reflect.deleteProperty(target, prop);
|
|
395
|
+
},
|
|
396
|
+
ownKeys(_) {
|
|
397
|
+
target ?? (target = getter());
|
|
398
|
+
return Reflect.ownKeys(target);
|
|
399
|
+
},
|
|
400
|
+
getOwnPropertyDescriptor(_, prop) {
|
|
401
|
+
target ?? (target = getter());
|
|
402
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
403
|
+
},
|
|
404
|
+
defineProperty(_, prop, descriptor) {
|
|
405
|
+
target ?? (target = getter());
|
|
406
|
+
return Reflect.defineProperty(target, prop, descriptor);
|
|
407
|
+
}
|
|
734
408
|
});
|
|
735
409
|
}
|
|
736
|
-
function
|
|
737
|
-
|
|
410
|
+
function stringifyPrimitive(value) {
|
|
411
|
+
if (typeof value === "bigint")
|
|
412
|
+
return value.toString() + "n";
|
|
413
|
+
if (typeof value === "string")
|
|
414
|
+
return `"${value}"`;
|
|
415
|
+
return `${value}`;
|
|
738
416
|
}
|
|
739
|
-
function
|
|
740
|
-
Object.
|
|
741
|
-
|
|
742
|
-
writable: true,
|
|
743
|
-
enumerable: true,
|
|
744
|
-
configurable: true
|
|
417
|
+
function optionalKeys(shape) {
|
|
418
|
+
return Object.keys(shape).filter((k) => {
|
|
419
|
+
return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
|
|
745
420
|
});
|
|
746
421
|
}
|
|
747
|
-
function
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
422
|
+
function pick(schema, mask) {
|
|
423
|
+
const currDef = schema._zod.def;
|
|
424
|
+
const checks = currDef.checks;
|
|
425
|
+
const hasChecks = checks && checks.length > 0;
|
|
426
|
+
if (hasChecks) {
|
|
427
|
+
throw new Error(".pick() cannot be used on object schemas containing refinements");
|
|
752
428
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
}
|
|
771
|
-
return resolvedObj;
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
function randomString(length = 10) {
|
|
775
|
-
const chars = "abcdefghijklmnopqrstuvwxyz";
|
|
776
|
-
let str = "";
|
|
777
|
-
for (let i = 0; i < length; i++) {
|
|
778
|
-
str += chars[Math.floor(Math.random() * chars.length)];
|
|
779
|
-
}
|
|
780
|
-
return str;
|
|
781
|
-
}
|
|
782
|
-
function esc(str) {
|
|
783
|
-
return JSON.stringify(str);
|
|
784
|
-
}
|
|
785
|
-
function slugify(input) {
|
|
786
|
-
return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
787
|
-
}
|
|
788
|
-
function isObject(data) {
|
|
789
|
-
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
790
|
-
}
|
|
791
|
-
function isPlainObject(o) {
|
|
792
|
-
if (isObject(o) === false)
|
|
793
|
-
return false;
|
|
794
|
-
const ctor = o.constructor;
|
|
795
|
-
if (ctor === void 0)
|
|
796
|
-
return true;
|
|
797
|
-
if (typeof ctor !== "function")
|
|
798
|
-
return true;
|
|
799
|
-
const prot = ctor.prototype;
|
|
800
|
-
if (isObject(prot) === false)
|
|
801
|
-
return false;
|
|
802
|
-
if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
|
|
803
|
-
return false;
|
|
804
|
-
}
|
|
805
|
-
return true;
|
|
806
|
-
}
|
|
807
|
-
function shallowClone(o) {
|
|
808
|
-
if (isPlainObject(o))
|
|
809
|
-
return { ...o };
|
|
810
|
-
if (Array.isArray(o))
|
|
811
|
-
return [...o];
|
|
812
|
-
return o;
|
|
813
|
-
}
|
|
814
|
-
function numKeys(data) {
|
|
815
|
-
let keyCount = 0;
|
|
816
|
-
for (const key in data) {
|
|
817
|
-
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
818
|
-
keyCount++;
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
return keyCount;
|
|
822
|
-
}
|
|
823
|
-
function escapeRegex(str) {
|
|
824
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
825
|
-
}
|
|
826
|
-
function clone(inst, def, params) {
|
|
827
|
-
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
828
|
-
if (!def || params?.parent)
|
|
829
|
-
cl._zod.parent = inst;
|
|
830
|
-
return cl;
|
|
831
|
-
}
|
|
832
|
-
function normalizeParams(_params) {
|
|
833
|
-
const params = _params;
|
|
834
|
-
if (!params)
|
|
835
|
-
return {};
|
|
836
|
-
if (typeof params === "string")
|
|
837
|
-
return { error: () => params };
|
|
838
|
-
if (params?.message !== void 0) {
|
|
839
|
-
if (params?.error !== void 0)
|
|
840
|
-
throw new Error("Cannot specify both `message` and `error` params");
|
|
841
|
-
params.error = params.message;
|
|
842
|
-
}
|
|
843
|
-
delete params.message;
|
|
844
|
-
if (typeof params.error === "string")
|
|
845
|
-
return { ...params, error: () => params.error };
|
|
846
|
-
return params;
|
|
847
|
-
}
|
|
848
|
-
function createTransparentProxy(getter) {
|
|
849
|
-
let target;
|
|
850
|
-
return new Proxy({}, {
|
|
851
|
-
get(_, prop, receiver) {
|
|
852
|
-
target ?? (target = getter());
|
|
853
|
-
return Reflect.get(target, prop, receiver);
|
|
854
|
-
},
|
|
855
|
-
set(_, prop, value, receiver) {
|
|
856
|
-
target ?? (target = getter());
|
|
857
|
-
return Reflect.set(target, prop, value, receiver);
|
|
858
|
-
},
|
|
859
|
-
has(_, prop) {
|
|
860
|
-
target ?? (target = getter());
|
|
861
|
-
return Reflect.has(target, prop);
|
|
862
|
-
},
|
|
863
|
-
deleteProperty(_, prop) {
|
|
864
|
-
target ?? (target = getter());
|
|
865
|
-
return Reflect.deleteProperty(target, prop);
|
|
866
|
-
},
|
|
867
|
-
ownKeys(_) {
|
|
868
|
-
target ?? (target = getter());
|
|
869
|
-
return Reflect.ownKeys(target);
|
|
870
|
-
},
|
|
871
|
-
getOwnPropertyDescriptor(_, prop) {
|
|
872
|
-
target ?? (target = getter());
|
|
873
|
-
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
874
|
-
},
|
|
875
|
-
defineProperty(_, prop, descriptor) {
|
|
876
|
-
target ?? (target = getter());
|
|
877
|
-
return Reflect.defineProperty(target, prop, descriptor);
|
|
878
|
-
}
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
function stringifyPrimitive(value) {
|
|
882
|
-
if (typeof value === "bigint")
|
|
883
|
-
return value.toString() + "n";
|
|
884
|
-
if (typeof value === "string")
|
|
885
|
-
return `"${value}"`;
|
|
886
|
-
return `${value}`;
|
|
887
|
-
}
|
|
888
|
-
function optionalKeys(shape) {
|
|
889
|
-
return Object.keys(shape).filter((k) => {
|
|
890
|
-
return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
|
|
891
|
-
});
|
|
892
|
-
}
|
|
893
|
-
function pick(schema, mask) {
|
|
894
|
-
const currDef = schema._zod.def;
|
|
895
|
-
const checks = currDef.checks;
|
|
896
|
-
const hasChecks = checks && checks.length > 0;
|
|
897
|
-
if (hasChecks) {
|
|
898
|
-
throw new Error(".pick() cannot be used on object schemas containing refinements");
|
|
899
|
-
}
|
|
900
|
-
const def = mergeDefs(schema._zod.def, {
|
|
901
|
-
get shape() {
|
|
902
|
-
const newShape = {};
|
|
903
|
-
for (const key in mask) {
|
|
904
|
-
if (!(key in currDef.shape)) {
|
|
905
|
-
throw new Error(`Unrecognized key: "${key}"`);
|
|
906
|
-
}
|
|
907
|
-
if (!mask[key])
|
|
908
|
-
continue;
|
|
909
|
-
newShape[key] = currDef.shape[key];
|
|
910
|
-
}
|
|
911
|
-
assignProp(this, "shape", newShape);
|
|
912
|
-
return newShape;
|
|
913
|
-
},
|
|
914
|
-
checks: []
|
|
915
|
-
});
|
|
916
|
-
return clone(schema, def);
|
|
429
|
+
const def = mergeDefs(schema._zod.def, {
|
|
430
|
+
get shape() {
|
|
431
|
+
const newShape = {};
|
|
432
|
+
for (const key in mask) {
|
|
433
|
+
if (!(key in currDef.shape)) {
|
|
434
|
+
throw new Error(`Unrecognized key: "${key}"`);
|
|
435
|
+
}
|
|
436
|
+
if (!mask[key])
|
|
437
|
+
continue;
|
|
438
|
+
newShape[key] = currDef.shape[key];
|
|
439
|
+
}
|
|
440
|
+
assignProp(this, "shape", newShape);
|
|
441
|
+
return newShape;
|
|
442
|
+
},
|
|
443
|
+
checks: []
|
|
444
|
+
});
|
|
445
|
+
return clone(schema, def);
|
|
917
446
|
}
|
|
918
447
|
function omit(schema, mask) {
|
|
919
448
|
const currDef = schema._zod.def;
|
|
@@ -15104,99 +14633,706 @@ var init_dist = __esm({
|
|
|
15104
14633
|
3329325298
|
|
15105
14634
|
]);
|
|
15106
14635
|
}
|
|
15107
|
-
});
|
|
15108
|
-
|
|
15109
|
-
// src/anon-key.ts
|
|
15110
|
-
async function loadFsPath() {
|
|
15111
|
-
if (fsPathCache !== void 0) return fsPathCache;
|
|
15112
|
-
try {
|
|
15113
|
-
const [fs10, path10] = await Promise.all([
|
|
15114
|
-
import("node:fs/promises"),
|
|
15115
|
-
import("node:path")
|
|
15116
|
-
]);
|
|
15117
|
-
fsPathCache = { fs: fs10, path: path10 };
|
|
15118
|
-
return fsPathCache;
|
|
15119
|
-
} catch {
|
|
15120
|
-
fsPathCache = null;
|
|
15121
|
-
return null;
|
|
14636
|
+
});
|
|
14637
|
+
|
|
14638
|
+
// src/anon-key.ts
|
|
14639
|
+
async function loadFsPath() {
|
|
14640
|
+
if (fsPathCache !== void 0) return fsPathCache;
|
|
14641
|
+
try {
|
|
14642
|
+
const [fs10, path10] = await Promise.all([
|
|
14643
|
+
import("node:fs/promises"),
|
|
14644
|
+
import("node:path")
|
|
14645
|
+
]);
|
|
14646
|
+
fsPathCache = { fs: fs10, path: path10 };
|
|
14647
|
+
return fsPathCache;
|
|
14648
|
+
} catch {
|
|
14649
|
+
fsPathCache = null;
|
|
14650
|
+
return null;
|
|
14651
|
+
}
|
|
14652
|
+
}
|
|
14653
|
+
async function readAnonKey(projectRoot) {
|
|
14654
|
+
const root = projectRoot ?? process.cwd();
|
|
14655
|
+
const modules = await loadFsPath();
|
|
14656
|
+
if (modules) {
|
|
14657
|
+
const keyPath = modules.path.join(root, GLASSTRACE_DIR, ANON_KEY_FILE);
|
|
14658
|
+
try {
|
|
14659
|
+
const content = await modules.fs.readFile(keyPath, "utf-8");
|
|
14660
|
+
const result = AnonApiKeySchema.safeParse(content);
|
|
14661
|
+
if (result.success) {
|
|
14662
|
+
return result.data;
|
|
14663
|
+
}
|
|
14664
|
+
} catch {
|
|
14665
|
+
}
|
|
14666
|
+
}
|
|
14667
|
+
const cached2 = ephemeralKeyCache.get(root);
|
|
14668
|
+
if (cached2 !== void 0) {
|
|
14669
|
+
return cached2;
|
|
14670
|
+
}
|
|
14671
|
+
return null;
|
|
14672
|
+
}
|
|
14673
|
+
async function readClaimedKey(projectRoot) {
|
|
14674
|
+
const root = projectRoot ?? process.cwd();
|
|
14675
|
+
const modules = await loadFsPath();
|
|
14676
|
+
if (!modules) return null;
|
|
14677
|
+
const keyPath = modules.path.join(root, GLASSTRACE_DIR, CLAIMED_KEY_FILE);
|
|
14678
|
+
try {
|
|
14679
|
+
const content = await modules.fs.readFile(keyPath, "utf-8");
|
|
14680
|
+
const trimmed = content.trim();
|
|
14681
|
+
const parsed = DevApiKeySchema.safeParse(trimmed);
|
|
14682
|
+
if (parsed.success) {
|
|
14683
|
+
return parsed.data;
|
|
14684
|
+
}
|
|
14685
|
+
} catch {
|
|
14686
|
+
}
|
|
14687
|
+
return null;
|
|
14688
|
+
}
|
|
14689
|
+
async function getOrCreateAnonKey(projectRoot) {
|
|
14690
|
+
const root = projectRoot ?? process.cwd();
|
|
14691
|
+
const existingKey = await readAnonKey(root);
|
|
14692
|
+
if (existingKey !== null) {
|
|
14693
|
+
return existingKey;
|
|
14694
|
+
}
|
|
14695
|
+
const cached2 = ephemeralKeyCache.get(root);
|
|
14696
|
+
if (cached2 !== void 0) {
|
|
14697
|
+
return cached2;
|
|
14698
|
+
}
|
|
14699
|
+
const newKey = createAnonApiKey();
|
|
14700
|
+
const modules = await loadFsPath();
|
|
14701
|
+
if (!modules) {
|
|
14702
|
+
ephemeralKeyCache.set(root, newKey);
|
|
14703
|
+
return newKey;
|
|
14704
|
+
}
|
|
14705
|
+
const dirPath = modules.path.join(root, GLASSTRACE_DIR);
|
|
14706
|
+
const keyPath = modules.path.join(dirPath, ANON_KEY_FILE);
|
|
14707
|
+
try {
|
|
14708
|
+
await modules.fs.mkdir(dirPath, { recursive: true, mode: 448 });
|
|
14709
|
+
await modules.fs.writeFile(keyPath, newKey, { flag: "wx", mode: 384 });
|
|
14710
|
+
return newKey;
|
|
14711
|
+
} catch (err) {
|
|
14712
|
+
const code = err.code;
|
|
14713
|
+
if (code === "EEXIST") {
|
|
14714
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
14715
|
+
const winnerKey = await readAnonKey(root);
|
|
14716
|
+
if (winnerKey !== null) {
|
|
14717
|
+
return winnerKey;
|
|
14718
|
+
}
|
|
14719
|
+
if (attempt < 2) {
|
|
14720
|
+
await new Promise((resolve2) => setTimeout(resolve2, 50));
|
|
14721
|
+
}
|
|
14722
|
+
}
|
|
14723
|
+
try {
|
|
14724
|
+
await modules.fs.writeFile(keyPath, newKey, { mode: 384 });
|
|
14725
|
+
await modules.fs.chmod(keyPath, 384);
|
|
14726
|
+
return newKey;
|
|
14727
|
+
} catch {
|
|
14728
|
+
}
|
|
14729
|
+
}
|
|
14730
|
+
ephemeralKeyCache.set(root, newKey);
|
|
14731
|
+
console.warn(
|
|
14732
|
+
`[glasstrace] Failed to persist anonymous key to ${keyPath}: ${err instanceof Error ? err.message : String(err)}. Using ephemeral key.`
|
|
14733
|
+
);
|
|
14734
|
+
return newKey;
|
|
14735
|
+
}
|
|
14736
|
+
}
|
|
14737
|
+
var GLASSTRACE_DIR, ANON_KEY_FILE, CLAIMED_KEY_FILE, fsPathCache, ephemeralKeyCache;
|
|
14738
|
+
var init_anon_key = __esm({
|
|
14739
|
+
"src/anon-key.ts"() {
|
|
14740
|
+
"use strict";
|
|
14741
|
+
init_dist();
|
|
14742
|
+
GLASSTRACE_DIR = ".glasstrace";
|
|
14743
|
+
ANON_KEY_FILE = "anon_key";
|
|
14744
|
+
CLAIMED_KEY_FILE = "claimed-key";
|
|
14745
|
+
ephemeralKeyCache = /* @__PURE__ */ new Map();
|
|
14746
|
+
}
|
|
14747
|
+
});
|
|
14748
|
+
|
|
14749
|
+
// src/mcp-runtime.ts
|
|
14750
|
+
async function loadFsPath2() {
|
|
14751
|
+
if (fsPathCache2 !== void 0) return fsPathCache2;
|
|
14752
|
+
try {
|
|
14753
|
+
const [fs10, path10] = await Promise.all([
|
|
14754
|
+
import("node:fs/promises"),
|
|
14755
|
+
import("node:path")
|
|
14756
|
+
]);
|
|
14757
|
+
fsPathCache2 = { fs: fs10, path: path10 };
|
|
14758
|
+
return fsPathCache2;
|
|
14759
|
+
} catch {
|
|
14760
|
+
fsPathCache2 = null;
|
|
14761
|
+
return null;
|
|
14762
|
+
}
|
|
14763
|
+
}
|
|
14764
|
+
function identityFingerprint(token) {
|
|
14765
|
+
return `sha256:${(0, import_node_crypto.createHash)("sha256").update(token).digest("hex")}`;
|
|
14766
|
+
}
|
|
14767
|
+
function mcpConfigMatches(existingContent, expectedContent) {
|
|
14768
|
+
const trimmedExpected = expectedContent.trim();
|
|
14769
|
+
try {
|
|
14770
|
+
const existingParsed = JSON.parse(existingContent);
|
|
14771
|
+
const expectedParsed = JSON.parse(trimmedExpected);
|
|
14772
|
+
return JSON.stringify(canonicalize(existingParsed)) === JSON.stringify(canonicalize(expectedParsed));
|
|
14773
|
+
} catch {
|
|
14774
|
+
}
|
|
14775
|
+
return existingContent.trim() === trimmedExpected;
|
|
14776
|
+
}
|
|
14777
|
+
function canonicalize(value) {
|
|
14778
|
+
if (Array.isArray(value)) {
|
|
14779
|
+
return value.map(canonicalize);
|
|
14780
|
+
}
|
|
14781
|
+
if (value !== null && typeof value === "object") {
|
|
14782
|
+
const obj = value;
|
|
14783
|
+
const sorted = {};
|
|
14784
|
+
for (const key of Object.keys(obj).sort()) {
|
|
14785
|
+
sorted[key] = canonicalize(obj[key]);
|
|
14786
|
+
}
|
|
14787
|
+
return sorted;
|
|
14788
|
+
}
|
|
14789
|
+
return value;
|
|
14790
|
+
}
|
|
14791
|
+
function readEnvLocalApiKey(content) {
|
|
14792
|
+
let last = null;
|
|
14793
|
+
const regex = /^\s*GLASSTRACE_API_KEY\s*=\s*(.*)$/gm;
|
|
14794
|
+
let match;
|
|
14795
|
+
while ((match = regex.exec(content)) !== null) {
|
|
14796
|
+
const raw = match[1].trim();
|
|
14797
|
+
if (raw === "") continue;
|
|
14798
|
+
const unquoted = raw.replace(/^(['"])(.*)\1$/, "$2");
|
|
14799
|
+
if (unquoted === "" || unquoted === "your_key_here") continue;
|
|
14800
|
+
last = unquoted;
|
|
14801
|
+
}
|
|
14802
|
+
return last;
|
|
14803
|
+
}
|
|
14804
|
+
function isDevApiKey(value) {
|
|
14805
|
+
if (value === null || value === void 0) return false;
|
|
14806
|
+
return value.trim().startsWith("gt_dev_");
|
|
14807
|
+
}
|
|
14808
|
+
function isAnonApiKey(value) {
|
|
14809
|
+
if (value === null || value === void 0) return false;
|
|
14810
|
+
return AnonApiKeySchema.safeParse(value).success;
|
|
14811
|
+
}
|
|
14812
|
+
async function resolveEffectiveMcpCredential(projectRoot) {
|
|
14813
|
+
const root = projectRoot ?? process.cwd();
|
|
14814
|
+
const warnings = [];
|
|
14815
|
+
const envLocalKey = await readEnvLocalDevKey(root, warnings);
|
|
14816
|
+
const claimedKey = envLocalKey === null ? await readClaimedKey(root) : null;
|
|
14817
|
+
const anonKey = await readAnonKey(root);
|
|
14818
|
+
let effective = null;
|
|
14819
|
+
if (envLocalKey !== null) {
|
|
14820
|
+
effective = { source: "env-local", key: envLocalKey };
|
|
14821
|
+
} else if (claimedKey !== null) {
|
|
14822
|
+
effective = { source: "claimed-key", key: claimedKey };
|
|
14823
|
+
warnings.push("claimed-key-only");
|
|
14824
|
+
} else if (anonKey !== null) {
|
|
14825
|
+
effective = { source: "anon", key: anonKey };
|
|
14826
|
+
}
|
|
14827
|
+
return { effective, anonKey, warnings };
|
|
14828
|
+
}
|
|
14829
|
+
async function readEnvLocalDevKey(root, warnings) {
|
|
14830
|
+
const modules = await loadFsPath2();
|
|
14831
|
+
if (!modules) return null;
|
|
14832
|
+
const envPath = modules.path.join(root, ".env.local");
|
|
14833
|
+
let content;
|
|
14834
|
+
try {
|
|
14835
|
+
content = await modules.fs.readFile(envPath, "utf-8");
|
|
14836
|
+
} catch {
|
|
14837
|
+
return null;
|
|
14838
|
+
}
|
|
14839
|
+
const raw = readEnvLocalApiKey(content);
|
|
14840
|
+
if (raw === null) return null;
|
|
14841
|
+
const parsed = DevApiKeySchema.safeParse(raw);
|
|
14842
|
+
if (!parsed.success) {
|
|
14843
|
+
warnings.push("malformed-env-local");
|
|
14844
|
+
return null;
|
|
14845
|
+
}
|
|
14846
|
+
return parsed.data;
|
|
14847
|
+
}
|
|
14848
|
+
async function readMcpMarker(projectRoot) {
|
|
14849
|
+
const root = projectRoot ?? process.cwd();
|
|
14850
|
+
const modules = await loadFsPath2();
|
|
14851
|
+
if (!modules) return { status: "absent" };
|
|
14852
|
+
const markerPath = modules.path.join(root, GLASSTRACE_DIR2, MCP_MARKER_FILE);
|
|
14853
|
+
let content;
|
|
14854
|
+
try {
|
|
14855
|
+
content = await modules.fs.readFile(markerPath, "utf-8");
|
|
14856
|
+
} catch {
|
|
14857
|
+
return { status: "absent" };
|
|
14858
|
+
}
|
|
14859
|
+
let parsed;
|
|
14860
|
+
try {
|
|
14861
|
+
parsed = JSON.parse(content);
|
|
14862
|
+
} catch {
|
|
14863
|
+
return { status: "corrupted" };
|
|
14864
|
+
}
|
|
14865
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
14866
|
+
return { status: "corrupted" };
|
|
14867
|
+
}
|
|
14868
|
+
const obj = parsed;
|
|
14869
|
+
const version2 = obj["version"];
|
|
14870
|
+
if (version2 === void 0) {
|
|
14871
|
+
const keyHash = obj["keyHash"];
|
|
14872
|
+
if (typeof keyHash !== "string" || keyHash === "") {
|
|
14873
|
+
return { status: "corrupted" };
|
|
14874
|
+
}
|
|
14875
|
+
return {
|
|
14876
|
+
status: "valid",
|
|
14877
|
+
credentialSource: "anon",
|
|
14878
|
+
credentialHash: keyHash
|
|
14879
|
+
};
|
|
14880
|
+
}
|
|
14881
|
+
if (version2 === 2) {
|
|
14882
|
+
const source = obj["credentialSource"];
|
|
14883
|
+
const hash2 = obj["credentialHash"];
|
|
14884
|
+
if (source !== "env-local" && source !== "claimed-key" && source !== "anon" || typeof hash2 !== "string" || hash2 === "") {
|
|
14885
|
+
return { status: "corrupted" };
|
|
14886
|
+
}
|
|
14887
|
+
return {
|
|
14888
|
+
status: "valid",
|
|
14889
|
+
credentialSource: source,
|
|
14890
|
+
credentialHash: hash2
|
|
14891
|
+
};
|
|
14892
|
+
}
|
|
14893
|
+
if (typeof version2 === "number" && version2 > 2) {
|
|
14894
|
+
return { status: "unknown-version" };
|
|
14895
|
+
}
|
|
14896
|
+
return { status: "corrupted" };
|
|
14897
|
+
}
|
|
14898
|
+
async function writeMcpMarker(projectRoot, target) {
|
|
14899
|
+
const modules = await loadFsPath2();
|
|
14900
|
+
if (!modules) return false;
|
|
14901
|
+
const dirPath = modules.path.join(projectRoot, GLASSTRACE_DIR2);
|
|
14902
|
+
const markerPath = modules.path.join(dirPath, MCP_MARKER_FILE);
|
|
14903
|
+
const state = await readMcpMarker(projectRoot);
|
|
14904
|
+
if (state.status === "valid" && state.credentialSource === target.credentialSource && state.credentialHash === target.credentialHash) {
|
|
14905
|
+
return false;
|
|
14906
|
+
}
|
|
14907
|
+
await modules.fs.mkdir(dirPath, { recursive: true, mode: 448 });
|
|
14908
|
+
const body = JSON.stringify(
|
|
14909
|
+
{
|
|
14910
|
+
version: 2,
|
|
14911
|
+
credentialSource: target.credentialSource,
|
|
14912
|
+
credentialHash: target.credentialHash,
|
|
14913
|
+
configuredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
14914
|
+
},
|
|
14915
|
+
null,
|
|
14916
|
+
2
|
|
14917
|
+
);
|
|
14918
|
+
await modules.fs.writeFile(markerPath, body, { mode: 384 });
|
|
14919
|
+
await modules.fs.chmod(markerPath, 384);
|
|
14920
|
+
return true;
|
|
14921
|
+
}
|
|
14922
|
+
var import_node_crypto, MCP_ENDPOINT, fsPathCache2, MCP_MARKER_FILE, GLASSTRACE_DIR2;
|
|
14923
|
+
var init_mcp_runtime = __esm({
|
|
14924
|
+
"src/mcp-runtime.ts"() {
|
|
14925
|
+
"use strict";
|
|
14926
|
+
import_node_crypto = require("node:crypto");
|
|
14927
|
+
init_dist();
|
|
14928
|
+
init_anon_key();
|
|
14929
|
+
MCP_ENDPOINT = "https://api.glasstrace.dev/mcp";
|
|
14930
|
+
MCP_MARKER_FILE = "mcp-connected";
|
|
14931
|
+
GLASSTRACE_DIR2 = ".glasstrace";
|
|
14932
|
+
}
|
|
14933
|
+
});
|
|
14934
|
+
|
|
14935
|
+
// src/cli/constants.ts
|
|
14936
|
+
function formatAgentName(name) {
|
|
14937
|
+
const displayNames = {
|
|
14938
|
+
claude: "Claude Code",
|
|
14939
|
+
codex: "Codex",
|
|
14940
|
+
gemini: "Gemini",
|
|
14941
|
+
cursor: "Cursor",
|
|
14942
|
+
windsurf: "Windsurf",
|
|
14943
|
+
generic: "Generic"
|
|
14944
|
+
};
|
|
14945
|
+
return displayNames[name];
|
|
14946
|
+
}
|
|
14947
|
+
var NEXT_CONFIG_NAMES;
|
|
14948
|
+
var init_constants = __esm({
|
|
14949
|
+
"src/cli/constants.ts"() {
|
|
14950
|
+
"use strict";
|
|
14951
|
+
init_mcp_runtime();
|
|
14952
|
+
NEXT_CONFIG_NAMES = ["next.config.ts", "next.config.js", "next.config.mjs"];
|
|
14953
|
+
}
|
|
14954
|
+
});
|
|
14955
|
+
|
|
14956
|
+
// src/cli/scaffolder.ts
|
|
14957
|
+
function hasRegisterGlasstraceCall(content) {
|
|
14958
|
+
return content.split("\n").some((line) => {
|
|
14959
|
+
const uncommented = line.replace(/\/\/.*$/, "");
|
|
14960
|
+
return /\bregisterGlasstrace\s*\(/.test(uncommented);
|
|
14961
|
+
});
|
|
14962
|
+
}
|
|
14963
|
+
function injectRegisterGlasstrace(content) {
|
|
14964
|
+
if (hasRegisterGlasstraceCall(content)) {
|
|
14965
|
+
return { injected: false, content };
|
|
14966
|
+
}
|
|
14967
|
+
const registerFnRegex = /export\s+(?:async\s+)?function\s+register\s*\([^)]*\)\s*\{/;
|
|
14968
|
+
const match = registerFnRegex.exec(content);
|
|
14969
|
+
if (!match) {
|
|
14970
|
+
return { injected: false, content };
|
|
14971
|
+
}
|
|
14972
|
+
const afterBrace = content.slice(match.index + match[0].length);
|
|
14973
|
+
const indentMatch = /\n([ \t]+)/.exec(afterBrace);
|
|
14974
|
+
const indent = indentMatch ? indentMatch[1] : " ";
|
|
14975
|
+
const importLine = 'import { registerGlasstrace } from "@glasstrace/sdk";\n';
|
|
14976
|
+
const hasGlasstraceImport2 = content.includes("@glasstrace/sdk");
|
|
14977
|
+
const insertPoint = match.index + match[0].length;
|
|
14978
|
+
const callInjection = `
|
|
14979
|
+
${indent}// Glasstrace must be registered before other instrumentation
|
|
14980
|
+
${indent}registerGlasstrace();
|
|
14981
|
+
`;
|
|
14982
|
+
let modified;
|
|
14983
|
+
if (hasGlasstraceImport2) {
|
|
14984
|
+
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@glasstrace\/sdk["']/;
|
|
14985
|
+
const importMatch = importRegex.exec(content);
|
|
14986
|
+
if (importMatch) {
|
|
14987
|
+
const specifiers = importMatch[1];
|
|
14988
|
+
const alreadyImported = specifiers.split(",").some((s) => s.trim() === "registerGlasstrace");
|
|
14989
|
+
if (alreadyImported) {
|
|
14990
|
+
modified = content.slice(0, insertPoint) + callInjection + content.slice(insertPoint);
|
|
14991
|
+
} else {
|
|
14992
|
+
const existingImports = specifiers.trimEnd();
|
|
14993
|
+
const separator = existingImports.endsWith(",") ? " " : ", ";
|
|
14994
|
+
const updatedImport = `import { ${existingImports.trim()}${separator}registerGlasstrace } from "@glasstrace/sdk"`;
|
|
14995
|
+
modified = content.replace(importMatch[0], updatedImport);
|
|
14996
|
+
const newMatch = registerFnRegex.exec(modified);
|
|
14997
|
+
if (newMatch) {
|
|
14998
|
+
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
14999
|
+
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
15000
|
+
}
|
|
15001
|
+
}
|
|
15002
|
+
} else {
|
|
15003
|
+
modified = importLine + content;
|
|
15004
|
+
const newMatch = registerFnRegex.exec(modified);
|
|
15005
|
+
if (newMatch) {
|
|
15006
|
+
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
15007
|
+
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
15008
|
+
}
|
|
15009
|
+
}
|
|
15010
|
+
} else {
|
|
15011
|
+
modified = importLine + content.slice(0, insertPoint) + callInjection + content.slice(insertPoint);
|
|
15012
|
+
}
|
|
15013
|
+
return { injected: true, content: modified };
|
|
15014
|
+
}
|
|
15015
|
+
function resolveInstrumentationTarget(projectRoot) {
|
|
15016
|
+
const rootExisting = [];
|
|
15017
|
+
const srcExisting = [];
|
|
15018
|
+
for (const name of INSTRUMENTATION_FILENAMES) {
|
|
15019
|
+
const rootPath = path.join(projectRoot, name);
|
|
15020
|
+
if (isRegularFile(rootPath)) {
|
|
15021
|
+
rootExisting.push(rootPath);
|
|
15022
|
+
}
|
|
15023
|
+
const srcPath = path.join(projectRoot, "src", name);
|
|
15024
|
+
if (isRegularFile(srcPath)) {
|
|
15025
|
+
srcExisting.push(srcPath);
|
|
15026
|
+
}
|
|
15027
|
+
}
|
|
15028
|
+
const existing = [...rootExisting, ...srcExisting];
|
|
15029
|
+
if (rootExisting.length > 0 && srcExisting.length > 0) {
|
|
15030
|
+
return {
|
|
15031
|
+
target: null,
|
|
15032
|
+
layout: null,
|
|
15033
|
+
existing,
|
|
15034
|
+
rootExisting,
|
|
15035
|
+
srcExisting,
|
|
15036
|
+
conflict: true
|
|
15037
|
+
};
|
|
15038
|
+
}
|
|
15039
|
+
if (srcExisting.length > 0) {
|
|
15040
|
+
return {
|
|
15041
|
+
target: srcExisting[0],
|
|
15042
|
+
layout: "src",
|
|
15043
|
+
existing,
|
|
15044
|
+
rootExisting,
|
|
15045
|
+
srcExisting,
|
|
15046
|
+
conflict: false
|
|
15047
|
+
};
|
|
15048
|
+
}
|
|
15049
|
+
if (rootExisting.length > 0) {
|
|
15050
|
+
return {
|
|
15051
|
+
target: rootExisting[0],
|
|
15052
|
+
layout: "root",
|
|
15053
|
+
existing,
|
|
15054
|
+
rootExisting,
|
|
15055
|
+
srcExisting,
|
|
15056
|
+
conflict: false
|
|
15057
|
+
};
|
|
15058
|
+
}
|
|
15059
|
+
const srcDir = path.join(projectRoot, "src");
|
|
15060
|
+
const layout = isDirectory(srcDir) ? "src" : "root";
|
|
15061
|
+
const target = layout === "src" ? path.join(projectRoot, "src", "instrumentation.ts") : path.join(projectRoot, "instrumentation.ts");
|
|
15062
|
+
return {
|
|
15063
|
+
target,
|
|
15064
|
+
layout,
|
|
15065
|
+
existing,
|
|
15066
|
+
rootExisting,
|
|
15067
|
+
srcExisting,
|
|
15068
|
+
conflict: false
|
|
15069
|
+
};
|
|
15070
|
+
}
|
|
15071
|
+
function isDirectory(p) {
|
|
15072
|
+
try {
|
|
15073
|
+
return fs.statSync(p).isDirectory();
|
|
15074
|
+
} catch {
|
|
15075
|
+
return false;
|
|
15076
|
+
}
|
|
15077
|
+
}
|
|
15078
|
+
function isRegularFile(p) {
|
|
15079
|
+
try {
|
|
15080
|
+
const stat2 = fs.lstatSync(p);
|
|
15081
|
+
if (stat2.isSymbolicLink()) {
|
|
15082
|
+
return fs.statSync(p).isFile();
|
|
15083
|
+
}
|
|
15084
|
+
return stat2.isFile();
|
|
15085
|
+
} catch {
|
|
15086
|
+
return false;
|
|
15087
|
+
}
|
|
15088
|
+
}
|
|
15089
|
+
function appendRegisterFunction(content) {
|
|
15090
|
+
const importLine = 'import { registerGlasstrace } from "@glasstrace/sdk";\n';
|
|
15091
|
+
const functionBlock = "\nexport async function register() {\n // Glasstrace must be registered before Prisma instrumentation\n // to ensure all ORM spans are captured correctly.\n // If you use @prisma/instrumentation, import it after this call.\n registerGlasstrace();\n}\n";
|
|
15092
|
+
let withImport = content;
|
|
15093
|
+
const hasGlasstraceImport2 = content.includes("@glasstrace/sdk");
|
|
15094
|
+
if (!hasGlasstraceImport2) {
|
|
15095
|
+
withImport = importLine + content;
|
|
15096
|
+
} else {
|
|
15097
|
+
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@glasstrace\/sdk["']/;
|
|
15098
|
+
const importMatch = importRegex.exec(content);
|
|
15099
|
+
if (importMatch) {
|
|
15100
|
+
const specifiers = importMatch[1];
|
|
15101
|
+
const alreadyImported = specifiers.split(",").some((s) => s.trim() === "registerGlasstrace");
|
|
15102
|
+
if (!alreadyImported) {
|
|
15103
|
+
const existingImports = specifiers.trimEnd();
|
|
15104
|
+
const separator = existingImports.endsWith(",") ? " " : ", ";
|
|
15105
|
+
const updatedImport = `import { ${existingImports.trim()}${separator}registerGlasstrace } from "@glasstrace/sdk"`;
|
|
15106
|
+
withImport = content.replace(importMatch[0], updatedImport);
|
|
15107
|
+
}
|
|
15108
|
+
} else {
|
|
15109
|
+
withImport = importLine + content;
|
|
15110
|
+
}
|
|
15111
|
+
}
|
|
15112
|
+
const trailingNewline = withImport.endsWith("\n") ? "" : "\n";
|
|
15113
|
+
return withImport + trailingNewline + functionBlock;
|
|
15114
|
+
}
|
|
15115
|
+
async function defaultInstrumentationPrompt(question, defaultValue) {
|
|
15116
|
+
if (!process.stdin.isTTY) return defaultValue;
|
|
15117
|
+
const readline2 = await import("node:readline");
|
|
15118
|
+
const rl = readline2.createInterface({
|
|
15119
|
+
input: process.stdin,
|
|
15120
|
+
output: process.stdout
|
|
15121
|
+
});
|
|
15122
|
+
return new Promise((resolve2) => {
|
|
15123
|
+
const suffix = defaultValue ? " [Y/n] " : " [y/N] ";
|
|
15124
|
+
rl.question(question + suffix, (answer) => {
|
|
15125
|
+
rl.close();
|
|
15126
|
+
const trimmed = answer.trim().toLowerCase();
|
|
15127
|
+
if (trimmed === "") {
|
|
15128
|
+
resolve2(defaultValue);
|
|
15129
|
+
return;
|
|
15130
|
+
}
|
|
15131
|
+
resolve2(trimmed === "y" || trimmed === "yes");
|
|
15132
|
+
});
|
|
15133
|
+
});
|
|
15134
|
+
}
|
|
15135
|
+
async function scaffoldInstrumentation(projectRoot, options = {}) {
|
|
15136
|
+
const target = resolveInstrumentationTarget(projectRoot);
|
|
15137
|
+
if (target.conflict) {
|
|
15138
|
+
return {
|
|
15139
|
+
action: "conflict",
|
|
15140
|
+
// Point the user at the `src/` variant — modern Next.js apps with a
|
|
15141
|
+
// `src/` directory load from there, so that's the merge target. The
|
|
15142
|
+
// competing path is reported separately for the error message.
|
|
15143
|
+
filePath: target.srcExisting[0],
|
|
15144
|
+
conflictingPath: target.rootExisting[0]
|
|
15145
|
+
};
|
|
15146
|
+
}
|
|
15147
|
+
const filePath = target.target;
|
|
15148
|
+
const layout = target.layout;
|
|
15149
|
+
if (filePath === null || layout === null) {
|
|
15150
|
+
return { action: "unrecognized" };
|
|
15151
|
+
}
|
|
15152
|
+
const force = options.force === true;
|
|
15153
|
+
const prompt = options.prompt ?? defaultInstrumentationPrompt;
|
|
15154
|
+
if (!fs.existsSync(filePath)) {
|
|
15155
|
+
const content = `import { registerGlasstrace } from "@glasstrace/sdk";
|
|
15156
|
+
|
|
15157
|
+
export async function register() {
|
|
15158
|
+
// Glasstrace must be registered before Prisma instrumentation
|
|
15159
|
+
// to ensure all ORM spans are captured correctly.
|
|
15160
|
+
// If you use @prisma/instrumentation, import it after this call.
|
|
15161
|
+
registerGlasstrace();
|
|
15162
|
+
}
|
|
15163
|
+
`;
|
|
15164
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
15165
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
15166
|
+
return { action: "created", filePath, layout };
|
|
15167
|
+
}
|
|
15168
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
15169
|
+
if (hasRegisterGlasstraceCall(existing)) {
|
|
15170
|
+
return { action: "already-registered", filePath, layout };
|
|
15171
|
+
}
|
|
15172
|
+
if (!force) {
|
|
15173
|
+
const approved = await prompt(
|
|
15174
|
+
`Merge registerGlasstrace() into ${path.relative(projectRoot, filePath)}?`,
|
|
15175
|
+
false
|
|
15176
|
+
);
|
|
15177
|
+
if (!approved) {
|
|
15178
|
+
return { action: "skipped", filePath, layout };
|
|
15179
|
+
}
|
|
15180
|
+
}
|
|
15181
|
+
const injectResult = injectRegisterGlasstrace(existing);
|
|
15182
|
+
if (injectResult.injected) {
|
|
15183
|
+
fs.writeFileSync(filePath, injectResult.content, "utf-8");
|
|
15184
|
+
return { action: "injected", filePath, layout };
|
|
15122
15185
|
}
|
|
15186
|
+
const appended = appendRegisterFunction(existing);
|
|
15187
|
+
fs.writeFileSync(filePath, appended, "utf-8");
|
|
15188
|
+
return { action: "appended", filePath, layout };
|
|
15123
15189
|
}
|
|
15124
|
-
async function
|
|
15125
|
-
|
|
15126
|
-
|
|
15127
|
-
|
|
15128
|
-
const
|
|
15129
|
-
|
|
15130
|
-
|
|
15131
|
-
|
|
15132
|
-
|
|
15133
|
-
return result.data;
|
|
15134
|
-
}
|
|
15135
|
-
} catch {
|
|
15190
|
+
async function scaffoldNextConfig(projectRoot) {
|
|
15191
|
+
let configPath;
|
|
15192
|
+
let configName;
|
|
15193
|
+
for (const name of NEXT_CONFIG_NAMES) {
|
|
15194
|
+
const candidate = path.join(projectRoot, name);
|
|
15195
|
+
if (fs.existsSync(candidate)) {
|
|
15196
|
+
configPath = candidate;
|
|
15197
|
+
configName = name;
|
|
15198
|
+
break;
|
|
15136
15199
|
}
|
|
15137
15200
|
}
|
|
15138
|
-
|
|
15139
|
-
|
|
15140
|
-
return cached2;
|
|
15201
|
+
if (configPath === void 0 || configName === void 0) {
|
|
15202
|
+
return null;
|
|
15141
15203
|
}
|
|
15142
|
-
|
|
15204
|
+
const existing = fs.readFileSync(configPath, "utf-8");
|
|
15205
|
+
if (existing.trim().length === 0) {
|
|
15206
|
+
return { modified: false, reason: "empty-file" };
|
|
15207
|
+
}
|
|
15208
|
+
if (existing.includes("withGlasstraceConfig")) {
|
|
15209
|
+
return { modified: false, reason: "already-wrapped" };
|
|
15210
|
+
}
|
|
15211
|
+
const isESM = configName.endsWith(".ts") || configName.endsWith(".mjs");
|
|
15212
|
+
if (isESM) {
|
|
15213
|
+
const importLine = 'import { withGlasstraceConfig } from "@glasstrace/sdk";\n';
|
|
15214
|
+
const wrapResult2 = wrapExport(existing);
|
|
15215
|
+
if (!wrapResult2.wrapped) {
|
|
15216
|
+
return { modified: false, reason: "no-export" };
|
|
15217
|
+
}
|
|
15218
|
+
const modified2 = importLine + "\n" + wrapResult2.content;
|
|
15219
|
+
fs.writeFileSync(configPath, modified2, "utf-8");
|
|
15220
|
+
return { modified: true };
|
|
15221
|
+
}
|
|
15222
|
+
const requireLine = 'const { withGlasstraceConfig } = require("@glasstrace/sdk");\n';
|
|
15223
|
+
const wrapResult = wrapCJSExport(existing);
|
|
15224
|
+
if (!wrapResult.wrapped) {
|
|
15225
|
+
return { modified: false, reason: "no-export" };
|
|
15226
|
+
}
|
|
15227
|
+
const modified = requireLine + "\n" + wrapResult.content;
|
|
15228
|
+
fs.writeFileSync(configPath, modified, "utf-8");
|
|
15229
|
+
return { modified: true };
|
|
15143
15230
|
}
|
|
15144
|
-
|
|
15145
|
-
const
|
|
15146
|
-
const
|
|
15147
|
-
if (
|
|
15148
|
-
return
|
|
15231
|
+
function wrapExport(content) {
|
|
15232
|
+
const marker = "export default";
|
|
15233
|
+
const idx = content.lastIndexOf(marker);
|
|
15234
|
+
if (idx === -1) {
|
|
15235
|
+
return { content, wrapped: false };
|
|
15149
15236
|
}
|
|
15150
|
-
const
|
|
15151
|
-
|
|
15152
|
-
|
|
15237
|
+
const preamble = content.slice(0, idx);
|
|
15238
|
+
const exprRaw = content.slice(idx + marker.length);
|
|
15239
|
+
const expr = exprRaw.trim().replace(/;?\s*$/, "");
|
|
15240
|
+
if (expr.length === 0) {
|
|
15241
|
+
return { content, wrapped: false };
|
|
15153
15242
|
}
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
|
|
15243
|
+
return {
|
|
15244
|
+
content: preamble + `export default withGlasstraceConfig(${expr});
|
|
15245
|
+
`,
|
|
15246
|
+
wrapped: true
|
|
15247
|
+
};
|
|
15248
|
+
}
|
|
15249
|
+
function wrapCJSExport(content) {
|
|
15250
|
+
const cjsMarker = "module.exports";
|
|
15251
|
+
const cjsIdx = content.lastIndexOf(cjsMarker);
|
|
15252
|
+
if (cjsIdx === -1) {
|
|
15253
|
+
return { content, wrapped: false };
|
|
15159
15254
|
}
|
|
15160
|
-
const
|
|
15161
|
-
const
|
|
15162
|
-
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
|
|
15167
|
-
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
}
|
|
15255
|
+
const preamble = content.slice(0, cjsIdx);
|
|
15256
|
+
const afterMarker = content.slice(cjsIdx + cjsMarker.length);
|
|
15257
|
+
const eqMatch = /^\s*=\s*/.exec(afterMarker);
|
|
15258
|
+
if (!eqMatch) {
|
|
15259
|
+
return { content, wrapped: false };
|
|
15260
|
+
}
|
|
15261
|
+
const exprRaw = afterMarker.slice(eqMatch[0].length);
|
|
15262
|
+
const expr = exprRaw.trim().replace(/;?\s*$/, "");
|
|
15263
|
+
if (expr.length === 0) {
|
|
15264
|
+
return { content, wrapped: false };
|
|
15265
|
+
}
|
|
15266
|
+
return {
|
|
15267
|
+
content: preamble + `module.exports = withGlasstraceConfig(${expr});
|
|
15268
|
+
`,
|
|
15269
|
+
wrapped: true
|
|
15270
|
+
};
|
|
15271
|
+
}
|
|
15272
|
+
async function scaffoldEnvLocal(projectRoot) {
|
|
15273
|
+
const filePath = path.join(projectRoot, ".env.local");
|
|
15274
|
+
if (fs.existsSync(filePath)) {
|
|
15275
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
15276
|
+
if (/^\s*#?\s*GLASSTRACE_API_KEY\s*=/m.test(existing)) {
|
|
15277
|
+
return false;
|
|
15184
15278
|
}
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
);
|
|
15189
|
-
return newKey;
|
|
15279
|
+
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
15280
|
+
fs.writeFileSync(filePath, existing + separator + "# GLASSTRACE_API_KEY=your_key_here\n", "utf-8");
|
|
15281
|
+
return true;
|
|
15190
15282
|
}
|
|
15283
|
+
fs.writeFileSync(filePath, "# GLASSTRACE_API_KEY=your_key_here\n", "utf-8");
|
|
15284
|
+
return true;
|
|
15191
15285
|
}
|
|
15192
|
-
|
|
15193
|
-
|
|
15194
|
-
|
|
15286
|
+
async function addCoverageMapEnv(projectRoot) {
|
|
15287
|
+
const filePath = path.join(projectRoot, ".env.local");
|
|
15288
|
+
if (!fs.existsSync(filePath)) {
|
|
15289
|
+
fs.writeFileSync(filePath, "GLASSTRACE_COVERAGE_MAP=true\n", "utf-8");
|
|
15290
|
+
return true;
|
|
15291
|
+
}
|
|
15292
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
15293
|
+
const keyRegex = /^(\s*GLASSTRACE_COVERAGE_MAP\s*=\s*)(.*)$/m;
|
|
15294
|
+
const keyMatch = keyRegex.exec(existing);
|
|
15295
|
+
if (keyMatch) {
|
|
15296
|
+
const currentValue = keyMatch[2].trim();
|
|
15297
|
+
if (currentValue === "true") {
|
|
15298
|
+
return false;
|
|
15299
|
+
}
|
|
15300
|
+
const updated = existing.replace(keyRegex, `${keyMatch[1]}true`);
|
|
15301
|
+
fs.writeFileSync(filePath, updated, "utf-8");
|
|
15302
|
+
return true;
|
|
15303
|
+
}
|
|
15304
|
+
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
15305
|
+
fs.writeFileSync(filePath, existing + separator + "GLASSTRACE_COVERAGE_MAP=true\n", "utf-8");
|
|
15306
|
+
return true;
|
|
15307
|
+
}
|
|
15308
|
+
async function scaffoldGitignore(projectRoot) {
|
|
15309
|
+
const filePath = path.join(projectRoot, ".gitignore");
|
|
15310
|
+
if (fs.existsSync(filePath)) {
|
|
15311
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
15312
|
+
const lines = existing.split("\n").map((l) => l.trim());
|
|
15313
|
+
if (lines.includes(".glasstrace/")) {
|
|
15314
|
+
return false;
|
|
15315
|
+
}
|
|
15316
|
+
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
15317
|
+
fs.writeFileSync(filePath, existing + separator + ".glasstrace/\n", "utf-8");
|
|
15318
|
+
return true;
|
|
15319
|
+
}
|
|
15320
|
+
fs.writeFileSync(filePath, ".glasstrace/\n", "utf-8");
|
|
15321
|
+
return true;
|
|
15322
|
+
}
|
|
15323
|
+
var fs, path, INSTRUMENTATION_FILENAMES;
|
|
15324
|
+
var init_scaffolder = __esm({
|
|
15325
|
+
"src/cli/scaffolder.ts"() {
|
|
15195
15326
|
"use strict";
|
|
15196
|
-
|
|
15197
|
-
|
|
15198
|
-
|
|
15199
|
-
|
|
15327
|
+
fs = __toESM(require("node:fs"), 1);
|
|
15328
|
+
path = __toESM(require("node:path"), 1);
|
|
15329
|
+
init_constants();
|
|
15330
|
+
init_mcp_runtime();
|
|
15331
|
+
INSTRUMENTATION_FILENAMES = [
|
|
15332
|
+
"instrumentation.ts",
|
|
15333
|
+
"instrumentation.js",
|
|
15334
|
+
"instrumentation.mjs"
|
|
15335
|
+
];
|
|
15200
15336
|
}
|
|
15201
15337
|
});
|
|
15202
15338
|
|
|
@@ -15360,12 +15496,12 @@ var init_detect = __esm({
|
|
|
15360
15496
|
});
|
|
15361
15497
|
|
|
15362
15498
|
// src/agent-detection/configs.ts
|
|
15363
|
-
function generateMcpConfig(agent, endpoint,
|
|
15499
|
+
function generateMcpConfig(agent, endpoint, bearer) {
|
|
15364
15500
|
if (!endpoint || endpoint.trim() === "") {
|
|
15365
15501
|
throw new Error("endpoint must not be empty");
|
|
15366
15502
|
}
|
|
15367
|
-
if (!
|
|
15368
|
-
throw new Error("
|
|
15503
|
+
if (!bearer || bearer.trim() === "") {
|
|
15504
|
+
throw new Error("bearer must not be empty");
|
|
15369
15505
|
}
|
|
15370
15506
|
switch (agent.name) {
|
|
15371
15507
|
case "claude":
|
|
@@ -15376,7 +15512,7 @@ function generateMcpConfig(agent, endpoint, anonKey) {
|
|
|
15376
15512
|
type: "http",
|
|
15377
15513
|
url: endpoint,
|
|
15378
15514
|
headers: {
|
|
15379
|
-
Authorization: `Bearer ${
|
|
15515
|
+
Authorization: `Bearer ${bearer}`
|
|
15380
15516
|
}
|
|
15381
15517
|
}
|
|
15382
15518
|
}
|
|
@@ -15400,7 +15536,7 @@ function generateMcpConfig(agent, endpoint, anonKey) {
|
|
|
15400
15536
|
glasstrace: {
|
|
15401
15537
|
httpUrl: endpoint,
|
|
15402
15538
|
headers: {
|
|
15403
|
-
Authorization: `Bearer ${
|
|
15539
|
+
Authorization: `Bearer ${bearer}`
|
|
15404
15540
|
}
|
|
15405
15541
|
}
|
|
15406
15542
|
}
|
|
@@ -15415,7 +15551,7 @@ function generateMcpConfig(agent, endpoint, anonKey) {
|
|
|
15415
15551
|
glasstrace: {
|
|
15416
15552
|
url: endpoint,
|
|
15417
15553
|
headers: {
|
|
15418
|
-
Authorization: `Bearer ${
|
|
15554
|
+
Authorization: `Bearer ${bearer}`
|
|
15419
15555
|
}
|
|
15420
15556
|
}
|
|
15421
15557
|
}
|
|
@@ -15430,7 +15566,7 @@ function generateMcpConfig(agent, endpoint, anonKey) {
|
|
|
15430
15566
|
glasstrace: {
|
|
15431
15567
|
serverUrl: endpoint,
|
|
15432
15568
|
headers: {
|
|
15433
|
-
Authorization: `Bearer ${
|
|
15569
|
+
Authorization: `Bearer ${bearer}`
|
|
15434
15570
|
}
|
|
15435
15571
|
}
|
|
15436
15572
|
}
|
|
@@ -15445,7 +15581,7 @@ function generateMcpConfig(agent, endpoint, anonKey) {
|
|
|
15445
15581
|
glasstrace: {
|
|
15446
15582
|
url: endpoint,
|
|
15447
15583
|
headers: {
|
|
15448
|
-
Authorization: `Bearer ${
|
|
15584
|
+
Authorization: `Bearer ${bearer}`
|
|
15449
15585
|
}
|
|
15450
15586
|
}
|
|
15451
15587
|
}
|
|
@@ -16873,19 +17009,23 @@ var init_uninit = __esm({
|
|
|
16873
17009
|
// src/cli/mcp-add.ts
|
|
16874
17010
|
var mcp_add_exports = {};
|
|
16875
17011
|
__export(mcp_add_exports, {
|
|
16876
|
-
mcpAdd: () => mcpAdd
|
|
17012
|
+
mcpAdd: () => mcpAdd,
|
|
17013
|
+
registerViaCli: () => registerViaCli
|
|
16877
17014
|
});
|
|
16878
|
-
async function registerViaCli(agent,
|
|
17015
|
+
async function registerViaCli(agent, bearer) {
|
|
16879
17016
|
if (!agent.cliAvailable) {
|
|
16880
17017
|
return false;
|
|
16881
17018
|
}
|
|
17019
|
+
if (agent.name !== "codex" && !isAnonApiKey(bearer)) {
|
|
17020
|
+
return false;
|
|
17021
|
+
}
|
|
16882
17022
|
try {
|
|
16883
17023
|
switch (agent.name) {
|
|
16884
17024
|
case "claude": {
|
|
16885
17025
|
const payload = JSON.stringify({
|
|
16886
17026
|
type: "http",
|
|
16887
17027
|
url: MCP_ENDPOINT,
|
|
16888
|
-
headers: { Authorization: `Bearer ${
|
|
17028
|
+
headers: { Authorization: `Bearer ${bearer}` }
|
|
16889
17029
|
});
|
|
16890
17030
|
await execFileAsync("claude", [
|
|
16891
17031
|
"mcp",
|
|
@@ -16929,7 +17069,7 @@ async function registerViaCli(agent, anonKey) {
|
|
|
16929
17069
|
"--transport",
|
|
16930
17070
|
"http",
|
|
16931
17071
|
"--header",
|
|
16932
|
-
`Authorization: Bearer ${
|
|
17072
|
+
`Authorization: Bearer ${bearer}`,
|
|
16933
17073
|
"glasstrace",
|
|
16934
17074
|
MCP_ENDPOINT
|
|
16935
17075
|
]);
|
|
@@ -16942,26 +17082,41 @@ async function registerViaCli(agent, anonKey) {
|
|
|
16942
17082
|
return false;
|
|
16943
17083
|
}
|
|
16944
17084
|
}
|
|
17085
|
+
async function markerMatchesEffective(projectRoot, effective) {
|
|
17086
|
+
const state = await readMcpMarker(projectRoot);
|
|
17087
|
+
if (state.status !== "valid") return false;
|
|
17088
|
+
return state.credentialHash === identityFingerprint(effective.key);
|
|
17089
|
+
}
|
|
16945
17090
|
async function mcpAdd(options) {
|
|
16946
17091
|
const force = options?.force ?? false;
|
|
16947
17092
|
const dryRun = options?.dryRun ?? false;
|
|
16948
17093
|
const projectRoot = process.cwd();
|
|
16949
17094
|
const messages = [];
|
|
16950
|
-
const
|
|
16951
|
-
if (
|
|
17095
|
+
const resolved = await resolveEffectiveMcpCredential(projectRoot);
|
|
17096
|
+
if (resolved.effective === null) {
|
|
16952
17097
|
return {
|
|
16953
17098
|
exitCode: 1,
|
|
16954
17099
|
results: [],
|
|
16955
17100
|
messages: ["Error: Run `glasstrace init` first to generate an API key."]
|
|
16956
17101
|
};
|
|
16957
17102
|
}
|
|
17103
|
+
if (resolved.warnings.includes("claimed-key-only")) {
|
|
17104
|
+
messages.push(
|
|
17105
|
+
"Note: dev key was loaded from .glasstrace/claimed-key. Copy it into .env.local so your app and Codex pick it up automatically."
|
|
17106
|
+
);
|
|
17107
|
+
}
|
|
16958
17108
|
const markerPath = path6.join(projectRoot, ".glasstrace", "mcp-connected");
|
|
16959
17109
|
if (fs6.existsSync(markerPath) && !force) {
|
|
16960
|
-
|
|
16961
|
-
|
|
16962
|
-
|
|
16963
|
-
|
|
16964
|
-
|
|
17110
|
+
if (await markerMatchesEffective(projectRoot, resolved.effective)) {
|
|
17111
|
+
return {
|
|
17112
|
+
exitCode: 0,
|
|
17113
|
+
results: [],
|
|
17114
|
+
messages: ["MCP already configured. Use --force to reconfigure."]
|
|
17115
|
+
};
|
|
17116
|
+
}
|
|
17117
|
+
messages.push(
|
|
17118
|
+
"Detected a credential change since MCP was last configured. Refreshing MCP config so queries use the current account credential."
|
|
17119
|
+
);
|
|
16965
17120
|
}
|
|
16966
17121
|
const agents = await detectAgents(projectRoot);
|
|
16967
17122
|
const detectedNonGeneric = agents.filter((a) => a.name !== "generic");
|
|
@@ -16970,7 +17125,7 @@ async function mcpAdd(options) {
|
|
|
16970
17125
|
messages.push("Dry run: would perform the following actions:", "");
|
|
16971
17126
|
for (const agent of targetAgents) {
|
|
16972
17127
|
const name = formatAgentName(agent.name);
|
|
16973
|
-
if (agent.cliAvailable) {
|
|
17128
|
+
if (agent.cliAvailable && resolved.effective.source === "anon") {
|
|
16974
17129
|
messages.push(
|
|
16975
17130
|
` ${name}: Register via CLI (${agent.name} mcp add)`
|
|
16976
17131
|
);
|
|
@@ -16993,10 +17148,11 @@ async function mcpAdd(options) {
|
|
|
16993
17148
|
return { exitCode: 0, results: [], messages };
|
|
16994
17149
|
}
|
|
16995
17150
|
const results = [];
|
|
17151
|
+
const bearer = resolved.effective.key;
|
|
16996
17152
|
for (const agent of targetAgents) {
|
|
16997
17153
|
const name = formatAgentName(agent.name);
|
|
16998
17154
|
if (agent.name !== "generic") {
|
|
16999
|
-
const cliSuccess = await registerViaCli(agent,
|
|
17155
|
+
const cliSuccess = await registerViaCli(agent, bearer);
|
|
17000
17156
|
if (cliSuccess) {
|
|
17001
17157
|
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
17002
17158
|
if (infoContent !== "") {
|
|
@@ -17013,7 +17169,7 @@ async function mcpAdd(options) {
|
|
|
17013
17169
|
}
|
|
17014
17170
|
if (agent.mcpConfigPath !== null) {
|
|
17015
17171
|
try {
|
|
17016
|
-
const configContent = generateMcpConfig(agent, MCP_ENDPOINT,
|
|
17172
|
+
const configContent = generateMcpConfig(agent, MCP_ENDPOINT, bearer);
|
|
17017
17173
|
await writeMcpConfig(agent, configContent, projectRoot);
|
|
17018
17174
|
if (fs6.existsSync(agent.mcpConfigPath)) {
|
|
17019
17175
|
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
@@ -17058,7 +17214,10 @@ async function mcpAdd(options) {
|
|
|
17058
17214
|
);
|
|
17059
17215
|
const anySuccess = results.some((r) => r.success);
|
|
17060
17216
|
if (anySuccess) {
|
|
17061
|
-
await
|
|
17217
|
+
await writeMcpMarker(projectRoot, {
|
|
17218
|
+
credentialSource: resolved.effective.source,
|
|
17219
|
+
credentialHash: identityFingerprint(resolved.effective.key)
|
|
17220
|
+
});
|
|
17062
17221
|
}
|
|
17063
17222
|
messages.push("", "MCP registration summary:");
|
|
17064
17223
|
for (const result of results) {
|
|
@@ -17090,11 +17249,10 @@ var init_mcp_add = __esm({
|
|
|
17090
17249
|
fs6 = __toESM(require("node:fs"), 1);
|
|
17091
17250
|
path6 = __toESM(require("node:path"), 1);
|
|
17092
17251
|
import_node_util = require("node:util");
|
|
17093
|
-
|
|
17252
|
+
init_mcp_runtime();
|
|
17094
17253
|
init_detect();
|
|
17095
17254
|
init_configs();
|
|
17096
17255
|
init_inject();
|
|
17097
|
-
init_scaffolder();
|
|
17098
17256
|
init_constants();
|
|
17099
17257
|
execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
17100
17258
|
}
|
|
@@ -17414,6 +17572,7 @@ var fs9 = __toESM(require("node:fs"), 1);
|
|
|
17414
17572
|
var path9 = __toESM(require("node:path"), 1);
|
|
17415
17573
|
var readline = __toESM(require("node:readline"), 1);
|
|
17416
17574
|
init_scaffolder();
|
|
17575
|
+
init_mcp_runtime();
|
|
17417
17576
|
|
|
17418
17577
|
// src/import-graph.ts
|
|
17419
17578
|
var fs2 = __toESM(require("node:fs/promises"), 1);
|
|
@@ -18332,6 +18491,9 @@ Then add this as the first statement in your register() function:
|
|
|
18332
18491
|
);
|
|
18333
18492
|
}
|
|
18334
18493
|
let anyConfigWritten = false;
|
|
18494
|
+
let anyConfigRewrittenWithBearer = false;
|
|
18495
|
+
const resolved = await resolveEffectiveMcpCredential(projectRoot);
|
|
18496
|
+
const bearer = resolved.effective?.key ?? anonKey;
|
|
18335
18497
|
if (isCI) {
|
|
18336
18498
|
const genericAgent = {
|
|
18337
18499
|
name: "generic",
|
|
@@ -18340,7 +18502,7 @@ Then add this as the first statement in your register() function:
|
|
|
18340
18502
|
cliAvailable: false,
|
|
18341
18503
|
registrationCommand: null
|
|
18342
18504
|
};
|
|
18343
|
-
const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT,
|
|
18505
|
+
const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT, bearer);
|
|
18344
18506
|
const decision = await decideMcpConfigAction({
|
|
18345
18507
|
configPath: genericAgent.mcpConfigPath,
|
|
18346
18508
|
expectedContent: genericConfig,
|
|
@@ -18348,6 +18510,9 @@ Then add this as the first statement in your register() function:
|
|
|
18348
18510
|
});
|
|
18349
18511
|
if (decision !== "skip") {
|
|
18350
18512
|
await writeMcpConfig(genericAgent, genericConfig, projectRoot);
|
|
18513
|
+
if (genericAgent.mcpConfigPath !== null && fs9.existsSync(genericAgent.mcpConfigPath)) {
|
|
18514
|
+
anyConfigRewrittenWithBearer = true;
|
|
18515
|
+
}
|
|
18351
18516
|
}
|
|
18352
18517
|
if (genericAgent.mcpConfigPath !== null && fs9.existsSync(genericAgent.mcpConfigPath)) {
|
|
18353
18518
|
anyConfigWritten = true;
|
|
@@ -18368,17 +18533,18 @@ Then add this as the first statement in your register() function:
|
|
|
18368
18533
|
cliAvailable: false,
|
|
18369
18534
|
registrationCommand: null
|
|
18370
18535
|
};
|
|
18371
|
-
const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT,
|
|
18536
|
+
const genericConfig = generateMcpConfig(genericAgent, MCP_ENDPOINT, bearer);
|
|
18372
18537
|
await writeMcpConfig(genericAgent, genericConfig, projectRoot);
|
|
18373
18538
|
if (genericAgent.mcpConfigPath !== null && fs9.existsSync(genericAgent.mcpConfigPath)) {
|
|
18374
18539
|
anyConfigWritten = true;
|
|
18540
|
+
anyConfigRewrittenWithBearer = true;
|
|
18375
18541
|
}
|
|
18376
18542
|
agents = [];
|
|
18377
18543
|
}
|
|
18378
18544
|
const configuredNames = [];
|
|
18379
18545
|
for (const agent of agents) {
|
|
18380
18546
|
try {
|
|
18381
|
-
const configContent = generateMcpConfig(agent, MCP_ENDPOINT,
|
|
18547
|
+
const configContent = generateMcpConfig(agent, MCP_ENDPOINT, bearer);
|
|
18382
18548
|
const decision = await decideMcpConfigAction({
|
|
18383
18549
|
configPath: agent.mcpConfigPath,
|
|
18384
18550
|
expectedContent: configContent,
|
|
@@ -18399,6 +18565,7 @@ Then add this as the first statement in your register() function:
|
|
|
18399
18565
|
continue;
|
|
18400
18566
|
}
|
|
18401
18567
|
anyConfigWritten = true;
|
|
18568
|
+
anyConfigRewrittenWithBearer = true;
|
|
18402
18569
|
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
18403
18570
|
if (infoContent !== "") {
|
|
18404
18571
|
await injectInfoSection(agent, infoContent, projectRoot);
|
|
@@ -18422,8 +18589,13 @@ Then add this as the first statement in your register() function:
|
|
|
18422
18589
|
[".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".codex/config.toml"],
|
|
18423
18590
|
projectRoot
|
|
18424
18591
|
);
|
|
18425
|
-
if (
|
|
18426
|
-
const
|
|
18592
|
+
if (anyConfigRewrittenWithBearer) {
|
|
18593
|
+
const markerSource = resolved.effective?.source ?? "anon";
|
|
18594
|
+
const markerHash = identityFingerprint(bearer);
|
|
18595
|
+
const markerCreated = await writeMcpMarker(projectRoot, {
|
|
18596
|
+
credentialSource: markerSource,
|
|
18597
|
+
credentialHash: markerHash
|
|
18598
|
+
});
|
|
18427
18599
|
if (markerCreated) {
|
|
18428
18600
|
summary.push("Created .glasstrace/mcp-connected marker");
|
|
18429
18601
|
}
|
|
@@ -18492,7 +18664,7 @@ async function verifyAnonKeyRegistration(projectRoot) {
|
|
|
18492
18664
|
}
|
|
18493
18665
|
const baseConfig = resolveConfig({ apiKey: devKey });
|
|
18494
18666
|
const config2 = { ...baseConfig, apiKey: devKey };
|
|
18495
|
-
const sdkVersion = true ? "1.1.
|
|
18667
|
+
const sdkVersion = true ? "1.1.1" : "0.0.0-dev";
|
|
18496
18668
|
const result = await verifyInitReachable(config2, anonKey, sdkVersion);
|
|
18497
18669
|
if (result.ok) {
|
|
18498
18670
|
return { outcome: "verified" };
|