@rashidee/co2 1.3.11 → 1.3.13
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/.co2-dat/app.db +0 -0
- package/dist/.co2-dat/app.db-shm +0 -0
- package/dist/.co2-dat/app.db-wal +0 -0
- package/dist/index.js +254 -73
- package/package.json +41 -41
- package/plugin/.claude-plugin/marketplace.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/README.md +3 -1
- package/plugin/SKILLS.md +5 -2
- package/plugin/skills/conductor-feature-develop/SKILL.md +13 -0
- package/plugin/skills/conductor-feature-prepare/SKILL.md +39 -11
- package/plugin/skills/specgen-custom/SKILL.md +442 -0
- package/plugin/skills/specgen-custom/references/spec-template.md +271 -0
- package/plugin/skills/specgen-custom/references/stack-doc-template.md +154 -0
- package/plugin/skills/util-gencicdscript/references/cicd-app-template.md +798 -796
- package/plugin/skills/util-plancicd/SKILL.md +1 -1
- package/static/assets/{abnfDiagram-VRR7QNED-DBzgA_2G.js → abnfDiagram-VRR7QNED-Qm0Wk_H_.js} +1 -1
- package/static/assets/{arc-Bc02_4l6.js → arc-Cfk6Kt0D.js} +1 -1
- package/static/assets/{architectureDiagram-ZJ3FMSHR-ixN9wSDW.js → architectureDiagram-ZJ3FMSHR-DQTlZaUK.js} +1 -1
- package/static/assets/{blockDiagram-677ZJIJ3-Ob4lZkCY.js → blockDiagram-677ZJIJ3-D-4ibdoX.js} +1 -1
- package/static/assets/{c4Diagram-LMCZKHZV-BeJY3Zks.js → c4Diagram-LMCZKHZV-CHuqcdJm.js} +1 -1
- package/static/assets/channel-H9DRrduO.js +1 -0
- package/static/assets/{chunk-2Q5K7J3B-DTFIWNGb.js → chunk-2Q5K7J3B-MB9pWQe1.js} +1 -1
- package/static/assets/{chunk-32BRIVSS-DLTvoPpT.js → chunk-32BRIVSS-BttYlwU1.js} +1 -1
- package/static/assets/{chunk-5VM5RSS4-BKlvf6hI.js → chunk-5VM5RSS4-oyt0Tagd.js} +1 -1
- package/static/assets/{chunk-EX3LRPZG-B9ej8_ma.js → chunk-EX3LRPZG-DaTxdTWl.js} +1 -1
- package/static/assets/{chunk-JWPE2WC7-DAYaiy17.js → chunk-JWPE2WC7-CNgDxPAD.js} +1 -1
- package/static/assets/{chunk-MOJQB5TN-D6rRKzWc.js → chunk-MOJQB5TN-CoAudO3B.js} +1 -1
- package/static/assets/{chunk-RYQCIY6F-CE4CHN6p.js → chunk-RYQCIY6F-BrkDEEha.js} +1 -1
- package/static/assets/{chunk-V7JOEXUC-BR-Kl6S2.js → chunk-V7JOEXUC-D14rGvBO.js} +1 -1
- package/static/assets/{chunk-VR4S4FIN-Bo9J3WGe.js → chunk-VR4S4FIN-CAtas2vF.js} +1 -1
- package/static/assets/{chunk-XXDRQBXY-DjI5dJHR.js → chunk-XXDRQBXY-DcVAnNUQ.js} +1 -1
- package/static/assets/classDiagram-OUVF2IWQ-DRNPM383.js +1 -0
- package/static/assets/classDiagram-v2-EOCWNBFH-DRNPM383.js +1 -0
- package/static/assets/{cose-bilkent-JH36ORCC-DLciz-3w.js → cose-bilkent-JH36ORCC-B7y4MI6Z.js} +1 -1
- package/static/assets/{cynefin-VYW2F7L2-DqfVJKpm.js → cynefin-VYW2F7L2-D2mnk-iJ.js} +1 -1
- package/static/assets/{cynefinDiagram-TSTJHNR4-D14oLdNM.js → cynefinDiagram-TSTJHNR4-DNzQJhG7.js} +1 -1
- package/static/assets/{dagre-VKFMJZFB-BduMbW80.js → dagre-VKFMJZFB-NMSyTo8N.js} +1 -1
- package/static/assets/{diagram-FQU43EPY-CLQg7RWT.js → diagram-FQU43EPY-CdqS5Ike.js} +1 -1
- package/static/assets/{diagram-G47NLZAW-Dq3Ymr1b.js → diagram-G47NLZAW-Bsb4T5JI.js} +1 -1
- package/static/assets/{diagram-NH7WQ7WH-BPjov8S5.js → diagram-NH7WQ7WH-Z-PyzBSC.js} +1 -1
- package/static/assets/{diagram-OA4YK3LP-BgQgpiJD.js → diagram-OA4YK3LP-BZBTYbxg.js} +1 -1
- package/static/assets/{diagram-WEI45ONY-BeOPSl27.js → diagram-WEI45ONY-BL2LA5H_.js} +1 -1
- package/static/assets/{ebnfDiagram-CCIWWBDH-DFsTw8OM.js → ebnfDiagram-CCIWWBDH-BGtukMeo.js} +1 -1
- package/static/assets/{erDiagram-Q63AITRT-scBEBawL.js → erDiagram-Q63AITRT-B6OJ4YCl.js} +1 -1
- package/static/assets/{flowDiagram-23GEKE2U-BfX-2ZO-.js → flowDiagram-23GEKE2U-BBkMgJ1i.js} +1 -1
- package/static/assets/{ganttDiagram-NO4QXBWP-BR5IJ1mv.js → ganttDiagram-NO4QXBWP-Cv8KHFBD.js} +1 -1
- package/static/assets/{gitGraphDiagram-IHSO6WYX-zPu_QDUM.js → gitGraphDiagram-IHSO6WYX-hYxDNjWx.js} +1 -1
- package/static/assets/{index-Dnp-sAA_.js → index-DnYGyYET.js} +81 -79
- package/static/assets/{infoDiagram-FWYZ7A6U-CpyKTQb9.js → infoDiagram-FWYZ7A6U-WuQIiedv.js} +1 -1
- package/static/assets/{ishikawaDiagram-FXEZZL3T-C2SXt-2Y.js → ishikawaDiagram-FXEZZL3T-BJGOD-IY.js} +1 -1
- package/static/assets/{journeyDiagram-5HDEW3XC-DJavk0C4.js → journeyDiagram-5HDEW3XC-Ba_NXseS.js} +1 -1
- package/static/assets/{kanban-definition-HUTT4EX6-xN4pVGL7.js → kanban-definition-HUTT4EX6-C5RMm9uF.js} +1 -1
- package/static/assets/{linear-BMWKojRX.js → linear-CLKppNoj.js} +1 -1
- package/static/assets/{mindmap-definition-LN4V7U3C-DOaDf7u0.js → mindmap-definition-LN4V7U3C-ClSG_qmQ.js} +1 -1
- package/static/assets/{pegDiagram-2B236MQR-B1px906A.js → pegDiagram-2B236MQR-C_JEZqk3.js} +1 -1
- package/static/assets/{pieDiagram-ENE6RG2P-s0vEagFS.js → pieDiagram-ENE6RG2P-D0lx7wDi.js} +1 -1
- package/static/assets/{quadrantDiagram-ABIIQ3AL-BEhIl8IZ.js → quadrantDiagram-ABIIQ3AL-BBKy0PVs.js} +1 -1
- package/static/assets/{railroadDiagram-RFXS5EU6-fFsin92S.js → railroadDiagram-RFXS5EU6-C1Badu5q.js} +1 -1
- package/static/assets/{requirementDiagram-TGXJPOKE-Cf9J7tii.js → requirementDiagram-TGXJPOKE-1j59jBQH.js} +1 -1
- package/static/assets/{sankeyDiagram-HTMAVEWB-Cy5gaZqM.js → sankeyDiagram-HTMAVEWB-BLR5S8aZ.js} +1 -1
- package/static/assets/{sequenceDiagram-DBY2YBRQ-DI61Vnk1.js → sequenceDiagram-DBY2YBRQ-BlqdK4qm.js} +1 -1
- package/static/assets/{sizeCapture-X5ZJPWSS-CmUBUW3B.js → sizeCapture-X5ZJPWSS-C27ndGIT.js} +1 -1
- package/static/assets/{stateDiagram-2N3HPSRC-CBMhhwuE.js → stateDiagram-2N3HPSRC-DOu4536_.js} +1 -1
- package/static/assets/stateDiagram-v2-6OUMAXLB-DvP1ZCp8.js +1 -0
- package/static/assets/{swimlanes-5IMT3BWC-CtZlr9wD.js → swimlanes-5IMT3BWC-BpGitR9A.js} +2 -2
- package/static/assets/swimlanesDiagram-G3AALYLV-B5cf18Ey.js +8 -0
- package/static/assets/{timeline-definition-FHXFAJF6-BC69PWR-.js → timeline-definition-FHXFAJF6-JIvdjH7z.js} +1 -1
- package/static/assets/{vennDiagram-L72KCM5P-jEaqKPSP.js → vennDiagram-L72KCM5P-DulnqLWm.js} +1 -1
- package/static/assets/{wardleyDiagram-EHGQE667-CKFWi3EK.js → wardleyDiagram-EHGQE667--MhZNL8M.js} +1 -1
- package/static/assets/{xychartDiagram-FW5EYKEG-CjyCKfOu.js → xychartDiagram-FW5EYKEG-CjnNgnMQ.js} +1 -1
- package/static/index.html +1 -1
- package/static/assets/channel-CJFxgMC1.js +0 -1
- package/static/assets/classDiagram-OUVF2IWQ-B5OYUyBf.js +0 -1
- package/static/assets/classDiagram-v2-EOCWNBFH-B5OYUyBf.js +0 -1
- package/static/assets/stateDiagram-v2-6OUMAXLB-BD1I889C.js +0 -1
- package/static/assets/swimlanesDiagram-G3AALYLV-BfEZlw_9.js +0 -8
package/dist/.co2-dat/app.db
CHANGED
|
Binary file
|
package/dist/.co2-dat/app.db-shm
CHANGED
|
Binary file
|
package/dist/.co2-dat/app.db-wal
CHANGED
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -6809,7 +6809,7 @@ var {
|
|
|
6809
6809
|
// package.json
|
|
6810
6810
|
var package_default = {
|
|
6811
6811
|
name: "@rashidee/co2",
|
|
6812
|
-
version: "1.3.
|
|
6812
|
+
version: "1.3.13",
|
|
6813
6813
|
description: "Compound Context Studio \u2014 self-hosted team context authoring for CO2 projects",
|
|
6814
6814
|
type: "module",
|
|
6815
6815
|
license: "MIT",
|
|
@@ -14785,6 +14785,15 @@ function resolveSession(db) {
|
|
|
14785
14785
|
await next();
|
|
14786
14786
|
};
|
|
14787
14787
|
}
|
|
14788
|
+
function findSessionUser(db, rawToken) {
|
|
14789
|
+
if (!rawToken) return null;
|
|
14790
|
+
const session = db.select().from(sessions).where(
|
|
14791
|
+
and(eq(sessions.tokenHash, hashToken(rawToken)), gt(sessions.expiresAt, (/* @__PURE__ */ new Date()).toISOString()))
|
|
14792
|
+
).limit(1).get();
|
|
14793
|
+
if (!session) return null;
|
|
14794
|
+
const user = db.select().from(users).where(eq(users.id, session.userId)).limit(1).get();
|
|
14795
|
+
return user && user.isDeleted === 0 ? user : null;
|
|
14796
|
+
}
|
|
14788
14797
|
|
|
14789
14798
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
14790
14799
|
var external_exports = {};
|
|
@@ -21854,16 +21863,19 @@ function brainstormRoutes(db, workspacePath) {
|
|
|
21854
21863
|
import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
|
|
21855
21864
|
import { join as join14 } from "path";
|
|
21856
21865
|
|
|
21866
|
+
// ../server/src/features/cicd/app-proxy.ts
|
|
21867
|
+
import { connect as connect2 } from "net";
|
|
21868
|
+
|
|
21857
21869
|
// ../server/src/features/cicd/app-runner.ts
|
|
21858
21870
|
import { spawn as spawn2 } from "child_process";
|
|
21859
21871
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
21860
|
-
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
|
|
21872
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
21861
21873
|
import { request as httpRequest2 } from "http";
|
|
21862
21874
|
import { join as join9 } from "path";
|
|
21863
21875
|
function svcError6(code, status) {
|
|
21864
21876
|
return Object.assign(new Error(code), { code, status });
|
|
21865
21877
|
}
|
|
21866
|
-
var DEFAULT_CICD_APP_PORT =
|
|
21878
|
+
var DEFAULT_CICD_APP_PORT = 5e3;
|
|
21867
21879
|
var spawnedApps = /* @__PURE__ */ new Map();
|
|
21868
21880
|
var guardTokens = /* @__PURE__ */ new Map();
|
|
21869
21881
|
function killSpawnedApps() {
|
|
@@ -21914,55 +21926,81 @@ function probeApp(port, timeoutMs = 1e3) {
|
|
|
21914
21926
|
req.end();
|
|
21915
21927
|
});
|
|
21916
21928
|
}
|
|
21917
|
-
function toStatus2(location, running,
|
|
21918
|
-
const hostname = requestHost.replace(/:\d+$/, "") || "localhost";
|
|
21929
|
+
function toStatus2(location, running, projectId) {
|
|
21919
21930
|
return {
|
|
21920
21931
|
present: location.present,
|
|
21921
21932
|
running,
|
|
21922
21933
|
port: location.present ? location.port : null,
|
|
21923
|
-
|
|
21934
|
+
// Same-origin proxy path (app-proxy.ts routes) — works locally AND behind HTTPS/reverse
|
|
21935
|
+
// proxies; the iframe and "Open in new tab" both load through it.
|
|
21936
|
+
url: location.present ? `/api/cicd/${projectId}/app-proxy/` : null
|
|
21924
21937
|
};
|
|
21925
21938
|
}
|
|
21926
|
-
async function getCicdAppStatus(db, workspacePath, projectId
|
|
21939
|
+
async function getCicdAppStatus(db, workspacePath, projectId) {
|
|
21927
21940
|
const location = resolveCicdApp(db, workspacePath, projectId);
|
|
21928
21941
|
const running = location.present ? await probeApp(location.port) : false;
|
|
21929
|
-
return toStatus2(location, running,
|
|
21942
|
+
return toStatus2(location, running, projectId);
|
|
21930
21943
|
}
|
|
21931
|
-
async function startCicdApp(db, workspacePath, projectId,
|
|
21944
|
+
async function startCicdApp(db, workspacePath, projectId, studioPort, port) {
|
|
21932
21945
|
const location = resolveCicdApp(db, workspacePath, projectId);
|
|
21933
21946
|
if (!location.present) throw svcError6("CICD_APP_MISSING", 404);
|
|
21934
|
-
|
|
21947
|
+
const targetPort = port ?? location.port;
|
|
21948
|
+
if (targetPort !== location.port) {
|
|
21949
|
+
const configPath = join9(location.appDir, "cicd.config.json");
|
|
21950
|
+
let config = {};
|
|
21951
|
+
try {
|
|
21952
|
+
config = JSON.parse(readFileSync6(configPath, "utf8"));
|
|
21953
|
+
} catch {
|
|
21954
|
+
}
|
|
21955
|
+
config.port = targetPort;
|
|
21956
|
+
try {
|
|
21957
|
+
writeFileSync5(configPath, `${JSON.stringify(config, null, 2)}
|
|
21958
|
+
`);
|
|
21959
|
+
} catch {
|
|
21960
|
+
}
|
|
21961
|
+
location.port = targetPort;
|
|
21962
|
+
}
|
|
21963
|
+
if (await probeApp(targetPort)) {
|
|
21964
|
+
location.port = targetPort;
|
|
21965
|
+
return toStatus2(location, true, projectId);
|
|
21966
|
+
}
|
|
21935
21967
|
const existing = spawnedApps.get(projectId);
|
|
21936
|
-
if (
|
|
21937
|
-
|
|
21938
|
-
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
21942
|
-
|
|
21943
|
-
...process.env,
|
|
21944
|
-
PORT: String(location.port),
|
|
21945
|
-
CO2_STUDIO_URL: `http://127.0.0.1:${studioPort}`,
|
|
21946
|
-
CO2_PROJECT_ID: String(projectId),
|
|
21947
|
-
CO2_GUARD_TOKEN: token
|
|
21948
|
-
}
|
|
21949
|
-
});
|
|
21950
|
-
child.on("error", () => {
|
|
21951
|
-
spawnedApps.delete(projectId);
|
|
21952
|
-
guardTokens.delete(projectId);
|
|
21953
|
-
});
|
|
21954
|
-
child.on("exit", () => {
|
|
21955
|
-
spawnedApps.delete(projectId);
|
|
21956
|
-
guardTokens.delete(projectId);
|
|
21957
|
-
});
|
|
21958
|
-
spawnedApps.set(projectId, child);
|
|
21959
|
-
db.update(cicdSetups).set({ appPort: location.port, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq(cicdSetups.projectId, projectId)).run();
|
|
21968
|
+
if (existing && existing.exitCode === null) {
|
|
21969
|
+
try {
|
|
21970
|
+
existing.kill();
|
|
21971
|
+
} catch {
|
|
21972
|
+
}
|
|
21973
|
+
spawnedApps.delete(projectId);
|
|
21974
|
+
guardTokens.delete(projectId);
|
|
21960
21975
|
}
|
|
21976
|
+
const token = randomBytes2(24).toString("hex");
|
|
21977
|
+
guardTokens.set(projectId, token);
|
|
21978
|
+
const child = spawn2(process.execPath, ["server.js"], {
|
|
21979
|
+
cwd: location.appDir,
|
|
21980
|
+
stdio: "ignore",
|
|
21981
|
+
env: {
|
|
21982
|
+
...process.env,
|
|
21983
|
+
PORT: String(location.port),
|
|
21984
|
+
CO2_STUDIO_URL: `http://127.0.0.1:${studioPort}`,
|
|
21985
|
+
CO2_PROJECT_ID: String(projectId),
|
|
21986
|
+
CO2_GUARD_TOKEN: token
|
|
21987
|
+
}
|
|
21988
|
+
});
|
|
21989
|
+
child.on("error", () => {
|
|
21990
|
+
spawnedApps.delete(projectId);
|
|
21991
|
+
guardTokens.delete(projectId);
|
|
21992
|
+
});
|
|
21993
|
+
child.on("exit", () => {
|
|
21994
|
+
spawnedApps.delete(projectId);
|
|
21995
|
+
guardTokens.delete(projectId);
|
|
21996
|
+
});
|
|
21997
|
+
spawnedApps.set(projectId, child);
|
|
21998
|
+
db.update(cicdSetups).set({ appPort: location.port, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq(cicdSetups.projectId, projectId)).run();
|
|
21961
21999
|
for (let attempt = 0; attempt < 20; attempt++) {
|
|
21962
|
-
if (await probeApp(location.port, 500)) return toStatus2(location, true,
|
|
22000
|
+
if (await probeApp(location.port, 500)) return toStatus2(location, true, projectId);
|
|
21963
22001
|
await new Promise((r) => setTimeout(r, 250));
|
|
21964
22002
|
}
|
|
21965
|
-
return toStatus2(location, false,
|
|
22003
|
+
return toStatus2(location, false, projectId);
|
|
21966
22004
|
}
|
|
21967
22005
|
function stopCicdApp(projectId) {
|
|
21968
22006
|
const child = spawnedApps.get(projectId);
|
|
@@ -21976,13 +22014,103 @@ function stopCicdApp(projectId) {
|
|
|
21976
22014
|
return true;
|
|
21977
22015
|
}
|
|
21978
22016
|
|
|
22017
|
+
// ../server/src/features/cicd/app-proxy.ts
|
|
22018
|
+
async function proxyCicdAppRequest(db, workspacePath, projectId, prefix, subPath, req) {
|
|
22019
|
+
const location = resolveCicdApp(db, workspacePath, projectId);
|
|
22020
|
+
if (!location.present) throw svcError6("CICD_APP_MISSING", 404);
|
|
22021
|
+
const url = new URL(req.url);
|
|
22022
|
+
const target = `http://127.0.0.1:${location.port}${subPath}${url.search}`;
|
|
22023
|
+
const headers = new Headers();
|
|
22024
|
+
req.headers.forEach((value, name) => {
|
|
22025
|
+
if (!STRIP_HEADERS.has(name.toLowerCase())) headers.set(name, value);
|
|
22026
|
+
});
|
|
22027
|
+
headers.set("x-forwarded-prefix", prefix);
|
|
22028
|
+
headers.set("x-forwarded-host", url.host);
|
|
22029
|
+
headers.set("x-forwarded-proto", url.protocol.replace(/:$/, ""));
|
|
22030
|
+
const hasBody = req.method !== "GET" && req.method !== "HEAD";
|
|
22031
|
+
let upstream;
|
|
22032
|
+
try {
|
|
22033
|
+
upstream = await fetch(target, {
|
|
22034
|
+
method: req.method,
|
|
22035
|
+
headers,
|
|
22036
|
+
body: hasBody ? await req.arrayBuffer() : void 0,
|
|
22037
|
+
redirect: "manual"
|
|
22038
|
+
});
|
|
22039
|
+
} catch {
|
|
22040
|
+
throw svcError6("CICD_APP_DOWN", 502);
|
|
22041
|
+
}
|
|
22042
|
+
const responseHeaders = new Headers();
|
|
22043
|
+
upstream.headers.forEach((value, name) => {
|
|
22044
|
+
if (!STRIP_HEADERS.has(name.toLowerCase())) responseHeaders.set(name, value);
|
|
22045
|
+
});
|
|
22046
|
+
const redirectTo = responseHeaders.get("location");
|
|
22047
|
+
if (redirectTo?.startsWith("/") && redirectTo !== prefix && !redirectTo.startsWith(`${prefix}/`)) {
|
|
22048
|
+
responseHeaders.set("location", `${prefix}${redirectTo}`);
|
|
22049
|
+
}
|
|
22050
|
+
return new Response(upstream.body, { status: upstream.status, headers: responseHeaders });
|
|
22051
|
+
}
|
|
22052
|
+
var CICD_PROXY_UPGRADE_RE = /^\/api\/cicd\/(\d+)\/app-proxy(\/.*)$/;
|
|
22053
|
+
function sessionTokenFromCookieHeader(cookieHeader) {
|
|
22054
|
+
if (!cookieHeader) return void 0;
|
|
22055
|
+
for (const part of cookieHeader.split(";")) {
|
|
22056
|
+
const [name, ...rest] = part.trim().split("=");
|
|
22057
|
+
if (name === SESSION_COOKIE) return rest.join("=");
|
|
22058
|
+
}
|
|
22059
|
+
return void 0;
|
|
22060
|
+
}
|
|
22061
|
+
function handleCicdProxyUpgrade(db, workspacePath, req, socket, head) {
|
|
22062
|
+
const url = new URL(req.url ?? "", "http://localhost");
|
|
22063
|
+
const match2 = url.pathname.match(CICD_PROXY_UPGRADE_RE);
|
|
22064
|
+
if (!match2) {
|
|
22065
|
+
socket.destroy();
|
|
22066
|
+
return;
|
|
22067
|
+
}
|
|
22068
|
+
const user = findSessionUser(db, sessionTokenFromCookieHeader(req.headers.cookie));
|
|
22069
|
+
if (!user || user.mustChangePassword) {
|
|
22070
|
+
socket.write("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
|
|
22071
|
+
socket.destroy();
|
|
22072
|
+
return;
|
|
22073
|
+
}
|
|
22074
|
+
let port;
|
|
22075
|
+
try {
|
|
22076
|
+
const location = resolveCicdApp(db, workspacePath, Number(match2[1]));
|
|
22077
|
+
if (!location.present) {
|
|
22078
|
+
socket.destroy();
|
|
22079
|
+
return;
|
|
22080
|
+
}
|
|
22081
|
+
port = location.port;
|
|
22082
|
+
} catch {
|
|
22083
|
+
socket.destroy();
|
|
22084
|
+
return;
|
|
22085
|
+
}
|
|
22086
|
+
const upstream = connect2(port, "127.0.0.1", () => {
|
|
22087
|
+
let raw2 = `${req.method} ${match2[2]}${url.search} HTTP/1.1\r
|
|
22088
|
+
`;
|
|
22089
|
+
for (let i = 0; i < req.rawHeaders.length; i += 2) {
|
|
22090
|
+
const name = req.rawHeaders[i];
|
|
22091
|
+
const value = name.toLowerCase() === "host" ? `127.0.0.1:${port}` : req.rawHeaders[i + 1];
|
|
22092
|
+
raw2 += `${name}: ${value}\r
|
|
22093
|
+
`;
|
|
22094
|
+
}
|
|
22095
|
+
upstream.write(`${raw2}\r
|
|
22096
|
+
`);
|
|
22097
|
+
if (head.length > 0) upstream.write(head);
|
|
22098
|
+
socket.pipe(upstream);
|
|
22099
|
+
upstream.pipe(socket);
|
|
22100
|
+
});
|
|
22101
|
+
upstream.on("error", () => socket.destroy());
|
|
22102
|
+
socket.on("error", () => upstream.destroy());
|
|
22103
|
+
upstream.on("close", () => socket.destroy());
|
|
22104
|
+
socket.on("close", () => upstream.destroy());
|
|
22105
|
+
}
|
|
22106
|
+
|
|
21979
22107
|
// ../server/src/features/cicd/guard.ts
|
|
21980
22108
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
21981
22109
|
import { existsSync as existsSync10 } from "fs";
|
|
21982
22110
|
import { join as join11 } from "path";
|
|
21983
22111
|
|
|
21984
22112
|
// ../server/src/features/prd-wizard/service.ts
|
|
21985
|
-
import { existsSync as existsSync9, mkdirSync as mkdirSync3, statSync as statSync2, writeFileSync as
|
|
22113
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
21986
22114
|
import { join as join10 } from "path";
|
|
21987
22115
|
function svcError7(code, status) {
|
|
21988
22116
|
return Object.assign(new Error(code), { code, status });
|
|
@@ -22060,7 +22188,7 @@ function generatePrdWizardMarkdown(db, workspacePath, requestId, targetModule) {
|
|
|
22060
22188
|
`execution/${filename}`,
|
|
22061
22189
|
targetModule
|
|
22062
22190
|
);
|
|
22063
|
-
|
|
22191
|
+
writeFileSync6(filePath, markdown, "utf8");
|
|
22064
22192
|
db.update(prdWizardRequests).set({
|
|
22065
22193
|
generatedMarkdownPath: filePath,
|
|
22066
22194
|
status: "generated",
|
|
@@ -22297,7 +22425,7 @@ function evaluateBuildGuard(db, workspacePath, projectId, versionId) {
|
|
|
22297
22425
|
}
|
|
22298
22426
|
|
|
22299
22427
|
// ../server/src/features/cicd/service.ts
|
|
22300
|
-
import { appendFileSync, existsSync as existsSync12, mkdirSync as mkdirSync4, statSync as statSync4, writeFileSync as
|
|
22428
|
+
import { appendFileSync, existsSync as existsSync12, mkdirSync as mkdirSync4, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
22301
22429
|
import { join as join13 } from "path";
|
|
22302
22430
|
|
|
22303
22431
|
// ../server/src/features/batch-job/constants.ts
|
|
@@ -22440,7 +22568,7 @@ function requestPlan(db, workspacePath, projectId, userId) {
|
|
|
22440
22568
|
const filename = `cicd-plan-${setup.id}-${Date.now()}.md`;
|
|
22441
22569
|
const filePath = join13(executionDir, filename);
|
|
22442
22570
|
const relative3 = `execution/${filename}`;
|
|
22443
|
-
|
|
22571
|
+
writeFileSync7(
|
|
22444
22572
|
filePath,
|
|
22445
22573
|
buildPlanRequestMarkdown(
|
|
22446
22574
|
project.name,
|
|
@@ -22600,9 +22728,12 @@ function parseProjectId(c) {
|
|
|
22600
22728
|
const id = Number(c.req.param("projectId"));
|
|
22601
22729
|
return Number.isNaN(id) ? null : id;
|
|
22602
22730
|
}
|
|
22731
|
+
var startBodySchema = external_exports.object({
|
|
22732
|
+
port: external_exports.coerce.number().int().min(1024).max(65535).optional()
|
|
22733
|
+
});
|
|
22603
22734
|
function cicdRoutes(db, workspacePath, studioPort) {
|
|
22604
22735
|
const app = new Hono2();
|
|
22605
|
-
const toDto8 = async (
|
|
22736
|
+
const toDto8 = async (setup) => {
|
|
22606
22737
|
const planFile = setup.planRequestPath?.split(/[\\/]/).pop();
|
|
22607
22738
|
return {
|
|
22608
22739
|
id: setup.id,
|
|
@@ -22614,7 +22745,7 @@ function cicdRoutes(db, workspacePath, studioPort) {
|
|
|
22614
22745
|
approvedAt: setup.approvedAt,
|
|
22615
22746
|
generatedAt: setup.generatedAt,
|
|
22616
22747
|
stale: isStale(db, setup),
|
|
22617
|
-
app: await getCicdAppStatus(db, workspacePath, setup.projectId
|
|
22748
|
+
app: await getCicdAppStatus(db, workspacePath, setup.projectId),
|
|
22618
22749
|
createdAt: setup.createdAt,
|
|
22619
22750
|
updatedAt: setup.updatedAt
|
|
22620
22751
|
};
|
|
@@ -22632,7 +22763,7 @@ function cicdRoutes(db, workspacePath, studioPort) {
|
|
|
22632
22763
|
startCicdWatcher(db, workspacePath, setup.id, "generation", user.id);
|
|
22633
22764
|
}
|
|
22634
22765
|
const fresh = getOrCreateSetup(db, projectId, user.id);
|
|
22635
|
-
return c.json(await toDto8(
|
|
22766
|
+
return c.json(await toDto8(fresh));
|
|
22636
22767
|
} catch (e) {
|
|
22637
22768
|
return errorResponse3(c, e);
|
|
22638
22769
|
}
|
|
@@ -22655,7 +22786,7 @@ function cicdRoutes(db, workspacePath, studioPort) {
|
|
|
22655
22786
|
if (fresh.status === "generating" && !hasCicdWatcher(fresh.id, "generation")) {
|
|
22656
22787
|
startCicdWatcher(db, workspacePath, fresh.id, "generation", user.id);
|
|
22657
22788
|
}
|
|
22658
|
-
return c.json(await toDto8(
|
|
22789
|
+
return c.json(await toDto8(fresh));
|
|
22659
22790
|
} catch (e) {
|
|
22660
22791
|
return errorResponse3(c, e);
|
|
22661
22792
|
}
|
|
@@ -22709,10 +22840,11 @@ function cicdRoutes(db, workspacePath, studioPort) {
|
|
|
22709
22840
|
app.post("/:projectId/app/start", async (c) => {
|
|
22710
22841
|
const projectId = parseProjectId(c);
|
|
22711
22842
|
if (projectId === null) return c.json({ code: "INVALID_ID" }, 400);
|
|
22843
|
+
const parsed = startBodySchema.safeParse(await c.req.json().catch(() => ({})));
|
|
22844
|
+
if (!parsed.success) return c.json({ code: "INVALID_PORT" }, 400);
|
|
22845
|
+
if (parsed.data.port === studioPort) return c.json({ code: "CICD_PORT_CONFLICT" }, 400);
|
|
22712
22846
|
try {
|
|
22713
|
-
return c.json(
|
|
22714
|
-
await startCicdApp(db, workspacePath, projectId, c.req.header("host") ?? "", studioPort)
|
|
22715
|
-
);
|
|
22847
|
+
return c.json(await startCicdApp(db, workspacePath, projectId, studioPort, parsed.data.port));
|
|
22716
22848
|
} catch (e) {
|
|
22717
22849
|
return errorResponse3(c, e);
|
|
22718
22850
|
}
|
|
@@ -22722,9 +22854,25 @@ function cicdRoutes(db, workspacePath, studioPort) {
|
|
|
22722
22854
|
if (projectId === null) return c.json({ code: "INVALID_ID" }, 400);
|
|
22723
22855
|
try {
|
|
22724
22856
|
stopCicdApp(projectId);
|
|
22725
|
-
return c.json(
|
|
22726
|
-
|
|
22727
|
-
);
|
|
22857
|
+
return c.json(await getCicdAppStatus(db, workspacePath, projectId));
|
|
22858
|
+
} catch (e) {
|
|
22859
|
+
return errorResponse3(c, e);
|
|
22860
|
+
}
|
|
22861
|
+
});
|
|
22862
|
+
app.all(
|
|
22863
|
+
"/:projectId/app-proxy",
|
|
22864
|
+
(c) => (
|
|
22865
|
+
// Normalize to the trailing-slash form so relative URLs in the page resolve under the prefix.
|
|
22866
|
+
c.redirect(`${c.req.path}/`, 301)
|
|
22867
|
+
)
|
|
22868
|
+
);
|
|
22869
|
+
app.all("/:projectId/app-proxy/*", async (c) => {
|
|
22870
|
+
const projectId = parseProjectId(c);
|
|
22871
|
+
if (projectId === null) return c.json({ code: "INVALID_ID" }, 400);
|
|
22872
|
+
const prefix = `/api/cicd/${projectId}/app-proxy`;
|
|
22873
|
+
const subPath = c.req.path.slice(prefix.length) || "/";
|
|
22874
|
+
try {
|
|
22875
|
+
return await proxyCicdAppRequest(db, workspacePath, projectId, prefix, subPath, c.req.raw);
|
|
22728
22876
|
} catch (e) {
|
|
22729
22877
|
return errorResponse3(c, e);
|
|
22730
22878
|
}
|
|
@@ -22750,11 +22898,11 @@ function cicdGuardRoutes(db, workspacePath) {
|
|
|
22750
22898
|
}
|
|
22751
22899
|
|
|
22752
22900
|
// ../server/src/features/project/service.ts
|
|
22753
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as
|
|
22901
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
22754
22902
|
import { join as join16 } from "path";
|
|
22755
22903
|
|
|
22756
22904
|
// ../server/src/features/project-config/service.ts
|
|
22757
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync9, writeFileSync as
|
|
22905
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
22758
22906
|
import { join as join15 } from "path";
|
|
22759
22907
|
function svcError9(code, status) {
|
|
22760
22908
|
return Object.assign(new Error(code), { code, status });
|
|
@@ -22778,7 +22926,7 @@ function resolveImportedByName(db, importedBy) {
|
|
|
22778
22926
|
function writeProjectFile(workspacePath, folder, fileName, content) {
|
|
22779
22927
|
const dir = join15(workspacePath, folder);
|
|
22780
22928
|
mkdirSync5(dir, { recursive: true });
|
|
22781
|
-
|
|
22929
|
+
writeFileSync8(join15(dir, fileName), content, "utf8");
|
|
22782
22930
|
}
|
|
22783
22931
|
function toDto5(db, row, field) {
|
|
22784
22932
|
return {
|
|
@@ -22945,8 +23093,8 @@ function scaffoldProjectFolder(workspacePath, folderName, name, baseIdea) {
|
|
|
22945
23093
|
"# Feedback",
|
|
22946
23094
|
"<!-- Human answers appear here -->"
|
|
22947
23095
|
].join("\n");
|
|
22948
|
-
|
|
22949
|
-
|
|
23096
|
+
writeFileSync9(join16(projectDir2, `${folderName}.brainstorm.md`), template, "utf8");
|
|
23097
|
+
writeFileSync9(
|
|
22950
23098
|
join16(projectDir2, "context", "references", "brainstorm-protocol.md"),
|
|
22951
23099
|
"# Brainstorm Protocol\n\n[Installed by the co2 plugin]\n",
|
|
22952
23100
|
"utf8"
|
|
@@ -22984,7 +23132,7 @@ function updateBrainstormMd(db, workspacePath, projectId, content) {
|
|
|
22984
23132
|
project.workspaceFolderName,
|
|
22985
23133
|
`${project.workspaceFolderName}.brainstorm.md`
|
|
22986
23134
|
);
|
|
22987
|
-
|
|
23135
|
+
writeFileSync9(filePath, content, "utf8");
|
|
22988
23136
|
}
|
|
22989
23137
|
function listProjects(db, archived) {
|
|
22990
23138
|
return db.select({
|
|
@@ -23107,7 +23255,7 @@ function regenerateCO2Files(db, workspacePath, projectId) {
|
|
|
23107
23255
|
const projectDir2 = join16(workspacePath, project.workspaceFolderName);
|
|
23108
23256
|
mkdirSync6(projectDir2, { recursive: true });
|
|
23109
23257
|
const apps = db.select().from(applications).where(and(eq(applications.projectId, projectId), eq(applications.isDeleted, 0))).all();
|
|
23110
|
-
|
|
23258
|
+
writeFileSync9(
|
|
23111
23259
|
join16(projectDir2, "CLAUDE.md"),
|
|
23112
23260
|
project.rawClaudeMd ?? buildClaudeMd(project.name, apps),
|
|
23113
23261
|
"utf8"
|
|
@@ -23124,7 +23272,7 @@ function regenerateCO2Files(db, workspacePath, projectId) {
|
|
|
23124
23272
|
const appRel = resolveAppFolderName(projectDir2, app.name);
|
|
23125
23273
|
const appDir = join16(projectDir2, appRel, "context");
|
|
23126
23274
|
mkdirSync6(appDir, { recursive: true });
|
|
23127
|
-
|
|
23275
|
+
writeFileSync9(
|
|
23128
23276
|
join16(appDir, "PRD.md"),
|
|
23129
23277
|
prdSnapshot[String(app.id)] ?? buildPrdMd(app.name, mods, loadPrdSections(db, app.id)),
|
|
23130
23278
|
"utf8"
|
|
@@ -23517,7 +23665,7 @@ function dashboardRoutes(db) {
|
|
|
23517
23665
|
}
|
|
23518
23666
|
|
|
23519
23667
|
// ../server/src/features/defect/service.ts
|
|
23520
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as
|
|
23668
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
23521
23669
|
import { join as join17 } from "path";
|
|
23522
23670
|
|
|
23523
23671
|
// ../server/src/features/project-import/bug-md.ts
|
|
@@ -23949,7 +24097,7 @@ function writeBugMdFile(db, workspacePath, app, projectFolderName) {
|
|
|
23949
24097
|
const appRel = resolveAppFolderName(projectDir2, app.name);
|
|
23950
24098
|
const appContextDir = join17(projectDir2, appRel, "context");
|
|
23951
24099
|
mkdirSync7(appContextDir, { recursive: true });
|
|
23952
|
-
|
|
24100
|
+
writeFileSync10(join17(appContextDir, "BUG.md"), content, "utf8");
|
|
23953
24101
|
return { content, bugCount: bugs.length };
|
|
23954
24102
|
}
|
|
23955
24103
|
function syncBugStatusesFromMaster(db, trackingFilePath, applicationId) {
|
|
@@ -23993,7 +24141,7 @@ function syncBugMdToDisk(db, workspacePath, applicationId, bugId, mode = "replac
|
|
|
23993
24141
|
).all().find((m) => m.name.toLowerCase() === bug.module?.toLowerCase())?.category : void 0) ?? null;
|
|
23994
24142
|
const merged = mergeBugIntoBugMd(readFileSync11(file, "utf8"), bug, semver, category, mode);
|
|
23995
24143
|
if (merged !== null) {
|
|
23996
|
-
|
|
24144
|
+
writeFileSync10(file, merged, "utf8");
|
|
23997
24145
|
return;
|
|
23998
24146
|
}
|
|
23999
24147
|
}
|
|
@@ -24127,7 +24275,7 @@ function defectRoutes(db, workspacePath) {
|
|
|
24127
24275
|
}
|
|
24128
24276
|
|
|
24129
24277
|
// ../server/src/features/document/service.ts
|
|
24130
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as
|
|
24278
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync11 } from "fs";
|
|
24131
24279
|
import { join as join18 } from "path";
|
|
24132
24280
|
function svcError12(code, status) {
|
|
24133
24281
|
return Object.assign(new Error(code), { code, status });
|
|
@@ -24140,7 +24288,7 @@ function uploadDocument(db, dataDir, projectId, file) {
|
|
|
24140
24288
|
mkdirSync8(dir, { recursive: true });
|
|
24141
24289
|
const safeName = file.name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
24142
24290
|
const stamped = `${Date.now()}_${safeName}`;
|
|
24143
|
-
|
|
24291
|
+
writeFileSync11(join18(dir, stamped), file.bytes);
|
|
24144
24292
|
const relativePath = `${projectId}/${stamped}`;
|
|
24145
24293
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24146
24294
|
const inserted = db.insert(documents).values({
|
|
@@ -24227,7 +24375,7 @@ function documentRoutes(db, dataDir) {
|
|
|
24227
24375
|
|
|
24228
24376
|
// ../server/src/features/git/service.ts
|
|
24229
24377
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
24230
|
-
import { existsSync as existsSync18, readFileSync as readFileSync13, rmSync, writeFileSync as
|
|
24378
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13, rmSync, writeFileSync as writeFileSync12 } from "fs";
|
|
24231
24379
|
import { join as join19 } from "path";
|
|
24232
24380
|
var GitServiceError = class extends Error {
|
|
24233
24381
|
code;
|
|
@@ -24478,7 +24626,7 @@ function resolveConflict(db, workspacePath, projectId, input) {
|
|
|
24478
24626
|
if (input.content === void 0) {
|
|
24479
24627
|
throw new GitServiceError("CONTENT_REQUIRED", 400, "Manual resolution requires content");
|
|
24480
24628
|
}
|
|
24481
|
-
|
|
24629
|
+
writeFileSync12(join19(dir, input.path), input.content, "utf8");
|
|
24482
24630
|
} else {
|
|
24483
24631
|
git3(dir, ["checkout", `--${input.resolution}`, "--", input.path]);
|
|
24484
24632
|
}
|
|
@@ -25250,7 +25398,7 @@ function scanProject(db, workspacePath, folderName) {
|
|
|
25250
25398
|
import { join as join22, relative as relative2 } from "path";
|
|
25251
25399
|
|
|
25252
25400
|
// ../server/src/features/workflow/service.ts
|
|
25253
|
-
import { existsSync as existsSync20, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as
|
|
25401
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync13 } from "fs";
|
|
25254
25402
|
import { join as join21, relative, resolve as resolve2, sep } from "path";
|
|
25255
25403
|
var ACTIVE_RUN_STATUSES = ["pending", "in_progress"];
|
|
25256
25404
|
function svcError14(code, status) {
|
|
@@ -25477,7 +25625,7 @@ function generateWorkflowMarkdown(db, workspacePath, input, creatingUser, watche
|
|
|
25477
25625
|
relPath
|
|
25478
25626
|
);
|
|
25479
25627
|
mkdirSync9(join21(projectDir2, "workflow", creatingUser.username), { recursive: true });
|
|
25480
|
-
|
|
25628
|
+
writeFileSync13(join21(projectDir2, relPath), content, "utf8");
|
|
25481
25629
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25482
25630
|
const wfm = db.insert(workflowMarkdowns).values({
|
|
25483
25631
|
projectId: input.projectId,
|
|
@@ -26321,7 +26469,7 @@ function projectRoutes(db, workspacePath) {
|
|
|
26321
26469
|
}
|
|
26322
26470
|
|
|
26323
26471
|
// ../server/src/features/shared-context/service.ts
|
|
26324
|
-
import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync16, readdirSync as readdirSync4, statSync as statSync6, writeFileSync as
|
|
26472
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync16, readdirSync as readdirSync4, statSync as statSync6, writeFileSync as writeFileSync14 } from "fs";
|
|
26325
26473
|
import { join as join23, resolve as resolve3, sep as sep2 } from "path";
|
|
26326
26474
|
function svcError16(code, status) {
|
|
26327
26475
|
return Object.assign(new Error(code), { code, status });
|
|
@@ -26412,7 +26560,7 @@ function uploadFile(db, workspacePath, projectId, folder, file) {
|
|
|
26412
26560
|
const dir = folder ? safeResolve(root, folder) : root;
|
|
26413
26561
|
if (folder && !existsSync21(dir)) throw svcError16("FOLDER_NOT_FOUND", 404);
|
|
26414
26562
|
const safeName = sanitizeSegment(file.name);
|
|
26415
|
-
|
|
26563
|
+
writeFileSync14(join23(dir, safeName), file.bytes);
|
|
26416
26564
|
return { path: folder ? `${folder}/${safeName}` : safeName };
|
|
26417
26565
|
}
|
|
26418
26566
|
function getFileContent(db, workspacePath, projectId, relPath) {
|
|
@@ -26427,7 +26575,7 @@ function saveMarkdown(db, workspacePath, projectId, relPath, content) {
|
|
|
26427
26575
|
const root = resolveSharedRoot(db, workspacePath, projectId);
|
|
26428
26576
|
const full = safeResolve(root, relPath);
|
|
26429
26577
|
if (!existsSync21(full) || !statSync6(full).isFile()) throw svcError16("NOT_FOUND", 404);
|
|
26430
|
-
|
|
26578
|
+
writeFileSync14(full, content, "utf8");
|
|
26431
26579
|
}
|
|
26432
26580
|
|
|
26433
26581
|
// ../server/src/features/shared-context/routes.ts
|
|
@@ -27141,6 +27289,26 @@ function appendScrollback(session, data) {
|
|
|
27141
27289
|
session.bufferBytes -= session.buffer.shift().length;
|
|
27142
27290
|
}
|
|
27143
27291
|
}
|
|
27292
|
+
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
27293
|
+
function attachHeartbeat(ws, intervalMs = HEARTBEAT_INTERVAL_MS) {
|
|
27294
|
+
let alive = true;
|
|
27295
|
+
ws.on("pong", () => {
|
|
27296
|
+
alive = true;
|
|
27297
|
+
});
|
|
27298
|
+
const timer = setInterval(() => {
|
|
27299
|
+
if (!alive) {
|
|
27300
|
+
clearInterval(timer);
|
|
27301
|
+
ws.terminate();
|
|
27302
|
+
return;
|
|
27303
|
+
}
|
|
27304
|
+
alive = false;
|
|
27305
|
+
try {
|
|
27306
|
+
ws.ping();
|
|
27307
|
+
} catch {
|
|
27308
|
+
}
|
|
27309
|
+
}, intervalMs);
|
|
27310
|
+
ws.on("close", () => clearInterval(timer));
|
|
27311
|
+
}
|
|
27144
27312
|
var sessions2 = /* @__PURE__ */ new Map();
|
|
27145
27313
|
function closeTerminalSessions(projectId, reason) {
|
|
27146
27314
|
const session = sessions2.get(projectId);
|
|
@@ -27172,8 +27340,21 @@ function resolveProjectFolder(db, projectId) {
|
|
|
27172
27340
|
return row?.folder ?? null;
|
|
27173
27341
|
}
|
|
27174
27342
|
function createWsServer(httpServer, db, workspacePath) {
|
|
27175
|
-
const wss = new import_websocket_server.default({
|
|
27343
|
+
const wss = new import_websocket_server.default({ noServer: true });
|
|
27344
|
+
httpServer.on("upgrade", (req, socket, head) => {
|
|
27345
|
+
const pathname = new URL(req.url ?? "", "http://localhost").pathname;
|
|
27346
|
+
if (pathname === "/ws/terminal") {
|
|
27347
|
+
wss.handleUpgrade(req, socket, head, (ws) => wss.emit("connection", ws, req));
|
|
27348
|
+
return;
|
|
27349
|
+
}
|
|
27350
|
+
if (pathname.startsWith("/api/cicd/")) {
|
|
27351
|
+
handleCicdProxyUpgrade(db, workspacePath, req, socket, head);
|
|
27352
|
+
return;
|
|
27353
|
+
}
|
|
27354
|
+
socket.destroy();
|
|
27355
|
+
});
|
|
27176
27356
|
wss.on("connection", async (ws, req) => {
|
|
27357
|
+
attachHeartbeat(ws);
|
|
27177
27358
|
const url = new URL(req.url ?? "", "http://localhost");
|
|
27178
27359
|
const projectId = Number(url.searchParams.get("projectId"));
|
|
27179
27360
|
const userId = Number(url.searchParams.get("userId"));
|
|
@@ -27417,7 +27598,7 @@ function workspaceRoutes(_db, config, port, host, workspacePath) {
|
|
|
27417
27598
|
}
|
|
27418
27599
|
|
|
27419
27600
|
// ../server/src/lib/config.ts
|
|
27420
|
-
import { existsSync as existsSync23, readFileSync as readFileSync18, writeFileSync as
|
|
27601
|
+
import { existsSync as existsSync23, readFileSync as readFileSync18, writeFileSync as writeFileSync15 } from "fs";
|
|
27421
27602
|
import { join as join25 } from "path";
|
|
27422
27603
|
var configSchema = external_exports.object({
|
|
27423
27604
|
port: external_exports.number().int().min(1).max(65535).optional(),
|
|
@@ -27435,7 +27616,7 @@ function loadConfig(dataDir) {
|
|
|
27435
27616
|
}
|
|
27436
27617
|
}
|
|
27437
27618
|
function saveConfig(dataDir, config) {
|
|
27438
|
-
|
|
27619
|
+
writeFileSync15(join25(dataDir, "config.json"), JSON.stringify(config, null, 2));
|
|
27439
27620
|
}
|
|
27440
27621
|
|
|
27441
27622
|
// ../server/src/lib/logger.ts
|