@glasstrace/sdk 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/dist/{chunk-XNDHQN4S.js → chunk-6JRI4OGB.js} +286 -54
- package/dist/chunk-6JRI4OGB.js.map +1 -0
- package/dist/cli/init.cjs +481 -152
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +48 -2
- package/dist/cli/init.d.ts +48 -2
- package/dist/cli/init.js +104 -4
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/mcp-add.js +1 -1
- package/dist/cli/uninit.cjs +172 -54
- package/dist/cli/uninit.cjs.map +1 -1
- package/dist/cli/uninit.d.cts +2 -0
- package/dist/cli/uninit.d.ts +2 -0
- package/dist/cli/uninit.js +2 -1
- package/dist/index.cjs +13 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-XNDHQN4S.js.map +0 -1
package/README.md
CHANGED
|
@@ -155,6 +155,85 @@ GLASSTRACE_SUPPRESS_ACTION_NUDGE=1
|
|
|
155
155
|
The nudge never fires in production (detected via `NODE_ENV` or
|
|
156
156
|
`VERCEL_ENV`) unless `GLASSTRACE_FORCE_ENABLE=true` is also set.
|
|
157
157
|
|
|
158
|
+
## Browser-extension discovery
|
|
159
|
+
|
|
160
|
+
`glasstrace init` writes a small static file at
|
|
161
|
+
`public/.well-known/glasstrace.json` (or `static/.well-known/glasstrace.json`
|
|
162
|
+
on SvelteKit) so the Glasstrace browser extension can discover your
|
|
163
|
+
project's anonymous key without a runtime HTTP handler. The file
|
|
164
|
+
contains only a schema version and the project's anonymous key — it
|
|
165
|
+
is public metadata, not a secret, and should be committed to source
|
|
166
|
+
control alongside the rest of your project.
|
|
167
|
+
|
|
168
|
+
The SDK no longer requires `createDiscoveryHandler` to be wired into
|
|
169
|
+
your server. If you previously registered the handler (for example,
|
|
170
|
+
inside `middleware.ts` or `proxy.ts` on Next.js), you can remove the
|
|
171
|
+
handler code and the extension will read the static file instead.
|
|
172
|
+
|
|
173
|
+
### Migration: removing the runtime discovery handler
|
|
174
|
+
|
|
175
|
+
**Next.js 15 and earlier (`middleware.ts`):**
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
// Before: middleware.ts
|
|
179
|
+
import { createDiscoveryHandler } from "@glasstrace/sdk";
|
|
180
|
+
import { NextResponse } from "next/server";
|
|
181
|
+
|
|
182
|
+
const discoveryHandler = createDiscoveryHandler(/* getAnonKey */, /* getSessionId */);
|
|
183
|
+
|
|
184
|
+
export async function middleware(req: Request) {
|
|
185
|
+
const response = await discoveryHandler(req);
|
|
186
|
+
if (response !== null) return response;
|
|
187
|
+
return NextResponse.next();
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
// After: middleware.ts (only the non-Glasstrace logic remains)
|
|
193
|
+
import { NextResponse } from "next/server";
|
|
194
|
+
|
|
195
|
+
export function middleware(_req: Request) {
|
|
196
|
+
return NextResponse.next();
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Next.js 16 and later (`proxy.ts`):**
|
|
201
|
+
|
|
202
|
+
Next.js 16 replaces `middleware.ts` with `proxy.ts`. If your project
|
|
203
|
+
invoked the discovery handler from `middleware.ts`, migrate it to the
|
|
204
|
+
new file convention and drop the handler in the same edit:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
// Before: proxy.ts (Next 16+)
|
|
208
|
+
import { createDiscoveryHandler } from "@glasstrace/sdk";
|
|
209
|
+
import { NextResponse } from "next/server";
|
|
210
|
+
|
|
211
|
+
const discoveryHandler = createDiscoveryHandler(/* getAnonKey */, /* getSessionId */);
|
|
212
|
+
|
|
213
|
+
export async function proxy(req: Request) {
|
|
214
|
+
const response = await discoveryHandler(req);
|
|
215
|
+
if (response !== null) return response;
|
|
216
|
+
return NextResponse.next();
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
// After: proxy.ts (Next 16+)
|
|
222
|
+
import { NextResponse } from "next/server";
|
|
223
|
+
|
|
224
|
+
export function proxy(_req: Request) {
|
|
225
|
+
return NextResponse.next();
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
If `proxy.ts` no longer does anything else, you can delete it entirely.
|
|
230
|
+
|
|
231
|
+
`createDiscoveryHandler` remains available for one more major version
|
|
232
|
+
to avoid breaking integrations that depend on it, but it now prints a
|
|
233
|
+
one-time deprecation warning on first use and will be removed in
|
|
234
|
+
`v1.0.0`. Run `npx glasstrace init` after upgrading to generate the
|
|
235
|
+
static file.
|
|
236
|
+
|
|
158
237
|
## Security
|
|
159
238
|
|
|
160
239
|
The SDK transmits your API key exclusively via the `Authorization: Bearer`
|
|
@@ -2,14 +2,213 @@ import {
|
|
|
2
2
|
isDevApiKey,
|
|
3
3
|
readEnvLocalApiKey
|
|
4
4
|
} from "./chunk-O63DJKIJ.js";
|
|
5
|
+
import {
|
|
6
|
+
AnonApiKeySchema
|
|
7
|
+
} from "./chunk-5N2IR4EO.js";
|
|
5
8
|
import {
|
|
6
9
|
NEXT_CONFIG_NAMES
|
|
7
10
|
} from "./chunk-DXRZKKSO.js";
|
|
8
11
|
|
|
9
12
|
// src/cli/uninit.ts
|
|
10
|
-
import * as
|
|
13
|
+
import * as fs2 from "node:fs";
|
|
11
14
|
import * as os from "node:os";
|
|
15
|
+
import * as path2 from "node:path";
|
|
16
|
+
|
|
17
|
+
// src/cli/discovery-file.ts
|
|
18
|
+
import * as fs from "node:fs";
|
|
12
19
|
import * as path from "node:path";
|
|
20
|
+
var DISCOVERY_FILE_VERSION = 1;
|
|
21
|
+
function resolveStaticRoot(projectRoot) {
|
|
22
|
+
if (isSvelteKitProject(projectRoot)) {
|
|
23
|
+
return {
|
|
24
|
+
absolutePath: path.join(projectRoot, "static"),
|
|
25
|
+
layout: "static"
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
absolutePath: path.join(projectRoot, "public"),
|
|
30
|
+
layout: "public"
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function isSvelteKitProject(projectRoot) {
|
|
34
|
+
const pkgPath = path.join(projectRoot, "package.json");
|
|
35
|
+
let isEsm = false;
|
|
36
|
+
try {
|
|
37
|
+
const pkgContent = fs.readFileSync(pkgPath, "utf-8");
|
|
38
|
+
const parsed = JSON.parse(pkgContent);
|
|
39
|
+
isEsm = parsed.type === "module";
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (!isEsm) return false;
|
|
44
|
+
const svelteConfigJs = path.join(projectRoot, "svelte.config.js");
|
|
45
|
+
const svelteConfigTs = path.join(projectRoot, "svelte.config.ts");
|
|
46
|
+
const appHtml = path.join(projectRoot, "src", "app.html");
|
|
47
|
+
return fs.existsSync(svelteConfigJs) || fs.existsSync(svelteConfigTs) || fs.existsSync(appHtml);
|
|
48
|
+
}
|
|
49
|
+
function relativeDiscoveryPath(layout) {
|
|
50
|
+
return layout === "static" ? "static/.well-known/glasstrace.json" : "public/.well-known/glasstrace.json";
|
|
51
|
+
}
|
|
52
|
+
function readExistingDiscoveryFile(filePath) {
|
|
53
|
+
let raw;
|
|
54
|
+
try {
|
|
55
|
+
raw = fs.readFileSync(filePath, "utf-8");
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = JSON.parse(raw);
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const obj = parsed;
|
|
69
|
+
const versionRaw = obj.version;
|
|
70
|
+
if (typeof versionRaw !== "number" || !Number.isInteger(versionRaw) || versionRaw < 1) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const keyResult = AnonApiKeySchema.safeParse(obj.key);
|
|
74
|
+
if (!keyResult.success) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const extras = {};
|
|
78
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
79
|
+
if (k === "version" || k === "key") continue;
|
|
80
|
+
extras[k] = v;
|
|
81
|
+
}
|
|
82
|
+
return { key: keyResult.data, extras };
|
|
83
|
+
}
|
|
84
|
+
function serializeDiscoveryPayload(key, extras) {
|
|
85
|
+
const payload = {
|
|
86
|
+
version: DISCOVERY_FILE_VERSION,
|
|
87
|
+
key,
|
|
88
|
+
...extras
|
|
89
|
+
};
|
|
90
|
+
return JSON.stringify(payload, null, 2) + "\n";
|
|
91
|
+
}
|
|
92
|
+
function writeDiscoveryFile(projectRoot, anonKey) {
|
|
93
|
+
const { absolutePath: staticRoot, layout } = resolveStaticRoot(projectRoot);
|
|
94
|
+
const wellKnownDir = path.join(staticRoot, ".well-known");
|
|
95
|
+
const filePath = path.join(wellKnownDir, "glasstrace.json");
|
|
96
|
+
let existingAction;
|
|
97
|
+
let extras = {};
|
|
98
|
+
if (fs.existsSync(filePath)) {
|
|
99
|
+
const existing = readExistingDiscoveryFile(filePath);
|
|
100
|
+
if (existing === null) {
|
|
101
|
+
existingAction = "skipped-foreign";
|
|
102
|
+
} else if (existing.key === anonKey) {
|
|
103
|
+
return {
|
|
104
|
+
action: "skipped-matches",
|
|
105
|
+
filePath,
|
|
106
|
+
layout
|
|
107
|
+
};
|
|
108
|
+
} else {
|
|
109
|
+
extras = existing.extras;
|
|
110
|
+
existingAction = "updated-stale";
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
existingAction = "created";
|
|
114
|
+
}
|
|
115
|
+
const tmpPath = `${filePath}.tmp-${process.pid}`;
|
|
116
|
+
const needsWindowsReplace = process.platform === "win32" && fs.existsSync(filePath);
|
|
117
|
+
const backupPath = needsWindowsReplace ? `${filePath}.bak-${process.pid}` : null;
|
|
118
|
+
try {
|
|
119
|
+
fs.mkdirSync(wellKnownDir, { recursive: true });
|
|
120
|
+
const payload = serializeDiscoveryPayload(anonKey, extras);
|
|
121
|
+
fs.writeFileSync(tmpPath, payload, { encoding: "utf-8" });
|
|
122
|
+
if (backupPath !== null) {
|
|
123
|
+
fs.renameSync(filePath, backupPath);
|
|
124
|
+
try {
|
|
125
|
+
fs.renameSync(tmpPath, filePath);
|
|
126
|
+
} catch (renameErr) {
|
|
127
|
+
try {
|
|
128
|
+
fs.renameSync(backupPath, filePath);
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
throw renameErr;
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
fs.unlinkSync(backupPath);
|
|
135
|
+
} catch {
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
fs.renameSync(tmpPath, filePath);
|
|
139
|
+
}
|
|
140
|
+
return { action: existingAction, filePath, layout };
|
|
141
|
+
} catch (err) {
|
|
142
|
+
try {
|
|
143
|
+
if (fs.existsSync(tmpPath)) {
|
|
144
|
+
fs.unlinkSync(tmpPath);
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
action: "failed",
|
|
150
|
+
filePath,
|
|
151
|
+
layout,
|
|
152
|
+
error: err instanceof Error ? err.message : String(err)
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function removeDiscoveryFile(projectRoot) {
|
|
157
|
+
const { layout: inferredLayout } = resolveStaticRoot(projectRoot);
|
|
158
|
+
const layouts = ["public", "static"];
|
|
159
|
+
const outcomes = [];
|
|
160
|
+
for (const layout of layouts) {
|
|
161
|
+
const staticRoot = path.join(projectRoot, layout);
|
|
162
|
+
const wellKnownDir = path.join(staticRoot, ".well-known");
|
|
163
|
+
const filePath = path.join(wellKnownDir, "glasstrace.json");
|
|
164
|
+
let removed = false;
|
|
165
|
+
try {
|
|
166
|
+
if (fs.existsSync(filePath)) {
|
|
167
|
+
fs.unlinkSync(filePath);
|
|
168
|
+
removed = true;
|
|
169
|
+
}
|
|
170
|
+
} catch (err) {
|
|
171
|
+
return {
|
|
172
|
+
action: "failed",
|
|
173
|
+
filePath,
|
|
174
|
+
layout,
|
|
175
|
+
directoryRemoved: false,
|
|
176
|
+
error: err instanceof Error ? err.message : String(err)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
let directoryRemoved = false;
|
|
180
|
+
if (removed) {
|
|
181
|
+
try {
|
|
182
|
+
if (fs.existsSync(wellKnownDir)) {
|
|
183
|
+
const entries = fs.readdirSync(wellKnownDir);
|
|
184
|
+
if (entries.length === 0) {
|
|
185
|
+
fs.rmdirSync(wellKnownDir);
|
|
186
|
+
directoryRemoved = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
} catch {
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
outcomes.push({ layout, filePath, removed, directoryRemoved });
|
|
193
|
+
}
|
|
194
|
+
const removals = outcomes.filter((o) => o.removed);
|
|
195
|
+
const chosen = (() => {
|
|
196
|
+
if (removals.length === 0) {
|
|
197
|
+
return outcomes.find((o) => o.layout === inferredLayout) ?? outcomes[0];
|
|
198
|
+
}
|
|
199
|
+
if (removals.length === 1) return removals[0];
|
|
200
|
+
return removals.find((o) => o.layout === inferredLayout) ?? removals[0];
|
|
201
|
+
})();
|
|
202
|
+
const anyDirectoryRemoved = outcomes.some((o) => o.directoryRemoved);
|
|
203
|
+
return {
|
|
204
|
+
action: removals.length > 0 ? "removed" : "not-found",
|
|
205
|
+
filePath: chosen.filePath,
|
|
206
|
+
layout: chosen.layout,
|
|
207
|
+
directoryRemoved: chosen.directoryRemoved || anyDirectoryRemoved
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/cli/uninit.ts
|
|
13
212
|
var MCP_CONFIG_FILES = [".mcp.json", ".cursor/mcp.json", ".gemini/settings.json"];
|
|
14
213
|
var AGENT_INFO_FILES = [
|
|
15
214
|
"CLAUDE.md",
|
|
@@ -316,24 +515,24 @@ function processTomlMcpConfig(content) {
|
|
|
316
515
|
return { action: "removed-section", content: result + "\n" };
|
|
317
516
|
}
|
|
318
517
|
function writeShutdownMarker(projectRoot) {
|
|
319
|
-
const dirPath =
|
|
320
|
-
if (!
|
|
518
|
+
const dirPath = path2.join(projectRoot, ".glasstrace");
|
|
519
|
+
if (!fs2.existsSync(dirPath)) {
|
|
321
520
|
return false;
|
|
322
521
|
}
|
|
323
|
-
const markerPath =
|
|
522
|
+
const markerPath = path2.join(dirPath, "shutdown-requested");
|
|
324
523
|
const tmpPath = `${markerPath}.tmp`;
|
|
325
524
|
const body = JSON.stringify({ requestedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
326
525
|
try {
|
|
327
|
-
|
|
526
|
+
fs2.writeFileSync(tmpPath, body, { encoding: "utf-8", mode: 384 });
|
|
328
527
|
try {
|
|
329
|
-
|
|
528
|
+
fs2.chmodSync(tmpPath, 384);
|
|
330
529
|
} catch {
|
|
331
530
|
}
|
|
332
|
-
|
|
531
|
+
fs2.renameSync(tmpPath, markerPath);
|
|
333
532
|
return true;
|
|
334
533
|
} catch {
|
|
335
534
|
try {
|
|
336
|
-
|
|
535
|
+
fs2.unlinkSync(tmpPath);
|
|
337
536
|
} catch {
|
|
338
537
|
}
|
|
339
538
|
return false;
|
|
@@ -374,8 +573,8 @@ async function runUninit(options) {
|
|
|
374
573
|
summary.push("Wrote .glasstrace/shutdown-requested marker");
|
|
375
574
|
}
|
|
376
575
|
} else {
|
|
377
|
-
const dirPath =
|
|
378
|
-
if (
|
|
576
|
+
const dirPath = path2.join(projectRoot, ".glasstrace");
|
|
577
|
+
if (fs2.existsSync(dirPath)) {
|
|
379
578
|
summary.push(`${prefix}Would write .glasstrace/shutdown-requested marker`);
|
|
380
579
|
}
|
|
381
580
|
}
|
|
@@ -387,11 +586,11 @@ async function runUninit(options) {
|
|
|
387
586
|
try {
|
|
388
587
|
let configHandled = false;
|
|
389
588
|
for (const name of NEXT_CONFIG_NAMES) {
|
|
390
|
-
const configPath =
|
|
391
|
-
if (!
|
|
589
|
+
const configPath = path2.join(projectRoot, name);
|
|
590
|
+
if (!fs2.existsSync(configPath)) {
|
|
392
591
|
continue;
|
|
393
592
|
}
|
|
394
|
-
const content =
|
|
593
|
+
const content = fs2.readFileSync(configPath, "utf-8");
|
|
395
594
|
if (!content.includes("withGlasstraceConfig")) {
|
|
396
595
|
continue;
|
|
397
596
|
}
|
|
@@ -401,7 +600,7 @@ async function runUninit(options) {
|
|
|
401
600
|
const cleaned = removeGlasstraceConfigImport(unwrapResult.content);
|
|
402
601
|
const final = cleanLeadingBlankLines(cleaned);
|
|
403
602
|
if (!dryRun) {
|
|
404
|
-
|
|
603
|
+
fs2.writeFileSync(configPath, final, "utf-8");
|
|
405
604
|
}
|
|
406
605
|
summary.push(`${prefix}Unwrapped withGlasstraceConfig from ${name}`);
|
|
407
606
|
configHandled = true;
|
|
@@ -422,20 +621,20 @@ async function runUninit(options) {
|
|
|
422
621
|
);
|
|
423
622
|
}
|
|
424
623
|
try {
|
|
425
|
-
const instrPath =
|
|
426
|
-
if (
|
|
427
|
-
const content =
|
|
624
|
+
const instrPath = path2.join(projectRoot, "instrumentation.ts");
|
|
625
|
+
if (fs2.existsSync(instrPath)) {
|
|
626
|
+
const content = fs2.readFileSync(instrPath, "utf-8");
|
|
428
627
|
if (content.includes("registerGlasstrace") || content.includes("@glasstrace/sdk")) {
|
|
429
628
|
if (isInitCreatedInstrumentation(content)) {
|
|
430
629
|
if (!dryRun) {
|
|
431
|
-
|
|
630
|
+
fs2.unlinkSync(instrPath);
|
|
432
631
|
}
|
|
433
632
|
summary.push(`${prefix}Deleted instrumentation.ts (init-created)`);
|
|
434
633
|
} else {
|
|
435
634
|
const cleaned = removeRegisterGlasstrace(content);
|
|
436
635
|
if (cleaned !== content) {
|
|
437
636
|
if (!dryRun) {
|
|
438
|
-
|
|
637
|
+
fs2.writeFileSync(instrPath, cleaned, "utf-8");
|
|
439
638
|
}
|
|
440
639
|
summary.push(
|
|
441
640
|
`${prefix}Removed registerGlasstrace() from instrumentation.ts`
|
|
@@ -450,10 +649,10 @@ async function runUninit(options) {
|
|
|
450
649
|
);
|
|
451
650
|
}
|
|
452
651
|
try {
|
|
453
|
-
const glasstraceDir =
|
|
454
|
-
if (
|
|
652
|
+
const glasstraceDir = path2.join(projectRoot, ".glasstrace");
|
|
653
|
+
if (fs2.existsSync(glasstraceDir)) {
|
|
455
654
|
if (!dryRun) {
|
|
456
|
-
|
|
655
|
+
fs2.rmSync(glasstraceDir, { recursive: true, force: true });
|
|
457
656
|
}
|
|
458
657
|
summary.push(`${prefix}Removed .glasstrace/ directory`);
|
|
459
658
|
}
|
|
@@ -463,9 +662,38 @@ async function runUninit(options) {
|
|
|
463
662
|
);
|
|
464
663
|
}
|
|
465
664
|
try {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
665
|
+
if (dryRun) {
|
|
666
|
+
for (const previewLayout of ["public", "static"]) {
|
|
667
|
+
const relPath = relativeDiscoveryPath(previewLayout);
|
|
668
|
+
const absPath = path2.join(projectRoot, relPath);
|
|
669
|
+
if (fs2.existsSync(absPath)) {
|
|
670
|
+
summary.push(`${prefix}Would remove ${relPath}`);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
} else {
|
|
674
|
+
const result = removeDiscoveryFile(projectRoot);
|
|
675
|
+
if (result.action === "removed") {
|
|
676
|
+
const relPath = relativeDiscoveryPath(result.layout);
|
|
677
|
+
summary.push(`Removed ${relPath}`);
|
|
678
|
+
if (result.directoryRemoved) {
|
|
679
|
+
const dirRel = relPath.replace(/\/glasstrace\.json$/, "/");
|
|
680
|
+
summary.push(`Removed empty ${dirRel}`);
|
|
681
|
+
}
|
|
682
|
+
} else if (result.action === "failed") {
|
|
683
|
+
warnings.push(
|
|
684
|
+
`Failed to remove ${relativeDiscoveryPath(result.layout)}${result.error !== void 0 ? `: ${result.error}` : ""}`
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
} catch (err) {
|
|
689
|
+
warnings.push(
|
|
690
|
+
`Failed to remove discovery file: ${err instanceof Error ? err.message : String(err)}`
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
try {
|
|
694
|
+
const envPath = path2.join(projectRoot, ".env.local");
|
|
695
|
+
if (fs2.existsSync(envPath)) {
|
|
696
|
+
const content = fs2.readFileSync(envPath, "utf-8");
|
|
469
697
|
const existingKey = readEnvLocalApiKey(content);
|
|
470
698
|
const hasDevKey = isDevApiKey(existingKey);
|
|
471
699
|
let proceed = true;
|
|
@@ -498,12 +726,12 @@ async function runUninit(options) {
|
|
|
498
726
|
const result = filtered.join("\n");
|
|
499
727
|
if (result.trim().length === 0) {
|
|
500
728
|
if (!dryRun) {
|
|
501
|
-
|
|
729
|
+
fs2.unlinkSync(envPath);
|
|
502
730
|
}
|
|
503
731
|
summary.push(`${prefix}Deleted .env.local (no remaining entries)`);
|
|
504
732
|
} else {
|
|
505
733
|
if (!dryRun) {
|
|
506
|
-
|
|
734
|
+
fs2.writeFileSync(envPath, result, "utf-8");
|
|
507
735
|
}
|
|
508
736
|
let devKeyAnnotation = "";
|
|
509
737
|
if (devKeyPath === "interactive-confirmed") {
|
|
@@ -526,9 +754,9 @@ async function runUninit(options) {
|
|
|
526
754
|
);
|
|
527
755
|
}
|
|
528
756
|
try {
|
|
529
|
-
const gitignorePath =
|
|
530
|
-
if (
|
|
531
|
-
const content =
|
|
757
|
+
const gitignorePath = path2.join(projectRoot, ".gitignore");
|
|
758
|
+
if (fs2.existsSync(gitignorePath)) {
|
|
759
|
+
const content = fs2.readFileSync(gitignorePath, "utf-8");
|
|
532
760
|
const lines = content.split("\n");
|
|
533
761
|
const mcpGitignoreEntries = /* @__PURE__ */ new Set([
|
|
534
762
|
".glasstrace/",
|
|
@@ -544,12 +772,12 @@ async function runUninit(options) {
|
|
|
544
772
|
const result = filtered.join("\n");
|
|
545
773
|
if (result.trim().length === 0) {
|
|
546
774
|
if (!dryRun) {
|
|
547
|
-
|
|
775
|
+
fs2.unlinkSync(gitignorePath);
|
|
548
776
|
}
|
|
549
777
|
summary.push(`${prefix}Deleted .gitignore (no remaining entries)`);
|
|
550
778
|
} else {
|
|
551
779
|
if (!dryRun) {
|
|
552
|
-
|
|
780
|
+
fs2.writeFileSync(gitignorePath, result, "utf-8");
|
|
553
781
|
}
|
|
554
782
|
summary.push(`${prefix}Removed Glasstrace entries from .gitignore`);
|
|
555
783
|
}
|
|
@@ -562,63 +790,63 @@ async function runUninit(options) {
|
|
|
562
790
|
}
|
|
563
791
|
try {
|
|
564
792
|
for (const configFile of MCP_CONFIG_FILES) {
|
|
565
|
-
const configPath =
|
|
566
|
-
if (!
|
|
793
|
+
const configPath = path2.join(projectRoot, configFile);
|
|
794
|
+
if (!fs2.existsSync(configPath)) {
|
|
567
795
|
continue;
|
|
568
796
|
}
|
|
569
|
-
const content =
|
|
797
|
+
const content = fs2.readFileSync(configPath, "utf-8");
|
|
570
798
|
const result = processJsonMcpConfig(content);
|
|
571
799
|
if (result.action === "deleted") {
|
|
572
800
|
if (!dryRun) {
|
|
573
|
-
|
|
801
|
+
fs2.unlinkSync(configPath);
|
|
574
802
|
}
|
|
575
803
|
summary.push(`${prefix}Deleted ${configFile}`);
|
|
576
804
|
} else if (result.action === "removed-key" && result.content !== void 0) {
|
|
577
805
|
if (!dryRun) {
|
|
578
|
-
|
|
806
|
+
fs2.writeFileSync(configPath, result.content, "utf-8");
|
|
579
807
|
}
|
|
580
808
|
summary.push(`${prefix}Removed glasstrace from ${configFile}`);
|
|
581
809
|
}
|
|
582
810
|
}
|
|
583
|
-
const codexConfigPath =
|
|
584
|
-
if (
|
|
585
|
-
const content =
|
|
811
|
+
const codexConfigPath = path2.join(projectRoot, ".codex", "config.toml");
|
|
812
|
+
if (fs2.existsSync(codexConfigPath)) {
|
|
813
|
+
const content = fs2.readFileSync(codexConfigPath, "utf-8");
|
|
586
814
|
const tomlResult = processTomlMcpConfig(content);
|
|
587
815
|
if (tomlResult.action === "deleted") {
|
|
588
816
|
if (!dryRun) {
|
|
589
|
-
|
|
817
|
+
fs2.unlinkSync(codexConfigPath);
|
|
590
818
|
}
|
|
591
819
|
summary.push(`${prefix}Deleted .codex/config.toml`);
|
|
592
820
|
} else if (tomlResult.action === "removed-section" && tomlResult.content !== void 0) {
|
|
593
821
|
if (!dryRun) {
|
|
594
|
-
|
|
822
|
+
fs2.writeFileSync(codexConfigPath, tomlResult.content, "utf-8");
|
|
595
823
|
}
|
|
596
824
|
summary.push(`${prefix}Removed glasstrace from .codex/config.toml`);
|
|
597
825
|
}
|
|
598
826
|
}
|
|
599
|
-
const hasWindsurfMarkers =
|
|
827
|
+
const hasWindsurfMarkers = fs2.existsSync(path2.join(projectRoot, ".windsurfrules")) || fs2.existsSync(path2.join(projectRoot, ".windsurf"));
|
|
600
828
|
if (hasWindsurfMarkers) {
|
|
601
|
-
const windsurfConfigPath =
|
|
829
|
+
const windsurfConfigPath = path2.join(
|
|
602
830
|
os.homedir(),
|
|
603
831
|
".codeium",
|
|
604
832
|
"windsurf",
|
|
605
833
|
"mcp_config.json"
|
|
606
834
|
);
|
|
607
|
-
if (
|
|
608
|
-
const content =
|
|
835
|
+
if (fs2.existsSync(windsurfConfigPath)) {
|
|
836
|
+
const content = fs2.readFileSync(windsurfConfigPath, "utf-8");
|
|
609
837
|
const windsurfResult = processJsonMcpConfig(content);
|
|
610
838
|
const home = os.homedir();
|
|
611
839
|
const displayPath = windsurfConfigPath.startsWith(home) ? "~" + windsurfConfigPath.slice(home.length) : windsurfConfigPath;
|
|
612
840
|
if (windsurfResult.action === "deleted") {
|
|
613
841
|
if (!dryRun) {
|
|
614
|
-
|
|
842
|
+
fs2.unlinkSync(windsurfConfigPath);
|
|
615
843
|
}
|
|
616
844
|
summary.push(
|
|
617
845
|
`${prefix}Deleted global Windsurf config (${displayPath})`
|
|
618
846
|
);
|
|
619
847
|
} else if (windsurfResult.action === "removed-key" && windsurfResult.content !== void 0) {
|
|
620
848
|
if (!dryRun) {
|
|
621
|
-
|
|
849
|
+
fs2.writeFileSync(windsurfConfigPath, windsurfResult.content, "utf-8");
|
|
622
850
|
}
|
|
623
851
|
summary.push(
|
|
624
852
|
`${prefix}Removed glasstrace from global Windsurf config (${displayPath})`
|
|
@@ -633,21 +861,21 @@ async function runUninit(options) {
|
|
|
633
861
|
}
|
|
634
862
|
try {
|
|
635
863
|
for (const infoFile of AGENT_INFO_FILES) {
|
|
636
|
-
const filePath =
|
|
637
|
-
if (!
|
|
864
|
+
const filePath = path2.join(projectRoot, infoFile);
|
|
865
|
+
if (!fs2.existsSync(filePath)) {
|
|
638
866
|
continue;
|
|
639
867
|
}
|
|
640
|
-
const content =
|
|
868
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
641
869
|
const result = removeMarkerSection(content);
|
|
642
870
|
if (result.removed) {
|
|
643
871
|
if (result.content.trim().length === 0) {
|
|
644
872
|
if (!dryRun) {
|
|
645
|
-
|
|
873
|
+
fs2.unlinkSync(filePath);
|
|
646
874
|
}
|
|
647
875
|
summary.push(`${prefix}Deleted ${infoFile} (only contained Glasstrace section)`);
|
|
648
876
|
} else {
|
|
649
877
|
if (!dryRun) {
|
|
650
|
-
|
|
878
|
+
fs2.writeFileSync(filePath, result.content, "utf-8");
|
|
651
879
|
}
|
|
652
880
|
summary.push(`${prefix}Removed Glasstrace section from ${infoFile}`);
|
|
653
881
|
}
|
|
@@ -665,6 +893,10 @@ async function runUninit(options) {
|
|
|
665
893
|
}
|
|
666
894
|
|
|
667
895
|
export {
|
|
896
|
+
resolveStaticRoot,
|
|
897
|
+
relativeDiscoveryPath,
|
|
898
|
+
writeDiscoveryFile,
|
|
899
|
+
removeDiscoveryFile,
|
|
668
900
|
skipString,
|
|
669
901
|
findMatchingDelimiter,
|
|
670
902
|
findMatchingParen,
|
|
@@ -679,4 +911,4 @@ export {
|
|
|
679
911
|
writeShutdownMarker,
|
|
680
912
|
runUninit
|
|
681
913
|
};
|
|
682
|
-
//# sourceMappingURL=chunk-
|
|
914
|
+
//# sourceMappingURL=chunk-6JRI4OGB.js.map
|