@glasstrace/sdk 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/drizzle.js +1 -1
- package/dist/{chunk-2JUH3VGJ.js → chunk-6GRNJ722.js} +38 -17
- package/dist/chunk-6GRNJ722.js.map +1 -0
- package/dist/chunk-IPGOKORJ.js +580 -0
- package/dist/chunk-IPGOKORJ.js.map +1 -0
- package/dist/{chunk-M7RDFOFR.js → chunk-LW7DPKBA.js} +2 -2
- package/dist/{chunk-SLSWEQCC.js → chunk-MSMOH6IH.js} +108 -38
- package/dist/chunk-MSMOH6IH.js.map +1 -0
- package/dist/chunk-NSBPE2FW.js +17 -0
- package/dist/{chunk-D3JC3LAK.js → chunk-OKIP4SRG.js} +2 -2
- package/dist/cli/init.cjs +454 -329
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +25 -1
- package/dist/cli/init.d.ts +25 -1
- package/dist/cli/init.js +114 -4
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/mcp-add.cjs +60 -46
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +3 -3
- package/dist/cli/uninit.js +15 -564
- package/dist/cli/uninit.js.map +1 -1
- package/dist/{esm-POMEQPKL.js → esm-KBPHCVB4.js} +2 -2
- package/dist/{getMachineId-bsd-TC3JSTY5.js → getMachineId-bsd-345PYXFX.js} +2 -2
- package/dist/{getMachineId-darwin-2SUKQCE6.js → getMachineId-darwin-5L2D25AD.js} +2 -2
- package/dist/{getMachineId-linux-PNAFHLXH.js → getMachineId-linux-KJR4P5HN.js} +2 -2
- package/dist/{getMachineId-unsupported-L2MNYW3W.js → getMachineId-unsupported-NDNXDYDY.js} +2 -2
- package/dist/{getMachineId-win-D6D42WOQ.js → getMachineId-win-T7PJNJXG.js} +2 -2
- package/dist/index.cjs +297 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -10
- package/dist/index.d.ts +51 -10
- package/dist/index.js +133 -78
- package/dist/index.js.map +1 -1
- package/dist/{source-map-uploader-OFEM54UE.js → source-map-uploader-ZFCYOURS.js} +6 -4
- package/package.json +1 -1
- package/dist/chunk-2JUH3VGJ.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -10
- package/dist/chunk-SLSWEQCC.js.map +0 -1
- /package/dist/{chunk-M7RDFOFR.js.map → chunk-LW7DPKBA.js.map} +0 -0
- /package/dist/{chunk-PZ5AY32C.js.map → chunk-NSBPE2FW.js.map} +0 -0
- /package/dist/{chunk-D3JC3LAK.js.map → chunk-OKIP4SRG.js.map} +0 -0
- /package/dist/{esm-POMEQPKL.js.map → esm-KBPHCVB4.js.map} +0 -0
- /package/dist/{getMachineId-bsd-TC3JSTY5.js.map → getMachineId-bsd-345PYXFX.js.map} +0 -0
- /package/dist/{getMachineId-darwin-2SUKQCE6.js.map → getMachineId-darwin-5L2D25AD.js.map} +0 -0
- /package/dist/{getMachineId-linux-PNAFHLXH.js.map → getMachineId-linux-KJR4P5HN.js.map} +0 -0
- /package/dist/{getMachineId-unsupported-L2MNYW3W.js.map → getMachineId-unsupported-NDNXDYDY.js.map} +0 -0
- /package/dist/{getMachineId-win-D6D42WOQ.js.map → getMachineId-win-T7PJNJXG.js.map} +0 -0
- /package/dist/{source-map-uploader-OFEM54UE.js.map → source-map-uploader-ZFCYOURS.js.map} +0 -0
package/dist/cli/init.cjs
CHANGED
|
@@ -14845,16 +14845,33 @@ var init_dist = __esm({
|
|
|
14845
14845
|
});
|
|
14846
14846
|
|
|
14847
14847
|
// src/anon-key.ts
|
|
14848
|
+
async function loadFsPath() {
|
|
14849
|
+
if (fsPathCache !== void 0) return fsPathCache;
|
|
14850
|
+
try {
|
|
14851
|
+
const [fs7, path7] = await Promise.all([
|
|
14852
|
+
import("fs/promises"),
|
|
14853
|
+
import("path")
|
|
14854
|
+
]);
|
|
14855
|
+
fsPathCache = { fs: fs7, path: path7 };
|
|
14856
|
+
return fsPathCache;
|
|
14857
|
+
} catch {
|
|
14858
|
+
fsPathCache = null;
|
|
14859
|
+
return null;
|
|
14860
|
+
}
|
|
14861
|
+
}
|
|
14848
14862
|
async function readAnonKey(projectRoot) {
|
|
14849
14863
|
const root = projectRoot ?? process.cwd();
|
|
14850
|
-
const
|
|
14851
|
-
|
|
14852
|
-
const
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
|
|
14864
|
+
const modules = await loadFsPath();
|
|
14865
|
+
if (modules) {
|
|
14866
|
+
const keyPath = modules.path.join(root, GLASSTRACE_DIR, ANON_KEY_FILE);
|
|
14867
|
+
try {
|
|
14868
|
+
const content = await modules.fs.readFile(keyPath, "utf-8");
|
|
14869
|
+
const result = AnonApiKeySchema.safeParse(content);
|
|
14870
|
+
if (result.success) {
|
|
14871
|
+
return result.data;
|
|
14872
|
+
}
|
|
14873
|
+
} catch {
|
|
14856
14874
|
}
|
|
14857
|
-
} catch {
|
|
14858
14875
|
}
|
|
14859
14876
|
const cached2 = ephemeralKeyCache.get(root);
|
|
14860
14877
|
if (cached2 !== void 0) {
|
|
@@ -14864,8 +14881,6 @@ async function readAnonKey(projectRoot) {
|
|
|
14864
14881
|
}
|
|
14865
14882
|
async function getOrCreateAnonKey(projectRoot) {
|
|
14866
14883
|
const root = projectRoot ?? process.cwd();
|
|
14867
|
-
const dirPath = (0, import_node_path.join)(root, GLASSTRACE_DIR);
|
|
14868
|
-
const keyPath = (0, import_node_path.join)(dirPath, ANON_KEY_FILE);
|
|
14869
14884
|
const existingKey = await readAnonKey(root);
|
|
14870
14885
|
if (existingKey !== null) {
|
|
14871
14886
|
return existingKey;
|
|
@@ -14875,9 +14890,16 @@ async function getOrCreateAnonKey(projectRoot) {
|
|
|
14875
14890
|
return cached2;
|
|
14876
14891
|
}
|
|
14877
14892
|
const newKey = createAnonApiKey();
|
|
14893
|
+
const modules = await loadFsPath();
|
|
14894
|
+
if (!modules) {
|
|
14895
|
+
ephemeralKeyCache.set(root, newKey);
|
|
14896
|
+
return newKey;
|
|
14897
|
+
}
|
|
14898
|
+
const dirPath = modules.path.join(root, GLASSTRACE_DIR);
|
|
14899
|
+
const keyPath = modules.path.join(dirPath, ANON_KEY_FILE);
|
|
14878
14900
|
try {
|
|
14879
|
-
await
|
|
14880
|
-
await
|
|
14901
|
+
await modules.fs.mkdir(dirPath, { recursive: true, mode: 448 });
|
|
14902
|
+
await modules.fs.writeFile(keyPath, newKey, { flag: "wx", mode: 384 });
|
|
14881
14903
|
return newKey;
|
|
14882
14904
|
} catch (err) {
|
|
14883
14905
|
const code = err.code;
|
|
@@ -14892,8 +14914,8 @@ async function getOrCreateAnonKey(projectRoot) {
|
|
|
14892
14914
|
}
|
|
14893
14915
|
}
|
|
14894
14916
|
try {
|
|
14895
|
-
await
|
|
14896
|
-
await
|
|
14917
|
+
await modules.fs.writeFile(keyPath, newKey, { mode: 384 });
|
|
14918
|
+
await modules.fs.chmod(keyPath, 384);
|
|
14897
14919
|
return newKey;
|
|
14898
14920
|
} catch {
|
|
14899
14921
|
}
|
|
@@ -14905,12 +14927,10 @@ async function getOrCreateAnonKey(projectRoot) {
|
|
|
14905
14927
|
return newKey;
|
|
14906
14928
|
}
|
|
14907
14929
|
}
|
|
14908
|
-
var
|
|
14930
|
+
var GLASSTRACE_DIR, ANON_KEY_FILE, fsPathCache, ephemeralKeyCache;
|
|
14909
14931
|
var init_anon_key = __esm({
|
|
14910
14932
|
"src/anon-key.ts"() {
|
|
14911
14933
|
"use strict";
|
|
14912
|
-
import_promises = require("fs/promises");
|
|
14913
|
-
import_node_path = require("path");
|
|
14914
14934
|
init_dist();
|
|
14915
14935
|
GLASSTRACE_DIR = ".glasstrace";
|
|
14916
14936
|
ANON_KEY_FILE = "anon_key";
|
|
@@ -14921,25 +14941,25 @@ var init_anon_key = __esm({
|
|
|
14921
14941
|
// src/agent-detection/detect.ts
|
|
14922
14942
|
async function pathExists(path7, mode = import_node_fs.constants.R_OK) {
|
|
14923
14943
|
try {
|
|
14924
|
-
await (0,
|
|
14944
|
+
await (0, import_promises.access)(path7, mode);
|
|
14925
14945
|
return true;
|
|
14926
14946
|
} catch {
|
|
14927
14947
|
return false;
|
|
14928
14948
|
}
|
|
14929
14949
|
}
|
|
14930
14950
|
async function findGitRoot(startDir) {
|
|
14931
|
-
let current = (0,
|
|
14951
|
+
let current = (0, import_node_path.resolve)(startDir);
|
|
14932
14952
|
while (true) {
|
|
14933
|
-
if (await pathExists((0,
|
|
14953
|
+
if (await pathExists((0, import_node_path.join)(current, ".git"), import_node_fs.constants.F_OK)) {
|
|
14934
14954
|
return current;
|
|
14935
14955
|
}
|
|
14936
|
-
const parent = (0,
|
|
14956
|
+
const parent = (0, import_node_path.dirname)(current);
|
|
14937
14957
|
if (parent === current) {
|
|
14938
14958
|
break;
|
|
14939
14959
|
}
|
|
14940
14960
|
current = parent;
|
|
14941
14961
|
}
|
|
14942
|
-
return (0,
|
|
14962
|
+
return (0, import_node_path.resolve)(startDir);
|
|
14943
14963
|
}
|
|
14944
14964
|
function isCliAvailable(binary) {
|
|
14945
14965
|
return new Promise((resolve2) => {
|
|
@@ -14950,10 +14970,10 @@ function isCliAvailable(binary) {
|
|
|
14950
14970
|
});
|
|
14951
14971
|
}
|
|
14952
14972
|
async function detectAgents(projectRoot) {
|
|
14953
|
-
const resolvedRoot = (0,
|
|
14973
|
+
const resolvedRoot = (0, import_node_path.resolve)(projectRoot);
|
|
14954
14974
|
let rootStat;
|
|
14955
14975
|
try {
|
|
14956
|
-
rootStat = await (0,
|
|
14976
|
+
rootStat = await (0, import_promises.stat)(resolvedRoot);
|
|
14957
14977
|
} catch (err) {
|
|
14958
14978
|
const code = err.code;
|
|
14959
14979
|
throw new Error(
|
|
@@ -14971,7 +14991,7 @@ async function detectAgents(projectRoot) {
|
|
|
14971
14991
|
if (current === gitRoot) {
|
|
14972
14992
|
break;
|
|
14973
14993
|
}
|
|
14974
|
-
const parent = (0,
|
|
14994
|
+
const parent = (0, import_node_path.dirname)(current);
|
|
14975
14995
|
if (parent === current) {
|
|
14976
14996
|
break;
|
|
14977
14997
|
}
|
|
@@ -14984,7 +15004,7 @@ async function detectAgents(projectRoot) {
|
|
|
14984
15004
|
for (const dir of searchDirs) {
|
|
14985
15005
|
let markerFound = false;
|
|
14986
15006
|
for (const marker of rule.markers) {
|
|
14987
|
-
if (await pathExists((0,
|
|
15007
|
+
if (await pathExists((0, import_node_path.join)(dir, marker))) {
|
|
14988
15008
|
markerFound = true;
|
|
14989
15009
|
break;
|
|
14990
15010
|
}
|
|
@@ -15016,43 +15036,43 @@ async function detectAgents(projectRoot) {
|
|
|
15016
15036
|
}
|
|
15017
15037
|
detected.push({
|
|
15018
15038
|
name: "generic",
|
|
15019
|
-
mcpConfigPath: (0,
|
|
15039
|
+
mcpConfigPath: (0, import_node_path.join)(resolvedRoot, ".glasstrace", "mcp.json"),
|
|
15020
15040
|
infoFilePath: null,
|
|
15021
15041
|
cliAvailable: false,
|
|
15022
15042
|
registrationCommand: null
|
|
15023
15043
|
});
|
|
15024
15044
|
return detected;
|
|
15025
15045
|
}
|
|
15026
|
-
var import_node_child_process,
|
|
15046
|
+
var import_node_child_process, import_promises, import_node_path, import_node_os, import_node_fs, AGENT_RULES;
|
|
15027
15047
|
var init_detect = __esm({
|
|
15028
15048
|
"src/agent-detection/detect.ts"() {
|
|
15029
15049
|
"use strict";
|
|
15030
15050
|
import_node_child_process = require("child_process");
|
|
15031
|
-
|
|
15032
|
-
|
|
15051
|
+
import_promises = require("fs/promises");
|
|
15052
|
+
import_node_path = require("path");
|
|
15033
15053
|
import_node_os = require("os");
|
|
15034
15054
|
import_node_fs = require("fs");
|
|
15035
15055
|
AGENT_RULES = [
|
|
15036
15056
|
{
|
|
15037
15057
|
name: "claude",
|
|
15038
15058
|
markers: [".claude", "CLAUDE.md"],
|
|
15039
|
-
mcpConfigPath: (dir) => (0,
|
|
15040
|
-
infoFilePath: (dir) => (0,
|
|
15059
|
+
mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".mcp.json"),
|
|
15060
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, "CLAUDE.md"),
|
|
15041
15061
|
cliBinary: "claude",
|
|
15042
15062
|
registrationCommand: "npx glasstrace mcp add --agent claude"
|
|
15043
15063
|
},
|
|
15044
15064
|
{
|
|
15045
15065
|
name: "codex",
|
|
15046
15066
|
markers: ["codex.md", ".codex"],
|
|
15047
|
-
mcpConfigPath: (dir) => (0,
|
|
15048
|
-
infoFilePath: (dir) => (0,
|
|
15067
|
+
mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".codex", "config.toml"),
|
|
15068
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, "codex.md"),
|
|
15049
15069
|
cliBinary: "codex",
|
|
15050
15070
|
registrationCommand: "npx glasstrace mcp add --agent codex"
|
|
15051
15071
|
},
|
|
15052
15072
|
{
|
|
15053
15073
|
name: "gemini",
|
|
15054
15074
|
markers: [".gemini"],
|
|
15055
|
-
mcpConfigPath: (dir) => (0,
|
|
15075
|
+
mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".gemini", "settings.json"),
|
|
15056
15076
|
infoFilePath: () => null,
|
|
15057
15077
|
cliBinary: "gemini",
|
|
15058
15078
|
registrationCommand: "npx glasstrace mcp add --agent gemini"
|
|
@@ -15060,16 +15080,16 @@ var init_detect = __esm({
|
|
|
15060
15080
|
{
|
|
15061
15081
|
name: "cursor",
|
|
15062
15082
|
markers: [".cursor", ".cursorrules"],
|
|
15063
|
-
mcpConfigPath: (dir) => (0,
|
|
15064
|
-
infoFilePath: (dir) => (0,
|
|
15083
|
+
mcpConfigPath: (dir) => (0, import_node_path.join)(dir, ".cursor", "mcp.json"),
|
|
15084
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, ".cursorrules"),
|
|
15065
15085
|
cliBinary: null,
|
|
15066
15086
|
registrationCommand: "npx glasstrace mcp add --agent cursor"
|
|
15067
15087
|
},
|
|
15068
15088
|
{
|
|
15069
15089
|
name: "windsurf",
|
|
15070
15090
|
markers: [".windsurfrules", ".windsurf"],
|
|
15071
|
-
mcpConfigPath: () => (0,
|
|
15072
|
-
infoFilePath: (dir) => (0,
|
|
15091
|
+
mcpConfigPath: () => (0, import_node_path.join)((0, import_node_os.homedir)(), ".codeium", "windsurf", "mcp_config.json"),
|
|
15092
|
+
infoFilePath: (dir) => (0, import_node_path.join)(dir, ".windsurfrules"),
|
|
15073
15093
|
cliBinary: null,
|
|
15074
15094
|
registrationCommand: "npx glasstrace mcp add --agent windsurf"
|
|
15075
15095
|
}
|
|
@@ -15254,9 +15274,9 @@ async function writeMcpConfig(agent, content, projectRoot) {
|
|
|
15254
15274
|
return;
|
|
15255
15275
|
}
|
|
15256
15276
|
const configPath = agent.mcpConfigPath;
|
|
15257
|
-
const parentDir = (0,
|
|
15277
|
+
const parentDir = (0, import_node_path2.dirname)(configPath);
|
|
15258
15278
|
try {
|
|
15259
|
-
await (0,
|
|
15279
|
+
await (0, import_promises2.mkdir)(parentDir, { recursive: true });
|
|
15260
15280
|
} catch (err) {
|
|
15261
15281
|
if (isPermissionError(err)) {
|
|
15262
15282
|
process.stderr.write(
|
|
@@ -15268,7 +15288,7 @@ async function writeMcpConfig(agent, content, projectRoot) {
|
|
|
15268
15288
|
throw err;
|
|
15269
15289
|
}
|
|
15270
15290
|
try {
|
|
15271
|
-
await (0,
|
|
15291
|
+
await (0, import_promises2.writeFile)(configPath, content, { mode: 384 });
|
|
15272
15292
|
} catch (err) {
|
|
15273
15293
|
if (isPermissionError(err)) {
|
|
15274
15294
|
process.stderr.write(
|
|
@@ -15280,7 +15300,7 @@ async function writeMcpConfig(agent, content, projectRoot) {
|
|
|
15280
15300
|
throw err;
|
|
15281
15301
|
}
|
|
15282
15302
|
try {
|
|
15283
|
-
await (0,
|
|
15303
|
+
await (0, import_promises2.chmod)(configPath, 384);
|
|
15284
15304
|
} catch {
|
|
15285
15305
|
}
|
|
15286
15306
|
}
|
|
@@ -15313,7 +15333,7 @@ async function injectInfoSection(agent, content, projectRoot) {
|
|
|
15313
15333
|
const filePath = agent.infoFilePath;
|
|
15314
15334
|
let existingContent = null;
|
|
15315
15335
|
try {
|
|
15316
|
-
existingContent = await (0,
|
|
15336
|
+
existingContent = await (0, import_promises2.readFile)(filePath, "utf-8");
|
|
15317
15337
|
} catch (err) {
|
|
15318
15338
|
const code = err.code;
|
|
15319
15339
|
if (code !== "ENOENT") {
|
|
@@ -15329,8 +15349,8 @@ async function injectInfoSection(agent, content, projectRoot) {
|
|
|
15329
15349
|
}
|
|
15330
15350
|
if (existingContent === null) {
|
|
15331
15351
|
try {
|
|
15332
|
-
await (0,
|
|
15333
|
-
await (0,
|
|
15352
|
+
await (0, import_promises2.mkdir)((0, import_node_path2.dirname)(filePath), { recursive: true });
|
|
15353
|
+
await (0, import_promises2.writeFile)(filePath, content, "utf-8");
|
|
15334
15354
|
} catch (err) {
|
|
15335
15355
|
if (isPermissionError(err)) {
|
|
15336
15356
|
process.stderr.write(
|
|
@@ -15356,7 +15376,7 @@ async function injectInfoSection(agent, content, projectRoot) {
|
|
|
15356
15376
|
newContent = existingContent + separator + content;
|
|
15357
15377
|
}
|
|
15358
15378
|
try {
|
|
15359
|
-
await (0,
|
|
15379
|
+
await (0, import_promises2.writeFile)(filePath, newContent, "utf-8");
|
|
15360
15380
|
} catch (err) {
|
|
15361
15381
|
if (isPermissionError(err)) {
|
|
15362
15382
|
process.stderr.write(
|
|
@@ -15369,14 +15389,14 @@ async function injectInfoSection(agent, content, projectRoot) {
|
|
|
15369
15389
|
}
|
|
15370
15390
|
}
|
|
15371
15391
|
async function updateGitignore(paths, projectRoot) {
|
|
15372
|
-
const gitignorePath = (0,
|
|
15373
|
-
const relativePaths = paths.filter((p) => !(0,
|
|
15392
|
+
const gitignorePath = (0, import_node_path2.join)(projectRoot, ".gitignore");
|
|
15393
|
+
const relativePaths = paths.filter((p) => !(0, import_node_path2.isAbsolute)(p));
|
|
15374
15394
|
if (relativePaths.length === 0) {
|
|
15375
15395
|
return;
|
|
15376
15396
|
}
|
|
15377
15397
|
let existingContent = "";
|
|
15378
15398
|
try {
|
|
15379
|
-
existingContent = await (0,
|
|
15399
|
+
existingContent = await (0, import_promises2.readFile)(gitignorePath, "utf-8");
|
|
15380
15400
|
} catch (err) {
|
|
15381
15401
|
const code = err.code;
|
|
15382
15402
|
if (code !== "ENOENT") {
|
|
@@ -15402,7 +15422,7 @@ async function updateGitignore(paths, projectRoot) {
|
|
|
15402
15422
|
}
|
|
15403
15423
|
updatedContent += toAdd.join("\n") + "\n";
|
|
15404
15424
|
try {
|
|
15405
|
-
await (0,
|
|
15425
|
+
await (0, import_promises2.writeFile)(gitignorePath, updatedContent, "utf-8");
|
|
15406
15426
|
} catch (err) {
|
|
15407
15427
|
if (isPermissionError(err)) {
|
|
15408
15428
|
process.stderr.write(
|
|
@@ -15414,12 +15434,12 @@ async function updateGitignore(paths, projectRoot) {
|
|
|
15414
15434
|
throw err;
|
|
15415
15435
|
}
|
|
15416
15436
|
}
|
|
15417
|
-
var
|
|
15437
|
+
var import_promises2, import_node_path2, HTML_START, HTML_END, HASH_START, HASH_END;
|
|
15418
15438
|
var init_inject = __esm({
|
|
15419
15439
|
"src/agent-detection/inject.ts"() {
|
|
15420
15440
|
"use strict";
|
|
15421
|
-
|
|
15422
|
-
|
|
15441
|
+
import_promises2 = require("fs/promises");
|
|
15442
|
+
import_node_path2 = require("path");
|
|
15423
15443
|
HTML_START = "<!-- glasstrace:mcp:start -->";
|
|
15424
15444
|
HTML_END = "<!-- glasstrace:mcp:end -->";
|
|
15425
15445
|
HASH_START = "# glasstrace:mcp:start";
|
|
@@ -15427,236 +15447,6 @@ var init_inject = __esm({
|
|
|
15427
15447
|
}
|
|
15428
15448
|
});
|
|
15429
15449
|
|
|
15430
|
-
// src/cli/mcp-add.ts
|
|
15431
|
-
var mcp_add_exports = {};
|
|
15432
|
-
__export(mcp_add_exports, {
|
|
15433
|
-
mcpAdd: () => mcpAdd
|
|
15434
|
-
});
|
|
15435
|
-
async function registerViaCli(agent, anonKey) {
|
|
15436
|
-
if (!agent.cliAvailable) {
|
|
15437
|
-
return false;
|
|
15438
|
-
}
|
|
15439
|
-
try {
|
|
15440
|
-
switch (agent.name) {
|
|
15441
|
-
case "claude": {
|
|
15442
|
-
const payload = JSON.stringify({
|
|
15443
|
-
type: "http",
|
|
15444
|
-
url: MCP_ENDPOINT,
|
|
15445
|
-
headers: { Authorization: `Bearer ${anonKey}` }
|
|
15446
|
-
});
|
|
15447
|
-
await execFileAsync("claude", [
|
|
15448
|
-
"mcp",
|
|
15449
|
-
"add-json",
|
|
15450
|
-
"glasstrace",
|
|
15451
|
-
payload,
|
|
15452
|
-
"--scope",
|
|
15453
|
-
"project"
|
|
15454
|
-
]);
|
|
15455
|
-
return true;
|
|
15456
|
-
}
|
|
15457
|
-
case "codex": {
|
|
15458
|
-
await execFileAsync("codex", [
|
|
15459
|
-
"mcp",
|
|
15460
|
-
"add",
|
|
15461
|
-
"glasstrace",
|
|
15462
|
-
"--url",
|
|
15463
|
-
MCP_ENDPOINT
|
|
15464
|
-
]);
|
|
15465
|
-
const configPath = agent.mcpConfigPath;
|
|
15466
|
-
if (configPath !== null && fs4.existsSync(configPath)) {
|
|
15467
|
-
const content = fs4.readFileSync(configPath, "utf-8");
|
|
15468
|
-
if (!content.includes("bearer_token_env_var")) {
|
|
15469
|
-
const appendContent = content.endsWith("\n") ? "" : "\n";
|
|
15470
|
-
fs4.writeFileSync(
|
|
15471
|
-
configPath,
|
|
15472
|
-
content + appendContent + 'bearer_token_env_var = "GLASSTRACE_API_KEY"\n',
|
|
15473
|
-
"utf-8"
|
|
15474
|
-
);
|
|
15475
|
-
}
|
|
15476
|
-
}
|
|
15477
|
-
process.stderr.write(
|
|
15478
|
-
" Note: Set GLASSTRACE_API_KEY environment variable for Codex authentication.\n"
|
|
15479
|
-
);
|
|
15480
|
-
return true;
|
|
15481
|
-
}
|
|
15482
|
-
case "gemini": {
|
|
15483
|
-
await execFileAsync("gemini", [
|
|
15484
|
-
"mcp",
|
|
15485
|
-
"add",
|
|
15486
|
-
"--transport",
|
|
15487
|
-
"http",
|
|
15488
|
-
"--header",
|
|
15489
|
-
`Authorization: Bearer ${anonKey}`,
|
|
15490
|
-
"glasstrace",
|
|
15491
|
-
MCP_ENDPOINT
|
|
15492
|
-
]);
|
|
15493
|
-
return true;
|
|
15494
|
-
}
|
|
15495
|
-
default:
|
|
15496
|
-
return false;
|
|
15497
|
-
}
|
|
15498
|
-
} catch {
|
|
15499
|
-
return false;
|
|
15500
|
-
}
|
|
15501
|
-
}
|
|
15502
|
-
async function mcpAdd(options) {
|
|
15503
|
-
const force = options?.force ?? false;
|
|
15504
|
-
const dryRun = options?.dryRun ?? false;
|
|
15505
|
-
const projectRoot = process.cwd();
|
|
15506
|
-
const messages = [];
|
|
15507
|
-
const anonKey = await readAnonKey(projectRoot);
|
|
15508
|
-
if (anonKey === null) {
|
|
15509
|
-
return {
|
|
15510
|
-
exitCode: 1,
|
|
15511
|
-
results: [],
|
|
15512
|
-
messages: ["Error: Run `glasstrace init` first to generate an API key."]
|
|
15513
|
-
};
|
|
15514
|
-
}
|
|
15515
|
-
const markerPath = path4.join(projectRoot, ".glasstrace", "mcp-connected");
|
|
15516
|
-
if (fs4.existsSync(markerPath) && !force) {
|
|
15517
|
-
return {
|
|
15518
|
-
exitCode: 0,
|
|
15519
|
-
results: [],
|
|
15520
|
-
messages: ["MCP already configured. Use --force to reconfigure."]
|
|
15521
|
-
};
|
|
15522
|
-
}
|
|
15523
|
-
const agents = await detectAgents(projectRoot);
|
|
15524
|
-
const detectedNonGeneric = agents.filter((a) => a.name !== "generic");
|
|
15525
|
-
const targetAgents = detectedNonGeneric.length > 0 ? detectedNonGeneric : agents.filter((a) => a.name === "generic");
|
|
15526
|
-
if (dryRun) {
|
|
15527
|
-
messages.push("Dry run: would perform the following actions:", "");
|
|
15528
|
-
for (const agent of targetAgents) {
|
|
15529
|
-
const name = formatAgentName(agent.name);
|
|
15530
|
-
if (agent.cliAvailable) {
|
|
15531
|
-
messages.push(
|
|
15532
|
-
` ${name}: Register via CLI (${agent.name} mcp add)`
|
|
15533
|
-
);
|
|
15534
|
-
} else if (agent.mcpConfigPath !== null) {
|
|
15535
|
-
messages.push(
|
|
15536
|
-
` ${name}: Write config to ${agent.mcpConfigPath}`
|
|
15537
|
-
);
|
|
15538
|
-
}
|
|
15539
|
-
if (agent.infoFilePath !== null) {
|
|
15540
|
-
messages.push(
|
|
15541
|
-
` ${name}: Inject info section into ${agent.infoFilePath}`
|
|
15542
|
-
);
|
|
15543
|
-
}
|
|
15544
|
-
}
|
|
15545
|
-
messages.push(
|
|
15546
|
-
"",
|
|
15547
|
-
" Update .gitignore with MCP config paths",
|
|
15548
|
-
" Create .glasstrace/mcp-connected marker"
|
|
15549
|
-
);
|
|
15550
|
-
return { exitCode: 0, results: [], messages };
|
|
15551
|
-
}
|
|
15552
|
-
const results = [];
|
|
15553
|
-
for (const agent of targetAgents) {
|
|
15554
|
-
const name = formatAgentName(agent.name);
|
|
15555
|
-
if (agent.name !== "generic") {
|
|
15556
|
-
const cliSuccess = await registerViaCli(agent, anonKey);
|
|
15557
|
-
if (cliSuccess) {
|
|
15558
|
-
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
15559
|
-
if (infoContent !== "") {
|
|
15560
|
-
await injectInfoSection(agent, infoContent, projectRoot);
|
|
15561
|
-
}
|
|
15562
|
-
results.push({
|
|
15563
|
-
agent: agent.name,
|
|
15564
|
-
success: true,
|
|
15565
|
-
method: "cli",
|
|
15566
|
-
message: `${name}: Registered via CLI`
|
|
15567
|
-
});
|
|
15568
|
-
continue;
|
|
15569
|
-
}
|
|
15570
|
-
}
|
|
15571
|
-
if (agent.mcpConfigPath !== null) {
|
|
15572
|
-
try {
|
|
15573
|
-
const configContent = generateMcpConfig(agent, MCP_ENDPOINT, anonKey);
|
|
15574
|
-
await writeMcpConfig(agent, configContent, projectRoot);
|
|
15575
|
-
if (fs4.existsSync(agent.mcpConfigPath)) {
|
|
15576
|
-
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
15577
|
-
if (infoContent !== "") {
|
|
15578
|
-
await injectInfoSection(agent, infoContent, projectRoot);
|
|
15579
|
-
}
|
|
15580
|
-
results.push({
|
|
15581
|
-
agent: agent.name,
|
|
15582
|
-
success: true,
|
|
15583
|
-
method: "file",
|
|
15584
|
-
message: `${name}: Configured via ${agent.mcpConfigPath}`
|
|
15585
|
-
});
|
|
15586
|
-
continue;
|
|
15587
|
-
}
|
|
15588
|
-
results.push({
|
|
15589
|
-
agent: agent.name,
|
|
15590
|
-
success: false,
|
|
15591
|
-
method: "file",
|
|
15592
|
-
message: `${name}: Failed to write config to ${agent.mcpConfigPath} (permission denied)`
|
|
15593
|
-
});
|
|
15594
|
-
continue;
|
|
15595
|
-
} catch (err) {
|
|
15596
|
-
results.push({
|
|
15597
|
-
agent: agent.name,
|
|
15598
|
-
success: false,
|
|
15599
|
-
method: "file",
|
|
15600
|
-
message: `${name}: Failed - ${err instanceof Error ? err.message : String(err)}`
|
|
15601
|
-
});
|
|
15602
|
-
continue;
|
|
15603
|
-
}
|
|
15604
|
-
}
|
|
15605
|
-
results.push({
|
|
15606
|
-
agent: agent.name,
|
|
15607
|
-
success: false,
|
|
15608
|
-
method: "skipped",
|
|
15609
|
-
message: `${name}: No registration method available`
|
|
15610
|
-
});
|
|
15611
|
-
}
|
|
15612
|
-
await updateGitignore(
|
|
15613
|
-
[".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".codex/config.toml"],
|
|
15614
|
-
projectRoot
|
|
15615
|
-
);
|
|
15616
|
-
const anySuccess = results.some((r) => r.success);
|
|
15617
|
-
if (anySuccess) {
|
|
15618
|
-
await scaffoldMcpMarker(projectRoot, anonKey);
|
|
15619
|
-
}
|
|
15620
|
-
messages.push("", "MCP registration summary:");
|
|
15621
|
-
for (const result of results) {
|
|
15622
|
-
const icon = result.success ? "+" : "-";
|
|
15623
|
-
messages.push(` [${icon}] ${result.message}`);
|
|
15624
|
-
}
|
|
15625
|
-
if (results.length === 0) {
|
|
15626
|
-
messages.push(
|
|
15627
|
-
" No agents detected. Place agent marker files (e.g., CLAUDE.md, .cursor/) in your project."
|
|
15628
|
-
);
|
|
15629
|
-
}
|
|
15630
|
-
if (!anySuccess && results.length > 0) {
|
|
15631
|
-
messages.push(
|
|
15632
|
-
"",
|
|
15633
|
-
"All agent registrations failed. Check errors above."
|
|
15634
|
-
);
|
|
15635
|
-
return { exitCode: 1, results, messages };
|
|
15636
|
-
}
|
|
15637
|
-
if (anySuccess) {
|
|
15638
|
-
messages.push("", "MCP registration complete.");
|
|
15639
|
-
}
|
|
15640
|
-
return { exitCode: 0, results, messages };
|
|
15641
|
-
}
|
|
15642
|
-
var import_node_child_process2, fs4, path4, import_node_util, execFileAsync;
|
|
15643
|
-
var init_mcp_add = __esm({
|
|
15644
|
-
"src/cli/mcp-add.ts"() {
|
|
15645
|
-
"use strict";
|
|
15646
|
-
import_node_child_process2 = require("child_process");
|
|
15647
|
-
fs4 = __toESM(require("fs"), 1);
|
|
15648
|
-
path4 = __toESM(require("path"), 1);
|
|
15649
|
-
import_node_util = require("util");
|
|
15650
|
-
init_anon_key();
|
|
15651
|
-
init_detect();
|
|
15652
|
-
init_configs();
|
|
15653
|
-
init_inject();
|
|
15654
|
-
init_scaffolder();
|
|
15655
|
-
init_constants();
|
|
15656
|
-
execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
15657
|
-
}
|
|
15658
|
-
});
|
|
15659
|
-
|
|
15660
15450
|
// src/cli/uninit.ts
|
|
15661
15451
|
var uninit_exports = {};
|
|
15662
15452
|
__export(uninit_exports, {
|
|
@@ -15981,11 +15771,11 @@ async function runUninit(options) {
|
|
|
15981
15771
|
try {
|
|
15982
15772
|
let configHandled = false;
|
|
15983
15773
|
for (const name of NEXT_CONFIG_NAMES) {
|
|
15984
|
-
const configPath =
|
|
15985
|
-
if (!
|
|
15774
|
+
const configPath = path4.join(projectRoot, name);
|
|
15775
|
+
if (!fs4.existsSync(configPath)) {
|
|
15986
15776
|
continue;
|
|
15987
15777
|
}
|
|
15988
|
-
const content =
|
|
15778
|
+
const content = fs4.readFileSync(configPath, "utf-8");
|
|
15989
15779
|
if (!content.includes("withGlasstraceConfig")) {
|
|
15990
15780
|
continue;
|
|
15991
15781
|
}
|
|
@@ -15995,7 +15785,7 @@ async function runUninit(options) {
|
|
|
15995
15785
|
const cleaned = removeGlasstraceConfigImport(unwrapResult.content);
|
|
15996
15786
|
const final = cleanLeadingBlankLines(cleaned);
|
|
15997
15787
|
if (!dryRun) {
|
|
15998
|
-
|
|
15788
|
+
fs4.writeFileSync(configPath, final, "utf-8");
|
|
15999
15789
|
}
|
|
16000
15790
|
summary.push(`${prefix}Unwrapped withGlasstraceConfig from ${name}`);
|
|
16001
15791
|
configHandled = true;
|
|
@@ -16016,20 +15806,20 @@ async function runUninit(options) {
|
|
|
16016
15806
|
);
|
|
16017
15807
|
}
|
|
16018
15808
|
try {
|
|
16019
|
-
const instrPath =
|
|
16020
|
-
if (
|
|
16021
|
-
const content =
|
|
15809
|
+
const instrPath = path4.join(projectRoot, "instrumentation.ts");
|
|
15810
|
+
if (fs4.existsSync(instrPath)) {
|
|
15811
|
+
const content = fs4.readFileSync(instrPath, "utf-8");
|
|
16022
15812
|
if (content.includes("registerGlasstrace") || content.includes("@glasstrace/sdk")) {
|
|
16023
15813
|
if (isInitCreatedInstrumentation(content)) {
|
|
16024
15814
|
if (!dryRun) {
|
|
16025
|
-
|
|
15815
|
+
fs4.unlinkSync(instrPath);
|
|
16026
15816
|
}
|
|
16027
15817
|
summary.push(`${prefix}Deleted instrumentation.ts (init-created)`);
|
|
16028
15818
|
} else {
|
|
16029
15819
|
const cleaned = removeRegisterGlasstrace(content);
|
|
16030
15820
|
if (cleaned !== content) {
|
|
16031
15821
|
if (!dryRun) {
|
|
16032
|
-
|
|
15822
|
+
fs4.writeFileSync(instrPath, cleaned, "utf-8");
|
|
16033
15823
|
}
|
|
16034
15824
|
summary.push(
|
|
16035
15825
|
`${prefix}Removed registerGlasstrace() from instrumentation.ts`
|
|
@@ -16044,10 +15834,10 @@ async function runUninit(options) {
|
|
|
16044
15834
|
);
|
|
16045
15835
|
}
|
|
16046
15836
|
try {
|
|
16047
|
-
const glasstraceDir =
|
|
16048
|
-
if (
|
|
15837
|
+
const glasstraceDir = path4.join(projectRoot, ".glasstrace");
|
|
15838
|
+
if (fs4.existsSync(glasstraceDir)) {
|
|
16049
15839
|
if (!dryRun) {
|
|
16050
|
-
|
|
15840
|
+
fs4.rmSync(glasstraceDir, { recursive: true, force: true });
|
|
16051
15841
|
}
|
|
16052
15842
|
summary.push(`${prefix}Removed .glasstrace/ directory`);
|
|
16053
15843
|
}
|
|
@@ -16057,9 +15847,9 @@ async function runUninit(options) {
|
|
|
16057
15847
|
);
|
|
16058
15848
|
}
|
|
16059
15849
|
try {
|
|
16060
|
-
const envPath =
|
|
16061
|
-
if (
|
|
16062
|
-
const content =
|
|
15850
|
+
const envPath = path4.join(projectRoot, ".env.local");
|
|
15851
|
+
if (fs4.existsSync(envPath)) {
|
|
15852
|
+
const content = fs4.readFileSync(envPath, "utf-8");
|
|
16063
15853
|
const lines = content.split("\n");
|
|
16064
15854
|
const filtered = lines.filter((line) => {
|
|
16065
15855
|
const trimmed = line.trim();
|
|
@@ -16069,12 +15859,12 @@ async function runUninit(options) {
|
|
|
16069
15859
|
const result = filtered.join("\n");
|
|
16070
15860
|
if (result.trim().length === 0) {
|
|
16071
15861
|
if (!dryRun) {
|
|
16072
|
-
|
|
15862
|
+
fs4.unlinkSync(envPath);
|
|
16073
15863
|
}
|
|
16074
15864
|
summary.push(`${prefix}Deleted .env.local (no remaining entries)`);
|
|
16075
15865
|
} else {
|
|
16076
15866
|
if (!dryRun) {
|
|
16077
|
-
|
|
15867
|
+
fs4.writeFileSync(envPath, result, "utf-8");
|
|
16078
15868
|
}
|
|
16079
15869
|
summary.push(`${prefix}Removed GLASSTRACE entries from .env.local`);
|
|
16080
15870
|
}
|
|
@@ -16086,9 +15876,9 @@ async function runUninit(options) {
|
|
|
16086
15876
|
);
|
|
16087
15877
|
}
|
|
16088
15878
|
try {
|
|
16089
|
-
const gitignorePath =
|
|
16090
|
-
if (
|
|
16091
|
-
const content =
|
|
15879
|
+
const gitignorePath = path4.join(projectRoot, ".gitignore");
|
|
15880
|
+
if (fs4.existsSync(gitignorePath)) {
|
|
15881
|
+
const content = fs4.readFileSync(gitignorePath, "utf-8");
|
|
16092
15882
|
const lines = content.split("\n");
|
|
16093
15883
|
const mcpGitignoreEntries = /* @__PURE__ */ new Set([
|
|
16094
15884
|
".glasstrace/",
|
|
@@ -16104,12 +15894,12 @@ async function runUninit(options) {
|
|
|
16104
15894
|
const result = filtered.join("\n");
|
|
16105
15895
|
if (result.trim().length === 0) {
|
|
16106
15896
|
if (!dryRun) {
|
|
16107
|
-
|
|
15897
|
+
fs4.unlinkSync(gitignorePath);
|
|
16108
15898
|
}
|
|
16109
15899
|
summary.push(`${prefix}Deleted .gitignore (no remaining entries)`);
|
|
16110
15900
|
} else {
|
|
16111
15901
|
if (!dryRun) {
|
|
16112
|
-
|
|
15902
|
+
fs4.writeFileSync(gitignorePath, result, "utf-8");
|
|
16113
15903
|
}
|
|
16114
15904
|
summary.push(`${prefix}Removed Glasstrace entries from .gitignore`);
|
|
16115
15905
|
}
|
|
@@ -16122,63 +15912,63 @@ async function runUninit(options) {
|
|
|
16122
15912
|
}
|
|
16123
15913
|
try {
|
|
16124
15914
|
for (const configFile of MCP_CONFIG_FILES) {
|
|
16125
|
-
const configPath =
|
|
16126
|
-
if (!
|
|
15915
|
+
const configPath = path4.join(projectRoot, configFile);
|
|
15916
|
+
if (!fs4.existsSync(configPath)) {
|
|
16127
15917
|
continue;
|
|
16128
15918
|
}
|
|
16129
|
-
const content =
|
|
15919
|
+
const content = fs4.readFileSync(configPath, "utf-8");
|
|
16130
15920
|
const result = processJsonMcpConfig(content);
|
|
16131
15921
|
if (result.action === "deleted") {
|
|
16132
15922
|
if (!dryRun) {
|
|
16133
|
-
|
|
15923
|
+
fs4.unlinkSync(configPath);
|
|
16134
15924
|
}
|
|
16135
15925
|
summary.push(`${prefix}Deleted ${configFile}`);
|
|
16136
15926
|
} else if (result.action === "removed-key" && result.content !== void 0) {
|
|
16137
15927
|
if (!dryRun) {
|
|
16138
|
-
|
|
15928
|
+
fs4.writeFileSync(configPath, result.content, "utf-8");
|
|
16139
15929
|
}
|
|
16140
15930
|
summary.push(`${prefix}Removed glasstrace from ${configFile}`);
|
|
16141
15931
|
}
|
|
16142
15932
|
}
|
|
16143
|
-
const codexConfigPath =
|
|
16144
|
-
if (
|
|
16145
|
-
const content =
|
|
15933
|
+
const codexConfigPath = path4.join(projectRoot, ".codex", "config.toml");
|
|
15934
|
+
if (fs4.existsSync(codexConfigPath)) {
|
|
15935
|
+
const content = fs4.readFileSync(codexConfigPath, "utf-8");
|
|
16146
15936
|
const tomlResult = processTomlMcpConfig(content);
|
|
16147
15937
|
if (tomlResult.action === "deleted") {
|
|
16148
15938
|
if (!dryRun) {
|
|
16149
|
-
|
|
15939
|
+
fs4.unlinkSync(codexConfigPath);
|
|
16150
15940
|
}
|
|
16151
15941
|
summary.push(`${prefix}Deleted .codex/config.toml`);
|
|
16152
15942
|
} else if (tomlResult.action === "removed-section" && tomlResult.content !== void 0) {
|
|
16153
15943
|
if (!dryRun) {
|
|
16154
|
-
|
|
15944
|
+
fs4.writeFileSync(codexConfigPath, tomlResult.content, "utf-8");
|
|
16155
15945
|
}
|
|
16156
15946
|
summary.push(`${prefix}Removed glasstrace from .codex/config.toml`);
|
|
16157
15947
|
}
|
|
16158
15948
|
}
|
|
16159
|
-
const hasWindsurfMarkers =
|
|
15949
|
+
const hasWindsurfMarkers = fs4.existsSync(path4.join(projectRoot, ".windsurfrules")) || fs4.existsSync(path4.join(projectRoot, ".windsurf"));
|
|
16160
15950
|
if (hasWindsurfMarkers) {
|
|
16161
|
-
const windsurfConfigPath =
|
|
15951
|
+
const windsurfConfigPath = path4.join(
|
|
16162
15952
|
os.homedir(),
|
|
16163
15953
|
".codeium",
|
|
16164
15954
|
"windsurf",
|
|
16165
15955
|
"mcp_config.json"
|
|
16166
15956
|
);
|
|
16167
|
-
if (
|
|
16168
|
-
const content =
|
|
15957
|
+
if (fs4.existsSync(windsurfConfigPath)) {
|
|
15958
|
+
const content = fs4.readFileSync(windsurfConfigPath, "utf-8");
|
|
16169
15959
|
const windsurfResult = processJsonMcpConfig(content);
|
|
16170
15960
|
const home = os.homedir();
|
|
16171
15961
|
const displayPath = windsurfConfigPath.startsWith(home) ? "~" + windsurfConfigPath.slice(home.length) : windsurfConfigPath;
|
|
16172
15962
|
if (windsurfResult.action === "deleted") {
|
|
16173
15963
|
if (!dryRun) {
|
|
16174
|
-
|
|
15964
|
+
fs4.unlinkSync(windsurfConfigPath);
|
|
16175
15965
|
}
|
|
16176
15966
|
summary.push(
|
|
16177
15967
|
`${prefix}Deleted global Windsurf config (${displayPath})`
|
|
16178
15968
|
);
|
|
16179
15969
|
} else if (windsurfResult.action === "removed-key" && windsurfResult.content !== void 0) {
|
|
16180
15970
|
if (!dryRun) {
|
|
16181
|
-
|
|
15971
|
+
fs4.writeFileSync(windsurfConfigPath, windsurfResult.content, "utf-8");
|
|
16182
15972
|
}
|
|
16183
15973
|
summary.push(
|
|
16184
15974
|
`${prefix}Removed glasstrace from global Windsurf config (${displayPath})`
|
|
@@ -16193,21 +15983,21 @@ async function runUninit(options) {
|
|
|
16193
15983
|
}
|
|
16194
15984
|
try {
|
|
16195
15985
|
for (const infoFile of AGENT_INFO_FILES) {
|
|
16196
|
-
const filePath =
|
|
16197
|
-
if (!
|
|
15986
|
+
const filePath = path4.join(projectRoot, infoFile);
|
|
15987
|
+
if (!fs4.existsSync(filePath)) {
|
|
16198
15988
|
continue;
|
|
16199
15989
|
}
|
|
16200
|
-
const content =
|
|
15990
|
+
const content = fs4.readFileSync(filePath, "utf-8");
|
|
16201
15991
|
const result = removeMarkerSection(content);
|
|
16202
15992
|
if (result.removed) {
|
|
16203
15993
|
if (result.content.trim().length === 0) {
|
|
16204
15994
|
if (!dryRun) {
|
|
16205
|
-
|
|
15995
|
+
fs4.unlinkSync(filePath);
|
|
16206
15996
|
}
|
|
16207
15997
|
summary.push(`${prefix}Deleted ${infoFile} (only contained Glasstrace section)`);
|
|
16208
15998
|
} else {
|
|
16209
15999
|
if (!dryRun) {
|
|
16210
|
-
|
|
16000
|
+
fs4.writeFileSync(filePath, result.content, "utf-8");
|
|
16211
16001
|
}
|
|
16212
16002
|
summary.push(`${prefix}Removed Glasstrace section from ${infoFile}`);
|
|
16213
16003
|
}
|
|
@@ -16223,13 +16013,13 @@ async function runUninit(options) {
|
|
|
16223
16013
|
}
|
|
16224
16014
|
return { exitCode: errors.length > 0 ? 1 : 0, summary, warnings, errors };
|
|
16225
16015
|
}
|
|
16226
|
-
var
|
|
16016
|
+
var fs4, os, path4, MCP_CONFIG_FILES, AGENT_INFO_FILES;
|
|
16227
16017
|
var init_uninit = __esm({
|
|
16228
16018
|
"src/cli/uninit.ts"() {
|
|
16229
16019
|
"use strict";
|
|
16230
|
-
|
|
16020
|
+
fs4 = __toESM(require("fs"), 1);
|
|
16231
16021
|
os = __toESM(require("os"), 1);
|
|
16232
|
-
|
|
16022
|
+
path4 = __toESM(require("path"), 1);
|
|
16233
16023
|
init_constants();
|
|
16234
16024
|
MCP_CONFIG_FILES = [".mcp.json", ".cursor/mcp.json", ".gemini/settings.json"];
|
|
16235
16025
|
AGENT_INFO_FILES = [
|
|
@@ -16240,10 +16030,241 @@ var init_uninit = __esm({
|
|
|
16240
16030
|
}
|
|
16241
16031
|
});
|
|
16242
16032
|
|
|
16033
|
+
// src/cli/mcp-add.ts
|
|
16034
|
+
var mcp_add_exports = {};
|
|
16035
|
+
__export(mcp_add_exports, {
|
|
16036
|
+
mcpAdd: () => mcpAdd
|
|
16037
|
+
});
|
|
16038
|
+
async function registerViaCli(agent, anonKey) {
|
|
16039
|
+
if (!agent.cliAvailable) {
|
|
16040
|
+
return false;
|
|
16041
|
+
}
|
|
16042
|
+
try {
|
|
16043
|
+
switch (agent.name) {
|
|
16044
|
+
case "claude": {
|
|
16045
|
+
const payload = JSON.stringify({
|
|
16046
|
+
type: "http",
|
|
16047
|
+
url: MCP_ENDPOINT,
|
|
16048
|
+
headers: { Authorization: `Bearer ${anonKey}` }
|
|
16049
|
+
});
|
|
16050
|
+
await execFileAsync("claude", [
|
|
16051
|
+
"mcp",
|
|
16052
|
+
"add-json",
|
|
16053
|
+
"glasstrace",
|
|
16054
|
+
payload,
|
|
16055
|
+
"--scope",
|
|
16056
|
+
"project"
|
|
16057
|
+
]);
|
|
16058
|
+
return true;
|
|
16059
|
+
}
|
|
16060
|
+
case "codex": {
|
|
16061
|
+
await execFileAsync("codex", [
|
|
16062
|
+
"mcp",
|
|
16063
|
+
"add",
|
|
16064
|
+
"glasstrace",
|
|
16065
|
+
"--url",
|
|
16066
|
+
MCP_ENDPOINT
|
|
16067
|
+
]);
|
|
16068
|
+
const configPath = agent.mcpConfigPath;
|
|
16069
|
+
if (configPath !== null && fs5.existsSync(configPath)) {
|
|
16070
|
+
const content = fs5.readFileSync(configPath, "utf-8");
|
|
16071
|
+
if (!content.includes("bearer_token_env_var")) {
|
|
16072
|
+
const appendContent = content.endsWith("\n") ? "" : "\n";
|
|
16073
|
+
fs5.writeFileSync(
|
|
16074
|
+
configPath,
|
|
16075
|
+
content + appendContent + 'bearer_token_env_var = "GLASSTRACE_API_KEY"\n',
|
|
16076
|
+
"utf-8"
|
|
16077
|
+
);
|
|
16078
|
+
}
|
|
16079
|
+
}
|
|
16080
|
+
process.stderr.write(
|
|
16081
|
+
" Note: Set GLASSTRACE_API_KEY environment variable for Codex authentication.\n"
|
|
16082
|
+
);
|
|
16083
|
+
return true;
|
|
16084
|
+
}
|
|
16085
|
+
case "gemini": {
|
|
16086
|
+
await execFileAsync("gemini", [
|
|
16087
|
+
"mcp",
|
|
16088
|
+
"add",
|
|
16089
|
+
"--transport",
|
|
16090
|
+
"http",
|
|
16091
|
+
"--header",
|
|
16092
|
+
`Authorization: Bearer ${anonKey}`,
|
|
16093
|
+
"glasstrace",
|
|
16094
|
+
MCP_ENDPOINT
|
|
16095
|
+
]);
|
|
16096
|
+
return true;
|
|
16097
|
+
}
|
|
16098
|
+
default:
|
|
16099
|
+
return false;
|
|
16100
|
+
}
|
|
16101
|
+
} catch {
|
|
16102
|
+
return false;
|
|
16103
|
+
}
|
|
16104
|
+
}
|
|
16105
|
+
async function mcpAdd(options) {
|
|
16106
|
+
const force = options?.force ?? false;
|
|
16107
|
+
const dryRun = options?.dryRun ?? false;
|
|
16108
|
+
const projectRoot = process.cwd();
|
|
16109
|
+
const messages = [];
|
|
16110
|
+
const anonKey = await readAnonKey(projectRoot);
|
|
16111
|
+
if (anonKey === null) {
|
|
16112
|
+
return {
|
|
16113
|
+
exitCode: 1,
|
|
16114
|
+
results: [],
|
|
16115
|
+
messages: ["Error: Run `glasstrace init` first to generate an API key."]
|
|
16116
|
+
};
|
|
16117
|
+
}
|
|
16118
|
+
const markerPath = path5.join(projectRoot, ".glasstrace", "mcp-connected");
|
|
16119
|
+
if (fs5.existsSync(markerPath) && !force) {
|
|
16120
|
+
return {
|
|
16121
|
+
exitCode: 0,
|
|
16122
|
+
results: [],
|
|
16123
|
+
messages: ["MCP already configured. Use --force to reconfigure."]
|
|
16124
|
+
};
|
|
16125
|
+
}
|
|
16126
|
+
const agents = await detectAgents(projectRoot);
|
|
16127
|
+
const detectedNonGeneric = agents.filter((a) => a.name !== "generic");
|
|
16128
|
+
const targetAgents = detectedNonGeneric.length > 0 ? detectedNonGeneric : agents.filter((a) => a.name === "generic");
|
|
16129
|
+
if (dryRun) {
|
|
16130
|
+
messages.push("Dry run: would perform the following actions:", "");
|
|
16131
|
+
for (const agent of targetAgents) {
|
|
16132
|
+
const name = formatAgentName(agent.name);
|
|
16133
|
+
if (agent.cliAvailable) {
|
|
16134
|
+
messages.push(
|
|
16135
|
+
` ${name}: Register via CLI (${agent.name} mcp add)`
|
|
16136
|
+
);
|
|
16137
|
+
} else if (agent.mcpConfigPath !== null) {
|
|
16138
|
+
messages.push(
|
|
16139
|
+
` ${name}: Write config to ${agent.mcpConfigPath}`
|
|
16140
|
+
);
|
|
16141
|
+
}
|
|
16142
|
+
if (agent.infoFilePath !== null) {
|
|
16143
|
+
messages.push(
|
|
16144
|
+
` ${name}: Inject info section into ${agent.infoFilePath}`
|
|
16145
|
+
);
|
|
16146
|
+
}
|
|
16147
|
+
}
|
|
16148
|
+
messages.push(
|
|
16149
|
+
"",
|
|
16150
|
+
" Update .gitignore with MCP config paths",
|
|
16151
|
+
" Create .glasstrace/mcp-connected marker"
|
|
16152
|
+
);
|
|
16153
|
+
return { exitCode: 0, results: [], messages };
|
|
16154
|
+
}
|
|
16155
|
+
const results = [];
|
|
16156
|
+
for (const agent of targetAgents) {
|
|
16157
|
+
const name = formatAgentName(agent.name);
|
|
16158
|
+
if (agent.name !== "generic") {
|
|
16159
|
+
const cliSuccess = await registerViaCli(agent, anonKey);
|
|
16160
|
+
if (cliSuccess) {
|
|
16161
|
+
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
16162
|
+
if (infoContent !== "") {
|
|
16163
|
+
await injectInfoSection(agent, infoContent, projectRoot);
|
|
16164
|
+
}
|
|
16165
|
+
results.push({
|
|
16166
|
+
agent: agent.name,
|
|
16167
|
+
success: true,
|
|
16168
|
+
method: "cli",
|
|
16169
|
+
message: `${name}: Registered via CLI`
|
|
16170
|
+
});
|
|
16171
|
+
continue;
|
|
16172
|
+
}
|
|
16173
|
+
}
|
|
16174
|
+
if (agent.mcpConfigPath !== null) {
|
|
16175
|
+
try {
|
|
16176
|
+
const configContent = generateMcpConfig(agent, MCP_ENDPOINT, anonKey);
|
|
16177
|
+
await writeMcpConfig(agent, configContent, projectRoot);
|
|
16178
|
+
if (fs5.existsSync(agent.mcpConfigPath)) {
|
|
16179
|
+
const infoContent = generateInfoSection(agent, MCP_ENDPOINT);
|
|
16180
|
+
if (infoContent !== "") {
|
|
16181
|
+
await injectInfoSection(agent, infoContent, projectRoot);
|
|
16182
|
+
}
|
|
16183
|
+
results.push({
|
|
16184
|
+
agent: agent.name,
|
|
16185
|
+
success: true,
|
|
16186
|
+
method: "file",
|
|
16187
|
+
message: `${name}: Configured via ${agent.mcpConfigPath}`
|
|
16188
|
+
});
|
|
16189
|
+
continue;
|
|
16190
|
+
}
|
|
16191
|
+
results.push({
|
|
16192
|
+
agent: agent.name,
|
|
16193
|
+
success: false,
|
|
16194
|
+
method: "file",
|
|
16195
|
+
message: `${name}: Failed to write config to ${agent.mcpConfigPath} (permission denied)`
|
|
16196
|
+
});
|
|
16197
|
+
continue;
|
|
16198
|
+
} catch (err) {
|
|
16199
|
+
results.push({
|
|
16200
|
+
agent: agent.name,
|
|
16201
|
+
success: false,
|
|
16202
|
+
method: "file",
|
|
16203
|
+
message: `${name}: Failed - ${err instanceof Error ? err.message : String(err)}`
|
|
16204
|
+
});
|
|
16205
|
+
continue;
|
|
16206
|
+
}
|
|
16207
|
+
}
|
|
16208
|
+
results.push({
|
|
16209
|
+
agent: agent.name,
|
|
16210
|
+
success: false,
|
|
16211
|
+
method: "skipped",
|
|
16212
|
+
message: `${name}: No registration method available`
|
|
16213
|
+
});
|
|
16214
|
+
}
|
|
16215
|
+
await updateGitignore(
|
|
16216
|
+
[".mcp.json", ".cursor/mcp.json", ".gemini/settings.json", ".codex/config.toml"],
|
|
16217
|
+
projectRoot
|
|
16218
|
+
);
|
|
16219
|
+
const anySuccess = results.some((r) => r.success);
|
|
16220
|
+
if (anySuccess) {
|
|
16221
|
+
await scaffoldMcpMarker(projectRoot, anonKey);
|
|
16222
|
+
}
|
|
16223
|
+
messages.push("", "MCP registration summary:");
|
|
16224
|
+
for (const result of results) {
|
|
16225
|
+
const icon = result.success ? "+" : "-";
|
|
16226
|
+
messages.push(` [${icon}] ${result.message}`);
|
|
16227
|
+
}
|
|
16228
|
+
if (results.length === 0) {
|
|
16229
|
+
messages.push(
|
|
16230
|
+
" No agents detected. Place agent marker files (e.g., CLAUDE.md, .cursor/) in your project."
|
|
16231
|
+
);
|
|
16232
|
+
}
|
|
16233
|
+
if (!anySuccess && results.length > 0) {
|
|
16234
|
+
messages.push(
|
|
16235
|
+
"",
|
|
16236
|
+
"All agent registrations failed. Check errors above."
|
|
16237
|
+
);
|
|
16238
|
+
return { exitCode: 1, results, messages };
|
|
16239
|
+
}
|
|
16240
|
+
if (anySuccess) {
|
|
16241
|
+
messages.push("", "MCP registration complete.");
|
|
16242
|
+
}
|
|
16243
|
+
return { exitCode: 0, results, messages };
|
|
16244
|
+
}
|
|
16245
|
+
var import_node_child_process2, fs5, path5, import_node_util, execFileAsync;
|
|
16246
|
+
var init_mcp_add = __esm({
|
|
16247
|
+
"src/cli/mcp-add.ts"() {
|
|
16248
|
+
"use strict";
|
|
16249
|
+
import_node_child_process2 = require("child_process");
|
|
16250
|
+
fs5 = __toESM(require("fs"), 1);
|
|
16251
|
+
path5 = __toESM(require("path"), 1);
|
|
16252
|
+
import_node_util = require("util");
|
|
16253
|
+
init_anon_key();
|
|
16254
|
+
init_detect();
|
|
16255
|
+
init_configs();
|
|
16256
|
+
init_inject();
|
|
16257
|
+
init_scaffolder();
|
|
16258
|
+
init_constants();
|
|
16259
|
+
execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
16260
|
+
}
|
|
16261
|
+
});
|
|
16262
|
+
|
|
16243
16263
|
// src/cli/init.ts
|
|
16244
16264
|
var init_exports = {};
|
|
16245
16265
|
__export(init_exports, {
|
|
16246
16266
|
meetsNodeVersion: () => meetsNodeVersion,
|
|
16267
|
+
rollbackSteps: () => rollbackSteps,
|
|
16247
16268
|
runInit: () => runInit
|
|
16248
16269
|
});
|
|
16249
16270
|
module.exports = __toCommonJS(init_exports);
|
|
@@ -16661,6 +16682,7 @@ function walkDirectories(baseDir) {
|
|
|
16661
16682
|
}
|
|
16662
16683
|
|
|
16663
16684
|
// src/cli/init.ts
|
|
16685
|
+
init_uninit();
|
|
16664
16686
|
function meetsNodeVersion(minMajor) {
|
|
16665
16687
|
const [major] = process.versions.node.split(".").map(Number);
|
|
16666
16688
|
return major >= minMajor;
|
|
@@ -16686,6 +16708,94 @@ async function promptYesNo(question, defaultValue) {
|
|
|
16686
16708
|
});
|
|
16687
16709
|
});
|
|
16688
16710
|
}
|
|
16711
|
+
function cleanLeadingBlankLines2(content) {
|
|
16712
|
+
return content.replace(/^\n{2,}/, "\n");
|
|
16713
|
+
}
|
|
16714
|
+
async function rollbackSteps(steps, projectRoot, state) {
|
|
16715
|
+
for (const step of [...steps].reverse()) {
|
|
16716
|
+
try {
|
|
16717
|
+
switch (step) {
|
|
16718
|
+
case "instrumentation": {
|
|
16719
|
+
const instrPath = path6.join(projectRoot, "instrumentation.ts");
|
|
16720
|
+
if (fs6.existsSync(instrPath)) {
|
|
16721
|
+
const content = fs6.readFileSync(instrPath, "utf-8");
|
|
16722
|
+
if (isInitCreatedInstrumentation(content)) {
|
|
16723
|
+
fs6.unlinkSync(instrPath);
|
|
16724
|
+
} else if (state?.originalInstrumentationContent !== void 0) {
|
|
16725
|
+
fs6.writeFileSync(instrPath, state.originalInstrumentationContent, "utf-8");
|
|
16726
|
+
} else {
|
|
16727
|
+
const cleaned = removeRegisterGlasstrace(content);
|
|
16728
|
+
if (cleaned !== content) {
|
|
16729
|
+
fs6.writeFileSync(instrPath, cleaned, "utf-8");
|
|
16730
|
+
}
|
|
16731
|
+
}
|
|
16732
|
+
}
|
|
16733
|
+
break;
|
|
16734
|
+
}
|
|
16735
|
+
case "next-config": {
|
|
16736
|
+
for (const name of NEXT_CONFIG_NAMES) {
|
|
16737
|
+
const configPath = path6.join(projectRoot, name);
|
|
16738
|
+
if (!fs6.existsSync(configPath)) {
|
|
16739
|
+
continue;
|
|
16740
|
+
}
|
|
16741
|
+
const content = fs6.readFileSync(configPath, "utf-8");
|
|
16742
|
+
if (!content.includes("withGlasstraceConfig")) {
|
|
16743
|
+
continue;
|
|
16744
|
+
}
|
|
16745
|
+
const isESM = name.endsWith(".ts") || name.endsWith(".mjs");
|
|
16746
|
+
const unwrapResult = isESM ? unwrapExport(content) : unwrapCJSExport(content);
|
|
16747
|
+
if (unwrapResult.unwrapped) {
|
|
16748
|
+
const cleaned = removeGlasstraceConfigImport(unwrapResult.content);
|
|
16749
|
+
fs6.writeFileSync(configPath, cleanLeadingBlankLines2(cleaned), "utf-8");
|
|
16750
|
+
}
|
|
16751
|
+
break;
|
|
16752
|
+
}
|
|
16753
|
+
break;
|
|
16754
|
+
}
|
|
16755
|
+
case "env-local": {
|
|
16756
|
+
const envPath = path6.join(projectRoot, ".env.local");
|
|
16757
|
+
if (fs6.existsSync(envPath)) {
|
|
16758
|
+
const content = fs6.readFileSync(envPath, "utf-8");
|
|
16759
|
+
const lines = content.split("\n");
|
|
16760
|
+
const filtered = lines.filter((line) => {
|
|
16761
|
+
const trimmed = line.trim();
|
|
16762
|
+
return !/^\s*#?\s*GLASSTRACE_API_KEY\s*=/.test(trimmed);
|
|
16763
|
+
});
|
|
16764
|
+
if (filtered.length !== lines.length) {
|
|
16765
|
+
const result = filtered.join("\n");
|
|
16766
|
+
if (result.trim().length === 0) {
|
|
16767
|
+
fs6.unlinkSync(envPath);
|
|
16768
|
+
} else {
|
|
16769
|
+
fs6.writeFileSync(envPath, result, "utf-8");
|
|
16770
|
+
}
|
|
16771
|
+
}
|
|
16772
|
+
}
|
|
16773
|
+
break;
|
|
16774
|
+
}
|
|
16775
|
+
case "gitignore": {
|
|
16776
|
+
const gitignorePath = path6.join(projectRoot, ".gitignore");
|
|
16777
|
+
if (fs6.existsSync(gitignorePath)) {
|
|
16778
|
+
const content = fs6.readFileSync(gitignorePath, "utf-8");
|
|
16779
|
+
const lines = content.split("\n");
|
|
16780
|
+
const filtered = lines.filter(
|
|
16781
|
+
(line) => line.trim() !== ".glasstrace/"
|
|
16782
|
+
);
|
|
16783
|
+
if (filtered.length !== lines.length) {
|
|
16784
|
+
const result = filtered.join("\n");
|
|
16785
|
+
if (result.trim().length === 0) {
|
|
16786
|
+
fs6.unlinkSync(gitignorePath);
|
|
16787
|
+
} else {
|
|
16788
|
+
fs6.writeFileSync(gitignorePath, result, "utf-8");
|
|
16789
|
+
}
|
|
16790
|
+
}
|
|
16791
|
+
}
|
|
16792
|
+
break;
|
|
16793
|
+
}
|
|
16794
|
+
}
|
|
16795
|
+
} catch {
|
|
16796
|
+
}
|
|
16797
|
+
}
|
|
16798
|
+
}
|
|
16689
16799
|
async function runInit(options) {
|
|
16690
16800
|
const { yes, coverageMap } = options;
|
|
16691
16801
|
const summary = [];
|
|
@@ -16707,14 +16817,21 @@ async function runInit(options) {
|
|
|
16707
16817
|
errors.push("No package.json found. Run this command from a Node.js project root.");
|
|
16708
16818
|
return { exitCode: 1, summary, warnings, errors };
|
|
16709
16819
|
}
|
|
16820
|
+
const rollbackState = { steps: [] };
|
|
16710
16821
|
try {
|
|
16822
|
+
const instrPath = path6.join(projectRoot, "instrumentation.ts");
|
|
16823
|
+
if (fs6.existsSync(instrPath)) {
|
|
16824
|
+
rollbackState.originalInstrumentationContent = fs6.readFileSync(instrPath, "utf-8");
|
|
16825
|
+
}
|
|
16711
16826
|
const instrResult = await scaffoldInstrumentation(projectRoot);
|
|
16712
16827
|
switch (instrResult.action) {
|
|
16713
16828
|
case "created":
|
|
16714
16829
|
summary.push("Created instrumentation.ts");
|
|
16830
|
+
rollbackState.steps.push("instrumentation");
|
|
16715
16831
|
break;
|
|
16716
16832
|
case "injected":
|
|
16717
16833
|
summary.push("Added registerGlasstrace() to existing instrumentation.ts");
|
|
16834
|
+
rollbackState.steps.push("instrumentation");
|
|
16718
16835
|
break;
|
|
16719
16836
|
case "already-registered":
|
|
16720
16837
|
summary.push("Skipped instrumentation.ts (registerGlasstrace already present)");
|
|
@@ -16726,6 +16843,7 @@ async function runInit(options) {
|
|
|
16726
16843
|
break;
|
|
16727
16844
|
}
|
|
16728
16845
|
} catch (err) {
|
|
16846
|
+
await rollbackSteps(rollbackState.steps, projectRoot, rollbackState);
|
|
16729
16847
|
errors.push(`Failed to write instrumentation.ts: ${err instanceof Error ? err.message : String(err)}`);
|
|
16730
16848
|
return { exitCode: 1, summary, warnings, errors };
|
|
16731
16849
|
}
|
|
@@ -16733,6 +16851,7 @@ async function runInit(options) {
|
|
|
16733
16851
|
const configResult = await scaffoldNextConfig(projectRoot);
|
|
16734
16852
|
if (configResult?.modified) {
|
|
16735
16853
|
summary.push("Wrapped next.config with withGlasstraceConfig()");
|
|
16854
|
+
rollbackState.steps.push("next-config");
|
|
16736
16855
|
} else if (configResult === null) {
|
|
16737
16856
|
warnings.push("No next.config.* found. You may need to create one for Next.js projects.");
|
|
16738
16857
|
} else if (configResult.reason === "already-wrapped") {
|
|
@@ -16743,6 +16862,7 @@ async function runInit(options) {
|
|
|
16743
16862
|
warnings.push("next.config has no recognizable export pattern \u2014 add withGlasstraceConfig() manually");
|
|
16744
16863
|
}
|
|
16745
16864
|
} catch (err) {
|
|
16865
|
+
await rollbackSteps(rollbackState.steps, projectRoot, rollbackState);
|
|
16746
16866
|
errors.push(`Failed to modify next.config: ${err instanceof Error ? err.message : String(err)}`);
|
|
16747
16867
|
return { exitCode: 1, summary, warnings, errors };
|
|
16748
16868
|
}
|
|
@@ -16750,10 +16870,12 @@ async function runInit(options) {
|
|
|
16750
16870
|
const envCreated = await scaffoldEnvLocal(projectRoot);
|
|
16751
16871
|
if (envCreated) {
|
|
16752
16872
|
summary.push("Updated .env.local with Glasstrace configuration");
|
|
16873
|
+
rollbackState.steps.push("env-local");
|
|
16753
16874
|
} else {
|
|
16754
16875
|
summary.push("Skipped .env.local (GLASSTRACE_API_KEY already configured)");
|
|
16755
16876
|
}
|
|
16756
16877
|
} catch (err) {
|
|
16878
|
+
await rollbackSteps(rollbackState.steps, projectRoot, rollbackState);
|
|
16757
16879
|
errors.push(`Failed to update .env.local: ${err instanceof Error ? err.message : String(err)}`);
|
|
16758
16880
|
return { exitCode: 1, summary, warnings, errors };
|
|
16759
16881
|
}
|
|
@@ -16761,10 +16883,12 @@ async function runInit(options) {
|
|
|
16761
16883
|
const gitignoreUpdated = await scaffoldGitignore(projectRoot);
|
|
16762
16884
|
if (gitignoreUpdated) {
|
|
16763
16885
|
summary.push("Updated .gitignore with .glasstrace/");
|
|
16886
|
+
rollbackState.steps.push("gitignore");
|
|
16764
16887
|
} else {
|
|
16765
16888
|
summary.push("Skipped .gitignore (.glasstrace/ already listed)");
|
|
16766
16889
|
}
|
|
16767
16890
|
} catch (err) {
|
|
16891
|
+
await rollbackSteps(rollbackState.steps, projectRoot, rollbackState);
|
|
16768
16892
|
errors.push(`Failed to update .gitignore: ${err instanceof Error ? err.message : String(err)}`);
|
|
16769
16893
|
return { exitCode: 1, summary, warnings, errors };
|
|
16770
16894
|
}
|
|
@@ -17024,6 +17148,7 @@ Usage:
|
|
|
17024
17148
|
// Annotate the CommonJS export names for ESM import in node:
|
|
17025
17149
|
0 && (module.exports = {
|
|
17026
17150
|
meetsNodeVersion,
|
|
17151
|
+
rollbackSteps,
|
|
17027
17152
|
runInit
|
|
17028
17153
|
});
|
|
17029
17154
|
//# sourceMappingURL=init.cjs.map
|