@launchsecure/launch-kit 0.0.39 → 0.0.41
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/chart-client/assets/index-Dd6IotOZ.css +1 -0
- package/dist/chart-client/index.html +2 -2
- package/dist/client/assets/index-DE0uje6k.css +32 -0
- package/dist/client/index.html +2 -2
- package/dist/council-client/assets/index-CGYusOCK.css +1 -0
- package/dist/council-client/assets/{index-jjBWyhry.js → index-DkTFX53U.js} +1 -1
- package/dist/council-client/index.html +2 -2
- package/dist/deck-client/assets/_baseUniq-mvYvzeEJ.js +1 -0
- package/dist/deck-client/assets/arc-CX4ylnp2.js +1 -0
- package/dist/deck-client/assets/architectureDiagram-Q4EWVU46-BkR-5IRK.js +36 -0
- package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-CwAGy9lU.js → blockDiagram-DXYQGD6D-DVNQht7c.js} +2 -2
- package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-L_g_SS21.js → c4Diagram-AHTNJAMY-Cbq1rlG8.js} +2 -2
- package/dist/deck-client/assets/channel-B9GC-CLn.js +1 -0
- package/dist/deck-client/assets/chunk-4BX2VUAB-D58Co4lU.js +1 -0
- package/dist/deck-client/assets/{chunk-4TB4RGXK-Bk0FUbxU.js → chunk-4TB4RGXK-BYvhTm3d.js} +1 -1
- package/dist/deck-client/assets/chunk-55IACEB6-oWukUhYg.js +1 -0
- package/dist/deck-client/assets/chunk-EDXVE4YY-Cm58kVnZ.js +1 -0
- package/dist/deck-client/assets/{chunk-FMBD7UC4-DqOvWr1k.js → chunk-FMBD7UC4-Dg-i7kzi.js} +1 -1
- package/dist/deck-client/assets/{chunk-OYMX7WX6-1Kd7yK5u.js → chunk-OYMX7WX6-C72wigPl.js} +1 -1
- package/dist/deck-client/assets/chunk-QZHKN3VN-CLgeuAKw.js +1 -0
- package/dist/deck-client/assets/chunk-YZCP3GAM-HDDlJ5oI.js +1 -0
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-CFBvYQ9j.js +1 -0
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-CFBvYQ9j.js +1 -0
- package/dist/deck-client/assets/clone-n-WQlAGe.js +1 -0
- package/dist/deck-client/assets/cose-bilkent-S5V4N54A-CUXQKg2M.js +1 -0
- package/dist/deck-client/assets/dagre-KV5264BT-C5M-fVDc.js +4 -0
- package/dist/deck-client/assets/diagram-5BDNPKRD-CcVsQ0S8.js +10 -0
- package/dist/deck-client/assets/diagram-G4DWMVQ6-DJswXyep.js +24 -0
- package/dist/deck-client/assets/diagram-MMDJMWI5-CGT76fm1.js +43 -0
- package/dist/deck-client/assets/diagram-TYMM5635-BBsYUNN6.js +24 -0
- package/dist/deck-client/assets/{erDiagram-SMLLAGMA-aiv9GZnL.js → erDiagram-SMLLAGMA-DKWYEHQS.js} +2 -2
- package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-C6Fhvtsy.js → flowDiagram-DWJPFMVM-DLuDYIKT.js} +2 -2
- package/dist/deck-client/assets/ganttDiagram-T4ZO3ILL-B19b6Qtj.js +292 -0
- package/dist/deck-client/assets/gitGraphDiagram-UUTBAWPF-BYLAfYVS.js +106 -0
- package/dist/deck-client/assets/graph-CfzQUfPh.js +1 -0
- package/dist/deck-client/assets/index-DlwdTgE_.js +892 -0
- package/dist/deck-client/assets/index-evAPhGvM.css +1 -0
- package/dist/deck-client/assets/infoDiagram-42DDH7IO-Dp3mUA9c.js +2 -0
- package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-BwCUmUVt.js → ishikawaDiagram-UXIWVN3A-BhrNX_jI.js} +5 -5
- package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-C6qoqJmJ.js → journeyDiagram-VCZTEJTY-B5lJI492.js} +2 -2
- package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-Dz1Tt3sA.js → kanban-definition-6JOO6SKY-D9-lmhQf.js} +2 -2
- package/dist/deck-client/assets/layout-CfIe_Su8.js +1 -0
- package/dist/deck-client/assets/linear-09ZFRoh_.js +1 -0
- package/dist/deck-client/assets/mermaid.core-BaQyIOvj.js +309 -0
- package/dist/deck-client/assets/min-CYwCzYaL.js +1 -0
- package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-CfXcK1qH.js → mindmap-definition-QFDTVHPH-CouFxf6C.js} +2 -2
- package/dist/deck-client/assets/pieDiagram-DEJITSTG-DMB1ufC0.js +30 -0
- package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-CXwvZ1i1.js → quadrantDiagram-34T5L4WZ-CBiOKudN.js} +2 -2
- package/dist/deck-client/assets/{requirementDiagram-MS252O5E-Cl6xm0fR.js → requirementDiagram-MS252O5E-BMc3GJkx.js} +2 -2
- package/dist/deck-client/assets/sankeyDiagram-XADWPNL6-CxACUncm.js +10 -0
- package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-BC1MYBn6.js → sequenceDiagram-FGHM5R23-Ch-P3Mzc.js} +2 -2
- package/dist/deck-client/assets/stateDiagram-FHFEXIEX-Cy8n7Yzk.js +1 -0
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-C14VKCzi.js +1 -0
- package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-DKnITsD4.js → timeline-definition-GMOUNBTQ-C2V4sSkm.js} +2 -2
- package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-BdajXRrh.js → vennDiagram-DHZGUBPP-YOqt4VbE.js} +2 -2
- package/dist/deck-client/assets/wardley-RL74JXVD-Bxo5x40D.js +162 -0
- package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-B2hDCDl2.js → wardleyDiagram-NUSXRM2D-DW9SOqbx.js} +2 -2
- package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-CvnYFs51.js → xychartDiagram-5P7HB3ND-D-rZvZOL.js} +2 -2
- package/dist/deck-client/index.html +2 -2
- package/dist/server/beacon-monitor-entry.js +106 -24
- package/dist/server/chart-serve.js +544 -247
- package/dist/server/cli.js +1016 -324
- package/dist/server/council-entry.js +23 -4
- package/dist/server/council-serve.js +22 -3
- package/dist/server/deck-mcp-entry.js +523 -125
- package/dist/server/deck-serve.js +326 -40
- package/dist/server/graph-mcp-entry.js +1160 -357
- package/dist/server/init-entry.js +17 -7
- package/dist/server/orbit-entry.js +91 -7
- package/dist/server/recall-entry.js +94 -12
- package/dist/server/rover-entry.js +1 -1
- package/package.json +1 -1
- package/scaffolds/ls-marketplace/plugins/kit/skills/comms/SKILL.md +34 -1
- package/scaffolds/ls-marketplace/plugins/kit/skills/gen-test/SKILL.md +126 -0
- package/scaffolds/statusline/statusline-mcp.sh +68 -19
- package/scaffolds/statusline/statusline-wrapper.sh +12 -9
- package/dist/chart-client/assets/index-ysGpLeOW.css +0 -1
- package/dist/client/assets/index-CMN3tlGP.css +0 -32
- package/dist/council-client/assets/index-ChmNX6bZ.css +0 -1
- package/dist/deck-client/assets/_baseUniq-DOrnEQMI.js +0 -1
- package/dist/deck-client/assets/arc-DOWK7V3m.js +0 -1
- package/dist/deck-client/assets/architectureDiagram-Q4EWVU46-DPhzvk7q.js +0 -36
- package/dist/deck-client/assets/channel-DqiACUUq.js +0 -1
- package/dist/deck-client/assets/chunk-4BX2VUAB-RKm0LXpu.js +0 -1
- package/dist/deck-client/assets/chunk-55IACEB6-Cl3hja-M.js +0 -1
- package/dist/deck-client/assets/chunk-EDXVE4YY-CNIMQCV2.js +0 -1
- package/dist/deck-client/assets/chunk-QZHKN3VN-6_kraYpP.js +0 -1
- package/dist/deck-client/assets/chunk-YZCP3GAM-FgAwIWlo.js +0 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-D23cq2C3.js +0 -1
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-D23cq2C3.js +0 -1
- package/dist/deck-client/assets/clone-C7jSigGq.js +0 -1
- package/dist/deck-client/assets/cose-bilkent-S5V4N54A-CigVnnPr.js +0 -1
- package/dist/deck-client/assets/dagre-KV5264BT-DHZXTktX.js +0 -4
- package/dist/deck-client/assets/diagram-5BDNPKRD-H5k0eauU.js +0 -10
- package/dist/deck-client/assets/diagram-G4DWMVQ6-Bg3dFhSY.js +0 -24
- package/dist/deck-client/assets/diagram-MMDJMWI5-CQLC410N.js +0 -43
- package/dist/deck-client/assets/diagram-TYMM5635-DFTCHVkP.js +0 -24
- package/dist/deck-client/assets/ganttDiagram-T4ZO3ILL-DSaGMPM4.js +0 -292
- package/dist/deck-client/assets/gitGraphDiagram-UUTBAWPF-DMjL2Vix.js +0 -106
- package/dist/deck-client/assets/graph-B7Vn5lkK.js +0 -1
- package/dist/deck-client/assets/index-BD36e-tD.js +0 -1196
- package/dist/deck-client/assets/index-CGbNOpk9.css +0 -1
- package/dist/deck-client/assets/infoDiagram-42DDH7IO-mNi4iygG.js +0 -2
- package/dist/deck-client/assets/layout-CZTyRhOG.js +0 -1
- package/dist/deck-client/assets/linear--7n7iEvd.js +0 -1
- package/dist/deck-client/assets/min-Bh130DN8.js +0 -1
- package/dist/deck-client/assets/pieDiagram-DEJITSTG-DjVHLAVw.js +0 -30
- package/dist/deck-client/assets/sankeyDiagram-XADWPNL6-BOH9sLyh.js +0 -10
- package/dist/deck-client/assets/stateDiagram-FHFEXIEX-kNp9bv8K.js +0 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-hRsAFc2t.js +0 -1
- package/dist/deck-client/assets/wardley-RL74JXVD-BL802-su.js +0 -162
- /package/dist/chart-client/assets/{index-BlsuXuQ1.js → index-CrYM1-ac.js} +0 -0
- /package/dist/client/assets/{index-BA7BHBWT.js → index-BoIjawzY.js} +0 -0
package/dist/server/cli.js
CHANGED
|
@@ -1752,7 +1752,7 @@ var require_usage_reader = __commonJS({
|
|
|
1752
1752
|
async readJsonlFile(filePath, cutoffTime) {
|
|
1753
1753
|
const entries = [];
|
|
1754
1754
|
const fileProcessedEntries = /* @__PURE__ */ new Set();
|
|
1755
|
-
return new Promise((
|
|
1755
|
+
return new Promise((resolve7) => {
|
|
1756
1756
|
const rl = readline.createInterface({
|
|
1757
1757
|
input: createReadStream(filePath),
|
|
1758
1758
|
crlfDelay: Infinity
|
|
@@ -1810,11 +1810,11 @@ var require_usage_reader = __commonJS({
|
|
|
1810
1810
|
}
|
|
1811
1811
|
});
|
|
1812
1812
|
rl.on("close", () => {
|
|
1813
|
-
|
|
1813
|
+
resolve7(entries);
|
|
1814
1814
|
});
|
|
1815
1815
|
rl.on("error", (error) => {
|
|
1816
1816
|
console.error("Error reading file:", filePath, error);
|
|
1817
|
-
|
|
1817
|
+
resolve7(entries);
|
|
1818
1818
|
});
|
|
1819
1819
|
});
|
|
1820
1820
|
}
|
|
@@ -3623,7 +3623,7 @@ var require_src = __commonJS({
|
|
|
3623
3623
|
if (session.active) throw new Error(`Agent already running in session ${sessionId}`);
|
|
3624
3624
|
const { command, args = [], env = {} } = options;
|
|
3625
3625
|
if (!command) throw new Error("startScriptInSession requires a command");
|
|
3626
|
-
return new Promise((
|
|
3626
|
+
return new Promise((resolve7, reject) => {
|
|
3627
3627
|
this.scriptBridge.startSession(sessionId, {
|
|
3628
3628
|
command,
|
|
3629
3629
|
args,
|
|
@@ -3645,7 +3645,7 @@ var require_src = __commonJS({
|
|
|
3645
3645
|
session.lastActivity = /* @__PURE__ */ new Date();
|
|
3646
3646
|
this.broadcastToSession(sessionId, { type: "script_stopped", sessionId });
|
|
3647
3647
|
if (exitCode === 0) {
|
|
3648
|
-
|
|
3648
|
+
resolve7({ code: exitCode, signal });
|
|
3649
3649
|
} else {
|
|
3650
3650
|
reject(new Error(`Script exited with code ${exitCode}`));
|
|
3651
3651
|
}
|
|
@@ -5567,9 +5567,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
5567
5567
|
}
|
|
5568
5568
|
close(callback) {
|
|
5569
5569
|
if (callback === void 0) {
|
|
5570
|
-
return new Promise((
|
|
5570
|
+
return new Promise((resolve7, reject) => {
|
|
5571
5571
|
this.close((err2, data) => {
|
|
5572
|
-
return err2 ? reject(err2) :
|
|
5572
|
+
return err2 ? reject(err2) : resolve7(data);
|
|
5573
5573
|
});
|
|
5574
5574
|
});
|
|
5575
5575
|
}
|
|
@@ -5607,12 +5607,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
5607
5607
|
err2 = null;
|
|
5608
5608
|
}
|
|
5609
5609
|
if (callback === void 0) {
|
|
5610
|
-
return new Promise((
|
|
5610
|
+
return new Promise((resolve7, reject) => {
|
|
5611
5611
|
this.destroy(err2, (err3, data) => {
|
|
5612
5612
|
return err3 ? (
|
|
5613
5613
|
/* istanbul ignore next: should never error */
|
|
5614
5614
|
reject(err3)
|
|
5615
|
-
) :
|
|
5615
|
+
) : resolve7(data);
|
|
5616
5616
|
});
|
|
5617
5617
|
});
|
|
5618
5618
|
}
|
|
@@ -7879,8 +7879,8 @@ var require_util2 = __commonJS({
|
|
|
7879
7879
|
function createDeferredPromise() {
|
|
7880
7880
|
let res;
|
|
7881
7881
|
let rej;
|
|
7882
|
-
const promise = new Promise((
|
|
7883
|
-
res =
|
|
7882
|
+
const promise = new Promise((resolve7, reject) => {
|
|
7883
|
+
res = resolve7;
|
|
7884
7884
|
rej = reject;
|
|
7885
7885
|
});
|
|
7886
7886
|
return { promise, resolve: res, reject: rej };
|
|
@@ -10021,12 +10021,12 @@ upgrade: ${upgrade}\r
|
|
|
10021
10021
|
cb();
|
|
10022
10022
|
}
|
|
10023
10023
|
}
|
|
10024
|
-
const waitForDrain = () => new Promise((
|
|
10024
|
+
const waitForDrain = () => new Promise((resolve7, reject) => {
|
|
10025
10025
|
assert(callback === null);
|
|
10026
10026
|
if (socket[kError]) {
|
|
10027
10027
|
reject(socket[kError]);
|
|
10028
10028
|
} else {
|
|
10029
|
-
callback =
|
|
10029
|
+
callback = resolve7;
|
|
10030
10030
|
}
|
|
10031
10031
|
});
|
|
10032
10032
|
socket.on("close", onDrain).on("drain", onDrain);
|
|
@@ -10663,12 +10663,12 @@ var require_client_h2 = __commonJS({
|
|
|
10663
10663
|
cb();
|
|
10664
10664
|
}
|
|
10665
10665
|
}
|
|
10666
|
-
const waitForDrain = () => new Promise((
|
|
10666
|
+
const waitForDrain = () => new Promise((resolve7, reject) => {
|
|
10667
10667
|
assert(callback === null);
|
|
10668
10668
|
if (socket[kError]) {
|
|
10669
10669
|
reject(socket[kError]);
|
|
10670
10670
|
} else {
|
|
10671
|
-
callback =
|
|
10671
|
+
callback = resolve7;
|
|
10672
10672
|
}
|
|
10673
10673
|
});
|
|
10674
10674
|
h2stream.on("close", onDrain).on("drain", onDrain);
|
|
@@ -11146,16 +11146,16 @@ var require_client = __commonJS({
|
|
|
11146
11146
|
return this[kNeedDrain] < 2;
|
|
11147
11147
|
}
|
|
11148
11148
|
async [kClose]() {
|
|
11149
|
-
return new Promise((
|
|
11149
|
+
return new Promise((resolve7) => {
|
|
11150
11150
|
if (this[kSize]) {
|
|
11151
|
-
this[kClosedResolve] =
|
|
11151
|
+
this[kClosedResolve] = resolve7;
|
|
11152
11152
|
} else {
|
|
11153
|
-
|
|
11153
|
+
resolve7(null);
|
|
11154
11154
|
}
|
|
11155
11155
|
});
|
|
11156
11156
|
}
|
|
11157
11157
|
async [kDestroy](err2) {
|
|
11158
|
-
return new Promise((
|
|
11158
|
+
return new Promise((resolve7) => {
|
|
11159
11159
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
11160
11160
|
for (let i = 0; i < requests.length; i++) {
|
|
11161
11161
|
const request = requests[i];
|
|
@@ -11166,7 +11166,7 @@ var require_client = __commonJS({
|
|
|
11166
11166
|
this[kClosedResolve]();
|
|
11167
11167
|
this[kClosedResolve] = null;
|
|
11168
11168
|
}
|
|
11169
|
-
|
|
11169
|
+
resolve7(null);
|
|
11170
11170
|
};
|
|
11171
11171
|
if (this[kHTTPContext]) {
|
|
11172
11172
|
this[kHTTPContext].destroy(err2, callback);
|
|
@@ -11217,7 +11217,7 @@ var require_client = __commonJS({
|
|
|
11217
11217
|
});
|
|
11218
11218
|
}
|
|
11219
11219
|
try {
|
|
11220
|
-
const socket = await new Promise((
|
|
11220
|
+
const socket = await new Promise((resolve7, reject) => {
|
|
11221
11221
|
client[kConnector]({
|
|
11222
11222
|
host,
|
|
11223
11223
|
hostname,
|
|
@@ -11229,7 +11229,7 @@ var require_client = __commonJS({
|
|
|
11229
11229
|
if (err2) {
|
|
11230
11230
|
reject(err2);
|
|
11231
11231
|
} else {
|
|
11232
|
-
|
|
11232
|
+
resolve7(socket2);
|
|
11233
11233
|
}
|
|
11234
11234
|
});
|
|
11235
11235
|
});
|
|
@@ -11565,8 +11565,8 @@ var require_pool_base = __commonJS({
|
|
|
11565
11565
|
if (this[kQueue].isEmpty()) {
|
|
11566
11566
|
await Promise.all(this[kClients].map((c) => c.close()));
|
|
11567
11567
|
} else {
|
|
11568
|
-
await new Promise((
|
|
11569
|
-
this[kClosedResolve] =
|
|
11568
|
+
await new Promise((resolve7) => {
|
|
11569
|
+
this[kClosedResolve] = resolve7;
|
|
11570
11570
|
});
|
|
11571
11571
|
}
|
|
11572
11572
|
}
|
|
@@ -12781,7 +12781,7 @@ var require_readable = __commonJS({
|
|
|
12781
12781
|
if (this._readableState.closeEmitted) {
|
|
12782
12782
|
return null;
|
|
12783
12783
|
}
|
|
12784
|
-
return await new Promise((
|
|
12784
|
+
return await new Promise((resolve7, reject) => {
|
|
12785
12785
|
if (this[kContentLength] > limit) {
|
|
12786
12786
|
this.destroy(new AbortError());
|
|
12787
12787
|
}
|
|
@@ -12794,7 +12794,7 @@ var require_readable = __commonJS({
|
|
|
12794
12794
|
if (signal?.aborted) {
|
|
12795
12795
|
reject(signal.reason ?? new AbortError());
|
|
12796
12796
|
} else {
|
|
12797
|
-
|
|
12797
|
+
resolve7(null);
|
|
12798
12798
|
}
|
|
12799
12799
|
}).on("error", noop).on("data", function(chunk) {
|
|
12800
12800
|
limit -= chunk.length;
|
|
@@ -12813,7 +12813,7 @@ var require_readable = __commonJS({
|
|
|
12813
12813
|
}
|
|
12814
12814
|
async function consume(stream, type) {
|
|
12815
12815
|
assert(!stream[kConsume]);
|
|
12816
|
-
return new Promise((
|
|
12816
|
+
return new Promise((resolve7, reject) => {
|
|
12817
12817
|
if (isUnusable(stream)) {
|
|
12818
12818
|
const rState = stream._readableState;
|
|
12819
12819
|
if (rState.destroyed && rState.closeEmitted === false) {
|
|
@@ -12830,7 +12830,7 @@ var require_readable = __commonJS({
|
|
|
12830
12830
|
stream[kConsume] = {
|
|
12831
12831
|
type,
|
|
12832
12832
|
stream,
|
|
12833
|
-
resolve:
|
|
12833
|
+
resolve: resolve7,
|
|
12834
12834
|
reject,
|
|
12835
12835
|
length: 0,
|
|
12836
12836
|
body: []
|
|
@@ -12900,18 +12900,18 @@ var require_readable = __commonJS({
|
|
|
12900
12900
|
return buffer;
|
|
12901
12901
|
}
|
|
12902
12902
|
function consumeEnd(consume2) {
|
|
12903
|
-
const { type, body, resolve:
|
|
12903
|
+
const { type, body, resolve: resolve7, stream, length } = consume2;
|
|
12904
12904
|
try {
|
|
12905
12905
|
if (type === "text") {
|
|
12906
|
-
|
|
12906
|
+
resolve7(chunksDecode(body, length));
|
|
12907
12907
|
} else if (type === "json") {
|
|
12908
|
-
|
|
12908
|
+
resolve7(JSON.parse(chunksDecode(body, length)));
|
|
12909
12909
|
} else if (type === "arrayBuffer") {
|
|
12910
|
-
|
|
12910
|
+
resolve7(chunksConcat(body, length).buffer);
|
|
12911
12911
|
} else if (type === "blob") {
|
|
12912
|
-
|
|
12912
|
+
resolve7(new Blob(body, { type: stream[kContentType] }));
|
|
12913
12913
|
} else if (type === "bytes") {
|
|
12914
|
-
|
|
12914
|
+
resolve7(chunksConcat(body, length));
|
|
12915
12915
|
}
|
|
12916
12916
|
consumeFinish(consume2);
|
|
12917
12917
|
} catch (err2) {
|
|
@@ -13168,9 +13168,9 @@ var require_api_request = __commonJS({
|
|
|
13168
13168
|
};
|
|
13169
13169
|
function request(opts, callback) {
|
|
13170
13170
|
if (callback === void 0) {
|
|
13171
|
-
return new Promise((
|
|
13171
|
+
return new Promise((resolve7, reject) => {
|
|
13172
13172
|
request.call(this, opts, (err2, data) => {
|
|
13173
|
-
return err2 ? reject(err2) :
|
|
13173
|
+
return err2 ? reject(err2) : resolve7(data);
|
|
13174
13174
|
});
|
|
13175
13175
|
});
|
|
13176
13176
|
}
|
|
@@ -13393,9 +13393,9 @@ var require_api_stream = __commonJS({
|
|
|
13393
13393
|
};
|
|
13394
13394
|
function stream(opts, factory, callback) {
|
|
13395
13395
|
if (callback === void 0) {
|
|
13396
|
-
return new Promise((
|
|
13396
|
+
return new Promise((resolve7, reject) => {
|
|
13397
13397
|
stream.call(this, opts, factory, (err2, data) => {
|
|
13398
|
-
return err2 ? reject(err2) :
|
|
13398
|
+
return err2 ? reject(err2) : resolve7(data);
|
|
13399
13399
|
});
|
|
13400
13400
|
});
|
|
13401
13401
|
}
|
|
@@ -13680,9 +13680,9 @@ var require_api_upgrade = __commonJS({
|
|
|
13680
13680
|
};
|
|
13681
13681
|
function upgrade(opts, callback) {
|
|
13682
13682
|
if (callback === void 0) {
|
|
13683
|
-
return new Promise((
|
|
13683
|
+
return new Promise((resolve7, reject) => {
|
|
13684
13684
|
upgrade.call(this, opts, (err2, data) => {
|
|
13685
|
-
return err2 ? reject(err2) :
|
|
13685
|
+
return err2 ? reject(err2) : resolve7(data);
|
|
13686
13686
|
});
|
|
13687
13687
|
});
|
|
13688
13688
|
}
|
|
@@ -13774,9 +13774,9 @@ var require_api_connect = __commonJS({
|
|
|
13774
13774
|
};
|
|
13775
13775
|
function connect(opts, callback) {
|
|
13776
13776
|
if (callback === void 0) {
|
|
13777
|
-
return new Promise((
|
|
13777
|
+
return new Promise((resolve7, reject) => {
|
|
13778
13778
|
connect.call(this, opts, (err2, data) => {
|
|
13779
|
-
return err2 ? reject(err2) :
|
|
13779
|
+
return err2 ? reject(err2) : resolve7(data);
|
|
13780
13780
|
});
|
|
13781
13781
|
});
|
|
13782
13782
|
}
|
|
@@ -17638,7 +17638,7 @@ var require_fetch = __commonJS({
|
|
|
17638
17638
|
function dispatch({ body }) {
|
|
17639
17639
|
const url = requestCurrentURL(request);
|
|
17640
17640
|
const agent = fetchParams.controller.dispatcher;
|
|
17641
|
-
return new Promise((
|
|
17641
|
+
return new Promise((resolve7, reject) => agent.dispatch(
|
|
17642
17642
|
{
|
|
17643
17643
|
path: url.pathname + url.search,
|
|
17644
17644
|
origin: url.origin,
|
|
@@ -17714,7 +17714,7 @@ var require_fetch = __commonJS({
|
|
|
17714
17714
|
}
|
|
17715
17715
|
}
|
|
17716
17716
|
const onError = this.onError.bind(this);
|
|
17717
|
-
|
|
17717
|
+
resolve7({
|
|
17718
17718
|
status,
|
|
17719
17719
|
statusText,
|
|
17720
17720
|
headersList,
|
|
@@ -17760,7 +17760,7 @@ var require_fetch = __commonJS({
|
|
|
17760
17760
|
for (let i = 0; i < rawHeaders.length; i += 2) {
|
|
17761
17761
|
headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true);
|
|
17762
17762
|
}
|
|
17763
|
-
|
|
17763
|
+
resolve7({
|
|
17764
17764
|
status,
|
|
17765
17765
|
statusText: STATUS_CODES[status],
|
|
17766
17766
|
headersList,
|
|
@@ -21436,8 +21436,8 @@ var require_util8 = __commonJS({
|
|
|
21436
21436
|
return true;
|
|
21437
21437
|
}
|
|
21438
21438
|
function delay(ms) {
|
|
21439
|
-
return new Promise((
|
|
21440
|
-
setTimeout(
|
|
21439
|
+
return new Promise((resolve7) => {
|
|
21440
|
+
setTimeout(resolve7, ms).unref();
|
|
21441
21441
|
});
|
|
21442
21442
|
}
|
|
21443
21443
|
module2.exports = {
|
|
@@ -22628,7 +22628,7 @@ function resolveWorkerPath() {
|
|
|
22628
22628
|
);
|
|
22629
22629
|
}
|
|
22630
22630
|
function runParseInWorker(req) {
|
|
22631
|
-
return new Promise((
|
|
22631
|
+
return new Promise((resolve7, reject) => {
|
|
22632
22632
|
let workerPath;
|
|
22633
22633
|
try {
|
|
22634
22634
|
workerPath = resolveWorkerPath();
|
|
@@ -22647,7 +22647,7 @@ function runParseInWorker(req) {
|
|
|
22647
22647
|
};
|
|
22648
22648
|
worker.on("message", (reply) => {
|
|
22649
22649
|
if (reply.ok) {
|
|
22650
|
-
finish(() =>
|
|
22650
|
+
finish(() => resolve7({ results: reply.results, failedFiles: reply.failedFiles }));
|
|
22651
22651
|
} else {
|
|
22652
22652
|
const err2 = new Error(reply.error.message);
|
|
22653
22653
|
err2.name = reply.error.name;
|
|
@@ -22741,6 +22741,328 @@ var init_effects_index = __esm({
|
|
|
22741
22741
|
}
|
|
22742
22742
|
});
|
|
22743
22743
|
|
|
22744
|
+
// src/server/graph/core/context/types.ts
|
|
22745
|
+
function higherConfidence(a, b) {
|
|
22746
|
+
return CONFIDENCE_RANK[a] >= CONFIDENCE_RANK[b] ? a : b;
|
|
22747
|
+
}
|
|
22748
|
+
function stateId(token) {
|
|
22749
|
+
return `state:${token}`;
|
|
22750
|
+
}
|
|
22751
|
+
function actionId(key) {
|
|
22752
|
+
return `action:${key}`;
|
|
22753
|
+
}
|
|
22754
|
+
function stateNode(token, label) {
|
|
22755
|
+
return { id: stateId(token), type: CONTEXT_NODE_STATE, name: token, label };
|
|
22756
|
+
}
|
|
22757
|
+
function actionNode(key, name, meta = {}) {
|
|
22758
|
+
return { id: actionId(key), type: CONTEXT_NODE_ACTION, name, ...meta };
|
|
22759
|
+
}
|
|
22760
|
+
function contextEdge(fromActionId, toStateId, type, confidence, origin) {
|
|
22761
|
+
return { source: fromActionId, target: toStateId, type, label: `${type} (${origin})`, confidence, origin };
|
|
22762
|
+
}
|
|
22763
|
+
var CONTEXT_NODE_ACTION, CONTEXT_NODE_STATE, CONFIDENCE_RANK;
|
|
22764
|
+
var init_types = __esm({
|
|
22765
|
+
"src/server/graph/core/context/types.ts"() {
|
|
22766
|
+
"use strict";
|
|
22767
|
+
CONTEXT_NODE_ACTION = "action";
|
|
22768
|
+
CONTEXT_NODE_STATE = "state";
|
|
22769
|
+
CONFIDENCE_RANK = { low: 0, medium: 1, high: 2 };
|
|
22770
|
+
}
|
|
22771
|
+
});
|
|
22772
|
+
|
|
22773
|
+
// src/server/graph/core/context/providers/nextjs-prisma.ts
|
|
22774
|
+
function isPublic(auth) {
|
|
22775
|
+
if (!auth || auth.length === 0) return true;
|
|
22776
|
+
return auth.every((a) => a === "public");
|
|
22777
|
+
}
|
|
22778
|
+
function notFoundEntity(consequence) {
|
|
22779
|
+
if (!consequence) return null;
|
|
22780
|
+
const m = consequence.match(/notFound\(\s*['"]([A-Za-z0-9_]+)['"]/);
|
|
22781
|
+
return m ? m[1] : null;
|
|
22782
|
+
}
|
|
22783
|
+
var PRODUCING_METHODS, nextjsPrismaContextProvider;
|
|
22784
|
+
var init_nextjs_prisma = __esm({
|
|
22785
|
+
"src/server/graph/core/context/providers/nextjs-prisma.ts"() {
|
|
22786
|
+
"use strict";
|
|
22787
|
+
init_types();
|
|
22788
|
+
PRODUCING_METHODS = /* @__PURE__ */ new Set(["create", "createMany", "upsert"]);
|
|
22789
|
+
nextjsPrismaContextProvider = {
|
|
22790
|
+
id: "nextjs-prisma",
|
|
22791
|
+
detect(layerOutputs) {
|
|
22792
|
+
const api = layerOutputs["api"];
|
|
22793
|
+
return !!api && (api.nodes ?? []).some((n) => n.type === "endpoint");
|
|
22794
|
+
},
|
|
22795
|
+
derive(layerOutputs) {
|
|
22796
|
+
const api = layerOutputs["api"];
|
|
22797
|
+
const states = /* @__PURE__ */ new Map();
|
|
22798
|
+
const actions = [];
|
|
22799
|
+
const edges = [];
|
|
22800
|
+
const seenEdge = /* @__PURE__ */ new Set();
|
|
22801
|
+
const ensureState = (token, label) => {
|
|
22802
|
+
const id = stateId(token);
|
|
22803
|
+
if (!states.has(id)) states.set(id, stateNode(token, label));
|
|
22804
|
+
return id;
|
|
22805
|
+
};
|
|
22806
|
+
const addEdge = (from, to, type, confidence, origin) => {
|
|
22807
|
+
const key = `${from}|${type}|${to}`;
|
|
22808
|
+
if (seenEdge.has(key)) return;
|
|
22809
|
+
seenEdge.add(key);
|
|
22810
|
+
edges.push(contextEdge(from, to, type, confidence, origin));
|
|
22811
|
+
};
|
|
22812
|
+
const endpoints = (api?.nodes ?? []).filter((n) => n.type === "endpoint");
|
|
22813
|
+
for (const ep of endpoints) {
|
|
22814
|
+
const aId = actionId(ep.id);
|
|
22815
|
+
actions.push(actionNode(ep.id, ep.name, { methods: ep.methods ?? [], endpoint: ep.id }));
|
|
22816
|
+
if (!isPublic(ep.auth)) {
|
|
22817
|
+
addEdge(aId, ensureState("session", "Authenticated session"), "requires", "high", "auth-wrapper");
|
|
22818
|
+
}
|
|
22819
|
+
for (const op of ep.db_operations ?? []) {
|
|
22820
|
+
const [model, method] = op.split(".");
|
|
22821
|
+
if (!model || !PRODUCING_METHODS.has(method ?? "")) continue;
|
|
22822
|
+
addEdge(aId, ensureState(model, `${model} record exists`), "produces", "medium", `db:${op}`);
|
|
22823
|
+
}
|
|
22824
|
+
for (const cond of ep.conditions ?? []) {
|
|
22825
|
+
const entity = notFoundEntity(cond.consequence);
|
|
22826
|
+
if (!entity) continue;
|
|
22827
|
+
const token = entity.toLowerCase();
|
|
22828
|
+
addEdge(aId, ensureState(token, `${token} record exists`), "requires", "low", "guard:notFound");
|
|
22829
|
+
}
|
|
22830
|
+
}
|
|
22831
|
+
return { nodes: [...actions, ...states.values()], edges };
|
|
22832
|
+
}
|
|
22833
|
+
};
|
|
22834
|
+
}
|
|
22835
|
+
});
|
|
22836
|
+
|
|
22837
|
+
// src/server/graph/core/context/overlay.ts
|
|
22838
|
+
function overlayPath(rootDir) {
|
|
22839
|
+
return (0, import_node_path12.join)(rootDir, OVERLAY_FILE);
|
|
22840
|
+
}
|
|
22841
|
+
function loadOverlay(rootDir) {
|
|
22842
|
+
const path13 = overlayPath(rootDir);
|
|
22843
|
+
if (!(0, import_node_fs10.existsSync)(path13)) return null;
|
|
22844
|
+
try {
|
|
22845
|
+
return JSON.parse((0, import_node_fs10.readFileSync)(path13, "utf-8"));
|
|
22846
|
+
} catch (e) {
|
|
22847
|
+
process.stderr.write(`[launch-chart] failed to parse ${OVERLAY_FILE}: ${e.message}
|
|
22848
|
+
`);
|
|
22849
|
+
return null;
|
|
22850
|
+
}
|
|
22851
|
+
}
|
|
22852
|
+
function applyOverlayRejections(edges, rootDir) {
|
|
22853
|
+
const overlay = loadOverlay(rootDir);
|
|
22854
|
+
const rejects = overlay?.reject ?? [];
|
|
22855
|
+
if (rejects.length === 0) return edges;
|
|
22856
|
+
const rejectKeys = new Set(
|
|
22857
|
+
rejects.map((r) => `${actionId(r.action)}|${r.type}|${stateId(r.state)}`)
|
|
22858
|
+
);
|
|
22859
|
+
return edges.filter((e) => !rejectKeys.has(`${e.source}|${e.type}|${e.target}`));
|
|
22860
|
+
}
|
|
22861
|
+
var import_node_fs10, import_node_path12, OVERLAY_FILE, overlayProvider;
|
|
22862
|
+
var init_overlay = __esm({
|
|
22863
|
+
"src/server/graph/core/context/overlay.ts"() {
|
|
22864
|
+
"use strict";
|
|
22865
|
+
import_node_fs10 = require("node:fs");
|
|
22866
|
+
import_node_path12 = require("node:path");
|
|
22867
|
+
init_types();
|
|
22868
|
+
OVERLAY_FILE = ".launchchart.context.json";
|
|
22869
|
+
overlayProvider = {
|
|
22870
|
+
id: "overlay",
|
|
22871
|
+
detect(_layerOutputs, rootDir) {
|
|
22872
|
+
return (0, import_node_fs10.existsSync)(overlayPath(rootDir));
|
|
22873
|
+
},
|
|
22874
|
+
derive(_layerOutputs, rootDir) {
|
|
22875
|
+
const overlay = loadOverlay(rootDir);
|
|
22876
|
+
if (!overlay) return { nodes: [], edges: [] };
|
|
22877
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
22878
|
+
const edges = [];
|
|
22879
|
+
const seenEdge = /* @__PURE__ */ new Set();
|
|
22880
|
+
const ensureState = (token, label) => {
|
|
22881
|
+
const id = stateId(token);
|
|
22882
|
+
if (!nodes.has(id)) nodes.set(id, stateNode(token, label ?? `${token} (overlay)`));
|
|
22883
|
+
return id;
|
|
22884
|
+
};
|
|
22885
|
+
const ensureAction = (key, name) => {
|
|
22886
|
+
const id = actionId(key);
|
|
22887
|
+
if (!nodes.has(id)) nodes.set(id, actionNode(key, name ?? key, { source: "overlay" }));
|
|
22888
|
+
return id;
|
|
22889
|
+
};
|
|
22890
|
+
for (const s of overlay.states ?? []) ensureState(s.token, s.label);
|
|
22891
|
+
for (const a of overlay.actions ?? []) ensureAction(a.id, a.name);
|
|
22892
|
+
for (const e of overlay.edges ?? []) {
|
|
22893
|
+
const aId = ensureAction(e.action);
|
|
22894
|
+
const link = (token, type) => {
|
|
22895
|
+
const sId = ensureState(token);
|
|
22896
|
+
const key = `${aId}|${type}|${sId}`;
|
|
22897
|
+
if (seenEdge.has(key)) return;
|
|
22898
|
+
seenEdge.add(key);
|
|
22899
|
+
edges.push(contextEdge(aId, sId, type, "high", "overlay"));
|
|
22900
|
+
};
|
|
22901
|
+
for (const token of e.requires ?? []) link(token, "requires");
|
|
22902
|
+
for (const token of e.produces ?? []) link(token, "produces");
|
|
22903
|
+
}
|
|
22904
|
+
return { nodes: [...nodes.values()], edges };
|
|
22905
|
+
}
|
|
22906
|
+
};
|
|
22907
|
+
}
|
|
22908
|
+
});
|
|
22909
|
+
|
|
22910
|
+
// src/server/graph/core/context/registry.ts
|
|
22911
|
+
function registerBuiltins2(registry, disabled) {
|
|
22912
|
+
const builtins = [nextjsPrismaContextProvider, overlayProvider];
|
|
22913
|
+
for (const provider of builtins) {
|
|
22914
|
+
if (disabled.has(provider.id)) continue;
|
|
22915
|
+
registry.register(provider);
|
|
22916
|
+
}
|
|
22917
|
+
}
|
|
22918
|
+
function loadCustomProviders(registry, config, rootDir, disabled) {
|
|
22919
|
+
for (const entry of config.context?.providers ?? []) {
|
|
22920
|
+
try {
|
|
22921
|
+
const absPath = (0, import_node_path13.resolve)(rootDir, entry.path);
|
|
22922
|
+
const mod = require(absPath);
|
|
22923
|
+
const provider = "default" in mod ? mod.default : mod;
|
|
22924
|
+
if (disabled.has(provider.id)) continue;
|
|
22925
|
+
registry.register(provider);
|
|
22926
|
+
} catch (err2) {
|
|
22927
|
+
process.stderr.write(`[launch-chart] failed to load custom context provider from ${entry.path}: ${err2}
|
|
22928
|
+
`);
|
|
22929
|
+
}
|
|
22930
|
+
}
|
|
22931
|
+
}
|
|
22932
|
+
function createContextProviderRegistry(config, rootDir) {
|
|
22933
|
+
const registry = new ContextProviderRegistry();
|
|
22934
|
+
const disabled = new Set(config.context?.disabled ?? []);
|
|
22935
|
+
registerBuiltins2(registry, disabled);
|
|
22936
|
+
loadCustomProviders(registry, config, rootDir, disabled);
|
|
22937
|
+
return registry;
|
|
22938
|
+
}
|
|
22939
|
+
var import_node_path13, ContextProviderRegistry;
|
|
22940
|
+
var init_registry = __esm({
|
|
22941
|
+
"src/server/graph/core/context/registry.ts"() {
|
|
22942
|
+
"use strict";
|
|
22943
|
+
import_node_path13 = require("node:path");
|
|
22944
|
+
init_nextjs_prisma();
|
|
22945
|
+
init_overlay();
|
|
22946
|
+
ContextProviderRegistry = class {
|
|
22947
|
+
constructor() {
|
|
22948
|
+
this.providers = [];
|
|
22949
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
22950
|
+
}
|
|
22951
|
+
register(provider) {
|
|
22952
|
+
if (this.ids.has(provider.id)) {
|
|
22953
|
+
throw new Error(`Duplicate context provider id: ${provider.id}`);
|
|
22954
|
+
}
|
|
22955
|
+
this.ids.add(provider.id);
|
|
22956
|
+
this.providers.push(provider);
|
|
22957
|
+
}
|
|
22958
|
+
getAll() {
|
|
22959
|
+
return [...this.providers];
|
|
22960
|
+
}
|
|
22961
|
+
};
|
|
22962
|
+
}
|
|
22963
|
+
});
|
|
22964
|
+
|
|
22965
|
+
// src/server/graph/core/context-map.ts
|
|
22966
|
+
function buildContextMap(layerOutputs, rootDir) {
|
|
22967
|
+
const generated = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
22968
|
+
const config = loadConfig(rootDir);
|
|
22969
|
+
const registry = createContextProviderRegistry(config, rootDir);
|
|
22970
|
+
const nodesById = /* @__PURE__ */ new Map();
|
|
22971
|
+
const edgesByKey = /* @__PURE__ */ new Map();
|
|
22972
|
+
const providerStats = {};
|
|
22973
|
+
const usedProviders = [];
|
|
22974
|
+
for (const provider of registry.getAll()) {
|
|
22975
|
+
let detected = false;
|
|
22976
|
+
try {
|
|
22977
|
+
detected = provider.detect(layerOutputs, rootDir);
|
|
22978
|
+
} catch (e) {
|
|
22979
|
+
process.stderr.write(`[launch-chart] context provider "${provider.id}" detect failed: ${e.message}
|
|
22980
|
+
`);
|
|
22981
|
+
continue;
|
|
22982
|
+
}
|
|
22983
|
+
if (!detected) continue;
|
|
22984
|
+
let contribution;
|
|
22985
|
+
try {
|
|
22986
|
+
contribution = provider.derive(layerOutputs, rootDir);
|
|
22987
|
+
} catch (e) {
|
|
22988
|
+
process.stderr.write(`[launch-chart] context provider "${provider.id}" derive failed: ${e.message}
|
|
22989
|
+
`);
|
|
22990
|
+
continue;
|
|
22991
|
+
}
|
|
22992
|
+
usedProviders.push(provider.id);
|
|
22993
|
+
providerStats[provider.id] = { nodes: contribution.nodes.length, edges: contribution.edges.length };
|
|
22994
|
+
for (const node of contribution.nodes) {
|
|
22995
|
+
if (!nodesById.has(node.id)) nodesById.set(node.id, node);
|
|
22996
|
+
}
|
|
22997
|
+
for (const edge of contribution.edges) {
|
|
22998
|
+
const key = `${edge.source}|${edge.type}|${edge.target}`;
|
|
22999
|
+
const existing = edgesByKey.get(key);
|
|
23000
|
+
const edgeConf = edge.confidence ?? "low";
|
|
23001
|
+
if (!existing) {
|
|
23002
|
+
edgesByKey.set(key, { ...edge, providers: [provider.id] });
|
|
23003
|
+
} else {
|
|
23004
|
+
const existingConf = existing.confidence ?? "low";
|
|
23005
|
+
existing.confidence = higherConfidence(existingConf, edgeConf);
|
|
23006
|
+
const provs = existing.providers ?? [];
|
|
23007
|
+
if (!provs.includes(provider.id)) provs.push(provider.id);
|
|
23008
|
+
existing.providers = provs;
|
|
23009
|
+
}
|
|
23010
|
+
}
|
|
23011
|
+
}
|
|
23012
|
+
const merged = [...edgesByKey.values()];
|
|
23013
|
+
const edges = applyOverlayRejections(merged, rootDir);
|
|
23014
|
+
const rejectedCount = merged.length - edges.length;
|
|
23015
|
+
const flagged = edges.map((e) => ({
|
|
23016
|
+
source: e.source,
|
|
23017
|
+
target: e.target,
|
|
23018
|
+
type: e.type,
|
|
23019
|
+
label: e.label ?? `${e.type}`,
|
|
23020
|
+
confidence: e.confidence ?? "low"
|
|
23021
|
+
}));
|
|
23022
|
+
const nodes = [...nodesById.values()];
|
|
23023
|
+
const stateCount = nodes.filter((n) => n.type === CONTEXT_NODE_STATE).length;
|
|
23024
|
+
return {
|
|
23025
|
+
metadata: {
|
|
23026
|
+
generated,
|
|
23027
|
+
scope: "derived",
|
|
23028
|
+
layer: "context",
|
|
23029
|
+
source: "context-map-builder",
|
|
23030
|
+
derived: true,
|
|
23031
|
+
providers: usedProviders,
|
|
23032
|
+
provider_stats: providerStats,
|
|
23033
|
+
action_count: nodes.length - stateCount,
|
|
23034
|
+
state_count: stateCount,
|
|
23035
|
+
candidate_edge_count: edges.length,
|
|
23036
|
+
rejected_edge_count: rejectedCount,
|
|
23037
|
+
note: "Edges are candidates (see flagged_edges + confidence) from the context providers. Promote via the curation overlay."
|
|
23038
|
+
},
|
|
23039
|
+
nodes,
|
|
23040
|
+
edges,
|
|
23041
|
+
cross_refs: [],
|
|
23042
|
+
contradictions: [],
|
|
23043
|
+
warnings: [],
|
|
23044
|
+
flagged_edges: flagged
|
|
23045
|
+
};
|
|
23046
|
+
}
|
|
23047
|
+
function writeContextMap(rootDir, output) {
|
|
23048
|
+
const path13 = (0, import_node_path14.join)(rootDir, LAUNCHSECURE_DIR, "graphs", "context.json");
|
|
23049
|
+
atomicWriteFileSync(path13, JSON.stringify(output, null, 2) + "\n");
|
|
23050
|
+
return path13;
|
|
23051
|
+
}
|
|
23052
|
+
var import_node_path14;
|
|
23053
|
+
var init_context_map = __esm({
|
|
23054
|
+
"src/server/graph/core/context-map.ts"() {
|
|
23055
|
+
"use strict";
|
|
23056
|
+
init_atomic_write();
|
|
23057
|
+
import_node_path14 = require("node:path");
|
|
23058
|
+
init_launch_kit_paths();
|
|
23059
|
+
init_config();
|
|
23060
|
+
init_registry();
|
|
23061
|
+
init_overlay();
|
|
23062
|
+
init_types();
|
|
23063
|
+
}
|
|
23064
|
+
});
|
|
23065
|
+
|
|
22744
23066
|
// src/server/graph/core/freshness.ts
|
|
22745
23067
|
function exactFilenameRegex(name) {
|
|
22746
23068
|
return new RegExp(`^${name.replace(/\./g, "\\.")}$`);
|
|
@@ -22756,12 +23078,12 @@ function getFreshnessTracker(rootDir) {
|
|
|
22756
23078
|
}
|
|
22757
23079
|
return t;
|
|
22758
23080
|
}
|
|
22759
|
-
var
|
|
23081
|
+
var import_node_fs11, import_node_path15, SCHEMA_VERSION, MAX_PATCHED_FILES_TRACKED, DRIFTING_PATCH_THRESHOLD, HARD_ESCALATION_PATTERNS, FreshnessTracker, trackers;
|
|
22760
23082
|
var init_freshness = __esm({
|
|
22761
23083
|
"src/server/graph/core/freshness.ts"() {
|
|
22762
23084
|
"use strict";
|
|
22763
|
-
|
|
22764
|
-
|
|
23085
|
+
import_node_fs11 = require("node:fs");
|
|
23086
|
+
import_node_path15 = require("node:path");
|
|
22765
23087
|
init_launch_kit_paths();
|
|
22766
23088
|
init_atomic_write();
|
|
22767
23089
|
SCHEMA_VERSION = 1;
|
|
@@ -22778,7 +23100,7 @@ var init_freshness = __esm({
|
|
|
22778
23100
|
FreshnessTracker = class {
|
|
22779
23101
|
constructor(rootDir) {
|
|
22780
23102
|
this.dirty = false;
|
|
22781
|
-
this.filePath = (0,
|
|
23103
|
+
this.filePath = (0, import_node_path15.join)(rootDir, LAUNCHSECURE_DIR, "graphs", ".freshness.json");
|
|
22782
23104
|
this.snapshot = this.load() ?? {
|
|
22783
23105
|
state: "fresh",
|
|
22784
23106
|
lastFullRegenAt: null,
|
|
@@ -22865,9 +23187,9 @@ var init_freshness = __esm({
|
|
|
22865
23187
|
}
|
|
22866
23188
|
}
|
|
22867
23189
|
load() {
|
|
22868
|
-
if (!(0,
|
|
23190
|
+
if (!(0, import_node_fs11.existsSync)(this.filePath)) return null;
|
|
22869
23191
|
try {
|
|
22870
|
-
const parsed = JSON.parse((0,
|
|
23192
|
+
const parsed = JSON.parse((0, import_node_fs11.readFileSync)(this.filePath, "utf-8"));
|
|
22871
23193
|
if (parsed.schemaVersion !== SCHEMA_VERSION) return null;
|
|
22872
23194
|
return {
|
|
22873
23195
|
state: parsed.state,
|
|
@@ -22889,22 +23211,22 @@ var init_freshness = __esm({
|
|
|
22889
23211
|
|
|
22890
23212
|
// src/server/graph/index.ts
|
|
22891
23213
|
function getAvailableLayers(rootDir) {
|
|
22892
|
-
const dir = (0,
|
|
22893
|
-
if (!(0,
|
|
22894
|
-
return (0,
|
|
23214
|
+
const dir = (0, import_node_path16.join)(rootDir, GRAPHS_DIR2);
|
|
23215
|
+
if (!(0, import_node_fs12.existsSync)(dir)) return [];
|
|
23216
|
+
return (0, import_node_fs12.readdirSync)(dir).filter((f) => f.endsWith(".json") && !f.startsWith(".") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
|
|
22895
23217
|
}
|
|
22896
23218
|
function graphsDir(rootDir) {
|
|
22897
|
-
return (0,
|
|
23219
|
+
return (0, import_node_path16.join)(rootDir, GRAPHS_DIR2);
|
|
22898
23220
|
}
|
|
22899
23221
|
function graphFilePath(rootDir, layer) {
|
|
22900
|
-
return (0,
|
|
23222
|
+
return (0, import_node_path16.join)(graphsDir(rootDir), `${layer}.json`);
|
|
22901
23223
|
}
|
|
22902
23224
|
function tagsFilePath2(rootDir) {
|
|
22903
|
-
return (0,
|
|
23225
|
+
return (0, import_node_path16.join)(graphsDir(rootDir), "tags.json");
|
|
22904
23226
|
}
|
|
22905
23227
|
function getMtimeMs(filePath) {
|
|
22906
|
-
if (!(0,
|
|
22907
|
-
return (0,
|
|
23228
|
+
if (!(0, import_node_fs12.existsSync)(filePath)) return 0;
|
|
23229
|
+
return (0, import_node_fs12.statSync)(filePath).mtimeMs;
|
|
22908
23230
|
}
|
|
22909
23231
|
function invalidateCache(filePath) {
|
|
22910
23232
|
graphCache.delete(filePath);
|
|
@@ -22943,20 +23265,20 @@ function applyTags(graph, layer, rootDir) {
|
|
|
22943
23265
|
}
|
|
22944
23266
|
function readGraphRaw(rootDir, layer) {
|
|
22945
23267
|
const filePath = graphFilePath(rootDir, layer);
|
|
22946
|
-
if (!(0,
|
|
22947
|
-
const stat = (0,
|
|
23268
|
+
if (!(0, import_node_fs12.existsSync)(filePath)) return null;
|
|
23269
|
+
const stat = (0, import_node_fs12.statSync)(filePath);
|
|
22948
23270
|
const cached = graphCache.get(filePath);
|
|
22949
23271
|
if (cached && cached.mtimeMs === stat.mtimeMs) {
|
|
22950
23272
|
return cached.graph;
|
|
22951
23273
|
}
|
|
22952
|
-
const content = (0,
|
|
23274
|
+
const content = (0, import_node_fs12.readFileSync)(filePath, "utf-8");
|
|
22953
23275
|
const graph = JSON.parse(content);
|
|
22954
23276
|
graphCache.set(filePath, { mtimeMs: stat.mtimeMs, graph });
|
|
22955
23277
|
return graph;
|
|
22956
23278
|
}
|
|
22957
23279
|
function readGraph(rootDir, layer) {
|
|
22958
23280
|
const rawFilePath = graphFilePath(rootDir, layer);
|
|
22959
|
-
if (!(0,
|
|
23281
|
+
if (!(0, import_node_fs12.existsSync)(rawFilePath)) return null;
|
|
22960
23282
|
const rawMtime = getMtimeMs(rawFilePath);
|
|
22961
23283
|
const tagsMtime = getMtimeMs(tagsFilePath2(rootDir));
|
|
22962
23284
|
const cacheKey = `${rootDir}:${layer}`;
|
|
@@ -22980,7 +23302,7 @@ function readAllGraphs(rootDir) {
|
|
|
22980
23302
|
}
|
|
22981
23303
|
async function generateGraph(rootDir, layer) {
|
|
22982
23304
|
const dir = graphsDir(rootDir);
|
|
22983
|
-
(0,
|
|
23305
|
+
(0, import_node_fs12.mkdirSync)(dir, { recursive: true });
|
|
22984
23306
|
const { results, failedFiles } = await runParseInWorker({ rootDir, layer });
|
|
22985
23307
|
for (const result of results) {
|
|
22986
23308
|
const filePath = graphFilePath(rootDir, result.layer);
|
|
@@ -22991,13 +23313,13 @@ async function generateGraph(rootDir, layer) {
|
|
|
22991
23313
|
if (!layer) {
|
|
22992
23314
|
const producedLayers = new Set(results.map((r) => r.layer));
|
|
22993
23315
|
try {
|
|
22994
|
-
for (const f of (0,
|
|
22995
|
-
if (!f.endsWith(".json") || f === "tags.json" || f === "effects-index.json") continue;
|
|
23316
|
+
for (const f of (0, import_node_fs12.readdirSync)(dir)) {
|
|
23317
|
+
if (!f.endsWith(".json") || f === "tags.json" || f === "effects-index.json" || f === "context.json") continue;
|
|
22996
23318
|
const layerName = f.replace(/\.json$/, "");
|
|
22997
23319
|
if (producedLayers.has(layerName)) continue;
|
|
22998
|
-
const orphan = (0,
|
|
23320
|
+
const orphan = (0, import_node_path16.join)(dir, f);
|
|
22999
23321
|
try {
|
|
23000
|
-
(0,
|
|
23322
|
+
(0, import_node_fs12.unlinkSync)(orphan);
|
|
23001
23323
|
invalidateCache(orphan);
|
|
23002
23324
|
invalidateTaggedCache(rootDir, layerName);
|
|
23003
23325
|
process.stderr.write(`[launch-chart] removed orphan layer file: ${f} (no parser produced ${layerName} this run)
|
|
@@ -23008,22 +23330,31 @@ async function generateGraph(rootDir, layer) {
|
|
|
23008
23330
|
} catch {
|
|
23009
23331
|
}
|
|
23010
23332
|
}
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
|
|
23015
|
-
|
|
23016
|
-
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
if (existing) allLayers[layerName] = existing;
|
|
23021
|
-
}
|
|
23333
|
+
const allLayers = {};
|
|
23334
|
+
for (const r of results) allLayers[r.layer] = r.output;
|
|
23335
|
+
if (layer) {
|
|
23336
|
+
for (const f of (0, import_node_fs12.readdirSync)(dir)) {
|
|
23337
|
+
if (!f.endsWith(".json") || f.startsWith(".") || f === "tags.json" || f === "effects-index.json" || f === "context.json") continue;
|
|
23338
|
+
const layerName = f.replace(/\.json$/, "");
|
|
23339
|
+
if (allLayers[layerName]) continue;
|
|
23340
|
+
const existing = readGraphRaw(rootDir, layerName);
|
|
23341
|
+
if (existing) allLayers[layerName] = existing;
|
|
23022
23342
|
}
|
|
23343
|
+
}
|
|
23344
|
+
try {
|
|
23023
23345
|
const idx = buildEffectsIndex(allLayers);
|
|
23024
23346
|
writeEffectsIndex(rootDir, idx);
|
|
23025
23347
|
} catch (e) {
|
|
23026
23348
|
process.stderr.write(`[launch-chart] effects-index build failed: ${e.message}
|
|
23349
|
+
`);
|
|
23350
|
+
}
|
|
23351
|
+
try {
|
|
23352
|
+
const ctx = buildContextMap(allLayers, rootDir);
|
|
23353
|
+
const ctxPath = writeContextMap(rootDir, ctx);
|
|
23354
|
+
invalidateCache(ctxPath);
|
|
23355
|
+
invalidateTaggedCache(rootDir, "context");
|
|
23356
|
+
} catch (e) {
|
|
23357
|
+
process.stderr.write(`[launch-chart] context-map build failed: ${e.message}
|
|
23027
23358
|
`);
|
|
23028
23359
|
}
|
|
23029
23360
|
try {
|
|
@@ -23040,25 +23371,26 @@ async function generateGraph(rootDir, layer) {
|
|
|
23040
23371
|
return results;
|
|
23041
23372
|
}
|
|
23042
23373
|
function readEffectsIndex(rootDir) {
|
|
23043
|
-
const path13 = (0,
|
|
23044
|
-
if (!(0,
|
|
23374
|
+
const path13 = (0, import_node_path16.join)(rootDir, GRAPHS_DIR2, "effects-index.json");
|
|
23375
|
+
if (!(0, import_node_fs12.existsSync)(path13)) return null;
|
|
23045
23376
|
try {
|
|
23046
|
-
return JSON.parse((0,
|
|
23377
|
+
return JSON.parse((0, import_node_fs12.readFileSync)(path13, "utf-8"));
|
|
23047
23378
|
} catch {
|
|
23048
23379
|
return null;
|
|
23049
23380
|
}
|
|
23050
23381
|
}
|
|
23051
|
-
var
|
|
23382
|
+
var import_node_fs12, import_node_path16, GRAPHS_DIR2, NON_LAYER_GRAPH_FILES, graphCache, taggedCache;
|
|
23052
23383
|
var init_graph = __esm({
|
|
23053
23384
|
"src/server/graph/index.ts"() {
|
|
23054
23385
|
"use strict";
|
|
23055
|
-
|
|
23056
|
-
|
|
23386
|
+
import_node_fs12 = require("node:fs");
|
|
23387
|
+
import_node_path16 = require("node:path");
|
|
23057
23388
|
init_config();
|
|
23058
23389
|
init_tagger_registry();
|
|
23059
23390
|
init_tag_store();
|
|
23060
23391
|
init_parse_worker_host();
|
|
23061
23392
|
init_effects_index();
|
|
23393
|
+
init_context_map();
|
|
23062
23394
|
init_atomic_write();
|
|
23063
23395
|
init_freshness();
|
|
23064
23396
|
init_tag_store();
|
|
@@ -23136,8 +23468,8 @@ function getQuery(name) {
|
|
|
23136
23468
|
ensureInit();
|
|
23137
23469
|
const cached = queryCache.get(name);
|
|
23138
23470
|
if (cached) return cached;
|
|
23139
|
-
const scmPath = (0,
|
|
23140
|
-
const scm = (0,
|
|
23471
|
+
const scmPath = (0, import_node_path22.join)(queriesDir, `${name}.scm`);
|
|
23472
|
+
const scm = (0, import_node_fs17.readFileSync)(scmPath, "utf-8");
|
|
23141
23473
|
const query = tsxLanguage.query(scm);
|
|
23142
23474
|
queryCache.set(name, query);
|
|
23143
23475
|
return query;
|
|
@@ -23157,13 +23489,13 @@ function parseSource(absPath) {
|
|
|
23157
23489
|
ensureInit();
|
|
23158
23490
|
let content;
|
|
23159
23491
|
try {
|
|
23160
|
-
const stat = (0,
|
|
23492
|
+
const stat = (0, import_node_fs17.statSync)(absPath);
|
|
23161
23493
|
if (stat.size > MAX_PARSEABLE_BYTES) {
|
|
23162
23494
|
process.stderr.write(`[lc-extractor] skipping ${absPath}: ${stat.size} bytes exceeds max ${MAX_PARSEABLE_BYTES}
|
|
23163
23495
|
`);
|
|
23164
23496
|
return null;
|
|
23165
23497
|
}
|
|
23166
|
-
content = (0,
|
|
23498
|
+
content = (0, import_node_fs17.readFileSync)(absPath, "utf-8");
|
|
23167
23499
|
} catch (e) {
|
|
23168
23500
|
process.stderr.write(`[lc-extractor] read failed for ${absPath}: ${e instanceof Error ? e.message : String(e)}
|
|
23169
23501
|
`);
|
|
@@ -24197,18 +24529,18 @@ function collectUiLabels(root) {
|
|
|
24197
24529
|
visit(root);
|
|
24198
24530
|
return out;
|
|
24199
24531
|
}
|
|
24200
|
-
var
|
|
24532
|
+
var import_node_fs17, import_node_path22, tsxLanguage, parserInstance, TreeSitterCtor, initPromise, initialized, queriesDir, queryCache, MAX_PARSEABLE_BYTES, MAX_CONSECUTIVE_PARSE_FAILURES, consecutiveParseFailures, ParseCascadeError, PRISMA_MUTATION_METHODS_BUILTIN, SUPABASE_MUTATION_METHODS_BUILTIN, DB_IDENTIFIERS_FALLBACK, extraDbIdentifiers, extraMutationMethods, INLINE_AUTH_IMPORTS, EXEMPT_NAME_PATTERNS, PROTECT_NAME_PATTERNS, TRUST_AS_PROTECT_KEYS, TIMER_FNS, DOM_METHOD_NAMES, CLASSLIST_METHODS, STORAGE_OBJECTS, HISTORY_METHODS, LOCATION_METHODS, ASSIGN_DOM_PROPS, UI_LABEL_KEYS, UI_LABELS_MAX, NOTE_REGEX, NOTES_MAX;
|
|
24201
24533
|
var init_ts_extractor = __esm({
|
|
24202
24534
|
"src/server/graph/core/ts-extractor.ts"() {
|
|
24203
24535
|
"use strict";
|
|
24204
|
-
|
|
24205
|
-
|
|
24536
|
+
import_node_fs17 = require("node:fs");
|
|
24537
|
+
import_node_path22 = require("node:path");
|
|
24206
24538
|
init_parse_failure_cache();
|
|
24207
24539
|
initialized = false;
|
|
24208
24540
|
queriesDir = (() => {
|
|
24209
|
-
const srcPath = (0,
|
|
24541
|
+
const srcPath = (0, import_node_path22.join)((0, import_node_path22.dirname)(__filename), "..", "queries");
|
|
24210
24542
|
if (require("fs").existsSync(srcPath)) return srcPath;
|
|
24211
|
-
return (0,
|
|
24543
|
+
return (0, import_node_path22.join)((0, import_node_path22.dirname)(__filename), "graph", "queries");
|
|
24212
24544
|
})();
|
|
24213
24545
|
queryCache = /* @__PURE__ */ new Map();
|
|
24214
24546
|
MAX_PARSEABLE_BYTES = 2 * 1024 * 1024;
|
|
@@ -24348,7 +24680,7 @@ __export(watcher_exports, {
|
|
|
24348
24680
|
function isIgnoredPath(rel) {
|
|
24349
24681
|
if (rel.startsWith(GRAPHS_RELATIVE)) return true;
|
|
24350
24682
|
if (rel.endsWith(".lock") || rel.endsWith(".log")) return true;
|
|
24351
|
-
for (const part of rel.split(
|
|
24683
|
+
for (const part of rel.split(import_node_path37.sep)) {
|
|
24352
24684
|
if (IGNORE_SEGMENTS.has(part)) return true;
|
|
24353
24685
|
}
|
|
24354
24686
|
return false;
|
|
@@ -24390,7 +24722,7 @@ function startGraphWatcher(rootDir, opts = {}) {
|
|
|
24390
24722
|
regenerating = false;
|
|
24391
24723
|
}
|
|
24392
24724
|
}
|
|
24393
|
-
const watcher = (0,
|
|
24725
|
+
const watcher = (0, import_node_fs29.watch)(rootDir, { recursive: true }, (event, filename) => {
|
|
24394
24726
|
if (!filename) return;
|
|
24395
24727
|
const rel = filename.toString();
|
|
24396
24728
|
if (process.env.LAUNCH_CHART_WATCH_TRACE === "1") {
|
|
@@ -24423,12 +24755,12 @@ function startGraphWatcher(rootDir, opts = {}) {
|
|
|
24423
24755
|
freshness: () => getFreshnessTracker(rootDir).get()
|
|
24424
24756
|
};
|
|
24425
24757
|
}
|
|
24426
|
-
var
|
|
24758
|
+
var import_node_fs29, import_node_path37, IGNORE_SEGMENTS, TRIGGER_EXTENSIONS, GRAPHS_RELATIVE;
|
|
24427
24759
|
var init_watcher = __esm({
|
|
24428
24760
|
"src/server/graph/core/watcher.ts"() {
|
|
24429
24761
|
"use strict";
|
|
24430
|
-
|
|
24431
|
-
|
|
24762
|
+
import_node_fs29 = require("node:fs");
|
|
24763
|
+
import_node_path37 = require("node:path");
|
|
24432
24764
|
init_launch_kit_paths();
|
|
24433
24765
|
init_graph();
|
|
24434
24766
|
init_freshness();
|
|
@@ -24457,7 +24789,7 @@ var init_watcher = __esm({
|
|
|
24457
24789
|
".prisma",
|
|
24458
24790
|
".sql"
|
|
24459
24791
|
]);
|
|
24460
|
-
GRAPHS_RELATIVE = (0,
|
|
24792
|
+
GRAPHS_RELATIVE = (0, import_node_path37.join)(LAUNCHSECURE_DIR, "graphs");
|
|
24461
24793
|
}
|
|
24462
24794
|
});
|
|
24463
24795
|
|
|
@@ -26135,7 +26467,7 @@ var PostImplLaunchExecutor = class {
|
|
|
26135
26467
|
return 3001;
|
|
26136
26468
|
}
|
|
26137
26469
|
startDevServer(port, databaseUrl) {
|
|
26138
|
-
return new Promise((
|
|
26470
|
+
return new Promise((resolve7) => {
|
|
26139
26471
|
const env = { ...process.env, PORT: String(port), ...databaseUrl ? { DATABASE_URL: databaseUrl } : {} };
|
|
26140
26472
|
this.devProcess = (0, import_child_process3.spawn)("npm", ["run", "dev"], {
|
|
26141
26473
|
cwd: this.workingDir,
|
|
@@ -26147,7 +26479,7 @@ var PostImplLaunchExecutor = class {
|
|
|
26147
26479
|
const timeout = setTimeout(() => {
|
|
26148
26480
|
if (!resolved) {
|
|
26149
26481
|
resolved = true;
|
|
26150
|
-
this.healthCheck(port).then(
|
|
26482
|
+
this.healthCheck(port).then(resolve7);
|
|
26151
26483
|
}
|
|
26152
26484
|
}, 15e3);
|
|
26153
26485
|
const onData = (data) => {
|
|
@@ -26156,7 +26488,7 @@ var PostImplLaunchExecutor = class {
|
|
|
26156
26488
|
if (!resolved) {
|
|
26157
26489
|
resolved = true;
|
|
26158
26490
|
clearTimeout(timeout);
|
|
26159
|
-
|
|
26491
|
+
resolve7(true);
|
|
26160
26492
|
}
|
|
26161
26493
|
}
|
|
26162
26494
|
};
|
|
@@ -26167,7 +26499,7 @@ var PostImplLaunchExecutor = class {
|
|
|
26167
26499
|
if (!resolved) {
|
|
26168
26500
|
resolved = true;
|
|
26169
26501
|
clearTimeout(timeout);
|
|
26170
|
-
|
|
26502
|
+
resolve7(false);
|
|
26171
26503
|
}
|
|
26172
26504
|
});
|
|
26173
26505
|
this.devProcess.unref();
|
|
@@ -27564,7 +27896,7 @@ var ProjectMcpClient = class {
|
|
|
27564
27896
|
this.initialized = true;
|
|
27565
27897
|
}
|
|
27566
27898
|
send(body) {
|
|
27567
|
-
return new Promise((
|
|
27899
|
+
return new Promise((resolve7, reject) => {
|
|
27568
27900
|
const headers = {
|
|
27569
27901
|
...this.headers,
|
|
27570
27902
|
"Content-Length": String(Buffer.byteLength(body))
|
|
@@ -27589,7 +27921,7 @@ var ProjectMcpClient = class {
|
|
|
27589
27921
|
return;
|
|
27590
27922
|
}
|
|
27591
27923
|
const sid = res.headers["mcp-session-id"];
|
|
27592
|
-
|
|
27924
|
+
resolve7({ body: text, sessionId: typeof sid === "string" ? sid : void 0 });
|
|
27593
27925
|
});
|
|
27594
27926
|
}
|
|
27595
27927
|
);
|
|
@@ -28688,16 +29020,16 @@ var CloudflaredTunnel = class extends import_node_events.EventEmitter {
|
|
|
28688
29020
|
const tun = this.tunnel;
|
|
28689
29021
|
this.tunnel = null;
|
|
28690
29022
|
if (!tun) return;
|
|
28691
|
-
return new Promise((
|
|
29023
|
+
return new Promise((resolve7) => {
|
|
28692
29024
|
tun.once("exit", () => {
|
|
28693
29025
|
this.emit("stopped");
|
|
28694
|
-
|
|
29026
|
+
resolve7();
|
|
28695
29027
|
});
|
|
28696
29028
|
try {
|
|
28697
29029
|
tun.stop();
|
|
28698
29030
|
} catch {
|
|
28699
29031
|
}
|
|
28700
|
-
setTimeout(() =>
|
|
29032
|
+
setTimeout(() => resolve7(), 6e3);
|
|
28701
29033
|
});
|
|
28702
29034
|
}
|
|
28703
29035
|
spawnOnce() {
|
|
@@ -29439,38 +29771,249 @@ function streamTranscript(opts) {
|
|
|
29439
29771
|
}
|
|
29440
29772
|
|
|
29441
29773
|
// src/server/graph-mcp.ts
|
|
29442
|
-
var
|
|
29443
|
-
var
|
|
29774
|
+
var import_node_fs30 = require("node:fs");
|
|
29775
|
+
var import_node_path38 = require("node:path");
|
|
29444
29776
|
var import_node_child_process3 = require("node:child_process");
|
|
29445
29777
|
var import_node_os6 = require("node:os");
|
|
29446
29778
|
init_launch_kit_paths();
|
|
29447
29779
|
init_graph();
|
|
29448
29780
|
|
|
29781
|
+
// src/server/graph/core/context/snippet.ts
|
|
29782
|
+
function toExportName(name) {
|
|
29783
|
+
const words = name.replace(/^action:/, "").replace(/^state:/, "").split(/[^A-Za-z0-9]+/).filter(Boolean).filter((w) => w.toLowerCase() !== "api");
|
|
29784
|
+
if (words.length === 0) return "snippet";
|
|
29785
|
+
const camel = words.map((w, i) => i === 0 ? w.charAt(0).toLowerCase() + w.slice(1) : w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
29786
|
+
return /^[0-9]/.test(camel) ? `s${camel}` : camel;
|
|
29787
|
+
}
|
|
29788
|
+
function scaffoldSnippet(input) {
|
|
29789
|
+
const exportName = toExportName(input.name || input.nodeId);
|
|
29790
|
+
const arr = (xs) => `[${xs.map((x) => `'${x}'`).join(", ")}]`;
|
|
29791
|
+
const code = `import { type Page } from '@playwright/test';
|
|
29792
|
+
|
|
29793
|
+
/**
|
|
29794
|
+
* Snippet: ${input.name}
|
|
29795
|
+
* Scaffolded by launch-chart \`scaffold_snippet\` \u2014 conforms to the Snippet shape.
|
|
29796
|
+
* requires/produces are derived from the context graph. TODO(you):
|
|
29797
|
+
* 1. fill \`params\` from the endpoint's request/validation schema;
|
|
29798
|
+
* 2. implement \`run()\` with real Playwright steps (navigate, fill, click, assert).
|
|
29799
|
+
*/
|
|
29800
|
+
export const ${exportName} = {
|
|
29801
|
+
id: '${input.nodeId}',
|
|
29802
|
+
requires: ${arr(input.requires)},
|
|
29803
|
+
produces: ${arr(input.produces)},
|
|
29804
|
+
params: [], // TODO: e.g. ['name', 'color'] \u2014 from the endpoint schema
|
|
29805
|
+
async run(page: Page, params: Record<string, unknown>) {
|
|
29806
|
+
// TODO: implement with Playwright.
|
|
29807
|
+
// e.g. await page.goto('/...'); await page.fill('#...', params.x); await page.click('text=Save');
|
|
29808
|
+
},
|
|
29809
|
+
};
|
|
29810
|
+
`;
|
|
29811
|
+
return { exportName, code };
|
|
29812
|
+
}
|
|
29813
|
+
|
|
29814
|
+
// src/server/graph/core/context/snippet-registry.ts
|
|
29815
|
+
var import_node_fs13 = require("node:fs");
|
|
29816
|
+
var import_node_path17 = require("node:path");
|
|
29817
|
+
var DEFAULT_SNIPPETS_DIR = "tests/snippets";
|
|
29818
|
+
function parseStringArray(src, key) {
|
|
29819
|
+
const m = src.match(new RegExp(`${key}\\s*:\\s*\\[([^\\]]*)\\]`));
|
|
29820
|
+
if (!m) return [];
|
|
29821
|
+
return [...m[1].matchAll(/['"]([^'"]+)['"]/g)].map((x) => x[1]);
|
|
29822
|
+
}
|
|
29823
|
+
function parseSnippetFile(content, file) {
|
|
29824
|
+
const idM = content.match(/\bid\s*:\s*['"]([^'"]+)['"]/);
|
|
29825
|
+
if (!idM) return null;
|
|
29826
|
+
const exportM = content.match(/export\s+const\s+(\w+)/);
|
|
29827
|
+
return {
|
|
29828
|
+
id: idM[1],
|
|
29829
|
+
exportName: exportM ? exportM[1] : "default",
|
|
29830
|
+
file,
|
|
29831
|
+
requires: parseStringArray(content, "requires"),
|
|
29832
|
+
produces: parseStringArray(content, "produces"),
|
|
29833
|
+
params: parseStringArray(content, "params")
|
|
29834
|
+
};
|
|
29835
|
+
}
|
|
29836
|
+
function loadSnippetIndex(rootDir, snippetsDir = DEFAULT_SNIPPETS_DIR) {
|
|
29837
|
+
const dir = (0, import_node_path17.join)(rootDir, snippetsDir);
|
|
29838
|
+
const index = /* @__PURE__ */ new Map();
|
|
29839
|
+
if (!(0, import_node_fs13.existsSync)(dir)) return index;
|
|
29840
|
+
for (const f of (0, import_node_fs13.readdirSync)(dir)) {
|
|
29841
|
+
if (!f.endsWith(".ts") && !f.endsWith(".tsx")) continue;
|
|
29842
|
+
const full = (0, import_node_path17.join)(dir, f);
|
|
29843
|
+
try {
|
|
29844
|
+
if (!(0, import_node_fs13.statSync)(full).isFile()) continue;
|
|
29845
|
+
const entry = parseSnippetFile((0, import_node_fs13.readFileSync)(full, "utf-8"), (0, import_node_path17.join)(snippetsDir, f));
|
|
29846
|
+
if (entry) index.set(entry.id, entry);
|
|
29847
|
+
} catch {
|
|
29848
|
+
}
|
|
29849
|
+
}
|
|
29850
|
+
return index;
|
|
29851
|
+
}
|
|
29852
|
+
|
|
29853
|
+
// src/server/graph/core/context/test-plan.ts
|
|
29854
|
+
var stripState = (s) => s.replace(/^state:/, "");
|
|
29855
|
+
function buildTestPlan(graph, targetId, snippets) {
|
|
29856
|
+
const nodesById = /* @__PURE__ */ new Map();
|
|
29857
|
+
for (const n of graph.nodes) nodesById.set(n.id, n);
|
|
29858
|
+
const requiresOf = /* @__PURE__ */ new Map();
|
|
29859
|
+
const producesOf = /* @__PURE__ */ new Map();
|
|
29860
|
+
const producersOf = /* @__PURE__ */ new Map();
|
|
29861
|
+
for (const e of graph.edges) {
|
|
29862
|
+
if (e.type === "requires") {
|
|
29863
|
+
(requiresOf.get(e.source) ?? requiresOf.set(e.source, /* @__PURE__ */ new Set()).get(e.source)).add(e.target);
|
|
29864
|
+
} else if (e.type === "produces") {
|
|
29865
|
+
(producesOf.get(e.source) ?? producesOf.set(e.source, /* @__PURE__ */ new Set()).get(e.source)).add(e.target);
|
|
29866
|
+
(producersOf.get(e.target) ?? producersOf.set(e.target, /* @__PURE__ */ new Set()).get(e.target)).add(e.source);
|
|
29867
|
+
}
|
|
29868
|
+
}
|
|
29869
|
+
const pickProducer = (producers) => {
|
|
29870
|
+
const withSnippet = producers.filter((p) => snippets.has(p)).sort();
|
|
29871
|
+
return withSnippet.length ? withSnippet[0] : [...producers].sort()[0];
|
|
29872
|
+
};
|
|
29873
|
+
const order = [];
|
|
29874
|
+
const done = /* @__PURE__ */ new Set();
|
|
29875
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
29876
|
+
const gaps = [];
|
|
29877
|
+
const allRequired = /* @__PURE__ */ new Set();
|
|
29878
|
+
const visit = (actionId2) => {
|
|
29879
|
+
if (done.has(actionId2)) return;
|
|
29880
|
+
if (visiting.has(actionId2)) {
|
|
29881
|
+
gaps.push({ type: "cycle", action: actionId2, detail: `dependency cycle through ${actionId2}` });
|
|
29882
|
+
return;
|
|
29883
|
+
}
|
|
29884
|
+
visiting.add(actionId2);
|
|
29885
|
+
for (const state of requiresOf.get(actionId2) ?? []) {
|
|
29886
|
+
allRequired.add(state);
|
|
29887
|
+
const producers = [...producersOf.get(state) ?? []];
|
|
29888
|
+
if (producers.length === 0) {
|
|
29889
|
+
gaps.push({
|
|
29890
|
+
type: "no_producer",
|
|
29891
|
+
state: stripState(state),
|
|
29892
|
+
action: actionId2,
|
|
29893
|
+
detail: `${actionId2} requires "${stripState(state)}" but no action produces it`
|
|
29894
|
+
});
|
|
29895
|
+
continue;
|
|
29896
|
+
}
|
|
29897
|
+
visit(pickProducer(producers));
|
|
29898
|
+
}
|
|
29899
|
+
visiting.delete(actionId2);
|
|
29900
|
+
done.add(actionId2);
|
|
29901
|
+
order.push(actionId2);
|
|
29902
|
+
};
|
|
29903
|
+
visit(targetId);
|
|
29904
|
+
const steps = order.map((actionId2) => {
|
|
29905
|
+
const node = nodesById.get(actionId2);
|
|
29906
|
+
const entry = snippets.get(actionId2) ?? null;
|
|
29907
|
+
if (!entry) {
|
|
29908
|
+
gaps.push({
|
|
29909
|
+
type: "no_snippet",
|
|
29910
|
+
action: actionId2,
|
|
29911
|
+
detail: `no snippet bound to ${actionId2} \u2014 scaffold one with scaffold_snippet`
|
|
29912
|
+
});
|
|
29913
|
+
}
|
|
29914
|
+
const satisfies = [...producesOf.get(actionId2) ?? []].filter((s) => allRequired.has(s)).map(stripState).sort();
|
|
29915
|
+
return {
|
|
29916
|
+
action: actionId2,
|
|
29917
|
+
name: String(node?.name ?? actionId2),
|
|
29918
|
+
satisfies,
|
|
29919
|
+
snippet: entry ? { id: entry.id, exportName: entry.exportName, file: entry.file, params: entry.params } : null
|
|
29920
|
+
};
|
|
29921
|
+
});
|
|
29922
|
+
return { target: targetId, steps, gaps, runnable: gaps.length === 0 };
|
|
29923
|
+
}
|
|
29924
|
+
|
|
29925
|
+
// src/server/graph/core/context/spec-gen.ts
|
|
29926
|
+
var import_node_path18 = require("node:path");
|
|
29927
|
+
function toEnvRef(name) {
|
|
29928
|
+
return `process.env.${name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase()}`;
|
|
29929
|
+
}
|
|
29930
|
+
function classify(name) {
|
|
29931
|
+
const n = name.toLowerCase();
|
|
29932
|
+
if (/pass|secret|token|credential|apikey|api_key|_key$|^key$/.test(n)) return { kind: "secret" };
|
|
29933
|
+
if (/email|slug|(^|_)id$|uuid|userid|orgid|projectid/.test(n)) return { kind: "real" };
|
|
29934
|
+
if (/desc|summary|body|message|content|note/.test(n)) return { kind: "faker", faker: "faker.lorem.sentence()" };
|
|
29935
|
+
if (/colou?r/.test(n)) return { kind: "faker", faker: "faker.color.rgb({ format: 'hex' })" };
|
|
29936
|
+
if (/icon/.test(n)) return { kind: "faker", faker: "faker.helpers.arrayElement(['rocket','bug','star','flag','zap','heart'])" };
|
|
29937
|
+
if (/name|title|label/.test(n)) return { kind: "faker", faker: "faker.word.noun()" };
|
|
29938
|
+
if (/url|link|href/.test(n)) return { kind: "faker", faker: "faker.internet.url()" };
|
|
29939
|
+
if (/count|qty|quantity|amount|number|price/.test(n)) return { kind: "faker", faker: "String(faker.number.int({ min: 1, max: 100 }))" };
|
|
29940
|
+
return { kind: "faker", faker: "faker.lorem.word()" };
|
|
29941
|
+
}
|
|
29942
|
+
function relImport(specDir, file) {
|
|
29943
|
+
let r = (0, import_node_path18.relative)(specDir, file).replace(/\.tsx?$/, "");
|
|
29944
|
+
if (!r.startsWith(".")) r = `./${r}`;
|
|
29945
|
+
return r;
|
|
29946
|
+
}
|
|
29947
|
+
function generateSpec(plan, opts = {}) {
|
|
29948
|
+
const specDir = opts.specDir ?? "tests/generated";
|
|
29949
|
+
const fixtures = opts.fixtures ?? {};
|
|
29950
|
+
const missing = /* @__PURE__ */ new Set();
|
|
29951
|
+
let usesFaker = false;
|
|
29952
|
+
const bound = plan.steps.filter((s) => s.snippet);
|
|
29953
|
+
const unbound = plan.steps.filter((s) => !s.snippet);
|
|
29954
|
+
const importLines = /* @__PURE__ */ new Set();
|
|
29955
|
+
for (const s of bound) {
|
|
29956
|
+
importLines.add(`import { ${s.snippet.exportName} } from '${relImport(specDir, s.snippet.file)}';`);
|
|
29957
|
+
}
|
|
29958
|
+
const callLines = bound.map((s) => {
|
|
29959
|
+
const params = s.snippet.params.map((p) => {
|
|
29960
|
+
if (Object.prototype.hasOwnProperty.call(fixtures, p)) {
|
|
29961
|
+
return ` ${p}: ${JSON.stringify(fixtures[p])},`;
|
|
29962
|
+
}
|
|
29963
|
+
const c = classify(p);
|
|
29964
|
+
if (c.kind === "secret") return ` ${p}: ${toEnvRef(p)},`;
|
|
29965
|
+
if (c.kind === "faker") {
|
|
29966
|
+
usesFaker = true;
|
|
29967
|
+
return ` ${p}: ${c.faker},`;
|
|
29968
|
+
}
|
|
29969
|
+
missing.add(p);
|
|
29970
|
+
return ` ${p}: undefined, // TODO: real value (seeded ${p})`;
|
|
29971
|
+
});
|
|
29972
|
+
const block = params.length ? `{
|
|
29973
|
+
${params.join("\n")}
|
|
29974
|
+
}` : "{}";
|
|
29975
|
+
return ` await ${s.snippet.exportName}.run(page, ${block});`;
|
|
29976
|
+
});
|
|
29977
|
+
const warnings = unbound.map(
|
|
29978
|
+
(s) => ` // \u26A0 GAP: no snippet for ${s.action} \u2014 scaffold_snippet then re-plan.`
|
|
29979
|
+
);
|
|
29980
|
+
const header = [`import { test } from '@playwright/test';`];
|
|
29981
|
+
if (usesFaker) header.push(`import { faker } from '@faker-js/faker';`);
|
|
29982
|
+
const code = `${header.join("\n")}
|
|
29983
|
+
${[...importLines].join("\n")}
|
|
29984
|
+
|
|
29985
|
+
test(${JSON.stringify(opts.title ?? `plan: ${plan.target}`)}, async ({ page }) => {
|
|
29986
|
+
${[...warnings, ...callLines].join("\n")}
|
|
29987
|
+
});
|
|
29988
|
+
`;
|
|
29989
|
+
return { code, missingFixtures: [...missing], complete: plan.runnable && missing.size === 0 };
|
|
29990
|
+
}
|
|
29991
|
+
|
|
29449
29992
|
// src/server/lockfile.ts
|
|
29450
29993
|
var import_node_child_process2 = require("node:child_process");
|
|
29451
|
-
var
|
|
29994
|
+
var import_node_fs14 = require("node:fs");
|
|
29452
29995
|
var import_node_os4 = require("node:os");
|
|
29453
|
-
var
|
|
29996
|
+
var import_node_path19 = require("node:path");
|
|
29454
29997
|
init_launch_kit_paths();
|
|
29455
29998
|
function lockDir(projectRoot) {
|
|
29456
29999
|
if (projectRoot) {
|
|
29457
|
-
return (0,
|
|
30000
|
+
return (0, import_node_path19.join)(projectRoot, LAUNCHSECURE_DIR);
|
|
29458
30001
|
}
|
|
29459
|
-
return (0,
|
|
30002
|
+
return (0, import_node_path19.join)((0, import_node_os4.homedir)(), LAUNCHSECURE_DIR);
|
|
29460
30003
|
}
|
|
29461
30004
|
function lockPath(projectRoot) {
|
|
29462
|
-
return (0,
|
|
30005
|
+
return (0, import_node_path19.join)(lockDir(projectRoot), "launch-chart.lock");
|
|
29463
30006
|
}
|
|
29464
30007
|
var _activeProjectRoot;
|
|
29465
30008
|
function readLock(projectRoot) {
|
|
29466
30009
|
const root = projectRoot ?? _activeProjectRoot;
|
|
29467
30010
|
const p = lockPath(root);
|
|
29468
|
-
if (!(0,
|
|
30011
|
+
if (!(0, import_node_fs14.existsSync)(p)) {
|
|
29469
30012
|
if (root) {
|
|
29470
30013
|
const globalP = lockPath();
|
|
29471
|
-
if ((0,
|
|
30014
|
+
if ((0, import_node_fs14.existsSync)(globalP)) {
|
|
29472
30015
|
try {
|
|
29473
|
-
const data = JSON.parse((0,
|
|
30016
|
+
const data = JSON.parse((0, import_node_fs14.readFileSync)(globalP, "utf-8"));
|
|
29474
30017
|
if (typeof data.pid === "number" && typeof data.port === "number" && data.cwd === root) {
|
|
29475
30018
|
return data;
|
|
29476
30019
|
}
|
|
@@ -29481,7 +30024,7 @@ function readLock(projectRoot) {
|
|
|
29481
30024
|
return null;
|
|
29482
30025
|
}
|
|
29483
30026
|
try {
|
|
29484
|
-
const data = JSON.parse((0,
|
|
30027
|
+
const data = JSON.parse((0, import_node_fs14.readFileSync)(p, "utf-8"));
|
|
29485
30028
|
if (typeof data.pid !== "number" || typeof data.port !== "number") return null;
|
|
29486
30029
|
return data;
|
|
29487
30030
|
} catch {
|
|
@@ -29518,7 +30061,7 @@ function getLiveLock(projectRoot) {
|
|
|
29518
30061
|
const live = listenerPid !== null ? listenerPid === lock.pid : isPidAlive(lock.pid);
|
|
29519
30062
|
if (!live) {
|
|
29520
30063
|
try {
|
|
29521
|
-
(0,
|
|
30064
|
+
(0, import_node_fs14.unlinkSync)(lockPath(root));
|
|
29522
30065
|
} catch {
|
|
29523
30066
|
}
|
|
29524
30067
|
return null;
|
|
@@ -29528,7 +30071,7 @@ function getLiveLock(projectRoot) {
|
|
|
29528
30071
|
function clearLock(projectRoot) {
|
|
29529
30072
|
const root = projectRoot ?? _activeProjectRoot;
|
|
29530
30073
|
try {
|
|
29531
|
-
(0,
|
|
30074
|
+
(0, import_node_fs14.unlinkSync)(lockPath(root));
|
|
29532
30075
|
} catch {
|
|
29533
30076
|
}
|
|
29534
30077
|
}
|
|
@@ -29537,20 +30080,20 @@ function clearLock(projectRoot) {
|
|
|
29537
30080
|
init_config();
|
|
29538
30081
|
|
|
29539
30082
|
// src/server/graph/core/parser-registry.ts
|
|
29540
|
-
var
|
|
30083
|
+
var import_node_path30 = require("node:path");
|
|
29541
30084
|
|
|
29542
30085
|
// src/server/graph/parsers/ts/typescript-project.ts
|
|
29543
|
-
var
|
|
29544
|
-
var
|
|
30086
|
+
var import_node_fs18 = require("node:fs");
|
|
30087
|
+
var import_node_path23 = require("node:path");
|
|
29545
30088
|
init_config();
|
|
29546
30089
|
|
|
29547
30090
|
// src/server/graph/core/resolve-paths.ts
|
|
29548
|
-
var
|
|
29549
|
-
var
|
|
30091
|
+
var import_node_fs16 = require("node:fs");
|
|
30092
|
+
var import_node_path21 = require("node:path");
|
|
29550
30093
|
|
|
29551
30094
|
// src/server/graph/core/walk.ts
|
|
29552
|
-
var
|
|
29553
|
-
var
|
|
30095
|
+
var import_node_fs15 = require("node:fs");
|
|
30096
|
+
var import_node_path20 = require("node:path");
|
|
29554
30097
|
var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
29555
30098
|
"node_modules",
|
|
29556
30099
|
"dist",
|
|
@@ -29560,12 +30103,12 @@ var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
|
29560
30103
|
]);
|
|
29561
30104
|
function walk(dir, exts) {
|
|
29562
30105
|
const results = [];
|
|
29563
|
-
if (!(0,
|
|
29564
|
-
for (const entry of (0,
|
|
29565
|
-
const full = (0,
|
|
30106
|
+
if (!(0, import_node_fs15.existsSync)(dir)) return results;
|
|
30107
|
+
for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true })) {
|
|
30108
|
+
const full = (0, import_node_path20.join)(dir, entry.name);
|
|
29566
30109
|
if (entry.isDirectory()) {
|
|
29567
30110
|
results.push(...walk(full, exts));
|
|
29568
|
-
} else if (exts.includes((0,
|
|
30111
|
+
} else if (exts.includes((0, import_node_path20.extname)(entry.name))) {
|
|
29569
30112
|
results.push(full);
|
|
29570
30113
|
}
|
|
29571
30114
|
}
|
|
@@ -29573,15 +30116,15 @@ function walk(dir, exts) {
|
|
|
29573
30116
|
}
|
|
29574
30117
|
function walkWithIgnore(dir, exts, opts = {}) {
|
|
29575
30118
|
const results = [];
|
|
29576
|
-
if (!(0,
|
|
30119
|
+
if (!(0, import_node_fs15.existsSync)(dir)) return results;
|
|
29577
30120
|
const skip = opts.extraIgnore ? /* @__PURE__ */ new Set([...DEFAULT_IGNORE_DIRS, ...opts.extraIgnore]) : DEFAULT_IGNORE_DIRS;
|
|
29578
|
-
for (const entry of (0,
|
|
30121
|
+
for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true })) {
|
|
29579
30122
|
if (entry.isDirectory()) {
|
|
29580
30123
|
if (entry.name.startsWith(".")) continue;
|
|
29581
30124
|
if (skip.has(entry.name)) continue;
|
|
29582
|
-
results.push(...walkWithIgnore((0,
|
|
29583
|
-
} else if (exts.includes((0,
|
|
29584
|
-
results.push((0,
|
|
30125
|
+
results.push(...walkWithIgnore((0, import_node_path20.join)(dir, entry.name), exts, opts));
|
|
30126
|
+
} else if (exts.includes((0, import_node_path20.extname)(entry.name))) {
|
|
30127
|
+
results.push((0, import_node_path20.join)(dir, entry.name));
|
|
29585
30128
|
}
|
|
29586
30129
|
}
|
|
29587
30130
|
return results;
|
|
@@ -29589,9 +30132,9 @@ function walkWithIgnore(dir, exts, opts = {}) {
|
|
|
29589
30132
|
|
|
29590
30133
|
// src/server/graph/core/resolve-paths.ts
|
|
29591
30134
|
function hasSqlFiles(dir) {
|
|
29592
|
-
if (!(0,
|
|
30135
|
+
if (!(0, import_node_fs16.existsSync)(dir)) return false;
|
|
29593
30136
|
try {
|
|
29594
|
-
return (0,
|
|
30137
|
+
return (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true }).some(
|
|
29595
30138
|
(e) => e.isFile() && e.name.endsWith(".sql")
|
|
29596
30139
|
);
|
|
29597
30140
|
} catch {
|
|
@@ -29599,27 +30142,27 @@ function hasSqlFiles(dir) {
|
|
|
29599
30142
|
}
|
|
29600
30143
|
}
|
|
29601
30144
|
function hasNestedMigrationSql(dir) {
|
|
29602
|
-
if (!(0,
|
|
30145
|
+
if (!(0, import_node_fs16.existsSync)(dir)) return false;
|
|
29603
30146
|
try {
|
|
29604
|
-
return (0,
|
|
29605
|
-
(e) => e.isDirectory() && (0,
|
|
30147
|
+
return (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true }).some(
|
|
30148
|
+
(e) => e.isDirectory() && (0, import_node_fs16.existsSync)((0, import_node_path21.join)(dir, e.name, "migration.sql"))
|
|
29606
30149
|
);
|
|
29607
30150
|
} catch {
|
|
29608
30151
|
return false;
|
|
29609
30152
|
}
|
|
29610
30153
|
}
|
|
29611
30154
|
function resolveDbFromDir(dir) {
|
|
29612
|
-
if (!(0,
|
|
29613
|
-
const schemaPath = (0,
|
|
29614
|
-
if ((0,
|
|
29615
|
-
const migrationsDir2 = (0,
|
|
30155
|
+
if (!(0, import_node_fs16.existsSync)(dir)) return { kind: "none", schemaPath: null, migrationsDir: null };
|
|
30156
|
+
const schemaPath = (0, import_node_path21.join)(dir, "schema.prisma");
|
|
30157
|
+
if ((0, import_node_fs16.existsSync)(schemaPath)) {
|
|
30158
|
+
const migrationsDir2 = (0, import_node_path21.join)(dir, "migrations");
|
|
29616
30159
|
return {
|
|
29617
30160
|
kind: "prisma",
|
|
29618
30161
|
schemaPath,
|
|
29619
|
-
migrationsDir: (0,
|
|
30162
|
+
migrationsDir: (0, import_node_fs16.existsSync)(migrationsDir2) ? migrationsDir2 : null
|
|
29620
30163
|
};
|
|
29621
30164
|
}
|
|
29622
|
-
const migrationsDir = (0,
|
|
30165
|
+
const migrationsDir = (0, import_node_path21.join)(dir, "migrations");
|
|
29623
30166
|
if (hasSqlFiles(migrationsDir) || hasNestedMigrationSql(migrationsDir)) {
|
|
29624
30167
|
return { kind: "sql-migrations", migrationsDir, schemaPath: null };
|
|
29625
30168
|
}
|
|
@@ -29630,19 +30173,19 @@ function resolveDbFromDir(dir) {
|
|
|
29630
30173
|
}
|
|
29631
30174
|
function detectDbConfig(rootDir, config) {
|
|
29632
30175
|
if (config.paths?.dbDir) {
|
|
29633
|
-
return resolveDbFromDir((0,
|
|
30176
|
+
return resolveDbFromDir((0, import_node_path21.join)(rootDir, config.paths.dbDir));
|
|
29634
30177
|
}
|
|
29635
|
-
const candidates = ["prisma", "supabase", "drizzle", (0,
|
|
30178
|
+
const candidates = ["prisma", "supabase", "drizzle", (0, import_node_path21.join)("db", "migrations"), "migrations"];
|
|
29636
30179
|
for (const c of candidates) {
|
|
29637
|
-
const dir = (0,
|
|
30180
|
+
const dir = (0, import_node_path21.join)(rootDir, c);
|
|
29638
30181
|
const resolved = resolveDbFromDir(dir);
|
|
29639
30182
|
if (resolved.kind !== "none") return resolved;
|
|
29640
30183
|
}
|
|
29641
30184
|
return { kind: "none", schemaPath: null, migrationsDir: null };
|
|
29642
30185
|
}
|
|
29643
30186
|
function detectDbDir(rootDir, config, dbConfig) {
|
|
29644
|
-
if (config.paths?.dbDir) return (0,
|
|
29645
|
-
if (dbConfig.kind === "prisma") return (0,
|
|
30187
|
+
if (config.paths?.dbDir) return (0, import_node_path21.join)(rootDir, config.paths.dbDir);
|
|
30188
|
+
if (dbConfig.kind === "prisma") return (0, import_node_path21.dirname)(dbConfig.schemaPath);
|
|
29646
30189
|
if (dbConfig.kind === "sql-migrations") return dbConfig.migrationsDir;
|
|
29647
30190
|
return null;
|
|
29648
30191
|
}
|
|
@@ -29673,16 +30216,16 @@ var NON_SOURCE_DIRS = /* @__PURE__ */ new Set([
|
|
|
29673
30216
|
"libs"
|
|
29674
30217
|
]);
|
|
29675
30218
|
function dirHasTSFiles(dir) {
|
|
29676
|
-
if (!(0,
|
|
30219
|
+
if (!(0, import_node_fs16.existsSync)(dir)) return false;
|
|
29677
30220
|
try {
|
|
29678
30221
|
const stack = [dir];
|
|
29679
30222
|
while (stack.length > 0) {
|
|
29680
30223
|
const cur = stack.pop();
|
|
29681
|
-
const entries = (0,
|
|
30224
|
+
const entries = (0, import_node_fs16.readdirSync)(cur, { withFileTypes: true });
|
|
29682
30225
|
for (const e of entries) {
|
|
29683
30226
|
if (e.isFile() && (e.name.endsWith(".ts") || e.name.endsWith(".tsx"))) return true;
|
|
29684
30227
|
if (e.isDirectory() && !e.name.startsWith(".") && !DEFAULT_IGNORE_DIRS.has(e.name)) {
|
|
29685
|
-
stack.push((0,
|
|
30228
|
+
stack.push((0, import_node_path21.join)(cur, e.name));
|
|
29686
30229
|
}
|
|
29687
30230
|
}
|
|
29688
30231
|
}
|
|
@@ -29691,15 +30234,15 @@ function dirHasTSFiles(dir) {
|
|
|
29691
30234
|
return false;
|
|
29692
30235
|
}
|
|
29693
30236
|
function collectCodeBearingChildren(dir, extraSkip) {
|
|
29694
|
-
if (!(0,
|
|
30237
|
+
if (!(0, import_node_fs16.existsSync)(dir)) return [];
|
|
29695
30238
|
const out = [];
|
|
29696
30239
|
try {
|
|
29697
|
-
for (const entry of (0,
|
|
30240
|
+
for (const entry of (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true })) {
|
|
29698
30241
|
if (!entry.isDirectory()) continue;
|
|
29699
30242
|
if (entry.name.startsWith(".")) continue;
|
|
29700
30243
|
if (NON_SOURCE_DIRS.has(entry.name)) continue;
|
|
29701
30244
|
if (extraSkip?.has(entry.name)) continue;
|
|
29702
|
-
const full = (0,
|
|
30245
|
+
const full = (0, import_node_path21.join)(dir, entry.name);
|
|
29703
30246
|
if (dirHasTSFiles(full)) out.push(full);
|
|
29704
30247
|
}
|
|
29705
30248
|
} catch {
|
|
@@ -29711,7 +30254,7 @@ function detectSrcRoots(rootDir, srcDir, appDir, config) {
|
|
|
29711
30254
|
const roots2 = /* @__PURE__ */ new Set();
|
|
29712
30255
|
roots2.add(appDir);
|
|
29713
30256
|
for (const r of config.paths.srcRoots) {
|
|
29714
|
-
const abs = (0,
|
|
30257
|
+
const abs = (0, import_node_path21.isAbsolute)(r) ? r : (0, import_node_path21.resolve)(rootDir, r);
|
|
29715
30258
|
roots2.add(abs);
|
|
29716
30259
|
}
|
|
29717
30260
|
return [...roots2];
|
|
@@ -29720,7 +30263,7 @@ function detectSrcRoots(rootDir, srcDir, appDir, config) {
|
|
|
29720
30263
|
roots.add(appDir);
|
|
29721
30264
|
for (const c of collectCodeBearingChildren(srcDir)) roots.add(c);
|
|
29722
30265
|
if (srcDir !== rootDir) {
|
|
29723
|
-
const skipSrcWrapper = /* @__PURE__ */ new Set([(0,
|
|
30266
|
+
const skipSrcWrapper = /* @__PURE__ */ new Set([(0, import_node_path21.basename)(srcDir)]);
|
|
29724
30267
|
for (const c of collectCodeBearingChildren(rootDir, skipSrcWrapper)) roots.add(c);
|
|
29725
30268
|
}
|
|
29726
30269
|
return [...roots];
|
|
@@ -29732,10 +30275,10 @@ function detectConventionFiles(rootDir, srcDir) {
|
|
|
29732
30275
|
const dirs = srcDir === rootDir ? [rootDir] : [srcDir, rootDir];
|
|
29733
30276
|
for (const dir of dirs) {
|
|
29734
30277
|
for (const name of CONVENTION_NAMES) {
|
|
29735
|
-
const full = (0,
|
|
29736
|
-
if (!seen.has(full) && (0,
|
|
30278
|
+
const full = (0, import_node_path21.join)(dir, name);
|
|
30279
|
+
if (!seen.has(full) && (0, import_node_fs16.existsSync)(full)) {
|
|
29737
30280
|
try {
|
|
29738
|
-
if ((0,
|
|
30281
|
+
if ((0, import_node_fs16.statSync)(full).isFile()) {
|
|
29739
30282
|
seen.add(full);
|
|
29740
30283
|
out.push(full);
|
|
29741
30284
|
}
|
|
@@ -29750,22 +30293,22 @@ function resolveProjectPaths(rootDir, config) {
|
|
|
29750
30293
|
let srcDir;
|
|
29751
30294
|
let appDir;
|
|
29752
30295
|
if (config.paths?.appDir) {
|
|
29753
|
-
appDir = (0,
|
|
29754
|
-
srcDir = config.paths.srcDir ? (0,
|
|
30296
|
+
appDir = (0, import_node_path21.join)(rootDir, config.paths.appDir);
|
|
30297
|
+
srcDir = config.paths.srcDir ? (0, import_node_path21.join)(rootDir, config.paths.srcDir) : (0, import_node_path21.dirname)(appDir);
|
|
29755
30298
|
} else {
|
|
29756
|
-
const srcApp = (0,
|
|
29757
|
-
const rootApp = (0,
|
|
29758
|
-
if ((0,
|
|
29759
|
-
srcDir = (0,
|
|
30299
|
+
const srcApp = (0, import_node_path21.join)(rootDir, "src", "app");
|
|
30300
|
+
const rootApp = (0, import_node_path21.join)(rootDir, "app");
|
|
30301
|
+
if ((0, import_node_fs16.existsSync)(srcApp)) {
|
|
30302
|
+
srcDir = (0, import_node_path21.join)(rootDir, "src");
|
|
29760
30303
|
appDir = srcApp;
|
|
29761
|
-
} else if ((0,
|
|
30304
|
+
} else if ((0, import_node_fs16.existsSync)(rootApp)) {
|
|
29762
30305
|
srcDir = rootDir;
|
|
29763
30306
|
appDir = rootApp;
|
|
29764
30307
|
} else {
|
|
29765
30308
|
return null;
|
|
29766
30309
|
}
|
|
29767
30310
|
}
|
|
29768
|
-
const apiDir = (0,
|
|
30311
|
+
const apiDir = (0, import_node_path21.join)(appDir, "api");
|
|
29769
30312
|
const dbConfig = detectDbConfig(rootDir, config);
|
|
29770
30313
|
const dbDir = detectDbDir(rootDir, config, dbConfig);
|
|
29771
30314
|
const srcRoots = detectSrcRoots(rootDir, srcDir, appDir, config);
|
|
@@ -29792,25 +30335,25 @@ var CLASSIFICATION_TO_LAYER = {
|
|
|
29792
30335
|
external: "ui"
|
|
29793
30336
|
};
|
|
29794
30337
|
function toNodeId(srcDir, rootDir, absPath) {
|
|
29795
|
-
const relFromSrc = (0,
|
|
30338
|
+
const relFromSrc = (0, import_node_path23.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
29796
30339
|
if (relFromSrc.startsWith("..")) {
|
|
29797
|
-
return (0,
|
|
30340
|
+
return (0, import_node_path23.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
29798
30341
|
}
|
|
29799
30342
|
return relFromSrc;
|
|
29800
30343
|
}
|
|
29801
30344
|
function resolveImport(srcDir, specifier) {
|
|
29802
30345
|
if (!specifier.startsWith("@/")) return null;
|
|
29803
30346
|
const rel = specifier.slice(2);
|
|
29804
|
-
const base = (0,
|
|
29805
|
-
for (const c of [base, base + ".ts", base + ".tsx", (0,
|
|
29806
|
-
if ((0,
|
|
30347
|
+
const base = (0, import_node_path23.join)(srcDir, rel);
|
|
30348
|
+
for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path23.join)(base, "index.ts"), (0, import_node_path23.join)(base, "index.tsx")]) {
|
|
30349
|
+
if ((0, import_node_fs18.existsSync)(c) && (0, import_node_fs18.statSync)(c).isFile()) return c;
|
|
29807
30350
|
}
|
|
29808
30351
|
return null;
|
|
29809
30352
|
}
|
|
29810
30353
|
function resolveRelativeImport(fromFile, specifier) {
|
|
29811
|
-
const base = (0,
|
|
29812
|
-
for (const c of [base, base + ".ts", base + ".tsx", (0,
|
|
29813
|
-
if ((0,
|
|
30354
|
+
const base = (0, import_node_path23.join)((0, import_node_path23.dirname)(fromFile), specifier);
|
|
30355
|
+
for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path23.join)(base, "index.ts"), (0, import_node_path23.join)(base, "index.tsx")]) {
|
|
30356
|
+
if ((0, import_node_fs18.existsSync)(c) && (0, import_node_fs18.statSync)(c).isFile()) return c;
|
|
29814
30357
|
}
|
|
29815
30358
|
return null;
|
|
29816
30359
|
}
|
|
@@ -29831,7 +30374,7 @@ function resolveBarrelMap(barrelAbsPath, parsedByPath, memo, visiting) {
|
|
|
29831
30374
|
const resolved = resolveRelativeImport(barrelAbsPath, re.from);
|
|
29832
30375
|
if (!resolved) continue;
|
|
29833
30376
|
if (re.isWildcard) {
|
|
29834
|
-
const targetBn = (0,
|
|
30377
|
+
const targetBn = (0, import_node_path23.basename)(resolved);
|
|
29835
30378
|
const targetIsBarrel = targetBn === "index.ts" || targetBn === "index.tsx";
|
|
29836
30379
|
if (targetIsBarrel) {
|
|
29837
30380
|
const nested = resolveBarrelMap(resolved, parsedByPath, memo, visiting);
|
|
@@ -29858,12 +30401,12 @@ function buildAllBarrelMaps(srcDir, parsedByPath) {
|
|
|
29858
30401
|
const barrels = /* @__PURE__ */ new Map();
|
|
29859
30402
|
const memo = /* @__PURE__ */ new Map();
|
|
29860
30403
|
for (const [absPath, parsed] of parsedByPath) {
|
|
29861
|
-
const bn = (0,
|
|
30404
|
+
const bn = (0, import_node_path23.basename)(absPath);
|
|
29862
30405
|
if (bn !== "index.ts" && bn !== "index.tsx") continue;
|
|
29863
30406
|
if (parsed.reExports.length === 0) continue;
|
|
29864
30407
|
const map = resolveBarrelMap(absPath, parsedByPath, memo, /* @__PURE__ */ new Set());
|
|
29865
30408
|
if (map.size > 0) {
|
|
29866
|
-
const barrelId = (0,
|
|
30409
|
+
const barrelId = (0, import_node_path23.relative)(srcDir, (0, import_node_path23.dirname)(absPath)).replace(/\\/g, "/");
|
|
29867
30410
|
barrels.set(barrelId, map);
|
|
29868
30411
|
}
|
|
29869
30412
|
}
|
|
@@ -29888,10 +30431,10 @@ function extractRoute(id) {
|
|
|
29888
30431
|
return route || "/";
|
|
29889
30432
|
}
|
|
29890
30433
|
function nameFromFilename(absPath) {
|
|
29891
|
-
return (0,
|
|
30434
|
+
return (0, import_node_path23.basename)(absPath, (0, import_node_path23.extname)(absPath)).replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^(\w)/, (_, c) => c.toUpperCase());
|
|
29892
30435
|
}
|
|
29893
30436
|
function filePathToAppRoute(appDir, absPath) {
|
|
29894
|
-
let route = ("/" + (0,
|
|
30437
|
+
let route = ("/" + (0, import_node_path23.relative)(appDir, absPath).replace(/\\/g, "/")).replace(/\/route\.tsx?$/, "");
|
|
29895
30438
|
route = route.replace(/\/\([^)]+\)/g, "");
|
|
29896
30439
|
route = route.replace(/\[\[\.\.\.([^\]]+)\]\]/g, "*$1?");
|
|
29897
30440
|
route = route.replace(/\[\.\.\.([^\]]+)\]/g, "*$1");
|
|
@@ -30139,7 +30682,7 @@ function generate(rootDir) {
|
|
|
30139
30682
|
const apiNodes = [];
|
|
30140
30683
|
const nodeIdSet = /* @__PURE__ */ new Set();
|
|
30141
30684
|
const routeToNodeId = /* @__PURE__ */ new Map();
|
|
30142
|
-
const fileSet = allDiscovered.filter((f) => !(0,
|
|
30685
|
+
const fileSet = allDiscovered.filter((f) => !(0, import_node_path23.basename)(f).startsWith("index."));
|
|
30143
30686
|
for (const absPath of fileSet) {
|
|
30144
30687
|
const id = toNodeId(srcDir, rootDir, absPath);
|
|
30145
30688
|
const type = classifyType(absPath, id);
|
|
@@ -30299,7 +30842,7 @@ function generate(rootDir) {
|
|
|
30299
30842
|
} catch {
|
|
30300
30843
|
continue;
|
|
30301
30844
|
}
|
|
30302
|
-
const externalId = (0,
|
|
30845
|
+
const externalId = (0, import_node_path23.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
30303
30846
|
const edgesFromThis = [];
|
|
30304
30847
|
const seen = /* @__PURE__ */ new Set();
|
|
30305
30848
|
for (const imp of parsed.imports) {
|
|
@@ -30649,7 +31192,7 @@ var typescriptProjectParser = {
|
|
|
30649
31192
|
};
|
|
30650
31193
|
|
|
30651
31194
|
// src/server/graph/parsers/db/prisma-schema.ts
|
|
30652
|
-
var
|
|
31195
|
+
var import_node_fs19 = require("node:fs");
|
|
30653
31196
|
init_config();
|
|
30654
31197
|
function parseModels(content) {
|
|
30655
31198
|
const nodes = [];
|
|
@@ -30742,7 +31285,7 @@ function parseEnums(content) {
|
|
|
30742
31285
|
}
|
|
30743
31286
|
function detect2(rootDir) {
|
|
30744
31287
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
30745
|
-
return paths?.dbConfig.kind === "prisma" && (0,
|
|
31288
|
+
return paths?.dbConfig.kind === "prisma" && (0, import_node_fs19.existsSync)(paths.dbConfig.schemaPath);
|
|
30746
31289
|
}
|
|
30747
31290
|
function generate2(rootDir) {
|
|
30748
31291
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
@@ -30759,7 +31302,7 @@ function generate2(rootDir) {
|
|
|
30759
31302
|
};
|
|
30760
31303
|
}
|
|
30761
31304
|
const schemaPath = paths.dbConfig.schemaPath;
|
|
30762
|
-
const content = (0,
|
|
31305
|
+
const content = (0, import_node_fs19.readFileSync)(schemaPath, "utf-8");
|
|
30763
31306
|
const { nodes: modelNodes, relations } = parseModels(content);
|
|
30764
31307
|
const enumNodes = parseEnums(content);
|
|
30765
31308
|
const allNodes = [...modelNodes, ...enumNodes];
|
|
@@ -30816,8 +31359,8 @@ var prismaSchemaParser = {
|
|
|
30816
31359
|
};
|
|
30817
31360
|
|
|
30818
31361
|
// src/server/graph/parsers/db/sql-migrations.ts
|
|
30819
|
-
var
|
|
30820
|
-
var
|
|
31362
|
+
var import_node_fs20 = require("node:fs");
|
|
31363
|
+
var import_node_path24 = require("node:path");
|
|
30821
31364
|
var import_pgsql_parser = require("pgsql-parser");
|
|
30822
31365
|
init_config();
|
|
30823
31366
|
var PG_TO_PRISMA = {
|
|
@@ -30851,15 +31394,15 @@ function pgTypeToPrisma(pgType) {
|
|
|
30851
31394
|
return PG_TO_PRISMA[upper] ?? upper;
|
|
30852
31395
|
}
|
|
30853
31396
|
function discoverMigrationFiles(migrationsDir) {
|
|
30854
|
-
if (!(0,
|
|
31397
|
+
if (!(0, import_node_fs20.existsSync)(migrationsDir)) return [];
|
|
30855
31398
|
const out = [];
|
|
30856
|
-
const entries = (0,
|
|
31399
|
+
const entries = (0, import_node_fs20.readdirSync)(migrationsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
30857
31400
|
for (const entry of entries) {
|
|
30858
31401
|
if (entry.isDirectory()) {
|
|
30859
|
-
const sqlPath = (0,
|
|
30860
|
-
if ((0,
|
|
31402
|
+
const sqlPath = (0, import_node_path24.join)(migrationsDir, entry.name, "migration.sql");
|
|
31403
|
+
if ((0, import_node_fs20.existsSync)(sqlPath)) out.push(sqlPath);
|
|
30861
31404
|
} else if (entry.isFile() && entry.name.endsWith(".sql")) {
|
|
30862
|
-
out.push((0,
|
|
31405
|
+
out.push((0, import_node_path24.join)(migrationsDir, entry.name));
|
|
30863
31406
|
}
|
|
30864
31407
|
}
|
|
30865
31408
|
return out;
|
|
@@ -30904,7 +31447,7 @@ function parseMigrations(migrationsDir, dialect = postgresDialect) {
|
|
|
30904
31447
|
};
|
|
30905
31448
|
if (!migrationsDir) return state;
|
|
30906
31449
|
for (const sqlPath of discoverMigrationFiles(migrationsDir)) {
|
|
30907
|
-
const sql = (0,
|
|
31450
|
+
const sql = (0, import_node_fs20.readFileSync)(sqlPath, "utf-8");
|
|
30908
31451
|
let ast;
|
|
30909
31452
|
try {
|
|
30910
31453
|
ast = dialect.parse(sql);
|
|
@@ -31473,8 +32016,8 @@ function indexIsPrismaUncoverable(idx) {
|
|
|
31473
32016
|
return idx.hasPredicate || idx.hasExpressions || idx.method !== "btree";
|
|
31474
32017
|
}
|
|
31475
32018
|
function loadPrismaState(schemaPath) {
|
|
31476
|
-
if (!schemaPath || !(0,
|
|
31477
|
-
const content = (0,
|
|
32019
|
+
if (!schemaPath || !(0, import_node_fs20.existsSync)(schemaPath)) return null;
|
|
32020
|
+
const content = (0, import_node_fs20.readFileSync)(schemaPath, "utf-8");
|
|
31478
32021
|
const tables = /* @__PURE__ */ new Map();
|
|
31479
32022
|
const enums = /* @__PURE__ */ new Map();
|
|
31480
32023
|
const relations = [];
|
|
@@ -31881,7 +32424,7 @@ function generate3(rootDir) {
|
|
|
31881
32424
|
const migrationFiles = migrationsDir ? discoverMigrationFiles(migrationsDir) : [];
|
|
31882
32425
|
let migrationNodeCount = 0;
|
|
31883
32426
|
for (const sqlPath of migrationFiles) {
|
|
31884
|
-
const sql = (0,
|
|
32427
|
+
const sql = (0, import_node_fs20.readFileSync)(sqlPath, "utf-8");
|
|
31885
32428
|
const name = deriveMigrationName(sqlPath);
|
|
31886
32429
|
let ast;
|
|
31887
32430
|
try {
|
|
@@ -32199,14 +32742,14 @@ var fetchResolverParser = {
|
|
|
32199
32742
|
};
|
|
32200
32743
|
|
|
32201
32744
|
// src/server/graph/parsers/crosslayer/api-annotations.ts
|
|
32202
|
-
var
|
|
32203
|
-
var
|
|
32745
|
+
var import_node_fs21 = require("node:fs");
|
|
32746
|
+
var import_node_path25 = require("node:path");
|
|
32204
32747
|
init_config();
|
|
32205
32748
|
var API_ANNOTATION_RE = /@api\s+(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+(\/\S+)/g;
|
|
32206
32749
|
function toNodeId2(srcDir, rootDir, absPath) {
|
|
32207
|
-
const relFromSrc = (0,
|
|
32750
|
+
const relFromSrc = (0, import_node_path25.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
32208
32751
|
if (relFromSrc.startsWith("..")) {
|
|
32209
|
-
return (0,
|
|
32752
|
+
return (0, import_node_path25.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
32210
32753
|
}
|
|
32211
32754
|
return relFromSrc;
|
|
32212
32755
|
}
|
|
@@ -32251,7 +32794,7 @@ var apiAnnotationsParser = {
|
|
|
32251
32794
|
const flaggedEdges = [];
|
|
32252
32795
|
const seenEdge = /* @__PURE__ */ new Set();
|
|
32253
32796
|
for (const absPath of files) {
|
|
32254
|
-
const content = (0,
|
|
32797
|
+
const content = (0, import_node_fs21.readFileSync)(absPath, "utf-8");
|
|
32255
32798
|
const sourceId = toNodeId2(srcDir, rootDir, absPath);
|
|
32256
32799
|
if (!uiNodeIds.has(sourceId)) continue;
|
|
32257
32800
|
let match;
|
|
@@ -32295,14 +32838,14 @@ var apiAnnotationsParser = {
|
|
|
32295
32838
|
};
|
|
32296
32839
|
|
|
32297
32840
|
// src/server/graph/parsers/crosslayer/url-literal-scanner.ts
|
|
32298
|
-
var
|
|
32299
|
-
var
|
|
32841
|
+
var import_node_fs22 = require("node:fs");
|
|
32842
|
+
var import_node_path26 = require("node:path");
|
|
32300
32843
|
init_config();
|
|
32301
32844
|
var URL_LITERAL_RE = /['"`](\/[a-zA-Z][^'"`\s]*?)['"`]/g;
|
|
32302
32845
|
function toNodeId3(srcDir, rootDir, absPath) {
|
|
32303
|
-
const relFromSrc = (0,
|
|
32846
|
+
const relFromSrc = (0, import_node_path26.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
32304
32847
|
if (relFromSrc.startsWith("..")) {
|
|
32305
|
-
return (0,
|
|
32848
|
+
return (0, import_node_path26.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
32306
32849
|
}
|
|
32307
32850
|
return relFromSrc;
|
|
32308
32851
|
}
|
|
@@ -32346,7 +32889,7 @@ var urlLiteralScannerParser = {
|
|
|
32346
32889
|
for (const absPath of files) {
|
|
32347
32890
|
const sourceId = toNodeId3(srcDir, rootDir, absPath);
|
|
32348
32891
|
if (!uiNodeIds.has(sourceId)) continue;
|
|
32349
|
-
const content = (0,
|
|
32892
|
+
const content = (0, import_node_fs22.readFileSync)(absPath, "utf-8");
|
|
32350
32893
|
let match;
|
|
32351
32894
|
URL_LITERAL_RE.lastIndex = 0;
|
|
32352
32895
|
while ((match = URL_LITERAL_RE.exec(content)) !== null) {
|
|
@@ -32377,8 +32920,8 @@ var urlLiteralScannerParser = {
|
|
|
32377
32920
|
};
|
|
32378
32921
|
|
|
32379
32922
|
// src/server/graph/parsers/static/static-values.ts
|
|
32380
|
-
var
|
|
32381
|
-
var
|
|
32923
|
+
var import_node_fs23 = require("node:fs");
|
|
32924
|
+
var import_node_path27 = require("node:path");
|
|
32382
32925
|
init_config();
|
|
32383
32926
|
var parseCode = null;
|
|
32384
32927
|
function tryLoadTreeSitter() {
|
|
@@ -32415,21 +32958,21 @@ function extractEnumValues(rootDir) {
|
|
|
32415
32958
|
const schemaPaths = [];
|
|
32416
32959
|
if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath) {
|
|
32417
32960
|
schemaPaths.push(paths.dbConfig.schemaPath);
|
|
32418
|
-
schemaPaths.push((0,
|
|
32961
|
+
schemaPaths.push((0, import_node_path27.join)((0, import_node_path27.dirname)(paths.dbConfig.schemaPath), "schema"));
|
|
32419
32962
|
} else {
|
|
32420
|
-
schemaPaths.push((0,
|
|
32421
|
-
schemaPaths.push((0,
|
|
32963
|
+
schemaPaths.push((0, import_node_path27.join)(rootDir, "prisma", "schema.prisma"));
|
|
32964
|
+
schemaPaths.push((0, import_node_path27.join)(rootDir, "prisma", "schema"));
|
|
32422
32965
|
}
|
|
32423
32966
|
let content = "";
|
|
32424
32967
|
for (const p of schemaPaths) {
|
|
32425
|
-
if ((0,
|
|
32968
|
+
if ((0, import_node_fs23.existsSync)(p)) {
|
|
32426
32969
|
try {
|
|
32427
|
-
const stat = (0,
|
|
32970
|
+
const stat = (0, import_node_fs23.statSync)(p);
|
|
32428
32971
|
if (stat.isFile()) {
|
|
32429
|
-
content = (0,
|
|
32972
|
+
content = (0, import_node_fs23.readFileSync)(p, "utf-8");
|
|
32430
32973
|
} else if (stat.isDirectory()) {
|
|
32431
|
-
const files = (0,
|
|
32432
|
-
content = files.map((f) => (0,
|
|
32974
|
+
const files = (0, import_node_fs23.readdirSync)(p).filter((f) => f.endsWith(".prisma"));
|
|
32975
|
+
content = files.map((f) => (0, import_node_fs23.readFileSync)((0, import_node_path27.join)(p, f), "utf-8")).join("\n");
|
|
32433
32976
|
}
|
|
32434
32977
|
} catch {
|
|
32435
32978
|
continue;
|
|
@@ -32587,27 +33130,27 @@ function extractSeedData(rootDir) {
|
|
|
32587
33130
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
32588
33131
|
const candidates = [];
|
|
32589
33132
|
if (paths?.dbDir) {
|
|
32590
|
-
candidates.push((0,
|
|
32591
|
-
candidates.push((0,
|
|
33133
|
+
candidates.push((0, import_node_path27.join)(paths.dbDir, "seed.ts"));
|
|
33134
|
+
candidates.push((0, import_node_path27.join)(paths.dbDir, "seed.js"));
|
|
32592
33135
|
} else {
|
|
32593
|
-
candidates.push((0,
|
|
32594
|
-
candidates.push((0,
|
|
33136
|
+
candidates.push((0, import_node_path27.join)(rootDir, "prisma", "seed.ts"));
|
|
33137
|
+
candidates.push((0, import_node_path27.join)(rootDir, "prisma", "seed.js"));
|
|
32595
33138
|
}
|
|
32596
|
-
const baseRoots = paths?.srcRoots ?? [(0,
|
|
33139
|
+
const baseRoots = paths?.srcRoots ?? [(0, import_node_path27.join)(rootDir, "src")];
|
|
32597
33140
|
for (const root of baseRoots) {
|
|
32598
|
-
candidates.push((0,
|
|
33141
|
+
candidates.push((0, import_node_path27.join)(root, "server", "lib", "system-tags.ts"));
|
|
32599
33142
|
}
|
|
32600
33143
|
const seedFiles = candidates.filter((p) => {
|
|
32601
33144
|
try {
|
|
32602
|
-
return (0,
|
|
33145
|
+
return (0, import_node_fs23.existsSync)(p) && (0, import_node_fs23.statSync)(p).isFile();
|
|
32603
33146
|
} catch {
|
|
32604
33147
|
return false;
|
|
32605
33148
|
}
|
|
32606
33149
|
});
|
|
32607
33150
|
const useTreeSitter = tryLoadTreeSitter();
|
|
32608
33151
|
for (const filePath of seedFiles) {
|
|
32609
|
-
const content = (0,
|
|
32610
|
-
const relPath = (0,
|
|
33152
|
+
const content = (0, import_node_fs23.readFileSync)(filePath, "utf-8");
|
|
33153
|
+
const relPath = (0, import_node_path27.relative)(rootDir, filePath);
|
|
32611
33154
|
const seeded = detectSeededArrays(content, relPath);
|
|
32612
33155
|
let astRoot = null;
|
|
32613
33156
|
if (useTreeSitter && parseCode) {
|
|
@@ -32701,11 +33244,11 @@ function extractSeedData(rootDir) {
|
|
|
32701
33244
|
return { nodes, edges };
|
|
32702
33245
|
}
|
|
32703
33246
|
function walkDir(dir, exts) {
|
|
32704
|
-
if (!(0,
|
|
33247
|
+
if (!(0, import_node_fs23.existsSync)(dir)) return [];
|
|
32705
33248
|
const results = [];
|
|
32706
|
-
for (const entry of (0,
|
|
33249
|
+
for (const entry of (0, import_node_fs23.readdirSync)(dir, { withFileTypes: true })) {
|
|
32707
33250
|
if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") continue;
|
|
32708
|
-
const full = (0,
|
|
33251
|
+
const full = (0, import_node_path27.join)(dir, entry.name);
|
|
32709
33252
|
if (entry.isDirectory()) results.push(...walkDir(full, exts));
|
|
32710
33253
|
else if (exts.some((ext) => entry.name.endsWith(ext))) results.push(full);
|
|
32711
33254
|
}
|
|
@@ -32714,7 +33257,7 @@ function walkDir(dir, exts) {
|
|
|
32714
33257
|
function extractConstants(rootDir) {
|
|
32715
33258
|
const nodes = [];
|
|
32716
33259
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
32717
|
-
const roots = paths?.srcRoots ?? [(0,
|
|
33260
|
+
const roots = paths?.srcRoots ?? [(0, import_node_path27.join)(rootDir, "src")];
|
|
32718
33261
|
const seenFile = /* @__PURE__ */ new Set();
|
|
32719
33262
|
const allFiles = [];
|
|
32720
33263
|
for (const root of roots) {
|
|
@@ -32727,8 +33270,8 @@ function extractConstants(rootDir) {
|
|
|
32727
33270
|
}
|
|
32728
33271
|
if (allFiles.length === 0) return { nodes };
|
|
32729
33272
|
for (const filePath of allFiles) {
|
|
32730
|
-
const content = (0,
|
|
32731
|
-
const relPath = (0,
|
|
33273
|
+
const content = (0, import_node_fs23.readFileSync)(filePath, "utf-8");
|
|
33274
|
+
const relPath = (0, import_node_path27.relative)(rootDir, filePath);
|
|
32732
33275
|
const constArrayRe = /export\s+const\s+([A-Z][A-Z_0-9]+)\s*(?::[^=]+)?\s*=\s*\[/g;
|
|
32733
33276
|
let cm;
|
|
32734
33277
|
while ((cm = constArrayRe.exec(content)) !== null) {
|
|
@@ -32762,13 +33305,13 @@ function extractConstants(rootDir) {
|
|
|
32762
33305
|
}
|
|
32763
33306
|
function detect4(rootDir) {
|
|
32764
33307
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
32765
|
-
if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath && (0,
|
|
33308
|
+
if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath && (0, import_node_fs23.existsSync)(paths.dbConfig.schemaPath)) {
|
|
32766
33309
|
return true;
|
|
32767
33310
|
}
|
|
32768
33311
|
if (paths?.dbDir) {
|
|
32769
|
-
if ((0,
|
|
33312
|
+
if ((0, import_node_fs23.existsSync)((0, import_node_path27.join)(paths.dbDir, "seed.ts")) || (0, import_node_fs23.existsSync)((0, import_node_path27.join)(paths.dbDir, "seed.js"))) return true;
|
|
32770
33313
|
}
|
|
32771
|
-
return (0,
|
|
33314
|
+
return (0, import_node_fs23.existsSync)((0, import_node_path27.join)(rootDir, "prisma", "schema.prisma")) || (0, import_node_fs23.existsSync)((0, import_node_path27.join)(rootDir, "prisma", "seed.ts"));
|
|
32772
33315
|
}
|
|
32773
33316
|
function generate4(rootDir) {
|
|
32774
33317
|
const enumResult = extractEnumValues(rootDir);
|
|
@@ -32843,8 +33386,8 @@ var staticValuesParser = {
|
|
|
32843
33386
|
};
|
|
32844
33387
|
|
|
32845
33388
|
// src/server/graph/parsers/crosslayer/static-ref-scanner.ts
|
|
32846
|
-
var
|
|
32847
|
-
var
|
|
33389
|
+
var import_node_fs24 = require("node:fs");
|
|
33390
|
+
var import_node_path28 = require("node:path");
|
|
32848
33391
|
init_config();
|
|
32849
33392
|
var MIN_VALUE_LENGTH = 4;
|
|
32850
33393
|
var SKIP_VALUES = /* @__PURE__ */ new Set([
|
|
@@ -33019,11 +33562,11 @@ var staticRefScannerParser = {
|
|
|
33019
33562
|
const seen = /* @__PURE__ */ new Set();
|
|
33020
33563
|
let filesScanned = 0;
|
|
33021
33564
|
for (const absPath of files) {
|
|
33022
|
-
const relFromSrc = (0,
|
|
33023
|
-
const sourceId = relFromSrc.startsWith("..") ? (0,
|
|
33565
|
+
const relFromSrc = (0, import_node_path28.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
33566
|
+
const sourceId = relFromSrc.startsWith("..") ? (0, import_node_path28.relative)(rootDir, absPath).replace(/\\/g, "/") : relFromSrc;
|
|
33024
33567
|
const sourceLayer = uiNodeIds.has(sourceId) ? "ui" : apiNodeIds.has(sourceId) ? "api" : null;
|
|
33025
33568
|
if (!sourceLayer) continue;
|
|
33026
|
-
const content = (0,
|
|
33569
|
+
const content = (0, import_node_fs24.readFileSync)(absPath, "utf-8");
|
|
33027
33570
|
filesScanned++;
|
|
33028
33571
|
let fileRefs;
|
|
33029
33572
|
if (parseCode2) {
|
|
@@ -33065,13 +33608,13 @@ var staticRefScannerParser = {
|
|
|
33065
33608
|
};
|
|
33066
33609
|
|
|
33067
33610
|
// src/server/graph/parsers/crosslayer/middleware-gates.ts
|
|
33068
|
-
var
|
|
33611
|
+
var import_node_path29 = require("node:path");
|
|
33069
33612
|
init_ts_extractor();
|
|
33070
33613
|
init_config();
|
|
33071
33614
|
function toNodeId4(srcDir, rootDir, absPath) {
|
|
33072
|
-
const relFromSrc = (0,
|
|
33615
|
+
const relFromSrc = (0, import_node_path29.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
33073
33616
|
if (relFromSrc.startsWith("..")) {
|
|
33074
|
-
return (0,
|
|
33617
|
+
return (0, import_node_path29.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
33075
33618
|
}
|
|
33076
33619
|
return relFromSrc;
|
|
33077
33620
|
}
|
|
@@ -33352,7 +33895,7 @@ var ParserRegistry = class {
|
|
|
33352
33895
|
return all2;
|
|
33353
33896
|
}
|
|
33354
33897
|
};
|
|
33355
|
-
function
|
|
33898
|
+
function registerBuiltins3(registry, disabled) {
|
|
33356
33899
|
const builtins = [
|
|
33357
33900
|
typescriptProjectParser,
|
|
33358
33901
|
prismaSchemaParser,
|
|
@@ -33373,7 +33916,7 @@ function registerBuiltins2(registry, disabled) {
|
|
|
33373
33916
|
function loadCustomParsers(registry, config, rootDir, disabled) {
|
|
33374
33917
|
for (const entry of config.parsers?.custom ?? []) {
|
|
33375
33918
|
try {
|
|
33376
|
-
const absPath = (0,
|
|
33919
|
+
const absPath = (0, import_node_path30.resolve)(rootDir, entry.path);
|
|
33377
33920
|
const mod = require(absPath);
|
|
33378
33921
|
const parser = "default" in mod ? mod.default : mod;
|
|
33379
33922
|
if (disabled.has(parser.id)) continue;
|
|
@@ -33396,14 +33939,14 @@ function loadCustomParsers(registry, config, rootDir, disabled) {
|
|
|
33396
33939
|
function createRegistry(config, rootDir) {
|
|
33397
33940
|
const registry = new ParserRegistry();
|
|
33398
33941
|
const disabled = new Set(config.parsers?.disabled ?? []);
|
|
33399
|
-
|
|
33942
|
+
registerBuiltins3(registry, disabled);
|
|
33400
33943
|
loadCustomParsers(registry, config, rootDir, disabled);
|
|
33401
33944
|
return registry;
|
|
33402
33945
|
}
|
|
33403
33946
|
|
|
33404
33947
|
// src/server/graph/core/language-detection.ts
|
|
33405
|
-
var
|
|
33406
|
-
var
|
|
33948
|
+
var import_node_fs25 = require("node:fs");
|
|
33949
|
+
var import_node_path31 = require("node:path");
|
|
33407
33950
|
init_launch_kit_paths();
|
|
33408
33951
|
var EXTENSION_TO_LANGUAGE = {
|
|
33409
33952
|
// Web / Frontend
|
|
@@ -33516,10 +34059,10 @@ var AUXILIARY_LANGUAGES = /* @__PURE__ */ new Set([
|
|
|
33516
34059
|
]);
|
|
33517
34060
|
function walkForExtensions(dir, extCounts, depth = 0) {
|
|
33518
34061
|
if (depth > 10) return;
|
|
33519
|
-
if (!(0,
|
|
34062
|
+
if (!(0, import_node_fs25.existsSync)(dir)) return;
|
|
33520
34063
|
let entries;
|
|
33521
34064
|
try {
|
|
33522
|
-
entries = (0,
|
|
34065
|
+
entries = (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true });
|
|
33523
34066
|
} catch {
|
|
33524
34067
|
return;
|
|
33525
34068
|
}
|
|
@@ -33527,9 +34070,9 @@ function walkForExtensions(dir, extCounts, depth = 0) {
|
|
|
33527
34070
|
if (entry.name.startsWith(".") && entry.isDirectory()) continue;
|
|
33528
34071
|
if (entry.isDirectory()) {
|
|
33529
34072
|
if (IGNORE_DIRS.has(entry.name)) continue;
|
|
33530
|
-
walkForExtensions((0,
|
|
34073
|
+
walkForExtensions((0, import_node_path31.join)(dir, entry.name), extCounts, depth + 1);
|
|
33531
34074
|
} else {
|
|
33532
|
-
const ext = (0,
|
|
34075
|
+
const ext = (0, import_node_path31.extname)(entry.name).toLowerCase();
|
|
33533
34076
|
if (ext && EXTENSION_TO_LANGUAGE[ext]) {
|
|
33534
34077
|
extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
33535
34078
|
}
|
|
@@ -33570,13 +34113,13 @@ function detectLanguages(rootDir, supportedLanguages) {
|
|
|
33570
34113
|
}
|
|
33571
34114
|
|
|
33572
34115
|
// src/server/graph/core/audit-core.ts
|
|
33573
|
-
var
|
|
33574
|
-
var
|
|
34116
|
+
var import_node_fs27 = require("node:fs");
|
|
34117
|
+
var import_node_path33 = require("node:path");
|
|
33575
34118
|
init_launch_kit_paths();
|
|
33576
34119
|
|
|
33577
34120
|
// src/server/graph/core/audit-security.ts
|
|
33578
|
-
var
|
|
33579
|
-
var
|
|
34121
|
+
var import_node_fs26 = require("node:fs");
|
|
34122
|
+
var import_node_path32 = require("node:path");
|
|
33580
34123
|
init_ts_extractor();
|
|
33581
34124
|
init_config();
|
|
33582
34125
|
function collectSourceFiles(rootDir) {
|
|
@@ -33601,9 +34144,9 @@ function collectSourceFiles(rootDir) {
|
|
|
33601
34144
|
return out;
|
|
33602
34145
|
}
|
|
33603
34146
|
function toNodeId5(rootDir, srcDir, absPath) {
|
|
33604
|
-
const relFromSrc = (0,
|
|
34147
|
+
const relFromSrc = (0, import_node_path32.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
33605
34148
|
if (relFromSrc.startsWith("..")) {
|
|
33606
|
-
return (0,
|
|
34149
|
+
return (0, import_node_path32.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
33607
34150
|
}
|
|
33608
34151
|
return relFromSrc;
|
|
33609
34152
|
}
|
|
@@ -33713,18 +34256,18 @@ function collectDeclaredEnvKeys(rootDir) {
|
|
|
33713
34256
|
const files = [];
|
|
33714
34257
|
let entries = [];
|
|
33715
34258
|
try {
|
|
33716
|
-
entries = (0,
|
|
34259
|
+
entries = (0, import_node_fs26.readdirSync)(rootDir);
|
|
33717
34260
|
} catch {
|
|
33718
34261
|
return { keys, files };
|
|
33719
34262
|
}
|
|
33720
34263
|
for (const name of entries) {
|
|
33721
34264
|
if (!name.startsWith(".env")) continue;
|
|
33722
|
-
const abs = (0,
|
|
33723
|
-
if (!(0,
|
|
34265
|
+
const abs = (0, import_node_path32.join)(rootDir, name);
|
|
34266
|
+
if (!(0, import_node_fs26.existsSync)(abs)) continue;
|
|
33724
34267
|
files.push(name);
|
|
33725
34268
|
let content = "";
|
|
33726
34269
|
try {
|
|
33727
|
-
content = (0,
|
|
34270
|
+
content = (0, import_node_fs26.readFileSync)(abs, "utf-8");
|
|
33728
34271
|
} catch {
|
|
33729
34272
|
continue;
|
|
33730
34273
|
}
|
|
@@ -33911,10 +34454,10 @@ function checkHardcodedUrlFallback(rootDir, core) {
|
|
|
33911
34454
|
|
|
33912
34455
|
// src/server/graph/core/audit-core.ts
|
|
33913
34456
|
function readGraphFile(rootDir, layer) {
|
|
33914
|
-
const filePath = (0,
|
|
33915
|
-
if (!(0,
|
|
34457
|
+
const filePath = (0, import_node_path33.join)(rootDir, LAUNCHSECURE_DIR, "graphs", `${layer}.json`);
|
|
34458
|
+
if (!(0, import_node_fs27.existsSync)(filePath)) return null;
|
|
33916
34459
|
try {
|
|
33917
|
-
return JSON.parse((0,
|
|
34460
|
+
return JSON.parse((0, import_node_fs27.readFileSync)(filePath, "utf-8"));
|
|
33918
34461
|
} catch {
|
|
33919
34462
|
return null;
|
|
33920
34463
|
}
|
|
@@ -33956,15 +34499,15 @@ function checkUnprotectedRoutes(rootDir) {
|
|
|
33956
34499
|
const findings = [];
|
|
33957
34500
|
const api = readGraphFile(rootDir, "api");
|
|
33958
34501
|
if (!api) return buildSkipped("api", "unprotected_routes", "no api graph");
|
|
33959
|
-
const routePermsPath = (0,
|
|
33960
|
-
if (!(0,
|
|
34502
|
+
const routePermsPath = (0, import_node_path33.join)(rootDir, "src", "config", "route-permissions.ts");
|
|
34503
|
+
if (!(0, import_node_fs27.existsSync)(routePermsPath)) {
|
|
33961
34504
|
return buildSkipped(
|
|
33962
34505
|
"api",
|
|
33963
34506
|
"unprotected_routes",
|
|
33964
34507
|
`no src/config/route-permissions.ts \u2014 this check needs a centralized ROUTE_PERMISSIONS inventory to compare endpoints against`
|
|
33965
34508
|
);
|
|
33966
34509
|
}
|
|
33967
|
-
const routePermsContent = (0,
|
|
34510
|
+
const routePermsContent = (0, import_node_fs27.readFileSync)(routePermsPath, "utf-8");
|
|
33968
34511
|
const registeredRoutes = /* @__PURE__ */ new Set();
|
|
33969
34512
|
const routeEntryRe = /path:\s*'([^']+)'/g;
|
|
33970
34513
|
let rm;
|
|
@@ -34049,15 +34592,15 @@ function checkUnenforcedPermissions(rootDir) {
|
|
|
34049
34592
|
`no seed_permission nodes \u2014 this project either has no seed permissions or hasn't tagged them in seed.ts`
|
|
34050
34593
|
);
|
|
34051
34594
|
}
|
|
34052
|
-
const routePermsPath = (0,
|
|
34053
|
-
if (!(0,
|
|
34595
|
+
const routePermsPath = (0, import_node_path33.join)(rootDir, "src", "config", "route-permissions.ts");
|
|
34596
|
+
if (!(0, import_node_fs27.existsSync)(routePermsPath)) {
|
|
34054
34597
|
return buildSkipped(
|
|
34055
34598
|
"static",
|
|
34056
34599
|
"unenforced_permissions",
|
|
34057
34600
|
`no src/config/route-permissions.ts to compare seed permissions against`
|
|
34058
34601
|
);
|
|
34059
34602
|
}
|
|
34060
|
-
const routePermsContent = (0,
|
|
34603
|
+
const routePermsContent = (0, import_node_fs27.readFileSync)(routePermsPath, "utf-8");
|
|
34061
34604
|
for (const perm of permissions) {
|
|
34062
34605
|
const regex = new RegExp(`permission:\\s*['"]${perm.key}['"]`);
|
|
34063
34606
|
if (!regex.test(routePermsContent)) {
|
|
@@ -34093,9 +34636,9 @@ function checkHardcodedValues(rootDir) {
|
|
|
34093
34636
|
const seen = /* @__PURE__ */ new Set();
|
|
34094
34637
|
for (const node of api.nodes) {
|
|
34095
34638
|
if (node.type !== "endpoint") continue;
|
|
34096
|
-
const filePath = (0,
|
|
34097
|
-
if (!(0,
|
|
34098
|
-
const content = (0,
|
|
34639
|
+
const filePath = (0, import_node_path33.join)(rootDir, "src", node.id);
|
|
34640
|
+
if (!(0, import_node_fs27.existsSync)(filePath)) continue;
|
|
34641
|
+
const content = (0, import_node_fs27.readFileSync)(filePath, "utf-8");
|
|
34099
34642
|
let m;
|
|
34100
34643
|
allCapsRe.lastIndex = 0;
|
|
34101
34644
|
while ((m = allCapsRe.exec(content)) !== null) {
|
|
@@ -34200,26 +34743,26 @@ function runAudit(rootDir, layer, check) {
|
|
|
34200
34743
|
}
|
|
34201
34744
|
|
|
34202
34745
|
// src/server/graph/core/projects.ts
|
|
34203
|
-
var
|
|
34746
|
+
var import_node_path36 = require("node:path");
|
|
34204
34747
|
|
|
34205
34748
|
// src/server/lib/worktree.ts
|
|
34206
|
-
var
|
|
34749
|
+
var import_node_path35 = require("node:path");
|
|
34207
34750
|
|
|
34208
34751
|
// src/server/orbit/registry.ts
|
|
34209
|
-
var
|
|
34752
|
+
var import_node_fs28 = require("node:fs");
|
|
34210
34753
|
var import_node_os5 = require("node:os");
|
|
34211
|
-
var
|
|
34754
|
+
var import_node_path34 = require("node:path");
|
|
34212
34755
|
init_launch_kit_paths();
|
|
34213
|
-
var REGISTRY_DIR = (0,
|
|
34214
|
-
var REGISTRY_PATH = (0,
|
|
34215
|
-
var LOCK_PATH = (0,
|
|
34756
|
+
var REGISTRY_DIR = (0, import_node_path34.join)((0, import_node_os5.homedir)(), LAUNCHSECURE_DIR, "orbit");
|
|
34757
|
+
var REGISTRY_PATH = (0, import_node_path34.join)(REGISTRY_DIR, "state.json");
|
|
34758
|
+
var LOCK_PATH = (0, import_node_path34.join)(REGISTRY_DIR, "state.json.lock");
|
|
34216
34759
|
function emptyRegistry() {
|
|
34217
34760
|
return { version: 1, worktrees: {} };
|
|
34218
34761
|
}
|
|
34219
34762
|
function readRegistry() {
|
|
34220
|
-
if (!(0,
|
|
34763
|
+
if (!(0, import_node_fs28.existsSync)(REGISTRY_PATH)) return emptyRegistry();
|
|
34221
34764
|
try {
|
|
34222
|
-
const parsed = JSON.parse((0,
|
|
34765
|
+
const parsed = JSON.parse((0, import_node_fs28.readFileSync)(REGISTRY_PATH, "utf-8"));
|
|
34223
34766
|
if (parsed?.version === 1 && parsed.worktrees && typeof parsed.worktrees === "object") {
|
|
34224
34767
|
return parsed;
|
|
34225
34768
|
}
|
|
@@ -34249,7 +34792,7 @@ function resolveWorktreeRoot(slug, monorepoRoot) {
|
|
|
34249
34792
|
function resolveWorktreeOrProjectRoot(args, monorepoRoot) {
|
|
34250
34793
|
const projectRoot = typeof args.project_root === "string" ? args.project_root.trim() : "";
|
|
34251
34794
|
if (projectRoot) {
|
|
34252
|
-
return (0,
|
|
34795
|
+
return (0, import_node_path35.isAbsolute)(projectRoot) ? projectRoot : (0, import_node_path35.resolve)(monorepoRoot, projectRoot);
|
|
34253
34796
|
}
|
|
34254
34797
|
const worktree = typeof args.worktree === "string" ? args.worktree.trim() : "";
|
|
34255
34798
|
if (worktree) {
|
|
@@ -34268,7 +34811,7 @@ function listProjects(monorepoRoot) {
|
|
|
34268
34811
|
return entries.map((p) => ({
|
|
34269
34812
|
name: p.name,
|
|
34270
34813
|
root: p.root,
|
|
34271
|
-
absoluteRoot: (0,
|
|
34814
|
+
absoluteRoot: (0, import_node_path36.resolve)(monorepoRoot, p.root)
|
|
34272
34815
|
}));
|
|
34273
34816
|
}
|
|
34274
34817
|
function resolveProject(name, projects) {
|
|
@@ -34677,6 +35220,53 @@ USE THIS FOR: "are there unsafe migrations on this branch", "audit the migration
|
|
|
34677
35220
|
required: ["from", "to"]
|
|
34678
35221
|
}
|
|
34679
35222
|
},
|
|
35223
|
+
{
|
|
35224
|
+
name: "scaffold_snippet",
|
|
35225
|
+
description: 'Scaffold a standardised test "snippet" for a context-graph action/state node. Returns a ready-to-complete snippet file: requires/produces are filled from the context graph (certain); params + the run() body are left as TODOs for you to fill from the endpoint source.\n\nUSE THIS FOR: turning a context `action` (e.g. "create tag", "pay via UPI") into a reusable Playwright snippet in the project\'s standard shape, instead of hand-writing the requires/produces wiring. Requires the `context` layer (run generate_graph first).',
|
|
35226
|
+
inputSchema: {
|
|
35227
|
+
type: "object",
|
|
35228
|
+
properties: {
|
|
35229
|
+
target: { type: "string", description: 'Context node id (e.g. "action:app/api/orgs/[orgSlug]/tags/route.ts") or the bare key (the "action:"/"state:" prefix is added if missing).' },
|
|
35230
|
+
project: { type: "string", description: PROJECT_PARAM_DESCRIPTION },
|
|
35231
|
+
worktree: { type: "string", description: WORKTREE_PARAM_DESCRIPTION2 },
|
|
35232
|
+
project_root: { type: "string", description: PROJECT_ROOT_PARAM_DESCRIPTION2 }
|
|
35233
|
+
},
|
|
35234
|
+
required: ["target"]
|
|
35235
|
+
}
|
|
35236
|
+
},
|
|
35237
|
+
{
|
|
35238
|
+
name: "test_plan",
|
|
35239
|
+
description: 'Assemble the ordered snippet chain needed to exercise a target action. Walks the context graph\'s requires/produces backward from the target (prerequisites first, target last), binds each step to its snippet (from tests/snippets/), and flags gaps \u2014 a required state nothing produces, an action with no snippet, or a cycle.\n\nUSE THIS FOR: "what\'s the test plan for creating a tag", "what setup does action X need". Returns { target, steps[], gaps[], runnable }. Requires the `context` layer (run generate_graph first). When runnable is false, the gaps tell you which snippets to scaffold next.',
|
|
35240
|
+
inputSchema: {
|
|
35241
|
+
type: "object",
|
|
35242
|
+
properties: {
|
|
35243
|
+
target: { type: "string", description: 'Context action node id (e.g. "action:app/api/orgs/[orgSlug]/tags/route.ts") or the bare key.' },
|
|
35244
|
+
snippets_dir: { type: "string", description: `Snippets directory relative to project root. Default "${DEFAULT_SNIPPETS_DIR}".` },
|
|
35245
|
+
project: { type: "string", description: PROJECT_PARAM_DESCRIPTION },
|
|
35246
|
+
worktree: { type: "string", description: WORKTREE_PARAM_DESCRIPTION2 },
|
|
35247
|
+
project_root: { type: "string", description: PROJECT_ROOT_PARAM_DESCRIPTION2 }
|
|
35248
|
+
},
|
|
35249
|
+
required: ["target"]
|
|
35250
|
+
}
|
|
35251
|
+
},
|
|
35252
|
+
{
|
|
35253
|
+
name: "generate_spec",
|
|
35254
|
+
description: 'Generate a runnable Playwright .spec.ts from a target action: builds the test_plan, then emits imports + ordered `await snippet.run(page, {...})` calls. Params are auto-classified \u2014 secrets \u2192 process.env, free-form (name/color/icon/description) \u2192 faker.*, and state-bound (email/slug/id) \u2192 TODO + returned in missingFixtures. Supply those via `fixtures`.\n\nUSE THIS FOR: "generate the test for creating a tag". Returns { code, missingFixtures, complete }. complete:true means every state-bound param had a fixture (secrets via env + faker auto). Requires the `context` layer + snippets.',
|
|
35255
|
+
inputSchema: {
|
|
35256
|
+
type: "object",
|
|
35257
|
+
properties: {
|
|
35258
|
+
target: { type: "string", description: "Context action node id (or bare key)." },
|
|
35259
|
+
fixtures: { type: "object", description: 'param name -> value for state-bound params (e.g. {"email":"...","orgSlug":"..."}). Overrides classification.', additionalProperties: true },
|
|
35260
|
+
title: { type: "string", description: "Test title. Defaults to the target." },
|
|
35261
|
+
spec_dir: { type: "string", description: 'Where the spec will live (for import paths). Default "tests/generated".' },
|
|
35262
|
+
snippets_dir: { type: "string", description: `Snippets directory. Default "${DEFAULT_SNIPPETS_DIR}".` },
|
|
35263
|
+
project: { type: "string", description: PROJECT_PARAM_DESCRIPTION },
|
|
35264
|
+
worktree: { type: "string", description: WORKTREE_PARAM_DESCRIPTION2 },
|
|
35265
|
+
project_root: { type: "string", description: PROJECT_ROOT_PARAM_DESCRIPTION2 }
|
|
35266
|
+
},
|
|
35267
|
+
required: ["target"]
|
|
35268
|
+
}
|
|
35269
|
+
},
|
|
34680
35270
|
{
|
|
34681
35271
|
name: "auth_coverage_report",
|
|
34682
35272
|
description: 'Aggregate every API endpoint by its auth[] wrapper(s) \u2014 surfaces endpoints with empty auth, groups by module, shows which auth strategies dominate. Computed from api.json endpoint auth field (100% populated).\n\nUSE THIS FOR: "are there unauthenticated endpoints", "which auth wrappers are in use", "audit auth strategy consistency across modules". Paginated. Returns { total, by_strategy: {strategy: count}, unauthenticated: [endpoint_ids], by_module: {module: {total, by_strategy}} } plus the paginated endpoint list.',
|
|
@@ -35660,12 +36250,12 @@ function handleReadGraph(args) {
|
|
|
35660
36250
|
return okJson(result);
|
|
35661
36251
|
}
|
|
35662
36252
|
function nodeToFilePath(rootDir, layer, nodeId) {
|
|
35663
|
-
if (layer === "ui" || layer === "api") return (0,
|
|
35664
|
-
if (layer === "db") return (0,
|
|
35665
|
-
const withSrc = (0,
|
|
35666
|
-
if ((0,
|
|
35667
|
-
const direct = (0,
|
|
35668
|
-
if ((0,
|
|
36253
|
+
if (layer === "ui" || layer === "api") return (0, import_node_path38.join)(rootDir, "src", nodeId);
|
|
36254
|
+
if (layer === "db") return (0, import_node_path38.join)(rootDir, "prisma", "schema.prisma");
|
|
36255
|
+
const withSrc = (0, import_node_path38.join)(rootDir, "src", nodeId);
|
|
36256
|
+
if ((0, import_node_fs30.existsSync)(withSrc)) return withSrc;
|
|
36257
|
+
const direct = (0, import_node_path38.join)(rootDir, nodeId);
|
|
36258
|
+
if ((0, import_node_fs30.existsSync)(direct)) return direct;
|
|
35669
36259
|
return null;
|
|
35670
36260
|
}
|
|
35671
36261
|
function handleInspectNode(args) {
|
|
@@ -35933,11 +36523,11 @@ function handleGrepNodes(args) {
|
|
|
35933
36523
|
let filesSearched = 0;
|
|
35934
36524
|
let truncated = false;
|
|
35935
36525
|
for (const [filePath, nodeId] of filePaths) {
|
|
35936
|
-
if (!(0,
|
|
36526
|
+
if (!(0, import_node_fs30.existsSync)(filePath)) continue;
|
|
35937
36527
|
filesSearched++;
|
|
35938
36528
|
let content;
|
|
35939
36529
|
try {
|
|
35940
|
-
content = (0,
|
|
36530
|
+
content = (0, import_node_fs30.readFileSync)(filePath, "utf-8");
|
|
35941
36531
|
} catch {
|
|
35942
36532
|
continue;
|
|
35943
36533
|
}
|
|
@@ -36156,11 +36746,11 @@ function handleStartChartServer(args) {
|
|
|
36156
36746
|
});
|
|
36157
36747
|
}
|
|
36158
36748
|
const entryPath = process.argv[1];
|
|
36159
|
-
const logDir = (0,
|
|
36160
|
-
(0,
|
|
36161
|
-
const logPath = (0,
|
|
36162
|
-
const out = (0,
|
|
36163
|
-
const err2 = (0,
|
|
36749
|
+
const logDir = (0, import_node_path38.join)((0, import_node_os6.homedir)(), LAUNCHSECURE_DIR);
|
|
36750
|
+
(0, import_node_fs30.mkdirSync)(logDir, { recursive: true });
|
|
36751
|
+
const logPath = (0, import_node_path38.join)(logDir, "launch-chart.log");
|
|
36752
|
+
const out = (0, import_node_fs30.openSync)(logPath, "a");
|
|
36753
|
+
const err2 = (0, import_node_fs30.openSync)(logPath, "a");
|
|
36164
36754
|
const portArgs = args.port ? ["--port", String(args.port)] : [];
|
|
36165
36755
|
const child = (0, import_node_child_process3.spawn)(process.execPath, [entryPath, "serve", ...portArgs], {
|
|
36166
36756
|
detached: true,
|
|
@@ -36338,6 +36928,96 @@ function handleDriftReport(args) {
|
|
|
36338
36928
|
items: page
|
|
36339
36929
|
});
|
|
36340
36930
|
}
|
|
36931
|
+
function handleGenerateSpec(args) {
|
|
36932
|
+
const __resolved = resolveOrErr(args);
|
|
36933
|
+
if ("content" in __resolved) return __resolved;
|
|
36934
|
+
const { rootDir } = __resolved;
|
|
36935
|
+
const target = typeof args.target === "string" ? args.target.trim() : "";
|
|
36936
|
+
if (!target) return err("target is required (a context action node id).");
|
|
36937
|
+
const snippetsDir = typeof args.snippets_dir === "string" && args.snippets_dir.trim() ? args.snippets_dir.trim() : DEFAULT_SNIPPETS_DIR;
|
|
36938
|
+
const specDir = typeof args.spec_dir === "string" && args.spec_dir.trim() ? args.spec_dir.trim() : "tests/generated";
|
|
36939
|
+
const fixtures = args.fixtures && typeof args.fixtures === "object" ? args.fixtures : {};
|
|
36940
|
+
const title = typeof args.title === "string" ? args.title : void 0;
|
|
36941
|
+
const g = readGraph(rootDir, "context");
|
|
36942
|
+
if (!g) return err("No `context` layer found. Run generate_graph first to build context.json.");
|
|
36943
|
+
let node = g.nodes.find((n) => n.id === target);
|
|
36944
|
+
if (!node && !target.startsWith("action:") && !target.startsWith("state:")) {
|
|
36945
|
+
node = g.nodes.find((n) => n.id === `action:${target}`) ?? g.nodes.find((n) => n.id === `state:${target}`);
|
|
36946
|
+
}
|
|
36947
|
+
if (!node) return err(`No context node matching "${target}". Use read_graph layer:context to list nodes.`);
|
|
36948
|
+
const snippets = loadSnippetIndex(rootDir, snippetsDir);
|
|
36949
|
+
const plan = buildTestPlan(g, node.id, snippets);
|
|
36950
|
+
const spec = generateSpec(plan, { title: title ?? String(node.name), specDir, fixtures });
|
|
36951
|
+
return okJson({
|
|
36952
|
+
target: node.id,
|
|
36953
|
+
spec_dir: specDir,
|
|
36954
|
+
suggested_path: `${specDir}/${String(node.name).replace(/[^A-Za-z0-9]+/g, "-").replace(/^-|-$/g, "") || "spec"}.spec.ts`,
|
|
36955
|
+
complete: spec.complete,
|
|
36956
|
+
missing_fixtures: spec.missingFixtures,
|
|
36957
|
+
plan_gaps: plan.gaps,
|
|
36958
|
+
code: spec.code,
|
|
36959
|
+
next: spec.complete ? "Write `code` to suggested_path and run `playwright test` (needs @faker-js/faker installed + the secret env vars set)." : "Supply `fixtures` for missing_fixtures (real seeded values), then regenerate."
|
|
36960
|
+
});
|
|
36961
|
+
}
|
|
36962
|
+
function handleTestPlan(args) {
|
|
36963
|
+
const __resolved = resolveOrErr(args);
|
|
36964
|
+
if ("content" in __resolved) return __resolved;
|
|
36965
|
+
const { rootDir } = __resolved;
|
|
36966
|
+
const target = typeof args.target === "string" ? args.target.trim() : "";
|
|
36967
|
+
if (!target) return err("target is required (a context action node id).");
|
|
36968
|
+
const snippetsDir = typeof args.snippets_dir === "string" && args.snippets_dir.trim() ? args.snippets_dir.trim() : DEFAULT_SNIPPETS_DIR;
|
|
36969
|
+
const g = readGraph(rootDir, "context");
|
|
36970
|
+
if (!g) return err("No `context` layer found. Run generate_graph first to build context.json.");
|
|
36971
|
+
let node = g.nodes.find((n) => n.id === target);
|
|
36972
|
+
if (!node && !target.startsWith("action:") && !target.startsWith("state:")) {
|
|
36973
|
+
node = g.nodes.find((n) => n.id === `action:${target}`) ?? g.nodes.find((n) => n.id === `state:${target}`);
|
|
36974
|
+
}
|
|
36975
|
+
if (!node) return err(`No context node matching "${target}". Use read_graph layer:context to list nodes.`);
|
|
36976
|
+
const snippets = loadSnippetIndex(rootDir, snippetsDir);
|
|
36977
|
+
const plan = buildTestPlan(g, node.id, snippets);
|
|
36978
|
+
return okJson({
|
|
36979
|
+
...plan,
|
|
36980
|
+
snippets_dir: snippetsDir,
|
|
36981
|
+
snippets_found: snippets.size,
|
|
36982
|
+
next: plan.runnable ? "Runnable: execute the snippets in `steps` order, threading produced state forward." : "Not yet runnable \u2014 resolve `gaps` (scaffold_snippet for missing bindings; add a producer for unmet states)."
|
|
36983
|
+
});
|
|
36984
|
+
}
|
|
36985
|
+
function handleScaffoldSnippet(args) {
|
|
36986
|
+
const __resolved = resolveOrErr(args);
|
|
36987
|
+
if ("content" in __resolved) return __resolved;
|
|
36988
|
+
const { rootDir } = __resolved;
|
|
36989
|
+
const target = typeof args.target === "string" ? args.target.trim() : "";
|
|
36990
|
+
if (!target) return err('target is required (a context node id, e.g. "action:app/api/.../tags/route.ts").');
|
|
36991
|
+
const g = readGraph(rootDir, "context");
|
|
36992
|
+
if (!g) return err("No `context` layer found. Run generate_graph first to build context.json.");
|
|
36993
|
+
let node = g.nodes.find((n) => n.id === target);
|
|
36994
|
+
if (!node && !target.startsWith("action:") && !target.startsWith("state:")) {
|
|
36995
|
+
node = g.nodes.find((n) => n.id === `action:${target}`) ?? g.nodes.find((n) => n.id === `state:${target}`);
|
|
36996
|
+
}
|
|
36997
|
+
if (!node) return err(`No context node matching "${target}". Use read_graph layer:context to list nodes.`);
|
|
36998
|
+
const out = g.edges.filter((e) => e.source === node.id);
|
|
36999
|
+
const tokensOf = (type) => [...new Set(out.filter((e) => e.type === type).map((e) => String(e.target).replace(/^state:/, "")))].sort();
|
|
37000
|
+
const requires = tokensOf("requires");
|
|
37001
|
+
const produces = tokensOf("produces");
|
|
37002
|
+
const { exportName, code } = scaffoldSnippet({
|
|
37003
|
+
nodeId: node.id,
|
|
37004
|
+
name: String(node.name ?? node.id),
|
|
37005
|
+
requires,
|
|
37006
|
+
produces
|
|
37007
|
+
});
|
|
37008
|
+
const requiresDetail = out.filter((e) => e.type === "requires").map((e) => ({ state: String(e.target).replace(/^state:/, ""), confidence: e.confidence ?? "low", origin: e.origin ?? null }));
|
|
37009
|
+
return okJson({
|
|
37010
|
+
target: node.id,
|
|
37011
|
+
name: node.name ?? node.id,
|
|
37012
|
+
requires,
|
|
37013
|
+
produces,
|
|
37014
|
+
requires_detail: requiresDetail,
|
|
37015
|
+
export_name: exportName,
|
|
37016
|
+
suggested_path: `tests/snippets/${exportName}.ts`,
|
|
37017
|
+
snippet: code,
|
|
37018
|
+
next: "Fill `params` from the endpoint request/validation schema and implement run() with Playwright, then write the file to suggested_path."
|
|
37019
|
+
});
|
|
37020
|
+
}
|
|
36341
37021
|
function handleWhoUses(args) {
|
|
36342
37022
|
const __resolved = resolveOrErr(args);
|
|
36343
37023
|
if ("content" in __resolved) return __resolved;
|
|
@@ -36583,20 +37263,20 @@ function handleDetectProjectStack() {
|
|
|
36583
37263
|
if (ref.type === "references_api") stats.references_api++;
|
|
36584
37264
|
}
|
|
36585
37265
|
}
|
|
36586
|
-
const srcDir = (0,
|
|
36587
|
-
if ((0,
|
|
37266
|
+
const srcDir = (0, import_node_path38.join)(rootDir, "src");
|
|
37267
|
+
if ((0, import_node_fs30.existsSync)(srcDir)) {
|
|
36588
37268
|
const scanDir = (dir) => {
|
|
36589
|
-
if (!(0,
|
|
36590
|
-
for (const entry of (0,
|
|
37269
|
+
if (!(0, import_node_fs30.existsSync)(dir)) return;
|
|
37270
|
+
for (const entry of (0, import_node_fs30.readdirSync)(dir, { withFileTypes: true })) {
|
|
36591
37271
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
36592
|
-
const full = (0,
|
|
37272
|
+
const full = (0, import_node_path38.join)(dir, entry.name);
|
|
36593
37273
|
if (entry.isDirectory()) {
|
|
36594
37274
|
scanDir(full);
|
|
36595
37275
|
continue;
|
|
36596
37276
|
}
|
|
36597
|
-
if (![".ts", ".tsx"].includes((0,
|
|
37277
|
+
if (![".ts", ".tsx"].includes((0, import_node_path38.extname)(entry.name))) continue;
|
|
36598
37278
|
try {
|
|
36599
|
-
const content = (0,
|
|
37279
|
+
const content = (0, import_node_fs30.readFileSync)(full, "utf-8");
|
|
36600
37280
|
const matches = content.match(/@api\s+(GET|POST|PUT|DELETE|PATCH)\s+\/\S+/g);
|
|
36601
37281
|
if (matches) stats.annotations += matches.length;
|
|
36602
37282
|
} catch {
|
|
@@ -36615,7 +37295,7 @@ function handleDetectProjectStack() {
|
|
|
36615
37295
|
name: p.name,
|
|
36616
37296
|
root: p.root,
|
|
36617
37297
|
absolute_root: p.absoluteRoot,
|
|
36618
|
-
has_graph: (0,
|
|
37298
|
+
has_graph: (0, import_node_fs30.existsSync)((0, import_node_path38.join)(p.absoluteRoot, LAUNCHSECURE_DIR, "graphs"))
|
|
36619
37299
|
}));
|
|
36620
37300
|
return okJson({
|
|
36621
37301
|
languages,
|
|
@@ -36745,6 +37425,18 @@ async function handleMessage(msg) {
|
|
|
36745
37425
|
respond(id ?? null, withFreshnessMeta(handleWhoUses(args), args));
|
|
36746
37426
|
return;
|
|
36747
37427
|
}
|
|
37428
|
+
if (toolName === "scaffold_snippet") {
|
|
37429
|
+
respond(id ?? null, withFreshnessMeta(handleScaffoldSnippet(args), args));
|
|
37430
|
+
return;
|
|
37431
|
+
}
|
|
37432
|
+
if (toolName === "test_plan") {
|
|
37433
|
+
respond(id ?? null, withFreshnessMeta(handleTestPlan(args), args));
|
|
37434
|
+
return;
|
|
37435
|
+
}
|
|
37436
|
+
if (toolName === "generate_spec") {
|
|
37437
|
+
respond(id ?? null, withFreshnessMeta(handleGenerateSpec(args), args));
|
|
37438
|
+
return;
|
|
37439
|
+
}
|
|
36748
37440
|
if (toolName === "trace_path") {
|
|
36749
37441
|
respond(id ?? null, withFreshnessMeta(handleTracePath(args), args));
|
|
36750
37442
|
return;
|
|
@@ -36932,7 +37624,7 @@ function parseArgs() {
|
|
|
36932
37624
|
return { port, token, serverUrl: LAUNCHSECURE_URL, subcommand, course };
|
|
36933
37625
|
}
|
|
36934
37626
|
function tryListen(server, port, maxRetries = 10) {
|
|
36935
|
-
return new Promise((
|
|
37627
|
+
return new Promise((resolve7, reject) => {
|
|
36936
37628
|
let attempts = 0;
|
|
36937
37629
|
function attempt(p) {
|
|
36938
37630
|
server.once("error", (err2) => {
|
|
@@ -36943,7 +37635,7 @@ function tryListen(server, port, maxRetries = 10) {
|
|
|
36943
37635
|
reject(err2);
|
|
36944
37636
|
}
|
|
36945
37637
|
});
|
|
36946
|
-
server.listen(p, "127.0.0.1", () =>
|
|
37638
|
+
server.listen(p, "127.0.0.1", () => resolve7(p));
|
|
36947
37639
|
}
|
|
36948
37640
|
attempt(port);
|
|
36949
37641
|
});
|
|
@@ -36964,7 +37656,7 @@ function saveCredentials(creds) {
|
|
|
36964
37656
|
});
|
|
36965
37657
|
}
|
|
36966
37658
|
function verifyToken(serverUrl, token) {
|
|
36967
|
-
return new Promise((
|
|
37659
|
+
return new Promise((resolve7) => {
|
|
36968
37660
|
const url = new URL("/api/mcp/verify", serverUrl);
|
|
36969
37661
|
const body = JSON.stringify({ token });
|
|
36970
37662
|
const mod = url.protocol === "https:" ? import_https.default : import_http.default;
|
|
@@ -36979,30 +37671,30 @@ function verifyToken(serverUrl, token) {
|
|
|
36979
37671
|
res.on("data", (chunk) => data += chunk);
|
|
36980
37672
|
res.on("end", () => {
|
|
36981
37673
|
try {
|
|
36982
|
-
|
|
37674
|
+
resolve7(JSON.parse(data));
|
|
36983
37675
|
} catch {
|
|
36984
|
-
|
|
37676
|
+
resolve7({ valid: false, error: "Invalid response from server" });
|
|
36985
37677
|
}
|
|
36986
37678
|
});
|
|
36987
37679
|
});
|
|
36988
37680
|
req.on("error", (err2) => {
|
|
36989
|
-
|
|
37681
|
+
resolve7({ valid: false, error: `Cannot reach server: ${err2.message}` });
|
|
36990
37682
|
});
|
|
36991
37683
|
req.setTimeout(1e4, () => {
|
|
36992
37684
|
req.destroy();
|
|
36993
|
-
|
|
37685
|
+
resolve7({ valid: false, error: "Connection timed out" });
|
|
36994
37686
|
});
|
|
36995
37687
|
req.write(body);
|
|
36996
37688
|
req.end();
|
|
36997
37689
|
});
|
|
36998
37690
|
}
|
|
36999
37691
|
function httpRequest2(reqUrl, options, body, timeout = 3e4) {
|
|
37000
|
-
return new Promise((
|
|
37692
|
+
return new Promise((resolve7, reject) => {
|
|
37001
37693
|
const mod = reqUrl.protocol === "https:" ? import_https.default : import_http.default;
|
|
37002
37694
|
const r = mod.request(reqUrl, options, (resp) => {
|
|
37003
37695
|
let data = "";
|
|
37004
37696
|
resp.on("data", (chunk) => data += chunk);
|
|
37005
|
-
resp.on("end", () =>
|
|
37697
|
+
resp.on("end", () => resolve7({ status: resp.statusCode || 0, headers: resp.headers, body: data }));
|
|
37006
37698
|
});
|
|
37007
37699
|
r.on("error", reject);
|
|
37008
37700
|
r.setTimeout(timeout, () => {
|