@costrict/csc 4.2.8 → 4.2.10-beta
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/cli.js +4133 -4541
- package/dist/services/rawDump/batchWorker.js +78 -72
- package/package.json +1 -1
|
@@ -459,8 +459,38 @@ async function appendDeadLetter(entry) {
|
|
|
459
459
|
import { promises as fs9 } from "fs";
|
|
460
460
|
import { createHash as createHash2 } from "crypto";
|
|
461
461
|
import os2 from "os";
|
|
462
|
-
import
|
|
462
|
+
import path12 from "path";
|
|
463
|
+
|
|
464
|
+
// src/utils/clientVersion.ts
|
|
465
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
466
|
+
import path4 from "path";
|
|
463
467
|
import { fileURLToPath } from "url";
|
|
468
|
+
var cached = null;
|
|
469
|
+
function getClientVersion() {
|
|
470
|
+
if (cached)
|
|
471
|
+
return cached;
|
|
472
|
+
try {
|
|
473
|
+
if ("4.2.10-beta") {
|
|
474
|
+
cached = "4.2.10-beta";
|
|
475
|
+
return cached;
|
|
476
|
+
}
|
|
477
|
+
} catch {}
|
|
478
|
+
let dir = path4.dirname(fileURLToPath(import.meta.url));
|
|
479
|
+
for (let i = 0;i < 6; i++) {
|
|
480
|
+
try {
|
|
481
|
+
const pkg = JSON.parse(readFileSync2(path4.join(dir, "package.json"), "utf-8"));
|
|
482
|
+
if (typeof pkg.version === "string" && pkg.version) {
|
|
483
|
+
cached = pkg.version;
|
|
484
|
+
return cached;
|
|
485
|
+
}
|
|
486
|
+
} catch {}
|
|
487
|
+
const parent = path4.dirname(dir);
|
|
488
|
+
if (parent === dir)
|
|
489
|
+
break;
|
|
490
|
+
dir = parent;
|
|
491
|
+
}
|
|
492
|
+
return "unknown";
|
|
493
|
+
}
|
|
464
494
|
|
|
465
495
|
// src/costrict/provider/credentials.ts
|
|
466
496
|
import { promises as fs3 } from "fs";
|
|
@@ -505,21 +535,7 @@ async function saveCoStrictCredentials(credentials) {
|
|
|
505
535
|
}
|
|
506
536
|
|
|
507
537
|
// src/costrict/provider/oauth-params.ts
|
|
508
|
-
|
|
509
|
-
function getVersion() {
|
|
510
|
-
try {
|
|
511
|
-
if (typeof MACRO !== "undefined" && "4.2.8")
|
|
512
|
-
return "4.2.8";
|
|
513
|
-
} catch {}
|
|
514
|
-
try {
|
|
515
|
-
const require2 = createRequire(import.meta.url);
|
|
516
|
-
const pkg = require2("../../../package.json");
|
|
517
|
-
return pkg.version;
|
|
518
|
-
} catch {
|
|
519
|
-
return "1.0.0";
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
var COSTRICT_PLUGIN_VERSION = `costrict-cli-${getVersion()}`;
|
|
538
|
+
var COSTRICT_PLUGIN_VERSION = `costrict-cli-${getClientVersion()}`;
|
|
523
539
|
function buildOAuthParams(includeMachineCode, machineId, state) {
|
|
524
540
|
const params = [];
|
|
525
541
|
if (includeMachineCode) {
|
|
@@ -595,7 +611,7 @@ async function refreshCoStrictToken(params) {
|
|
|
595
611
|
// src/services/rawDump/git.ts
|
|
596
612
|
import { execFile } from "child_process";
|
|
597
613
|
import { realpathSync } from "fs";
|
|
598
|
-
import
|
|
614
|
+
import path5 from "path";
|
|
599
615
|
import { promisify } from "util";
|
|
600
616
|
var execFileAsync = promisify(execFile);
|
|
601
617
|
var TRUNK_BRANCHES = ["origin/main", "origin/master", "main", "master"];
|
|
@@ -633,7 +649,7 @@ function computeRepoRelativePath(gitRoot, workDir) {
|
|
|
633
649
|
return "";
|
|
634
650
|
const root = tryRealpath(gitRoot);
|
|
635
651
|
const dir = tryRealpath(workDir);
|
|
636
|
-
const rel =
|
|
652
|
+
const rel = path5.relative(root, dir);
|
|
637
653
|
if (rel === "")
|
|
638
654
|
return ".";
|
|
639
655
|
if (rel.startsWith(".."))
|
|
@@ -644,7 +660,7 @@ function tryRealpath(p) {
|
|
|
644
660
|
try {
|
|
645
661
|
return realpathSync(p);
|
|
646
662
|
} catch {
|
|
647
|
-
return
|
|
663
|
+
return path5.resolve(p);
|
|
648
664
|
}
|
|
649
665
|
}
|
|
650
666
|
async function getBranchAncestry(cwd) {
|
|
@@ -754,10 +770,10 @@ function toCommitComment(subject) {
|
|
|
754
770
|
}
|
|
755
771
|
|
|
756
772
|
// src/services/rawDump/activeSessions.ts
|
|
757
|
-
import { readFileSync as
|
|
758
|
-
import
|
|
773
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync, renameSync, realpathSync as realpathSync2 } from "fs";
|
|
774
|
+
import path6 from "path";
|
|
759
775
|
var log2 = createLogger("activeSessions");
|
|
760
|
-
var ACTIVE_SESSIONS_FILE =
|
|
776
|
+
var ACTIVE_SESSIONS_FILE = path6.join(getRawDumpDir(), "csc-active-sessions.json");
|
|
761
777
|
var DEFAULT_WINDOW_MS = 30 * 60 * 1000;
|
|
762
778
|
var FUTURE_TOLERANCE_MS = 5 * 60 * 1000;
|
|
763
779
|
var MAX_ACTIVE_SESSION_IDS = 64;
|
|
@@ -777,16 +793,16 @@ function normalizeCwd(p) {
|
|
|
777
793
|
try {
|
|
778
794
|
resolved = realpathSync2(p);
|
|
779
795
|
} catch {
|
|
780
|
-
resolved =
|
|
796
|
+
resolved = path6.resolve(p);
|
|
781
797
|
}
|
|
782
|
-
if (resolved.length > 1 && resolved.endsWith(
|
|
798
|
+
if (resolved.length > 1 && resolved.endsWith(path6.sep)) {
|
|
783
799
|
resolved = resolved.slice(0, -1);
|
|
784
800
|
}
|
|
785
801
|
return resolved;
|
|
786
802
|
}
|
|
787
803
|
function readMap() {
|
|
788
804
|
try {
|
|
789
|
-
const text =
|
|
805
|
+
const text = readFileSync3(ACTIVE_SESSIONS_FILE, "utf-8");
|
|
790
806
|
const parsed = JSON.parse(text);
|
|
791
807
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
792
808
|
} catch {
|
|
@@ -815,7 +831,7 @@ function getActiveSessionIds(cwd, atMs) {
|
|
|
815
831
|
|
|
816
832
|
// src/services/rawDump/localStorage.ts
|
|
817
833
|
import { promises as fs4 } from "fs";
|
|
818
|
-
import
|
|
834
|
+
import path7 from "path";
|
|
819
835
|
var DEFAULT_LOCAL_DIR = getRawDumpDir();
|
|
820
836
|
var RAW_DUMP_MODE = {
|
|
821
837
|
DISABLED: 0,
|
|
@@ -864,12 +880,12 @@ async function writeLocalDump(type, body) {
|
|
|
864
880
|
endpoint = "/raw-store/task-summary";
|
|
865
881
|
} else if (type == "conversation") {
|
|
866
882
|
ymd = getDateFromTimestamp(getTimestampField("conversation", body));
|
|
867
|
-
subdir =
|
|
883
|
+
subdir = path7.join(ymd, body.task_id);
|
|
868
884
|
fname = body.request_id;
|
|
869
885
|
endpoint = "/raw-store/task-conversation";
|
|
870
886
|
} else if (type == "commit") {
|
|
871
887
|
ymd = getDateFromTimestamp(getTimestampField("commit", body));
|
|
872
|
-
subdir =
|
|
888
|
+
subdir = path7.join(normalizeProjectPath2(body.repo_addr), normalizeProjectPath2(body.repo_branch), ymd);
|
|
873
889
|
fname = body.commit_id;
|
|
874
890
|
endpoint = "/raw-store/commit";
|
|
875
891
|
} else if (type == "statistics") {
|
|
@@ -881,7 +897,7 @@ async function writeLocalDump(type, body) {
|
|
|
881
897
|
fname = `${h}-${m}-${s}`;
|
|
882
898
|
endpoint = "/raw-store/statistics";
|
|
883
899
|
} else if (type == "raw") {
|
|
884
|
-
subdir =
|
|
900
|
+
subdir = path7.join(normalizeProjectPath2(body.project), body.session_id);
|
|
885
901
|
fname = String(body.start_cursor);
|
|
886
902
|
endpoint = "/raw-store/raw-log";
|
|
887
903
|
} else {
|
|
@@ -889,9 +905,9 @@ async function writeLocalDump(type, body) {
|
|
|
889
905
|
fname = "unknown";
|
|
890
906
|
endpoint = "unknown";
|
|
891
907
|
}
|
|
892
|
-
const dumpDir =
|
|
908
|
+
const dumpDir = path7.join(dir, type, subdir);
|
|
893
909
|
const filename = `${fname}.json`;
|
|
894
|
-
const filePath =
|
|
910
|
+
const filePath = path7.join(dumpDir, filename);
|
|
895
911
|
const payload = {
|
|
896
912
|
_dumpMeta: {
|
|
897
913
|
type,
|
|
@@ -907,15 +923,15 @@ async function writeLocalDump(type, body) {
|
|
|
907
923
|
|
|
908
924
|
// src/services/rawDump/queue.ts
|
|
909
925
|
import { promises as fs6 } from "fs";
|
|
910
|
-
import
|
|
926
|
+
import path9 from "path";
|
|
911
927
|
|
|
912
928
|
// src/services/rawDump/lock.ts
|
|
913
929
|
import { promises as fs5 } from "fs";
|
|
914
|
-
import
|
|
930
|
+
import path8 from "path";
|
|
915
931
|
var LOCK_INFO_FILE = "lock.json";
|
|
916
932
|
async function isHolderAlive(lockDir) {
|
|
917
933
|
try {
|
|
918
|
-
const text = await fs5.readFile(
|
|
934
|
+
const text = await fs5.readFile(path8.join(lockDir, LOCK_INFO_FILE), "utf-8");
|
|
919
935
|
const info = JSON.parse(text);
|
|
920
936
|
if (!info.pid || typeof info.pid !== "number")
|
|
921
937
|
return false;
|
|
@@ -952,7 +968,7 @@ async function acquireLock(lockDir, info) {
|
|
|
952
968
|
return false;
|
|
953
969
|
}
|
|
954
970
|
try {
|
|
955
|
-
await fs5.writeFile(
|
|
971
|
+
await fs5.writeFile(path8.join(lockDir, LOCK_INFO_FILE), JSON.stringify(info), "utf-8");
|
|
956
972
|
return true;
|
|
957
973
|
} catch {
|
|
958
974
|
await releaseLock(lockDir);
|
|
@@ -967,8 +983,8 @@ async function releaseLock(lockDir) {
|
|
|
967
983
|
}
|
|
968
984
|
|
|
969
985
|
// src/services/rawDump/queue.ts
|
|
970
|
-
var QUEUE_FILE =
|
|
971
|
-
var QUEUE_LOCK_DIR =
|
|
986
|
+
var QUEUE_FILE = path9.join(getRawDumpDir(), "csc-work-queue.jsonl");
|
|
987
|
+
var QUEUE_LOCK_DIR = path9.join(getRawDumpDir(), "csc-work-queue.lock.d");
|
|
972
988
|
var MAX_ATTEMPTS = 4;
|
|
973
989
|
var queue = [];
|
|
974
990
|
var queueLoaded = false;
|
|
@@ -1009,8 +1025,8 @@ async function releaseQueueLock() {
|
|
|
1009
1025
|
|
|
1010
1026
|
// src/services/rawDump/history.ts
|
|
1011
1027
|
import { promises as fs7 } from "fs";
|
|
1012
|
-
import
|
|
1013
|
-
var HISTORY_FILE =
|
|
1028
|
+
import path10 from "path";
|
|
1029
|
+
var HISTORY_FILE = path10.join(getCscDir(), "history.jsonl");
|
|
1014
1030
|
var cache = null;
|
|
1015
1031
|
async function loadHistory() {
|
|
1016
1032
|
const items = [];
|
|
@@ -1076,7 +1092,7 @@ async function getProjectDirs() {
|
|
|
1076
1092
|
|
|
1077
1093
|
// src/services/rawDump/session.ts
|
|
1078
1094
|
import { promises as fs8 } from "fs";
|
|
1079
|
-
import
|
|
1095
|
+
import path11 from "path";
|
|
1080
1096
|
|
|
1081
1097
|
// src/services/rawDump/parse.ts
|
|
1082
1098
|
function buildFlows(events) {
|
|
@@ -1560,9 +1576,9 @@ function parseSession(cacheConversations, events) {
|
|
|
1560
1576
|
flows.forEach((flow) => {
|
|
1561
1577
|
const convResults = splitFlowToConversations(flow);
|
|
1562
1578
|
convResults.forEach((conversation) => {
|
|
1563
|
-
const
|
|
1564
|
-
if (
|
|
1565
|
-
conversations.push(
|
|
1579
|
+
const cached2 = cacheConversations.find((c) => c.id === conversation.id);
|
|
1580
|
+
if (cached2 && cached2.events.length === conversation.events.length) {
|
|
1581
|
+
conversations.push(cached2);
|
|
1566
1582
|
} else {
|
|
1567
1583
|
conversations.push(conversation);
|
|
1568
1584
|
}
|
|
@@ -1628,8 +1644,8 @@ function cleanupOldSessions() {
|
|
|
1628
1644
|
async function getParsedSession(taskDir, sessionId) {
|
|
1629
1645
|
const sessionDir = getSessionDirectory(taskDir);
|
|
1630
1646
|
const cacheKey = `${sessionDir}:${sessionId}`;
|
|
1631
|
-
const
|
|
1632
|
-
const sessionFile =
|
|
1647
|
+
const cached2 = sessionMessagesCache.get(cacheKey);
|
|
1648
|
+
const sessionFile = path11.join(sessionDir, `${sessionId}.jsonl`);
|
|
1633
1649
|
let stats;
|
|
1634
1650
|
try {
|
|
1635
1651
|
stats = await fs8.stat(sessionFile);
|
|
@@ -1643,19 +1659,19 @@ async function getParsedSession(taskDir, sessionId) {
|
|
|
1643
1659
|
parsedSession: parseSession([], [])
|
|
1644
1660
|
};
|
|
1645
1661
|
}
|
|
1646
|
-
const needsReanalysis = !
|
|
1647
|
-
if (!needsReanalysis &&
|
|
1662
|
+
const needsReanalysis = !cached2 || cached2.fileTimestamp !== stats.mtimeMs || cached2.fileSize !== stats.size || !cached2.parsedSession;
|
|
1663
|
+
if (!needsReanalysis && cached2) {
|
|
1648
1664
|
log3.debug("using cached parsed session", { sessionId });
|
|
1649
|
-
return
|
|
1665
|
+
return cached2;
|
|
1650
1666
|
}
|
|
1651
1667
|
cleanupOldSessions();
|
|
1652
1668
|
const start = Date.now();
|
|
1653
|
-
const messages =
|
|
1669
|
+
const messages = cached2?.messages ?? await loadSessionMessages(sessionFile);
|
|
1654
1670
|
const elapsed = Date.now() - start;
|
|
1655
1671
|
if (elapsed > 100) {
|
|
1656
1672
|
log3.info("loadSessionMessages slow", { sessionId, elapsedMs: elapsed });
|
|
1657
1673
|
}
|
|
1658
|
-
const cachedConvs =
|
|
1674
|
+
const cachedConvs = cached2?.parsedSession?.conversations ?? [];
|
|
1659
1675
|
const parsedSession = parseSession(cachedConvs, messages);
|
|
1660
1676
|
sessionMessagesCache.set(cacheKey, {
|
|
1661
1677
|
sessionJsonlFileName: sessionFile,
|
|
@@ -1812,9 +1828,9 @@ function capToolEventsPayload(events) {
|
|
|
1812
1828
|
var repoInfoCache = new Map;
|
|
1813
1829
|
var REPO_CACHE_TTL_MS = 60000;
|
|
1814
1830
|
async function getCachedRepoInfo(directory) {
|
|
1815
|
-
const
|
|
1816
|
-
if (
|
|
1817
|
-
return
|
|
1831
|
+
const cached2 = repoInfoCache.get(directory);
|
|
1832
|
+
if (cached2 && Date.now() - cached2.ts < REPO_CACHE_TTL_MS) {
|
|
1833
|
+
return cached2.repoInfo;
|
|
1818
1834
|
}
|
|
1819
1835
|
const repoInfo = await getRepoInfo(directory);
|
|
1820
1836
|
repoInfoCache.set(directory, { repoInfo, ts: Date.now() });
|
|
@@ -2019,12 +2035,7 @@ async function auth() {
|
|
|
2019
2035
|
headers.set("Content-Type", "application/json");
|
|
2020
2036
|
headers.set("HTTP-Referer", "https://github.com/zgsm-ai/costrict-cli");
|
|
2021
2037
|
headers.set("X-Title", "CoStrict-CLI");
|
|
2022
|
-
|
|
2023
|
-
try {
|
|
2024
|
-
const pkgPath = path11.resolve(fileURLToPath(import.meta.url), "../../package.json");
|
|
2025
|
-
const pkg = JSON.parse(await fs9.readFile(pkgPath, "utf-8"));
|
|
2026
|
-
version = pkg.version ?? "unknown";
|
|
2027
|
-
} catch {}
|
|
2038
|
+
const version = getClientVersion();
|
|
2028
2039
|
headers.set("X-Costrict-Version", `csc-${version}`);
|
|
2029
2040
|
const clientId = creds.machine_id || process.env.CSC_MACHINE_ID || "unknown";
|
|
2030
2041
|
headers.set("zgsm-client-id", clientId);
|
|
@@ -2060,15 +2071,10 @@ async function authWithFallback() {
|
|
|
2060
2071
|
try {
|
|
2061
2072
|
return await auth();
|
|
2062
2073
|
} catch (err) {
|
|
2063
|
-
|
|
2064
|
-
try {
|
|
2065
|
-
const pkgPath = path11.resolve(fileURLToPath(import.meta.url), "../../package.json");
|
|
2066
|
-
const pkg = JSON.parse(await fs9.readFile(pkgPath, "utf-8"));
|
|
2067
|
-
version = pkg.version ?? "unknown";
|
|
2068
|
-
} catch {}
|
|
2074
|
+
const version = getClientVersion();
|
|
2069
2075
|
let deviceId = process.env.CSC_DEVICE_ID;
|
|
2070
2076
|
if (!deviceId) {
|
|
2071
|
-
const deviceIdFile =
|
|
2077
|
+
const deviceIdFile = path12.join(getLocalDumpDir(), "device-id");
|
|
2072
2078
|
try {
|
|
2073
2079
|
deviceId = (await fs9.readFile(deviceIdFile, "utf-8")).trim();
|
|
2074
2080
|
} catch {}
|
|
@@ -2108,7 +2114,7 @@ async function authWithFallback() {
|
|
|
2108
2114
|
async function uploadRaw(sessionId, directory, authData) {
|
|
2109
2115
|
const normalizedProject = normalizeProjectPath2(directory);
|
|
2110
2116
|
const stateKey = `${normalizedProject}/${sessionId}`;
|
|
2111
|
-
const filePath =
|
|
2117
|
+
const filePath = path12.join(CSC_DIR, "projects", normalizedProject, `${sessionId}.jsonl`);
|
|
2112
2118
|
const lastReportedCount = state_raw.logs[stateKey] ?? 0;
|
|
2113
2119
|
let fileContent;
|
|
2114
2120
|
try {
|
|
@@ -2586,9 +2592,9 @@ if (scriptPath.endsWith("worker.ts") || scriptPath.endsWith("worker.js")) {
|
|
|
2586
2592
|
}
|
|
2587
2593
|
|
|
2588
2594
|
// src/services/rawDump/timerWorker.ts
|
|
2589
|
-
import
|
|
2595
|
+
import path13 from "path";
|
|
2590
2596
|
var log6 = createLogger("timer");
|
|
2591
|
-
var TIMER_LOCK_DIR =
|
|
2597
|
+
var TIMER_LOCK_DIR = path13.join(getRawDumpDir(), "csc-timer.lock.d");
|
|
2592
2598
|
var isRunning = false;
|
|
2593
2599
|
async function acquireTimerLock() {
|
|
2594
2600
|
return acquireLock(TIMER_LOCK_DIR, {
|
|
@@ -2653,10 +2659,10 @@ if (scriptPath2.endsWith("timerWorker.ts") || scriptPath2.endsWith("timerWorker.
|
|
|
2653
2659
|
|
|
2654
2660
|
// src/services/rawDump/parentHeartbeat.ts
|
|
2655
2661
|
import { promises as fs10 } from "fs";
|
|
2656
|
-
import
|
|
2662
|
+
import path14 from "path";
|
|
2657
2663
|
var HEARTBEAT_STALE_MS = 15000;
|
|
2658
2664
|
function getParentHeartbeatPath(pid) {
|
|
2659
|
-
return
|
|
2665
|
+
return path14.join(getRawDumpDir(), `csc-parent-heartbeat-${pid}.json`);
|
|
2660
2666
|
}
|
|
2661
2667
|
async function readParentHeartbeat(pid) {
|
|
2662
2668
|
try {
|
|
@@ -2790,5 +2796,5 @@ export {
|
|
|
2790
2796
|
startBatchWorker
|
|
2791
2797
|
};
|
|
2792
2798
|
|
|
2793
|
-
//# debugId=
|
|
2799
|
+
//# debugId=90ACB77FEE54E34264756E2164756E21
|
|
2794
2800
|
//# sourceMappingURL=batchWorker.js.map
|