agent-trajectories 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ENWKFNUD.js → chunk-BVTUGGYW.js} +206 -57
- package/dist/chunk-BVTUGGYW.js.map +1 -0
- package/dist/cli/index.js +153 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/{index-DEr3Rs32.d.ts → index-RDYnMyn2.d.ts} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-ENWKFNUD.js.map +0 -1
|
@@ -1,8 +1,157 @@
|
|
|
1
1
|
// src/sdk/client.ts
|
|
2
2
|
import { spawn } from "child_process";
|
|
3
|
-
import { existsSync as
|
|
3
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
|
-
import { dirname as
|
|
5
|
+
import { dirname as dirname3, resolve as resolvePath } from "path";
|
|
6
|
+
|
|
7
|
+
// src/core/project-id.ts
|
|
8
|
+
import { execFileSync } from "child_process";
|
|
9
|
+
import { existsSync, readFileSync } from "fs";
|
|
10
|
+
import { dirname, join, resolve } from "path";
|
|
11
|
+
function resolveProjectId(explicitProjectId, options = {}) {
|
|
12
|
+
return readString(explicitProjectId) ?? readString((options.env ?? process.env).TRAJECTORIES_PROJECT) ?? resolveDefaultProjectId(options.cwd);
|
|
13
|
+
}
|
|
14
|
+
function resolveDefaultProjectId(cwd = process.cwd()) {
|
|
15
|
+
const packageJson = readNearestPackageJson(cwd);
|
|
16
|
+
return resolvePackageRepositoryId(packageJson) ?? resolveGitRemoteProjectId(cwd) ?? resolvePackageName(packageJson);
|
|
17
|
+
}
|
|
18
|
+
function normalizeRepositoryId(value) {
|
|
19
|
+
const raw = readString(value);
|
|
20
|
+
if (!raw) {
|
|
21
|
+
return void 0;
|
|
22
|
+
}
|
|
23
|
+
const withoutGitPrefix = raw.replace(/^git\+/, "");
|
|
24
|
+
const shorthand = withoutGitPrefix.match(
|
|
25
|
+
/^(?:github|gitlab|bitbucket):([^/]+\/[^/]+(?:\/[^/]+)*)$/
|
|
26
|
+
);
|
|
27
|
+
if (shorthand) {
|
|
28
|
+
return cleanRepositoryPath(shorthand[1]);
|
|
29
|
+
}
|
|
30
|
+
const ownerRepo = withoutGitPrefix.match(
|
|
31
|
+
/^([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)$/
|
|
32
|
+
);
|
|
33
|
+
if (ownerRepo) {
|
|
34
|
+
return cleanRepositoryPath(ownerRepo[1]);
|
|
35
|
+
}
|
|
36
|
+
const sshUrlScpLike = withoutGitPrefix.match(
|
|
37
|
+
/^ssh:\/\/[^@/\s]+@[^:/\s]+:(.+)$/i
|
|
38
|
+
);
|
|
39
|
+
if (sshUrlScpLike) {
|
|
40
|
+
return cleanRepositoryPath(sshUrlScpLike[1]);
|
|
41
|
+
}
|
|
42
|
+
const scpLike = withoutGitPrefix.match(/^[^@/\s]+@[^:/\s]+:(.+)$/);
|
|
43
|
+
if (scpLike) {
|
|
44
|
+
return cleanRepositoryPath(scpLike[1]);
|
|
45
|
+
}
|
|
46
|
+
let parsed;
|
|
47
|
+
try {
|
|
48
|
+
parsed = new URL(withoutGitPrefix);
|
|
49
|
+
} catch {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
if (!["https:", "http:", "ssh:", "git:"].includes(parsed.protocol)) {
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
return cleanRepositoryPath(parsed.pathname);
|
|
56
|
+
}
|
|
57
|
+
function resolvePackageRepositoryId(packageJson) {
|
|
58
|
+
if (!packageJson) {
|
|
59
|
+
return void 0;
|
|
60
|
+
}
|
|
61
|
+
const repository = packageJson.repository;
|
|
62
|
+
if (typeof repository === "string") {
|
|
63
|
+
return normalizeRepositoryId(repository);
|
|
64
|
+
}
|
|
65
|
+
if (isRepositoryObject(repository) && typeof repository.url === "string") {
|
|
66
|
+
const projectId = normalizeRepositoryId(repository.url);
|
|
67
|
+
const directory = cleanRepositoryDirectory(repository.directory);
|
|
68
|
+
return directory && projectId ? `${projectId}//${directory}` : projectId;
|
|
69
|
+
}
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
function resolvePackageName(packageJson) {
|
|
73
|
+
return readString(packageJson?.name);
|
|
74
|
+
}
|
|
75
|
+
function resolveGitRemoteProjectId(cwd) {
|
|
76
|
+
for (const remote of ["upstream", "origin"]) {
|
|
77
|
+
const remoteUrl = getGitRemoteUrl(cwd, remote);
|
|
78
|
+
if (!remoteUrl) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const projectId = normalizeRepositoryId(remoteUrl);
|
|
82
|
+
if (projectId) {
|
|
83
|
+
return projectId;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return void 0;
|
|
87
|
+
}
|
|
88
|
+
function getGitRemoteUrl(cwd, remote) {
|
|
89
|
+
try {
|
|
90
|
+
return readString(
|
|
91
|
+
execFileSync("git", ["config", "--get", `remote.${remote}.url`], {
|
|
92
|
+
cwd,
|
|
93
|
+
encoding: "utf-8",
|
|
94
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
} catch {
|
|
98
|
+
return void 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function readNearestPackageJson(cwd) {
|
|
102
|
+
let current = resolve(cwd);
|
|
103
|
+
while (true) {
|
|
104
|
+
const candidate = join(current, "package.json");
|
|
105
|
+
if (existsSync(candidate)) {
|
|
106
|
+
try {
|
|
107
|
+
const parsed = JSON.parse(readFileSync(candidate, "utf-8"));
|
|
108
|
+
if (isPackageJson(parsed)) {
|
|
109
|
+
return parsed;
|
|
110
|
+
}
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const parent = dirname(current);
|
|
115
|
+
if (parent === current) {
|
|
116
|
+
return void 0;
|
|
117
|
+
}
|
|
118
|
+
current = parent;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function cleanRepositoryPath(path) {
|
|
122
|
+
const withoutQuery = path.split(/[?#]/, 1)[0] ?? "";
|
|
123
|
+
const withoutSlashes = withoutQuery.replace(/^\/+|\/+$/g, "");
|
|
124
|
+
const withoutGitSuffix = withoutSlashes.replace(/\.git$/i, "");
|
|
125
|
+
const parts = withoutGitSuffix.split("/").map((part) => part.trim()).filter(Boolean);
|
|
126
|
+
if (parts.length < 2) {
|
|
127
|
+
return void 0;
|
|
128
|
+
}
|
|
129
|
+
return parts.join("/");
|
|
130
|
+
}
|
|
131
|
+
function cleanRepositoryDirectory(directory) {
|
|
132
|
+
const raw = readString(directory);
|
|
133
|
+
if (!raw || raw.startsWith("/") || raw.startsWith("\\") || /^[A-Za-z]:[\\/]/.test(raw)) {
|
|
134
|
+
return void 0;
|
|
135
|
+
}
|
|
136
|
+
const parts = raw.split(/[\\/]/).map((part) => part.trim()).filter(Boolean);
|
|
137
|
+
if (parts.length === 0 || parts.some((part) => part === "." || part === "..")) {
|
|
138
|
+
return void 0;
|
|
139
|
+
}
|
|
140
|
+
return parts.join("/");
|
|
141
|
+
}
|
|
142
|
+
function readString(value) {
|
|
143
|
+
if (typeof value !== "string") {
|
|
144
|
+
return void 0;
|
|
145
|
+
}
|
|
146
|
+
const trimmed = value.trim();
|
|
147
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
148
|
+
}
|
|
149
|
+
function isPackageJson(value) {
|
|
150
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
151
|
+
}
|
|
152
|
+
function isRepositoryObject(value) {
|
|
153
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
154
|
+
}
|
|
6
155
|
|
|
7
156
|
// src/core/id.ts
|
|
8
157
|
import { webcrypto } from "crypto";
|
|
@@ -269,7 +418,7 @@ function createTrajectory(input) {
|
|
|
269
418
|
chapters: [],
|
|
270
419
|
commits: [],
|
|
271
420
|
filesChanged: [],
|
|
272
|
-
projectId: input.projectId
|
|
421
|
+
projectId: input.projectId,
|
|
273
422
|
tags: input.tags ?? []
|
|
274
423
|
};
|
|
275
424
|
}
|
|
@@ -666,7 +815,7 @@ function formatTime(isoString) {
|
|
|
666
815
|
}
|
|
667
816
|
|
|
668
817
|
// src/storage/file.ts
|
|
669
|
-
import { existsSync } from "fs";
|
|
818
|
+
import { existsSync as existsSync2 } from "fs";
|
|
670
819
|
import {
|
|
671
820
|
mkdir,
|
|
672
821
|
readFile,
|
|
@@ -677,27 +826,27 @@ import {
|
|
|
677
826
|
} from "fs/promises";
|
|
678
827
|
import {
|
|
679
828
|
basename,
|
|
680
|
-
dirname,
|
|
829
|
+
dirname as dirname2,
|
|
681
830
|
isAbsolute,
|
|
682
|
-
join,
|
|
831
|
+
join as join2,
|
|
683
832
|
relative,
|
|
684
|
-
resolve
|
|
833
|
+
resolve as resolve2
|
|
685
834
|
} from "path";
|
|
686
835
|
var TRAJECTORY_FILE = "trajectory.json";
|
|
687
836
|
var SUMMARY_FILE = "summary.md";
|
|
688
837
|
var COMPACTION_FILE = "compaction.json";
|
|
689
838
|
var LEGACY_COMPACTION_SUFFIX = ".compaction.json";
|
|
690
|
-
var DEFAULT_TRAJECTORY_DATA_DIR =
|
|
839
|
+
var DEFAULT_TRAJECTORY_DATA_DIR = join2(
|
|
691
840
|
".agentworkforce",
|
|
692
841
|
"trajectories"
|
|
693
842
|
);
|
|
694
843
|
var LEGACY_TRAJECTORY_DATA_DIR = ".trajectories";
|
|
695
844
|
function getDefaultTrajectoryDataDir(baseDir = process.cwd()) {
|
|
696
|
-
return
|
|
845
|
+
return join2(baseDir, DEFAULT_TRAJECTORY_DATA_DIR);
|
|
697
846
|
}
|
|
698
847
|
function expandPath(path) {
|
|
699
848
|
if (path.startsWith("~")) {
|
|
700
|
-
return
|
|
849
|
+
return join2(process.env.HOME ?? "", path.slice(1));
|
|
701
850
|
}
|
|
702
851
|
return path;
|
|
703
852
|
}
|
|
@@ -731,8 +880,8 @@ var FileStorage = class {
|
|
|
731
880
|
this.trajectoriesDir = getDefaultTrajectoryDataDir(this.baseDir);
|
|
732
881
|
this.shouldMigrateLegacyDefault = true;
|
|
733
882
|
}
|
|
734
|
-
this.activeDir =
|
|
735
|
-
this.completedDir =
|
|
883
|
+
this.activeDir = join2(this.trajectoriesDir, "active");
|
|
884
|
+
this.completedDir = join2(this.trajectoriesDir, "completed");
|
|
736
885
|
}
|
|
737
886
|
/**
|
|
738
887
|
* Initialize storage directories
|
|
@@ -743,18 +892,18 @@ var FileStorage = class {
|
|
|
743
892
|
await mkdir(this.activeDir, { recursive: true });
|
|
744
893
|
await mkdir(this.completedDir, { recursive: true });
|
|
745
894
|
await this.migrateLegacyIndexCompactionMarkers();
|
|
746
|
-
await rm(
|
|
895
|
+
await rm(join2(this.trajectoriesDir, "index.json"), { force: true });
|
|
747
896
|
await this.reconcileIndex();
|
|
748
897
|
}
|
|
749
898
|
async migrateLegacyDefaultDir() {
|
|
750
899
|
if (!this.shouldMigrateLegacyDefault) {
|
|
751
900
|
return;
|
|
752
901
|
}
|
|
753
|
-
const legacyDir =
|
|
754
|
-
if (!
|
|
902
|
+
const legacyDir = join2(this.baseDir, LEGACY_TRAJECTORY_DATA_DIR);
|
|
903
|
+
if (!existsSync2(legacyDir) || existsSync2(this.trajectoriesDir)) {
|
|
755
904
|
return;
|
|
756
905
|
}
|
|
757
|
-
await mkdir(
|
|
906
|
+
await mkdir(dirname2(this.trajectoriesDir), { recursive: true });
|
|
758
907
|
await rename(legacyDir, this.trajectoriesDir);
|
|
759
908
|
}
|
|
760
909
|
/**
|
|
@@ -837,7 +986,7 @@ var FileStorage = class {
|
|
|
837
986
|
*/
|
|
838
987
|
async quarantineInvalid() {
|
|
839
988
|
const summary = await this.reconcileIndex();
|
|
840
|
-
const targetDir =
|
|
989
|
+
const targetDir = join2(this.trajectoriesDir, "invalid");
|
|
841
990
|
const candidates = summary.failures.filter((f) => f.reason !== "io_error");
|
|
842
991
|
if (candidates.length === 0) {
|
|
843
992
|
return { moved: [], targetDir };
|
|
@@ -847,7 +996,7 @@ var FileStorage = class {
|
|
|
847
996
|
for (const failure of candidates) {
|
|
848
997
|
const dest = await this.resolveQuarantineDest(failure.path, targetDir);
|
|
849
998
|
try {
|
|
850
|
-
await mkdir(
|
|
999
|
+
await mkdir(dirname2(dest), { recursive: true });
|
|
851
1000
|
await rename(failure.path, dest);
|
|
852
1001
|
moved.push(failure);
|
|
853
1002
|
} catch (error) {
|
|
@@ -873,13 +1022,13 @@ var FileStorage = class {
|
|
|
873
1022
|
async resolveQuarantineDest(sourcePath, targetDir) {
|
|
874
1023
|
const rel = relative(this.trajectoriesDir, sourcePath);
|
|
875
1024
|
const safeRel = rel && !rel.startsWith("..") && !isAbsolute(rel) ? rel : basename(sourcePath);
|
|
876
|
-
let dest =
|
|
877
|
-
if (!
|
|
1025
|
+
let dest = join2(targetDir, safeRel);
|
|
1026
|
+
if (!existsSync2(dest)) return dest;
|
|
878
1027
|
const ext = safeRel.endsWith(".json") ? ".json" : "";
|
|
879
1028
|
const stem = ext ? safeRel.slice(0, -ext.length) : safeRel;
|
|
880
1029
|
for (let i = 1; i < 1e3; i += 1) {
|
|
881
|
-
dest =
|
|
882
|
-
if (!
|
|
1030
|
+
dest = join2(targetDir, `${stem}.${i}${ext}`);
|
|
1031
|
+
if (!existsSync2(dest)) return dest;
|
|
883
1032
|
}
|
|
884
1033
|
return dest;
|
|
885
1034
|
}
|
|
@@ -896,7 +1045,7 @@ var FileStorage = class {
|
|
|
896
1045
|
throw error;
|
|
897
1046
|
}
|
|
898
1047
|
for (const entry of entries) {
|
|
899
|
-
const entryPath =
|
|
1048
|
+
const entryPath = join2(dir, entry.name);
|
|
900
1049
|
if (entry.isDirectory()) {
|
|
901
1050
|
await this.walkJsonFilesInto(entryPath, out);
|
|
902
1051
|
} else if (entry.isFile() && isTrajectoryJsonFile(entry.name)) {
|
|
@@ -927,20 +1076,20 @@ var FileStorage = class {
|
|
|
927
1076
|
let trajectoryDir;
|
|
928
1077
|
if (isCompleted) {
|
|
929
1078
|
const date = new Date(trajectory2.completedAt ?? trajectory2.startedAt);
|
|
930
|
-
const monthDir =
|
|
1079
|
+
const monthDir = join2(
|
|
931
1080
|
this.completedDir,
|
|
932
1081
|
`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`
|
|
933
1082
|
);
|
|
934
|
-
trajectoryDir =
|
|
1083
|
+
trajectoryDir = join2(monthDir, trajectory2.id);
|
|
935
1084
|
} else {
|
|
936
|
-
trajectoryDir =
|
|
1085
|
+
trajectoryDir = join2(this.activeDir, trajectory2.id);
|
|
937
1086
|
}
|
|
938
|
-
const filePath =
|
|
1087
|
+
const filePath = join2(trajectoryDir, TRAJECTORY_FILE);
|
|
939
1088
|
await this.removeTrajectoryFiles(existingPaths, filePath);
|
|
940
1089
|
await mkdir(trajectoryDir, { recursive: true });
|
|
941
1090
|
if (isCompleted) {
|
|
942
1091
|
const markdown = exportToMarkdown(trajectory2);
|
|
943
|
-
await writeFile(
|
|
1092
|
+
await writeFile(join2(trajectoryDir, SUMMARY_FILE), markdown, "utf-8");
|
|
944
1093
|
}
|
|
945
1094
|
await writeFile(filePath, JSON.stringify(trajectory2, null, 2), "utf-8");
|
|
946
1095
|
}
|
|
@@ -949,7 +1098,7 @@ var FileStorage = class {
|
|
|
949
1098
|
*/
|
|
950
1099
|
async get(id) {
|
|
951
1100
|
for (const filePath of this.getActiveCandidatePaths(id)) {
|
|
952
|
-
if (!
|
|
1101
|
+
if (!existsSync2(filePath)) continue;
|
|
953
1102
|
const trajectory2 = await this.readTrajectoryOrNull(filePath);
|
|
954
1103
|
if (trajectory2?.id === id) {
|
|
955
1104
|
return trajectory2;
|
|
@@ -1154,9 +1303,9 @@ var FileStorage = class {
|
|
|
1154
1303
|
return [];
|
|
1155
1304
|
}
|
|
1156
1305
|
return [
|
|
1157
|
-
|
|
1306
|
+
join2(this.activeDir, id, TRAJECTORY_FILE),
|
|
1158
1307
|
// Legacy layout from v0.5.x and earlier.
|
|
1159
|
-
|
|
1308
|
+
join2(this.activeDir, `${id}.json`)
|
|
1160
1309
|
];
|
|
1161
1310
|
}
|
|
1162
1311
|
async loadAllTrajectories() {
|
|
@@ -1210,7 +1359,7 @@ var FileStorage = class {
|
|
|
1210
1359
|
}
|
|
1211
1360
|
getTrajectoryIdFromPath(filePath) {
|
|
1212
1361
|
if (basename(filePath) === TRAJECTORY_FILE) {
|
|
1213
|
-
const id = basename(
|
|
1362
|
+
const id = basename(dirname2(filePath));
|
|
1214
1363
|
return isSafeTrajectoryId(id) ? id : void 0;
|
|
1215
1364
|
}
|
|
1216
1365
|
const name = basename(filePath);
|
|
@@ -1231,10 +1380,10 @@ var FileStorage = class {
|
|
|
1231
1380
|
}
|
|
1232
1381
|
async removeTrajectoryFile(filePath, summary) {
|
|
1233
1382
|
if (basename(filePath) === TRAJECTORY_FILE) {
|
|
1234
|
-
const trajectoryDir =
|
|
1383
|
+
const trajectoryDir = dirname2(filePath);
|
|
1235
1384
|
await this.countDirectoryTrajectoryFiles(trajectoryDir, summary);
|
|
1236
1385
|
await this.removeFileIfExists(
|
|
1237
|
-
|
|
1386
|
+
join2(dirname2(trajectoryDir), `${basename(trajectoryDir)}.trace.json`),
|
|
1238
1387
|
"trace",
|
|
1239
1388
|
summary
|
|
1240
1389
|
);
|
|
@@ -1260,40 +1409,40 @@ var FileStorage = class {
|
|
|
1260
1409
|
}
|
|
1261
1410
|
async countDirectoryTrajectoryFiles(trajectoryDir, summary) {
|
|
1262
1411
|
await this.countFileIfExists(
|
|
1263
|
-
|
|
1412
|
+
join2(trajectoryDir, TRAJECTORY_FILE),
|
|
1264
1413
|
"json",
|
|
1265
1414
|
summary
|
|
1266
1415
|
);
|
|
1267
1416
|
await this.countFileIfExists(
|
|
1268
|
-
|
|
1417
|
+
join2(trajectoryDir, SUMMARY_FILE),
|
|
1269
1418
|
"markdown",
|
|
1270
1419
|
summary
|
|
1271
1420
|
);
|
|
1272
1421
|
await this.countFileIfExists(
|
|
1273
|
-
|
|
1422
|
+
join2(trajectoryDir, `${basename(trajectoryDir)}.trace.json`),
|
|
1274
1423
|
"trace",
|
|
1275
1424
|
summary
|
|
1276
1425
|
);
|
|
1277
1426
|
await this.countFileIfExists(
|
|
1278
|
-
|
|
1427
|
+
join2(trajectoryDir, "trace.json"),
|
|
1279
1428
|
"trace",
|
|
1280
1429
|
summary
|
|
1281
1430
|
);
|
|
1282
1431
|
await this.countFileIfExists(
|
|
1283
|
-
|
|
1432
|
+
join2(trajectoryDir, COMPACTION_FILE),
|
|
1284
1433
|
"compaction",
|
|
1285
1434
|
summary
|
|
1286
1435
|
);
|
|
1287
1436
|
}
|
|
1288
1437
|
async removeFileIfExists(path, kind, summary) {
|
|
1289
|
-
if (!
|
|
1438
|
+
if (!existsSync2(path)) {
|
|
1290
1439
|
return;
|
|
1291
1440
|
}
|
|
1292
1441
|
await rm(path, { force: true });
|
|
1293
1442
|
this.incrementDeleteSummary(kind, summary);
|
|
1294
1443
|
}
|
|
1295
1444
|
async countFileIfExists(path, kind, summary) {
|
|
1296
|
-
if (
|
|
1445
|
+
if (existsSync2(path)) {
|
|
1297
1446
|
this.incrementDeleteSummary(kind, summary);
|
|
1298
1447
|
}
|
|
1299
1448
|
}
|
|
@@ -1334,21 +1483,21 @@ var FileStorage = class {
|
|
|
1334
1483
|
}
|
|
1335
1484
|
getCompactionMarkerPath(filePath, id) {
|
|
1336
1485
|
if (basename(filePath) === TRAJECTORY_FILE) {
|
|
1337
|
-
return
|
|
1486
|
+
return join2(dirname2(filePath), COMPACTION_FILE);
|
|
1338
1487
|
}
|
|
1339
|
-
return
|
|
1488
|
+
return join2(dirname2(filePath), `${id}${LEGACY_COMPACTION_SUFFIX}`);
|
|
1340
1489
|
}
|
|
1341
1490
|
getTrajectoryIdFromCompactionMarkerPath(markerPath) {
|
|
1342
1491
|
if (basename(markerPath) === COMPACTION_FILE) {
|
|
1343
|
-
const id = basename(
|
|
1492
|
+
const id = basename(dirname2(markerPath));
|
|
1344
1493
|
return id.startsWith("traj_") ? id : void 0;
|
|
1345
1494
|
}
|
|
1346
1495
|
const markerName = basename(markerPath);
|
|
1347
1496
|
return markerName.endsWith(LEGACY_COMPACTION_SUFFIX) ? markerName.slice(0, -LEGACY_COMPACTION_SUFFIX.length) : void 0;
|
|
1348
1497
|
}
|
|
1349
1498
|
async migrateLegacyIndexCompactionMarkers() {
|
|
1350
|
-
const indexPath =
|
|
1351
|
-
if (!
|
|
1499
|
+
const indexPath = join2(this.trajectoriesDir, "index.json");
|
|
1500
|
+
if (!existsSync2(indexPath)) {
|
|
1352
1501
|
return;
|
|
1353
1502
|
}
|
|
1354
1503
|
let parsed;
|
|
@@ -1374,7 +1523,7 @@ var FileStorage = class {
|
|
|
1374
1523
|
if (typeof compactedInto !== "string") {
|
|
1375
1524
|
return;
|
|
1376
1525
|
}
|
|
1377
|
-
const paths = typeof path === "string" &&
|
|
1526
|
+
const paths = typeof path === "string" && existsSync2(path) && this.isPathInsideTrajectoriesDir(path) ? [path] : await this.findTrajectoryFilePaths(id);
|
|
1378
1527
|
if (paths.length === 0) return;
|
|
1379
1528
|
const marker = {
|
|
1380
1529
|
trajectoryId: id,
|
|
@@ -1394,7 +1543,7 @@ var FileStorage = class {
|
|
|
1394
1543
|
);
|
|
1395
1544
|
}
|
|
1396
1545
|
isPathInsideTrajectoriesDir(path) {
|
|
1397
|
-
const rel = relative(
|
|
1546
|
+
const rel = relative(resolve2(this.trajectoriesDir), resolve2(path));
|
|
1398
1547
|
return Boolean(rel && !rel.startsWith("..") && !isAbsolute(rel));
|
|
1399
1548
|
}
|
|
1400
1549
|
async walkFilesInto(dir, out, predicate) {
|
|
@@ -1406,7 +1555,7 @@ var FileStorage = class {
|
|
|
1406
1555
|
throw error;
|
|
1407
1556
|
}
|
|
1408
1557
|
for (const entry of entries) {
|
|
1409
|
-
const entryPath =
|
|
1558
|
+
const entryPath = join2(dir, entry.name);
|
|
1410
1559
|
if (entry.isDirectory()) {
|
|
1411
1560
|
await this.walkFilesInto(entryPath, out, predicate);
|
|
1412
1561
|
} else if (entry.isFile() && predicate(entry.name)) {
|
|
@@ -1539,12 +1688,12 @@ function resolveTrajectoryCliInvocation() {
|
|
|
1539
1688
|
try {
|
|
1540
1689
|
const packageJsonPath = require2.resolve("agent-trajectories/package.json");
|
|
1541
1690
|
const pkg = JSON.parse(
|
|
1542
|
-
|
|
1691
|
+
readFileSync2(packageJsonPath, "utf-8")
|
|
1543
1692
|
);
|
|
1544
1693
|
const binEntry = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.trail ?? (pkg.name ? pkg.bin?.[pkg.name] : void 0);
|
|
1545
1694
|
if (binEntry) {
|
|
1546
|
-
const cliPath = resolvePath(
|
|
1547
|
-
if (
|
|
1695
|
+
const cliPath = resolvePath(dirname3(packageJsonPath), binEntry);
|
|
1696
|
+
if (existsSync3(cliPath)) {
|
|
1548
1697
|
return { command: process.execPath, args: [cliPath] };
|
|
1549
1698
|
}
|
|
1550
1699
|
}
|
|
@@ -1589,7 +1738,7 @@ async function compactWorkflow(workflowId, options) {
|
|
|
1589
1738
|
if (options?.discardSources) {
|
|
1590
1739
|
args.push("--discard-sources");
|
|
1591
1740
|
}
|
|
1592
|
-
return new Promise((
|
|
1741
|
+
return new Promise((resolve3, reject) => {
|
|
1593
1742
|
const child = spawn(cli.command, args, {
|
|
1594
1743
|
cwd: options?.cwd,
|
|
1595
1744
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -1617,7 +1766,7 @@ async function compactWorkflow(workflowId, options) {
|
|
|
1617
1766
|
}
|
|
1618
1767
|
try {
|
|
1619
1768
|
const stdout = Buffer.concat(stdoutChunks).toString("utf-8");
|
|
1620
|
-
|
|
1769
|
+
resolve3(parseCompactWorkflowOutput(stdout));
|
|
1621
1770
|
} catch (error) {
|
|
1622
1771
|
reject(
|
|
1623
1772
|
error instanceof Error ? error : new Error("compactWorkflow failed: unable to parse CLI output")
|
|
@@ -1844,7 +1993,7 @@ var TrajectoryClient = class {
|
|
|
1844
1993
|
constructor(options = {}) {
|
|
1845
1994
|
this.storage = options.storage ?? new FileStorage(options.dataDir);
|
|
1846
1995
|
this.defaultAgent = options.defaultAgent ?? process.env.TRAJECTORIES_AGENT;
|
|
1847
|
-
this.projectId = options.projectId
|
|
1996
|
+
this.projectId = resolveProjectId(options.projectId);
|
|
1848
1997
|
this.autoSave = options.autoSave ?? true;
|
|
1849
1998
|
this.autoCompact = normalizeAutoCompactOptions(options.autoCompact);
|
|
1850
1999
|
this.autoCompactCwd = options.storage ? void 0 : options.dataDir;
|
|
@@ -2286,7 +2435,7 @@ function trajectory(title) {
|
|
|
2286
2435
|
|
|
2287
2436
|
// src/core/trailers.ts
|
|
2288
2437
|
import { execSync as execSync2 } from "child_process";
|
|
2289
|
-
import { readFileSync as
|
|
2438
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
2290
2439
|
|
|
2291
2440
|
// src/core/trace.ts
|
|
2292
2441
|
import { execSync } from "child_process";
|
|
@@ -2445,4 +2594,4 @@ export {
|
|
|
2445
2594
|
getCommitsBetween,
|
|
2446
2595
|
getFilesChangedBetween
|
|
2447
2596
|
};
|
|
2448
|
-
//# sourceMappingURL=chunk-
|
|
2597
|
+
//# sourceMappingURL=chunk-BVTUGGYW.js.map
|