@glasstrace/sdk 0.19.0 → 0.20.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/README.md +79 -0
- package/dist/chunk-BT2OCXCG.js +178 -0
- package/dist/chunk-BT2OCXCG.js.map +1 -0
- package/dist/{chunk-F2TZRBEH.js → chunk-DO2YPMQ5.js} +9 -181
- package/dist/chunk-DO2YPMQ5.js.map +1 -0
- package/dist/{chunk-YPXW2TN3.js → chunk-IP4NMDJK.js} +2 -2
- package/dist/{chunk-VN3GZDV6.js → chunk-IQN6TRMQ.js} +2 -2
- package/dist/{chunk-XNDHQN4S.js → chunk-LU3PPAOQ.js} +288 -54
- package/dist/chunk-LU3PPAOQ.js.map +1 -0
- package/dist/chunk-R4DAIPXD.js +4461 -0
- package/dist/chunk-R4DAIPXD.js.map +1 -0
- package/dist/{chunk-5N2IR4EO.js → chunk-TQ54WLCZ.js} +1 -1
- package/dist/{chunk-5N2IR4EO.js.map → chunk-TQ54WLCZ.js.map} +1 -1
- package/dist/chunk-Z2EGETTT.js +204 -0
- package/dist/chunk-Z2EGETTT.js.map +1 -0
- package/dist/cli/init.cjs +483 -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 +109 -7
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +2 -2
- package/dist/cli/uninit.cjs +174 -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/edge-entry-Ds2fNOeh.d.ts +157 -0
- package/dist/edge-entry-FJFKkeFF.d.cts +157 -0
- package/dist/edge-entry.cjs +14939 -0
- package/dist/edge-entry.cjs.map +1 -0
- package/dist/edge-entry.d.cts +6 -0
- package/dist/edge-entry.d.ts +6 -0
- package/dist/edge-entry.js +16 -0
- package/dist/index.cjs +13 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d-DgeH-pNJ.d.cts +191 -0
- package/dist/index.d-DgeH-pNJ.d.ts +191 -0
- package/dist/index.d.cts +9 -461
- package/dist/index.d.ts +9 -461
- package/dist/index.js +32 -4609
- package/dist/index.js.map +1 -1
- package/dist/node-entry.cjs +22492 -0
- package/dist/node-entry.cjs.map +1 -0
- package/dist/node-entry.d.cts +10 -0
- package/dist/node-entry.d.ts +10 -0
- package/dist/node-entry.js +101 -0
- package/dist/node-entry.js.map +1 -0
- package/dist/node-subpath.cjs +14506 -0
- package/dist/node-subpath.cjs.map +1 -0
- package/dist/node-subpath.d.cts +132 -0
- package/dist/node-subpath.d.ts +132 -0
- package/dist/node-subpath.js +30 -0
- package/dist/node-subpath.js.map +1 -0
- package/dist/{source-map-uploader-VPDZWWM2.js → source-map-uploader-YXWO6JLN.js} +3 -3
- package/dist/source-map-uploader-YXWO6JLN.js.map +1 -0
- package/package.json +4 -1
- package/dist/chunk-F2TZRBEH.js.map +0 -1
- package/dist/chunk-XNDHQN4S.js.map +0 -1
- /package/dist/{chunk-YPXW2TN3.js.map → chunk-IP4NMDJK.js.map} +0 -0
- /package/dist/{chunk-VN3GZDV6.js.map → chunk-IQN6TRMQ.js.map} +0 -0
- /package/dist/{source-map-uploader-VPDZWWM2.js.map → edge-entry.js.map} +0 -0
package/dist/cli/init.d.cts
CHANGED
|
@@ -53,7 +53,7 @@ declare function decideMcpConfigAction(options: {
|
|
|
53
53
|
* Identifies a scaffolding step that can be reversed during rollback.
|
|
54
54
|
* Steps are tracked in execution order and rolled back in reverse.
|
|
55
55
|
*/
|
|
56
|
-
type CompletedStep = "instrumentation" | "next-config" | "env-local" | "gitignore";
|
|
56
|
+
type CompletedStep = "instrumentation" | "next-config" | "env-local" | "gitignore" | "discovery-file";
|
|
57
57
|
/**
|
|
58
58
|
* Tracks state needed for accurate rollback of init steps.
|
|
59
59
|
* Separating this from the step list allows rollback to restore
|
|
@@ -74,6 +74,52 @@ interface RollbackState {
|
|
|
74
74
|
* When present, rollback restores this instead of using removeRegisterGlasstrace. */
|
|
75
75
|
originalInstrumentationContent?: string;
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns true when the given `.gitignore` content would exclude the
|
|
79
|
+
* static discovery file at `<root>/public/.well-known/glasstrace.json`
|
|
80
|
+
* or `<root>/static/.well-known/glasstrace.json` (depending on `layout`)
|
|
81
|
+
* from being committed.
|
|
82
|
+
*
|
|
83
|
+
* Model: the file has three ancestors in its committed path — the
|
|
84
|
+
* static root directory (`public/` or `static/`), the `.well-known/`
|
|
85
|
+
* sub-directory, and the file itself. Each pattern in `.gitignore` is
|
|
86
|
+
* classified by which ancestor paths it matches, and each ancestor
|
|
87
|
+
* carries its own current ignore state that later patterns can flip.
|
|
88
|
+
* Patterns that don't match any of the three ancestors are ignored.
|
|
89
|
+
*
|
|
90
|
+
* Per `gitignore(5)`:
|
|
91
|
+
*
|
|
92
|
+
* > It is not possible to re-include a file if a parent directory of
|
|
93
|
+
* > that file is excluded.
|
|
94
|
+
*
|
|
95
|
+
* Consequently, the file is reported as ignored when the final state
|
|
96
|
+
* of ANY ancestor (static root, `.well-known/`, or the file itself)
|
|
97
|
+
* is ignored — a `!<file>` negation alone cannot "escape" an ignored
|
|
98
|
+
* ancestor.
|
|
99
|
+
*
|
|
100
|
+
* Per-ancestor tracking is what distinguishes overlapping patterns:
|
|
101
|
+
*
|
|
102
|
+
* - `public/` then `!public/` — root re-included, file OK.
|
|
103
|
+
* - `public/` then `!public/.well-known/` — root still ignored (scope-2
|
|
104
|
+
* negation doesn't match the scope-1 ancestor path), file ignored.
|
|
105
|
+
* - `.well-known/` then `!public/.well-known/` — `.well-known/` re-included
|
|
106
|
+
* (both patterns match the scope-2 ancestor), file OK.
|
|
107
|
+
* - `.well-known/` then `!public/` — `!public/` matches the
|
|
108
|
+
* scope-1 ancestor only; the scope-2 ancestor (`.well-known/`) is still
|
|
109
|
+
* ignored, so the file is ignored.
|
|
110
|
+
* - `<file>` then `!<file>` — file-level ignore flipped.
|
|
111
|
+
* - `<file>` then `!public/.well-known/` — directory negation does
|
|
112
|
+
* not match the file path; file still ignored.
|
|
113
|
+
*
|
|
114
|
+
* Not-modeled rules — glob wildcards (star, question mark, character
|
|
115
|
+
* classes), overlapping any-depth matches across multiple parents, and
|
|
116
|
+
* nested `.gitignore` files — skew the heuristic toward false positives
|
|
117
|
+
* (extra warning output) rather than false negatives. The warning is
|
|
118
|
+
* advisory.
|
|
119
|
+
*
|
|
120
|
+
* @internal Exported for unit testing only.
|
|
121
|
+
*/
|
|
122
|
+
declare function gitignoreExcludesDiscoveryFile(gitignoreContent: string, layout: "public" | "static"): boolean;
|
|
77
123
|
/**
|
|
78
124
|
* Best-effort rollback of completed init steps in reverse order.
|
|
79
125
|
* Each step is individually try/caught so that a failure in one
|
|
@@ -132,4 +178,4 @@ type VerifyAnonKeyOutcome = {
|
|
|
132
178
|
*/
|
|
133
179
|
declare function verifyAnonKeyRegistration(projectRoot: string): Promise<VerifyAnonKeyOutcome>;
|
|
134
180
|
|
|
135
|
-
export { type InitOptions, type InitResult, type VerifyAnonKeyOutcome, decideMcpConfigAction, meetsNodeVersion, rollbackSteps, runInit, verifyAnonKeyRegistration };
|
|
181
|
+
export { type InitOptions, type InitResult, type VerifyAnonKeyOutcome, decideMcpConfigAction, gitignoreExcludesDiscoveryFile, meetsNodeVersion, rollbackSteps, runInit, verifyAnonKeyRegistration };
|
package/dist/cli/init.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ declare function decideMcpConfigAction(options: {
|
|
|
53
53
|
* Identifies a scaffolding step that can be reversed during rollback.
|
|
54
54
|
* Steps are tracked in execution order and rolled back in reverse.
|
|
55
55
|
*/
|
|
56
|
-
type CompletedStep = "instrumentation" | "next-config" | "env-local" | "gitignore";
|
|
56
|
+
type CompletedStep = "instrumentation" | "next-config" | "env-local" | "gitignore" | "discovery-file";
|
|
57
57
|
/**
|
|
58
58
|
* Tracks state needed for accurate rollback of init steps.
|
|
59
59
|
* Separating this from the step list allows rollback to restore
|
|
@@ -74,6 +74,52 @@ interface RollbackState {
|
|
|
74
74
|
* When present, rollback restores this instead of using removeRegisterGlasstrace. */
|
|
75
75
|
originalInstrumentationContent?: string;
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns true when the given `.gitignore` content would exclude the
|
|
79
|
+
* static discovery file at `<root>/public/.well-known/glasstrace.json`
|
|
80
|
+
* or `<root>/static/.well-known/glasstrace.json` (depending on `layout`)
|
|
81
|
+
* from being committed.
|
|
82
|
+
*
|
|
83
|
+
* Model: the file has three ancestors in its committed path — the
|
|
84
|
+
* static root directory (`public/` or `static/`), the `.well-known/`
|
|
85
|
+
* sub-directory, and the file itself. Each pattern in `.gitignore` is
|
|
86
|
+
* classified by which ancestor paths it matches, and each ancestor
|
|
87
|
+
* carries its own current ignore state that later patterns can flip.
|
|
88
|
+
* Patterns that don't match any of the three ancestors are ignored.
|
|
89
|
+
*
|
|
90
|
+
* Per `gitignore(5)`:
|
|
91
|
+
*
|
|
92
|
+
* > It is not possible to re-include a file if a parent directory of
|
|
93
|
+
* > that file is excluded.
|
|
94
|
+
*
|
|
95
|
+
* Consequently, the file is reported as ignored when the final state
|
|
96
|
+
* of ANY ancestor (static root, `.well-known/`, or the file itself)
|
|
97
|
+
* is ignored — a `!<file>` negation alone cannot "escape" an ignored
|
|
98
|
+
* ancestor.
|
|
99
|
+
*
|
|
100
|
+
* Per-ancestor tracking is what distinguishes overlapping patterns:
|
|
101
|
+
*
|
|
102
|
+
* - `public/` then `!public/` — root re-included, file OK.
|
|
103
|
+
* - `public/` then `!public/.well-known/` — root still ignored (scope-2
|
|
104
|
+
* negation doesn't match the scope-1 ancestor path), file ignored.
|
|
105
|
+
* - `.well-known/` then `!public/.well-known/` — `.well-known/` re-included
|
|
106
|
+
* (both patterns match the scope-2 ancestor), file OK.
|
|
107
|
+
* - `.well-known/` then `!public/` — `!public/` matches the
|
|
108
|
+
* scope-1 ancestor only; the scope-2 ancestor (`.well-known/`) is still
|
|
109
|
+
* ignored, so the file is ignored.
|
|
110
|
+
* - `<file>` then `!<file>` — file-level ignore flipped.
|
|
111
|
+
* - `<file>` then `!public/.well-known/` — directory negation does
|
|
112
|
+
* not match the file path; file still ignored.
|
|
113
|
+
*
|
|
114
|
+
* Not-modeled rules — glob wildcards (star, question mark, character
|
|
115
|
+
* classes), overlapping any-depth matches across multiple parents, and
|
|
116
|
+
* nested `.gitignore` files — skew the heuristic toward false positives
|
|
117
|
+
* (extra warning output) rather than false negatives. The warning is
|
|
118
|
+
* advisory.
|
|
119
|
+
*
|
|
120
|
+
* @internal Exported for unit testing only.
|
|
121
|
+
*/
|
|
122
|
+
declare function gitignoreExcludesDiscoveryFile(gitignoreContent: string, layout: "public" | "static"): boolean;
|
|
77
123
|
/**
|
|
78
124
|
* Best-effort rollback of completed init steps in reverse order.
|
|
79
125
|
* Each step is individually try/caught so that a failure in one
|
|
@@ -132,4 +178,4 @@ type VerifyAnonKeyOutcome = {
|
|
|
132
178
|
*/
|
|
133
179
|
declare function verifyAnonKeyRegistration(projectRoot: string): Promise<VerifyAnonKeyOutcome>;
|
|
134
180
|
|
|
135
|
-
export { type InitOptions, type InitResult, type VerifyAnonKeyOutcome, decideMcpConfigAction, meetsNodeVersion, rollbackSteps, runInit, verifyAnonKeyRegistration };
|
|
181
|
+
export { type InitOptions, type InitResult, type VerifyAnonKeyOutcome, decideMcpConfigAction, gitignoreExcludesDiscoveryFile, meetsNodeVersion, rollbackSteps, runInit, verifyAnonKeyRegistration };
|
package/dist/cli/init.js
CHANGED
|
@@ -3,19 +3,25 @@ import {
|
|
|
3
3
|
resolveProjectRoot
|
|
4
4
|
} from "../chunk-55FBXXER.js";
|
|
5
5
|
import {
|
|
6
|
-
buildImportGraph,
|
|
7
6
|
verifyInitReachable
|
|
8
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-DO2YPMQ5.js";
|
|
8
|
+
import {
|
|
9
|
+
buildImportGraph
|
|
10
|
+
} from "../chunk-BT2OCXCG.js";
|
|
9
11
|
import {
|
|
10
12
|
resolveConfig
|
|
11
13
|
} from "../chunk-VUZCLMIX.js";
|
|
12
14
|
import {
|
|
13
15
|
isInitCreatedInstrumentation,
|
|
16
|
+
relativeDiscoveryPath,
|
|
17
|
+
removeDiscoveryFile,
|
|
14
18
|
removeGlasstraceConfigImport,
|
|
15
19
|
removeRegisterGlasstrace,
|
|
20
|
+
resolveStaticRoot,
|
|
16
21
|
unwrapCJSExport,
|
|
17
|
-
unwrapExport
|
|
18
|
-
|
|
22
|
+
unwrapExport,
|
|
23
|
+
writeDiscoveryFile
|
|
24
|
+
} from "../chunk-LU3PPAOQ.js";
|
|
19
25
|
import {
|
|
20
26
|
detectAgents,
|
|
21
27
|
generateInfoSection,
|
|
@@ -27,8 +33,7 @@ import {
|
|
|
27
33
|
import {
|
|
28
34
|
getOrCreateAnonKey,
|
|
29
35
|
readAnonKey
|
|
30
|
-
} from "../chunk-
|
|
31
|
-
import "../chunk-5N2IR4EO.js";
|
|
36
|
+
} from "../chunk-IP4NMDJK.js";
|
|
32
37
|
import {
|
|
33
38
|
addCoverageMapEnv,
|
|
34
39
|
isDevApiKey,
|
|
@@ -41,6 +46,7 @@ import {
|
|
|
41
46
|
scaffoldMcpMarker,
|
|
42
47
|
scaffoldNextConfig
|
|
43
48
|
} from "../chunk-O63DJKIJ.js";
|
|
49
|
+
import "../chunk-TQ54WLCZ.js";
|
|
44
50
|
import {
|
|
45
51
|
MCP_ENDPOINT,
|
|
46
52
|
NEXT_CONFIG_NAMES,
|
|
@@ -105,6 +111,53 @@ async function promptYesNo(question, defaultValue) {
|
|
|
105
111
|
function cleanLeadingBlankLines(content) {
|
|
106
112
|
return content.replace(/^\n{2,}/, "\n");
|
|
107
113
|
}
|
|
114
|
+
function gitignoreExcludesDiscoveryFile(gitignoreContent, layout) {
|
|
115
|
+
const staticRoot = layout === "static" ? "static" : "public";
|
|
116
|
+
const rootTargets = [staticRoot, `${staticRoot}/`];
|
|
117
|
+
const wellKnownTargets = [
|
|
118
|
+
`${staticRoot}/.well-known`,
|
|
119
|
+
`${staticRoot}/.well-known/`,
|
|
120
|
+
".well-known",
|
|
121
|
+
".well-known/"
|
|
122
|
+
];
|
|
123
|
+
const fileTargets = [
|
|
124
|
+
`${staticRoot}/.well-known/glasstrace.json`,
|
|
125
|
+
".well-known/glasstrace.json"
|
|
126
|
+
];
|
|
127
|
+
let rootIgnored = false;
|
|
128
|
+
let wellKnownIgnored = false;
|
|
129
|
+
let fileIgnored = false;
|
|
130
|
+
for (const rawLine of gitignoreContent.split("\n")) {
|
|
131
|
+
const line = rawLine.trim();
|
|
132
|
+
if (line === "" || line.startsWith("#")) continue;
|
|
133
|
+
const negation = line.startsWith("!");
|
|
134
|
+
const pattern = negation ? line.slice(1).trim() : line;
|
|
135
|
+
if (pattern === "") continue;
|
|
136
|
+
const normalized = pattern.startsWith("/") ? pattern.slice(1) : pattern;
|
|
137
|
+
const matchesRoot = matchesDiscoveryPath(normalized, rootTargets);
|
|
138
|
+
const matchesWellKnown = matchesDiscoveryPath(normalized, wellKnownTargets);
|
|
139
|
+
const matchesFile = matchesDiscoveryPath(normalized, fileTargets);
|
|
140
|
+
if (!matchesRoot && !matchesWellKnown && !matchesFile) continue;
|
|
141
|
+
const newState = !negation;
|
|
142
|
+
if (matchesRoot) rootIgnored = newState;
|
|
143
|
+
if (matchesWellKnown) wellKnownIgnored = newState;
|
|
144
|
+
if (matchesFile) fileIgnored = newState;
|
|
145
|
+
}
|
|
146
|
+
return rootIgnored || wellKnownIgnored || fileIgnored;
|
|
147
|
+
}
|
|
148
|
+
function matchesDiscoveryPath(pattern, targets) {
|
|
149
|
+
const bare = pattern.endsWith("/") ? pattern.slice(0, -1) : pattern;
|
|
150
|
+
for (const target of targets) {
|
|
151
|
+
const tBare = target.endsWith("/") ? target.slice(0, -1) : target;
|
|
152
|
+
if (bare === tBare) return true;
|
|
153
|
+
if (pattern.startsWith("**/")) {
|
|
154
|
+
const suffix = pattern.slice(3);
|
|
155
|
+
const sBare = suffix.endsWith("/") ? suffix.slice(0, -1) : suffix;
|
|
156
|
+
if (tBare === sBare || tBare.endsWith(`/${sBare}`)) return true;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
108
161
|
async function rollbackSteps(steps, projectRoot, state) {
|
|
109
162
|
for (const step of [...steps].reverse()) {
|
|
110
163
|
try {
|
|
@@ -185,6 +238,10 @@ async function rollbackSteps(steps, projectRoot, state) {
|
|
|
185
238
|
}
|
|
186
239
|
break;
|
|
187
240
|
}
|
|
241
|
+
case "discovery-file": {
|
|
242
|
+
removeDiscoveryFile(projectRoot);
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
188
245
|
}
|
|
189
246
|
} catch {
|
|
190
247
|
}
|
|
@@ -348,6 +405,50 @@ Then add this as the first statement in your register() function:
|
|
|
348
405
|
if (preExistingAnonKey !== null) {
|
|
349
406
|
summary.push("Preserved existing .glasstrace/anon_key");
|
|
350
407
|
}
|
|
408
|
+
try {
|
|
409
|
+
const discoveryResult = writeDiscoveryFile(projectRoot, anonKey);
|
|
410
|
+
const relPath = relativeDiscoveryPath(discoveryResult.layout);
|
|
411
|
+
switch (discoveryResult.action) {
|
|
412
|
+
case "created":
|
|
413
|
+
summary.push(`Created ${relPath}`);
|
|
414
|
+
rollbackState.steps.push("discovery-file");
|
|
415
|
+
break;
|
|
416
|
+
case "updated-stale":
|
|
417
|
+
summary.push(`Updated ${relPath} (anon key had changed)`);
|
|
418
|
+
break;
|
|
419
|
+
case "skipped-matches":
|
|
420
|
+
summary.push(`Skipped ${relPath} (already matches anon key)`);
|
|
421
|
+
break;
|
|
422
|
+
case "skipped-foreign":
|
|
423
|
+
summary.push(
|
|
424
|
+
`Rewrote ${relPath} (existing file was malformed or not SDK-managed)`
|
|
425
|
+
);
|
|
426
|
+
break;
|
|
427
|
+
case "failed":
|
|
428
|
+
warnings.push(
|
|
429
|
+
`Failed to write ${relPath}${discoveryResult.error !== void 0 ? `: ${discoveryResult.error}` : ""}. The Glasstrace browser extension will fall back to the runtime handler until the file is written.`
|
|
430
|
+
);
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
const gitignorePath = path.join(projectRoot, ".gitignore");
|
|
434
|
+
if (fs.existsSync(gitignorePath)) {
|
|
435
|
+
try {
|
|
436
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, "utf-8");
|
|
437
|
+
if (gitignoreExcludesDiscoveryFile(gitignoreContent, discoveryResult.layout)) {
|
|
438
|
+
warnings.push(
|
|
439
|
+
`Your .gitignore excludes ${relPath} (directly or via a parent rule). The discovery file must be committed for the Glasstrace browser extension to find it in deployed builds. Remove the matching line from .gitignore or add an explicit negation (e.g. \`!` + relPath + "`)."
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
} catch {
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
} catch (err) {
|
|
446
|
+
warnings.push(
|
|
447
|
+
`Failed to write ${relativeDiscoveryPath(
|
|
448
|
+
resolveStaticRoot(projectRoot).layout
|
|
449
|
+
)}: ${err instanceof Error ? err.message : String(err)}`
|
|
450
|
+
);
|
|
451
|
+
}
|
|
351
452
|
let anyConfigWritten = false;
|
|
352
453
|
if (isCI) {
|
|
353
454
|
const genericAgent = {
|
|
@@ -509,7 +610,7 @@ async function verifyAnonKeyRegistration(projectRoot) {
|
|
|
509
610
|
}
|
|
510
611
|
const baseConfig = resolveConfig({ apiKey: devKey });
|
|
511
612
|
const config = { ...baseConfig, apiKey: devKey };
|
|
512
|
-
const sdkVersion = true ? "0.
|
|
613
|
+
const sdkVersion = true ? "0.20.1" : "0.0.0-dev";
|
|
513
614
|
const result = await verifyInitReachable(config, anonKey, sdkVersion);
|
|
514
615
|
if (result.ok) {
|
|
515
616
|
return { outcome: "verified" };
|
|
@@ -758,6 +859,7 @@ Usage:
|
|
|
758
859
|
}
|
|
759
860
|
export {
|
|
760
861
|
decideMcpConfigAction,
|
|
862
|
+
gitignoreExcludesDiscoveryFile,
|
|
761
863
|
meetsNodeVersion,
|
|
762
864
|
rollbackSteps,
|
|
763
865
|
runInit,
|