@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
|
@@ -1,51 +1,426 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NEXT_CONFIG_NAMES
|
|
3
|
+
} from "./chunk-7SZQN6IU.js";
|
|
1
4
|
import {
|
|
2
5
|
isDevApiKey,
|
|
3
6
|
readEnvLocalApiKey
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-P22UQ2OJ.js";
|
|
5
8
|
import {
|
|
6
9
|
AnonApiKeySchema
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
NEXT_CONFIG_NAMES
|
|
10
|
-
} from "./chunk-DXRZKKSO.js";
|
|
10
|
+
} from "./chunk-X5MAXP5T.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/uninit.ts
|
|
13
|
-
import * as
|
|
13
|
+
import * as fs3 from "node:fs";
|
|
14
14
|
import * as os from "node:os";
|
|
15
|
-
import * as
|
|
15
|
+
import * as path3 from "node:path";
|
|
16
16
|
|
|
17
|
-
// src/cli/
|
|
17
|
+
// src/cli/scaffolder.ts
|
|
18
18
|
import * as fs from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
+
function hasRegisterGlasstraceCall(content) {
|
|
21
|
+
return content.split("\n").some((line) => {
|
|
22
|
+
const uncommented = line.replace(/\/\/.*$/, "");
|
|
23
|
+
return /\bregisterGlasstrace\s*\(/.test(uncommented);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function injectRegisterGlasstrace(content) {
|
|
27
|
+
if (hasRegisterGlasstraceCall(content)) {
|
|
28
|
+
return { injected: false, content };
|
|
29
|
+
}
|
|
30
|
+
const registerFnRegex = /export\s+(?:async\s+)?function\s+register\s*\([^)]*\)\s*\{/;
|
|
31
|
+
const match = registerFnRegex.exec(content);
|
|
32
|
+
if (!match) {
|
|
33
|
+
return { injected: false, content };
|
|
34
|
+
}
|
|
35
|
+
const afterBrace = content.slice(match.index + match[0].length);
|
|
36
|
+
const indentMatch = /\n([ \t]+)/.exec(afterBrace);
|
|
37
|
+
const indent = indentMatch ? indentMatch[1] : " ";
|
|
38
|
+
const importLine = 'import { registerGlasstrace } from "@glasstrace/sdk";\n';
|
|
39
|
+
const hasGlasstraceImport = content.includes("@glasstrace/sdk");
|
|
40
|
+
const insertPoint = match.index + match[0].length;
|
|
41
|
+
const callInjection = `
|
|
42
|
+
${indent}// Glasstrace must be registered before other instrumentation
|
|
43
|
+
${indent}registerGlasstrace();
|
|
44
|
+
`;
|
|
45
|
+
let modified;
|
|
46
|
+
if (hasGlasstraceImport) {
|
|
47
|
+
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@glasstrace\/sdk["']/;
|
|
48
|
+
const importMatch = importRegex.exec(content);
|
|
49
|
+
if (importMatch) {
|
|
50
|
+
const specifiers = importMatch[1];
|
|
51
|
+
const alreadyImported = specifiers.split(",").some((s) => s.trim() === "registerGlasstrace");
|
|
52
|
+
if (alreadyImported) {
|
|
53
|
+
modified = content.slice(0, insertPoint) + callInjection + content.slice(insertPoint);
|
|
54
|
+
} else {
|
|
55
|
+
const existingImports = specifiers.trimEnd();
|
|
56
|
+
const separator = existingImports.endsWith(",") ? " " : ", ";
|
|
57
|
+
const updatedImport = `import { ${existingImports.trim()}${separator}registerGlasstrace } from "@glasstrace/sdk"`;
|
|
58
|
+
modified = content.replace(importMatch[0], updatedImport);
|
|
59
|
+
const newMatch = registerFnRegex.exec(modified);
|
|
60
|
+
if (newMatch) {
|
|
61
|
+
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
62
|
+
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
modified = importLine + content;
|
|
67
|
+
const newMatch = registerFnRegex.exec(modified);
|
|
68
|
+
if (newMatch) {
|
|
69
|
+
const newInsertPoint = newMatch.index + newMatch[0].length;
|
|
70
|
+
modified = modified.slice(0, newInsertPoint) + callInjection + modified.slice(newInsertPoint);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
modified = importLine + content.slice(0, insertPoint) + callInjection + content.slice(insertPoint);
|
|
75
|
+
}
|
|
76
|
+
return { injected: true, content: modified };
|
|
77
|
+
}
|
|
78
|
+
var INSTRUMENTATION_FILENAMES = [
|
|
79
|
+
"instrumentation.ts",
|
|
80
|
+
"instrumentation.js",
|
|
81
|
+
"instrumentation.mjs"
|
|
82
|
+
];
|
|
83
|
+
function resolveInstrumentationTarget(projectRoot) {
|
|
84
|
+
const rootExisting = [];
|
|
85
|
+
const srcExisting = [];
|
|
86
|
+
for (const name of INSTRUMENTATION_FILENAMES) {
|
|
87
|
+
const rootPath = path.join(projectRoot, name);
|
|
88
|
+
if (isRegularFile(rootPath)) {
|
|
89
|
+
rootExisting.push(rootPath);
|
|
90
|
+
}
|
|
91
|
+
const srcPath = path.join(projectRoot, "src", name);
|
|
92
|
+
if (isRegularFile(srcPath)) {
|
|
93
|
+
srcExisting.push(srcPath);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const existing = [...rootExisting, ...srcExisting];
|
|
97
|
+
if (rootExisting.length > 0 && srcExisting.length > 0) {
|
|
98
|
+
return {
|
|
99
|
+
target: null,
|
|
100
|
+
layout: null,
|
|
101
|
+
existing,
|
|
102
|
+
rootExisting,
|
|
103
|
+
srcExisting,
|
|
104
|
+
conflict: true
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (srcExisting.length > 0) {
|
|
108
|
+
return {
|
|
109
|
+
target: srcExisting[0],
|
|
110
|
+
layout: "src",
|
|
111
|
+
existing,
|
|
112
|
+
rootExisting,
|
|
113
|
+
srcExisting,
|
|
114
|
+
conflict: false
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (rootExisting.length > 0) {
|
|
118
|
+
return {
|
|
119
|
+
target: rootExisting[0],
|
|
120
|
+
layout: "root",
|
|
121
|
+
existing,
|
|
122
|
+
rootExisting,
|
|
123
|
+
srcExisting,
|
|
124
|
+
conflict: false
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const srcDir = path.join(projectRoot, "src");
|
|
128
|
+
const layout = isDirectory(srcDir) ? "src" : "root";
|
|
129
|
+
const target = layout === "src" ? path.join(projectRoot, "src", "instrumentation.ts") : path.join(projectRoot, "instrumentation.ts");
|
|
130
|
+
return {
|
|
131
|
+
target,
|
|
132
|
+
layout,
|
|
133
|
+
existing,
|
|
134
|
+
rootExisting,
|
|
135
|
+
srcExisting,
|
|
136
|
+
conflict: false
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function isDirectory(p) {
|
|
140
|
+
try {
|
|
141
|
+
return fs.statSync(p).isDirectory();
|
|
142
|
+
} catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function isRegularFile(p) {
|
|
147
|
+
try {
|
|
148
|
+
const stat = fs.lstatSync(p);
|
|
149
|
+
if (stat.isSymbolicLink()) {
|
|
150
|
+
return fs.statSync(p).isFile();
|
|
151
|
+
}
|
|
152
|
+
return stat.isFile();
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function appendRegisterFunction(content) {
|
|
158
|
+
const importLine = 'import { registerGlasstrace } from "@glasstrace/sdk";\n';
|
|
159
|
+
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";
|
|
160
|
+
let withImport = content;
|
|
161
|
+
const hasGlasstraceImport = content.includes("@glasstrace/sdk");
|
|
162
|
+
if (!hasGlasstraceImport) {
|
|
163
|
+
withImport = importLine + content;
|
|
164
|
+
} else {
|
|
165
|
+
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@glasstrace\/sdk["']/;
|
|
166
|
+
const importMatch = importRegex.exec(content);
|
|
167
|
+
if (importMatch) {
|
|
168
|
+
const specifiers = importMatch[1];
|
|
169
|
+
const alreadyImported = specifiers.split(",").some((s) => s.trim() === "registerGlasstrace");
|
|
170
|
+
if (!alreadyImported) {
|
|
171
|
+
const existingImports = specifiers.trimEnd();
|
|
172
|
+
const separator = existingImports.endsWith(",") ? " " : ", ";
|
|
173
|
+
const updatedImport = `import { ${existingImports.trim()}${separator}registerGlasstrace } from "@glasstrace/sdk"`;
|
|
174
|
+
withImport = content.replace(importMatch[0], updatedImport);
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
withImport = importLine + content;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const trailingNewline = withImport.endsWith("\n") ? "" : "\n";
|
|
181
|
+
return withImport + trailingNewline + functionBlock;
|
|
182
|
+
}
|
|
183
|
+
async function defaultInstrumentationPrompt(question, defaultValue) {
|
|
184
|
+
if (!process.stdin.isTTY) return defaultValue;
|
|
185
|
+
const readline = await import("node:readline");
|
|
186
|
+
const rl = readline.createInterface({
|
|
187
|
+
input: process.stdin,
|
|
188
|
+
output: process.stdout
|
|
189
|
+
});
|
|
190
|
+
return new Promise((resolve) => {
|
|
191
|
+
const suffix = defaultValue ? " [Y/n] " : " [y/N] ";
|
|
192
|
+
rl.question(question + suffix, (answer) => {
|
|
193
|
+
rl.close();
|
|
194
|
+
const trimmed = answer.trim().toLowerCase();
|
|
195
|
+
if (trimmed === "") {
|
|
196
|
+
resolve(defaultValue);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
resolve(trimmed === "y" || trimmed === "yes");
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
async function scaffoldInstrumentation(projectRoot, options = {}) {
|
|
204
|
+
const target = resolveInstrumentationTarget(projectRoot);
|
|
205
|
+
if (target.conflict) {
|
|
206
|
+
return {
|
|
207
|
+
action: "conflict",
|
|
208
|
+
// Point the user at the `src/` variant — modern Next.js apps with a
|
|
209
|
+
// `src/` directory load from there, so that's the merge target. The
|
|
210
|
+
// competing path is reported separately for the error message.
|
|
211
|
+
filePath: target.srcExisting[0],
|
|
212
|
+
conflictingPath: target.rootExisting[0]
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const filePath = target.target;
|
|
216
|
+
const layout = target.layout;
|
|
217
|
+
if (filePath === null || layout === null) {
|
|
218
|
+
return { action: "unrecognized" };
|
|
219
|
+
}
|
|
220
|
+
const force = options.force === true;
|
|
221
|
+
const prompt = options.prompt ?? defaultInstrumentationPrompt;
|
|
222
|
+
if (!fs.existsSync(filePath)) {
|
|
223
|
+
const content = `import { registerGlasstrace } from "@glasstrace/sdk";
|
|
224
|
+
|
|
225
|
+
export async function register() {
|
|
226
|
+
// Glasstrace must be registered before Prisma instrumentation
|
|
227
|
+
// to ensure all ORM spans are captured correctly.
|
|
228
|
+
// If you use @prisma/instrumentation, import it after this call.
|
|
229
|
+
registerGlasstrace();
|
|
230
|
+
}
|
|
231
|
+
`;
|
|
232
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
233
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
234
|
+
return { action: "created", filePath, layout };
|
|
235
|
+
}
|
|
236
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
237
|
+
if (hasRegisterGlasstraceCall(existing)) {
|
|
238
|
+
return { action: "already-registered", filePath, layout };
|
|
239
|
+
}
|
|
240
|
+
if (!force) {
|
|
241
|
+
const approved = await prompt(
|
|
242
|
+
`Merge registerGlasstrace() into ${path.relative(projectRoot, filePath)}?`,
|
|
243
|
+
false
|
|
244
|
+
);
|
|
245
|
+
if (!approved) {
|
|
246
|
+
return { action: "skipped", filePath, layout };
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const injectResult = injectRegisterGlasstrace(existing);
|
|
250
|
+
if (injectResult.injected) {
|
|
251
|
+
fs.writeFileSync(filePath, injectResult.content, "utf-8");
|
|
252
|
+
return { action: "injected", filePath, layout };
|
|
253
|
+
}
|
|
254
|
+
const appended = appendRegisterFunction(existing);
|
|
255
|
+
fs.writeFileSync(filePath, appended, "utf-8");
|
|
256
|
+
return { action: "appended", filePath, layout };
|
|
257
|
+
}
|
|
258
|
+
async function scaffoldNextConfig(projectRoot) {
|
|
259
|
+
let configPath;
|
|
260
|
+
let configName;
|
|
261
|
+
for (const name of NEXT_CONFIG_NAMES) {
|
|
262
|
+
const candidate = path.join(projectRoot, name);
|
|
263
|
+
if (fs.existsSync(candidate)) {
|
|
264
|
+
configPath = candidate;
|
|
265
|
+
configName = name;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (configPath === void 0 || configName === void 0) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
const existing = fs.readFileSync(configPath, "utf-8");
|
|
273
|
+
if (existing.trim().length === 0) {
|
|
274
|
+
return { modified: false, reason: "empty-file" };
|
|
275
|
+
}
|
|
276
|
+
if (existing.includes("withGlasstraceConfig")) {
|
|
277
|
+
return { modified: false, reason: "already-wrapped" };
|
|
278
|
+
}
|
|
279
|
+
const isESM = configName.endsWith(".ts") || configName.endsWith(".mjs");
|
|
280
|
+
if (isESM) {
|
|
281
|
+
const importLine = 'import { withGlasstraceConfig } from "@glasstrace/sdk";\n';
|
|
282
|
+
const wrapResult2 = wrapExport(existing);
|
|
283
|
+
if (!wrapResult2.wrapped) {
|
|
284
|
+
return { modified: false, reason: "no-export" };
|
|
285
|
+
}
|
|
286
|
+
const modified2 = importLine + "\n" + wrapResult2.content;
|
|
287
|
+
fs.writeFileSync(configPath, modified2, "utf-8");
|
|
288
|
+
return { modified: true };
|
|
289
|
+
}
|
|
290
|
+
const requireLine = 'const { withGlasstraceConfig } = require("@glasstrace/sdk");\n';
|
|
291
|
+
const wrapResult = wrapCJSExport(existing);
|
|
292
|
+
if (!wrapResult.wrapped) {
|
|
293
|
+
return { modified: false, reason: "no-export" };
|
|
294
|
+
}
|
|
295
|
+
const modified = requireLine + "\n" + wrapResult.content;
|
|
296
|
+
fs.writeFileSync(configPath, modified, "utf-8");
|
|
297
|
+
return { modified: true };
|
|
298
|
+
}
|
|
299
|
+
function wrapExport(content) {
|
|
300
|
+
const marker = "export default";
|
|
301
|
+
const idx = content.lastIndexOf(marker);
|
|
302
|
+
if (idx === -1) {
|
|
303
|
+
return { content, wrapped: false };
|
|
304
|
+
}
|
|
305
|
+
const preamble = content.slice(0, idx);
|
|
306
|
+
const exprRaw = content.slice(idx + marker.length);
|
|
307
|
+
const expr = exprRaw.trim().replace(/;?\s*$/, "");
|
|
308
|
+
if (expr.length === 0) {
|
|
309
|
+
return { content, wrapped: false };
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
content: preamble + `export default withGlasstraceConfig(${expr});
|
|
313
|
+
`,
|
|
314
|
+
wrapped: true
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function wrapCJSExport(content) {
|
|
318
|
+
const cjsMarker = "module.exports";
|
|
319
|
+
const cjsIdx = content.lastIndexOf(cjsMarker);
|
|
320
|
+
if (cjsIdx === -1) {
|
|
321
|
+
return { content, wrapped: false };
|
|
322
|
+
}
|
|
323
|
+
const preamble = content.slice(0, cjsIdx);
|
|
324
|
+
const afterMarker = content.slice(cjsIdx + cjsMarker.length);
|
|
325
|
+
const eqMatch = /^\s*=\s*/.exec(afterMarker);
|
|
326
|
+
if (!eqMatch) {
|
|
327
|
+
return { content, wrapped: false };
|
|
328
|
+
}
|
|
329
|
+
const exprRaw = afterMarker.slice(eqMatch[0].length);
|
|
330
|
+
const expr = exprRaw.trim().replace(/;?\s*$/, "");
|
|
331
|
+
if (expr.length === 0) {
|
|
332
|
+
return { content, wrapped: false };
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
content: preamble + `module.exports = withGlasstraceConfig(${expr});
|
|
336
|
+
`,
|
|
337
|
+
wrapped: true
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
async function scaffoldEnvLocal(projectRoot) {
|
|
341
|
+
const filePath = path.join(projectRoot, ".env.local");
|
|
342
|
+
if (fs.existsSync(filePath)) {
|
|
343
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
344
|
+
if (/^\s*#?\s*GLASSTRACE_API_KEY\s*=/m.test(existing)) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
348
|
+
fs.writeFileSync(filePath, existing + separator + "# GLASSTRACE_API_KEY=your_key_here\n", "utf-8");
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
fs.writeFileSync(filePath, "# GLASSTRACE_API_KEY=your_key_here\n", "utf-8");
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
async function addCoverageMapEnv(projectRoot) {
|
|
355
|
+
const filePath = path.join(projectRoot, ".env.local");
|
|
356
|
+
if (!fs.existsSync(filePath)) {
|
|
357
|
+
fs.writeFileSync(filePath, "GLASSTRACE_COVERAGE_MAP=true\n", "utf-8");
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
361
|
+
const keyRegex = /^(\s*GLASSTRACE_COVERAGE_MAP\s*=\s*)(.*)$/m;
|
|
362
|
+
const keyMatch = keyRegex.exec(existing);
|
|
363
|
+
if (keyMatch) {
|
|
364
|
+
const currentValue = keyMatch[2].trim();
|
|
365
|
+
if (currentValue === "true") {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
const updated = existing.replace(keyRegex, `${keyMatch[1]}true`);
|
|
369
|
+
fs.writeFileSync(filePath, updated, "utf-8");
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
373
|
+
fs.writeFileSync(filePath, existing + separator + "GLASSTRACE_COVERAGE_MAP=true\n", "utf-8");
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
async function scaffoldGitignore(projectRoot) {
|
|
377
|
+
const filePath = path.join(projectRoot, ".gitignore");
|
|
378
|
+
if (fs.existsSync(filePath)) {
|
|
379
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
380
|
+
const lines = existing.split("\n").map((l) => l.trim());
|
|
381
|
+
if (lines.includes(".glasstrace/")) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
385
|
+
fs.writeFileSync(filePath, existing + separator + ".glasstrace/\n", "utf-8");
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
fs.writeFileSync(filePath, ".glasstrace/\n", "utf-8");
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// src/cli/discovery-file.ts
|
|
393
|
+
import * as fs2 from "node:fs";
|
|
394
|
+
import * as path2 from "node:path";
|
|
20
395
|
var WELL_KNOWN_GLASSTRACE_PATH = ".well-known/glasstrace.json";
|
|
21
396
|
var DISCOVERY_FILE_VERSION = 1;
|
|
22
397
|
function resolveStaticRoot(projectRoot) {
|
|
23
398
|
if (isSvelteKitProject(projectRoot)) {
|
|
24
399
|
return {
|
|
25
|
-
absolutePath:
|
|
400
|
+
absolutePath: path2.join(projectRoot, "static"),
|
|
26
401
|
layout: "static"
|
|
27
402
|
};
|
|
28
403
|
}
|
|
29
404
|
return {
|
|
30
|
-
absolutePath:
|
|
405
|
+
absolutePath: path2.join(projectRoot, "public"),
|
|
31
406
|
layout: "public"
|
|
32
407
|
};
|
|
33
408
|
}
|
|
34
409
|
function isSvelteKitProject(projectRoot) {
|
|
35
|
-
const pkgPath =
|
|
410
|
+
const pkgPath = path2.join(projectRoot, "package.json");
|
|
36
411
|
let isEsm = false;
|
|
37
412
|
try {
|
|
38
|
-
const pkgContent =
|
|
413
|
+
const pkgContent = fs2.readFileSync(pkgPath, "utf-8");
|
|
39
414
|
const parsed = JSON.parse(pkgContent);
|
|
40
415
|
isEsm = parsed.type === "module";
|
|
41
416
|
} catch {
|
|
42
417
|
return false;
|
|
43
418
|
}
|
|
44
419
|
if (!isEsm) return false;
|
|
45
|
-
const svelteConfigJs =
|
|
46
|
-
const svelteConfigTs =
|
|
47
|
-
const appHtml =
|
|
48
|
-
return
|
|
420
|
+
const svelteConfigJs = path2.join(projectRoot, "svelte.config.js");
|
|
421
|
+
const svelteConfigTs = path2.join(projectRoot, "svelte.config.ts");
|
|
422
|
+
const appHtml = path2.join(projectRoot, "src", "app.html");
|
|
423
|
+
return fs2.existsSync(svelteConfigJs) || fs2.existsSync(svelteConfigTs) || fs2.existsSync(appHtml);
|
|
49
424
|
}
|
|
50
425
|
function relativeDiscoveryPath(layout) {
|
|
51
426
|
const rootDir = layout === "static" ? "static" : "public";
|
|
@@ -54,7 +429,7 @@ function relativeDiscoveryPath(layout) {
|
|
|
54
429
|
function readExistingDiscoveryFile(filePath) {
|
|
55
430
|
let raw;
|
|
56
431
|
try {
|
|
57
|
-
raw =
|
|
432
|
+
raw = fs2.readFileSync(filePath, "utf-8");
|
|
58
433
|
} catch {
|
|
59
434
|
return null;
|
|
60
435
|
}
|
|
@@ -93,11 +468,11 @@ function serializeDiscoveryPayload(key, extras) {
|
|
|
93
468
|
}
|
|
94
469
|
function writeDiscoveryFile(projectRoot, anonKey) {
|
|
95
470
|
const { absolutePath: staticRoot, layout } = resolveStaticRoot(projectRoot);
|
|
96
|
-
const wellKnownDir =
|
|
97
|
-
const filePath =
|
|
471
|
+
const wellKnownDir = path2.join(staticRoot, ".well-known");
|
|
472
|
+
const filePath = path2.join(wellKnownDir, "glasstrace.json");
|
|
98
473
|
let existingAction;
|
|
99
474
|
let extras = {};
|
|
100
|
-
if (
|
|
475
|
+
if (fs2.existsSync(filePath)) {
|
|
101
476
|
const existing = readExistingDiscoveryFile(filePath);
|
|
102
477
|
if (existing === null) {
|
|
103
478
|
existingAction = "skipped-foreign";
|
|
@@ -115,35 +490,35 @@ function writeDiscoveryFile(projectRoot, anonKey) {
|
|
|
115
490
|
existingAction = "created";
|
|
116
491
|
}
|
|
117
492
|
const tmpPath = `${filePath}.tmp-${process.pid}`;
|
|
118
|
-
const needsWindowsReplace = process.platform === "win32" &&
|
|
493
|
+
const needsWindowsReplace = process.platform === "win32" && fs2.existsSync(filePath);
|
|
119
494
|
const backupPath = needsWindowsReplace ? `${filePath}.bak-${process.pid}` : null;
|
|
120
495
|
try {
|
|
121
|
-
|
|
496
|
+
fs2.mkdirSync(wellKnownDir, { recursive: true });
|
|
122
497
|
const payload = serializeDiscoveryPayload(anonKey, extras);
|
|
123
|
-
|
|
498
|
+
fs2.writeFileSync(tmpPath, payload, { encoding: "utf-8" });
|
|
124
499
|
if (backupPath !== null) {
|
|
125
|
-
|
|
500
|
+
fs2.renameSync(filePath, backupPath);
|
|
126
501
|
try {
|
|
127
|
-
|
|
502
|
+
fs2.renameSync(tmpPath, filePath);
|
|
128
503
|
} catch (renameErr) {
|
|
129
504
|
try {
|
|
130
|
-
|
|
505
|
+
fs2.renameSync(backupPath, filePath);
|
|
131
506
|
} catch {
|
|
132
507
|
}
|
|
133
508
|
throw renameErr;
|
|
134
509
|
}
|
|
135
510
|
try {
|
|
136
|
-
|
|
511
|
+
fs2.unlinkSync(backupPath);
|
|
137
512
|
} catch {
|
|
138
513
|
}
|
|
139
514
|
} else {
|
|
140
|
-
|
|
515
|
+
fs2.renameSync(tmpPath, filePath);
|
|
141
516
|
}
|
|
142
517
|
return { action: existingAction, filePath, layout };
|
|
143
518
|
} catch (err) {
|
|
144
519
|
try {
|
|
145
|
-
if (
|
|
146
|
-
|
|
520
|
+
if (fs2.existsSync(tmpPath)) {
|
|
521
|
+
fs2.unlinkSync(tmpPath);
|
|
147
522
|
}
|
|
148
523
|
} catch {
|
|
149
524
|
}
|
|
@@ -160,13 +535,13 @@ function removeDiscoveryFile(projectRoot) {
|
|
|
160
535
|
const layouts = ["public", "static"];
|
|
161
536
|
const outcomes = [];
|
|
162
537
|
for (const layout of layouts) {
|
|
163
|
-
const staticRoot =
|
|
164
|
-
const wellKnownDir =
|
|
165
|
-
const filePath =
|
|
538
|
+
const staticRoot = path2.join(projectRoot, layout);
|
|
539
|
+
const wellKnownDir = path2.join(staticRoot, ".well-known");
|
|
540
|
+
const filePath = path2.join(wellKnownDir, "glasstrace.json");
|
|
166
541
|
let removed = false;
|
|
167
542
|
try {
|
|
168
|
-
if (
|
|
169
|
-
|
|
543
|
+
if (fs2.existsSync(filePath)) {
|
|
544
|
+
fs2.unlinkSync(filePath);
|
|
170
545
|
removed = true;
|
|
171
546
|
}
|
|
172
547
|
} catch (err) {
|
|
@@ -181,10 +556,10 @@ function removeDiscoveryFile(projectRoot) {
|
|
|
181
556
|
let directoryRemoved = false;
|
|
182
557
|
if (removed) {
|
|
183
558
|
try {
|
|
184
|
-
if (
|
|
185
|
-
const entries =
|
|
559
|
+
if (fs2.existsSync(wellKnownDir)) {
|
|
560
|
+
const entries = fs2.readdirSync(wellKnownDir);
|
|
186
561
|
if (entries.length === 0) {
|
|
187
|
-
|
|
562
|
+
fs2.rmdirSync(wellKnownDir);
|
|
188
563
|
directoryRemoved = true;
|
|
189
564
|
}
|
|
190
565
|
}
|
|
@@ -517,24 +892,24 @@ function processTomlMcpConfig(content) {
|
|
|
517
892
|
return { action: "removed-section", content: result + "\n" };
|
|
518
893
|
}
|
|
519
894
|
function writeShutdownMarker(projectRoot) {
|
|
520
|
-
const dirPath =
|
|
521
|
-
if (!
|
|
895
|
+
const dirPath = path3.join(projectRoot, ".glasstrace");
|
|
896
|
+
if (!fs3.existsSync(dirPath)) {
|
|
522
897
|
return false;
|
|
523
898
|
}
|
|
524
|
-
const markerPath =
|
|
899
|
+
const markerPath = path3.join(dirPath, "shutdown-requested");
|
|
525
900
|
const tmpPath = `${markerPath}.tmp`;
|
|
526
901
|
const body = JSON.stringify({ requestedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
527
902
|
try {
|
|
528
|
-
|
|
903
|
+
fs3.writeFileSync(tmpPath, body, { encoding: "utf-8", mode: 384 });
|
|
529
904
|
try {
|
|
530
|
-
|
|
905
|
+
fs3.chmodSync(tmpPath, 384);
|
|
531
906
|
} catch {
|
|
532
907
|
}
|
|
533
|
-
|
|
908
|
+
fs3.renameSync(tmpPath, markerPath);
|
|
534
909
|
return true;
|
|
535
910
|
} catch {
|
|
536
911
|
try {
|
|
537
|
-
|
|
912
|
+
fs3.unlinkSync(tmpPath);
|
|
538
913
|
} catch {
|
|
539
914
|
}
|
|
540
915
|
return false;
|
|
@@ -575,8 +950,8 @@ async function runUninit(options) {
|
|
|
575
950
|
summary.push("Wrote .glasstrace/shutdown-requested marker");
|
|
576
951
|
}
|
|
577
952
|
} else {
|
|
578
|
-
const dirPath =
|
|
579
|
-
if (
|
|
953
|
+
const dirPath = path3.join(projectRoot, ".glasstrace");
|
|
954
|
+
if (fs3.existsSync(dirPath)) {
|
|
580
955
|
summary.push(`${prefix}Would write .glasstrace/shutdown-requested marker`);
|
|
581
956
|
}
|
|
582
957
|
}
|
|
@@ -588,11 +963,11 @@ async function runUninit(options) {
|
|
|
588
963
|
try {
|
|
589
964
|
let configHandled = false;
|
|
590
965
|
for (const name of NEXT_CONFIG_NAMES) {
|
|
591
|
-
const configPath =
|
|
592
|
-
if (!
|
|
966
|
+
const configPath = path3.join(projectRoot, name);
|
|
967
|
+
if (!fs3.existsSync(configPath)) {
|
|
593
968
|
continue;
|
|
594
969
|
}
|
|
595
|
-
const content =
|
|
970
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
596
971
|
if (!content.includes("withGlasstraceConfig")) {
|
|
597
972
|
continue;
|
|
598
973
|
}
|
|
@@ -602,7 +977,7 @@ async function runUninit(options) {
|
|
|
602
977
|
const cleaned = removeGlasstraceConfigImport(unwrapResult.content);
|
|
603
978
|
const final = cleanLeadingBlankLines(cleaned);
|
|
604
979
|
if (!dryRun) {
|
|
605
|
-
|
|
980
|
+
fs3.writeFileSync(configPath, final, "utf-8");
|
|
606
981
|
}
|
|
607
982
|
summary.push(`${prefix}Unwrapped withGlasstraceConfig from ${name}`);
|
|
608
983
|
configHandled = true;
|
|
@@ -623,20 +998,20 @@ async function runUninit(options) {
|
|
|
623
998
|
);
|
|
624
999
|
}
|
|
625
1000
|
try {
|
|
626
|
-
const instrPath =
|
|
627
|
-
if (
|
|
628
|
-
const content =
|
|
1001
|
+
const instrPath = path3.join(projectRoot, "instrumentation.ts");
|
|
1002
|
+
if (fs3.existsSync(instrPath)) {
|
|
1003
|
+
const content = fs3.readFileSync(instrPath, "utf-8");
|
|
629
1004
|
if (content.includes("registerGlasstrace") || content.includes("@glasstrace/sdk")) {
|
|
630
1005
|
if (isInitCreatedInstrumentation(content)) {
|
|
631
1006
|
if (!dryRun) {
|
|
632
|
-
|
|
1007
|
+
fs3.unlinkSync(instrPath);
|
|
633
1008
|
}
|
|
634
1009
|
summary.push(`${prefix}Deleted instrumentation.ts (init-created)`);
|
|
635
1010
|
} else {
|
|
636
1011
|
const cleaned = removeRegisterGlasstrace(content);
|
|
637
1012
|
if (cleaned !== content) {
|
|
638
1013
|
if (!dryRun) {
|
|
639
|
-
|
|
1014
|
+
fs3.writeFileSync(instrPath, cleaned, "utf-8");
|
|
640
1015
|
}
|
|
641
1016
|
summary.push(
|
|
642
1017
|
`${prefix}Removed registerGlasstrace() from instrumentation.ts`
|
|
@@ -651,10 +1026,10 @@ async function runUninit(options) {
|
|
|
651
1026
|
);
|
|
652
1027
|
}
|
|
653
1028
|
try {
|
|
654
|
-
const glasstraceDir =
|
|
655
|
-
if (
|
|
1029
|
+
const glasstraceDir = path3.join(projectRoot, ".glasstrace");
|
|
1030
|
+
if (fs3.existsSync(glasstraceDir)) {
|
|
656
1031
|
if (!dryRun) {
|
|
657
|
-
|
|
1032
|
+
fs3.rmSync(glasstraceDir, { recursive: true, force: true });
|
|
658
1033
|
}
|
|
659
1034
|
summary.push(`${prefix}Removed .glasstrace/ directory`);
|
|
660
1035
|
}
|
|
@@ -667,8 +1042,8 @@ async function runUninit(options) {
|
|
|
667
1042
|
if (dryRun) {
|
|
668
1043
|
for (const previewLayout of ["public", "static"]) {
|
|
669
1044
|
const relPath = relativeDiscoveryPath(previewLayout);
|
|
670
|
-
const absPath =
|
|
671
|
-
if (
|
|
1045
|
+
const absPath = path3.join(projectRoot, relPath);
|
|
1046
|
+
if (fs3.existsSync(absPath)) {
|
|
672
1047
|
summary.push(`${prefix}Would remove ${relPath}`);
|
|
673
1048
|
}
|
|
674
1049
|
}
|
|
@@ -693,9 +1068,9 @@ async function runUninit(options) {
|
|
|
693
1068
|
);
|
|
694
1069
|
}
|
|
695
1070
|
try {
|
|
696
|
-
const envPath =
|
|
697
|
-
if (
|
|
698
|
-
const content =
|
|
1071
|
+
const envPath = path3.join(projectRoot, ".env.local");
|
|
1072
|
+
if (fs3.existsSync(envPath)) {
|
|
1073
|
+
const content = fs3.readFileSync(envPath, "utf-8");
|
|
699
1074
|
const existingKey = readEnvLocalApiKey(content);
|
|
700
1075
|
const hasDevKey = isDevApiKey(existingKey);
|
|
701
1076
|
let proceed = true;
|
|
@@ -728,12 +1103,12 @@ async function runUninit(options) {
|
|
|
728
1103
|
const result = filtered.join("\n");
|
|
729
1104
|
if (result.trim().length === 0) {
|
|
730
1105
|
if (!dryRun) {
|
|
731
|
-
|
|
1106
|
+
fs3.unlinkSync(envPath);
|
|
732
1107
|
}
|
|
733
1108
|
summary.push(`${prefix}Deleted .env.local (no remaining entries)`);
|
|
734
1109
|
} else {
|
|
735
1110
|
if (!dryRun) {
|
|
736
|
-
|
|
1111
|
+
fs3.writeFileSync(envPath, result, "utf-8");
|
|
737
1112
|
}
|
|
738
1113
|
let devKeyAnnotation = "";
|
|
739
1114
|
if (devKeyPath === "interactive-confirmed") {
|
|
@@ -756,9 +1131,9 @@ async function runUninit(options) {
|
|
|
756
1131
|
);
|
|
757
1132
|
}
|
|
758
1133
|
try {
|
|
759
|
-
const gitignorePath =
|
|
760
|
-
if (
|
|
761
|
-
const content =
|
|
1134
|
+
const gitignorePath = path3.join(projectRoot, ".gitignore");
|
|
1135
|
+
if (fs3.existsSync(gitignorePath)) {
|
|
1136
|
+
const content = fs3.readFileSync(gitignorePath, "utf-8");
|
|
762
1137
|
const lines = content.split("\n");
|
|
763
1138
|
const mcpGitignoreEntries = /* @__PURE__ */ new Set([
|
|
764
1139
|
".glasstrace/",
|
|
@@ -774,12 +1149,12 @@ async function runUninit(options) {
|
|
|
774
1149
|
const result = filtered.join("\n");
|
|
775
1150
|
if (result.trim().length === 0) {
|
|
776
1151
|
if (!dryRun) {
|
|
777
|
-
|
|
1152
|
+
fs3.unlinkSync(gitignorePath);
|
|
778
1153
|
}
|
|
779
1154
|
summary.push(`${prefix}Deleted .gitignore (no remaining entries)`);
|
|
780
1155
|
} else {
|
|
781
1156
|
if (!dryRun) {
|
|
782
|
-
|
|
1157
|
+
fs3.writeFileSync(gitignorePath, result, "utf-8");
|
|
783
1158
|
}
|
|
784
1159
|
summary.push(`${prefix}Removed Glasstrace entries from .gitignore`);
|
|
785
1160
|
}
|
|
@@ -792,63 +1167,63 @@ async function runUninit(options) {
|
|
|
792
1167
|
}
|
|
793
1168
|
try {
|
|
794
1169
|
for (const configFile of MCP_CONFIG_FILES) {
|
|
795
|
-
const configPath =
|
|
796
|
-
if (!
|
|
1170
|
+
const configPath = path3.join(projectRoot, configFile);
|
|
1171
|
+
if (!fs3.existsSync(configPath)) {
|
|
797
1172
|
continue;
|
|
798
1173
|
}
|
|
799
|
-
const content =
|
|
1174
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
800
1175
|
const result = processJsonMcpConfig(content);
|
|
801
1176
|
if (result.action === "deleted") {
|
|
802
1177
|
if (!dryRun) {
|
|
803
|
-
|
|
1178
|
+
fs3.unlinkSync(configPath);
|
|
804
1179
|
}
|
|
805
1180
|
summary.push(`${prefix}Deleted ${configFile}`);
|
|
806
1181
|
} else if (result.action === "removed-key" && result.content !== void 0) {
|
|
807
1182
|
if (!dryRun) {
|
|
808
|
-
|
|
1183
|
+
fs3.writeFileSync(configPath, result.content, "utf-8");
|
|
809
1184
|
}
|
|
810
1185
|
summary.push(`${prefix}Removed glasstrace from ${configFile}`);
|
|
811
1186
|
}
|
|
812
1187
|
}
|
|
813
|
-
const codexConfigPath =
|
|
814
|
-
if (
|
|
815
|
-
const content =
|
|
1188
|
+
const codexConfigPath = path3.join(projectRoot, ".codex", "config.toml");
|
|
1189
|
+
if (fs3.existsSync(codexConfigPath)) {
|
|
1190
|
+
const content = fs3.readFileSync(codexConfigPath, "utf-8");
|
|
816
1191
|
const tomlResult = processTomlMcpConfig(content);
|
|
817
1192
|
if (tomlResult.action === "deleted") {
|
|
818
1193
|
if (!dryRun) {
|
|
819
|
-
|
|
1194
|
+
fs3.unlinkSync(codexConfigPath);
|
|
820
1195
|
}
|
|
821
1196
|
summary.push(`${prefix}Deleted .codex/config.toml`);
|
|
822
1197
|
} else if (tomlResult.action === "removed-section" && tomlResult.content !== void 0) {
|
|
823
1198
|
if (!dryRun) {
|
|
824
|
-
|
|
1199
|
+
fs3.writeFileSync(codexConfigPath, tomlResult.content, "utf-8");
|
|
825
1200
|
}
|
|
826
1201
|
summary.push(`${prefix}Removed glasstrace from .codex/config.toml`);
|
|
827
1202
|
}
|
|
828
1203
|
}
|
|
829
|
-
const hasWindsurfMarkers =
|
|
1204
|
+
const hasWindsurfMarkers = fs3.existsSync(path3.join(projectRoot, ".windsurfrules")) || fs3.existsSync(path3.join(projectRoot, ".windsurf"));
|
|
830
1205
|
if (hasWindsurfMarkers) {
|
|
831
|
-
const windsurfConfigPath =
|
|
1206
|
+
const windsurfConfigPath = path3.join(
|
|
832
1207
|
os.homedir(),
|
|
833
1208
|
".codeium",
|
|
834
1209
|
"windsurf",
|
|
835
1210
|
"mcp_config.json"
|
|
836
1211
|
);
|
|
837
|
-
if (
|
|
838
|
-
const content =
|
|
1212
|
+
if (fs3.existsSync(windsurfConfigPath)) {
|
|
1213
|
+
const content = fs3.readFileSync(windsurfConfigPath, "utf-8");
|
|
839
1214
|
const windsurfResult = processJsonMcpConfig(content);
|
|
840
1215
|
const home = os.homedir();
|
|
841
1216
|
const displayPath = windsurfConfigPath.startsWith(home) ? "~" + windsurfConfigPath.slice(home.length) : windsurfConfigPath;
|
|
842
1217
|
if (windsurfResult.action === "deleted") {
|
|
843
1218
|
if (!dryRun) {
|
|
844
|
-
|
|
1219
|
+
fs3.unlinkSync(windsurfConfigPath);
|
|
845
1220
|
}
|
|
846
1221
|
summary.push(
|
|
847
1222
|
`${prefix}Deleted global Windsurf config (${displayPath})`
|
|
848
1223
|
);
|
|
849
1224
|
} else if (windsurfResult.action === "removed-key" && windsurfResult.content !== void 0) {
|
|
850
1225
|
if (!dryRun) {
|
|
851
|
-
|
|
1226
|
+
fs3.writeFileSync(windsurfConfigPath, windsurfResult.content, "utf-8");
|
|
852
1227
|
}
|
|
853
1228
|
summary.push(
|
|
854
1229
|
`${prefix}Removed glasstrace from global Windsurf config (${displayPath})`
|
|
@@ -863,21 +1238,21 @@ async function runUninit(options) {
|
|
|
863
1238
|
}
|
|
864
1239
|
try {
|
|
865
1240
|
for (const infoFile of AGENT_INFO_FILES) {
|
|
866
|
-
const filePath =
|
|
867
|
-
if (!
|
|
1241
|
+
const filePath = path3.join(projectRoot, infoFile);
|
|
1242
|
+
if (!fs3.existsSync(filePath)) {
|
|
868
1243
|
continue;
|
|
869
1244
|
}
|
|
870
|
-
const content =
|
|
1245
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
871
1246
|
const result = removeMarkerSection(content);
|
|
872
1247
|
if (result.removed) {
|
|
873
1248
|
if (result.content.trim().length === 0) {
|
|
874
1249
|
if (!dryRun) {
|
|
875
|
-
|
|
1250
|
+
fs3.unlinkSync(filePath);
|
|
876
1251
|
}
|
|
877
1252
|
summary.push(`${prefix}Deleted ${infoFile} (only contained Glasstrace section)`);
|
|
878
1253
|
} else {
|
|
879
1254
|
if (!dryRun) {
|
|
880
|
-
|
|
1255
|
+
fs3.writeFileSync(filePath, result.content, "utf-8");
|
|
881
1256
|
}
|
|
882
1257
|
summary.push(`${prefix}Removed Glasstrace section from ${infoFile}`);
|
|
883
1258
|
}
|
|
@@ -895,6 +1270,12 @@ async function runUninit(options) {
|
|
|
895
1270
|
}
|
|
896
1271
|
|
|
897
1272
|
export {
|
|
1273
|
+
resolveInstrumentationTarget,
|
|
1274
|
+
scaffoldInstrumentation,
|
|
1275
|
+
scaffoldNextConfig,
|
|
1276
|
+
scaffoldEnvLocal,
|
|
1277
|
+
addCoverageMapEnv,
|
|
1278
|
+
scaffoldGitignore,
|
|
898
1279
|
resolveStaticRoot,
|
|
899
1280
|
relativeDiscoveryPath,
|
|
900
1281
|
writeDiscoveryFile,
|
|
@@ -913,4 +1294,4 @@ export {
|
|
|
913
1294
|
writeShutdownMarker,
|
|
914
1295
|
runUninit
|
|
915
1296
|
};
|
|
916
|
-
//# sourceMappingURL=chunk-
|
|
1297
|
+
//# sourceMappingURL=chunk-ZRDQ6ZKI.js.map
|