@evo-dev/core 0.0.1-alpha.12 → 0.0.1-alpha.14
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/config/index.js +400 -47
- package/dist/index.js +6424 -5987
- package/package.json +1 -1
- package/src/evolution/knowledge/index.ts +93 -18
- package/src/projects/index.ts +490 -9
- package/src/runtime-logs/index.ts +96 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
1
2
|
import { appendFile, mkdir } from "node:fs/promises";
|
|
2
|
-
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
3
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
3
4
|
import { resolveEvoDevPaths } from "../config/paths.ts";
|
|
4
5
|
import { normalizeTimestamp, sha256Short } from "../utils/index.ts";
|
|
5
6
|
|
|
@@ -109,6 +110,15 @@ export interface TraceLogTeamContext {
|
|
|
109
110
|
projectKey: string;
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
export interface ProjectLogIdentity {
|
|
114
|
+
projectKey: string;
|
|
115
|
+
workspaceKey: string;
|
|
116
|
+
projectRoot: string;
|
|
117
|
+
workspaceRoot: string;
|
|
118
|
+
gitCommonDir: string | null;
|
|
119
|
+
linkedWorktree: boolean;
|
|
120
|
+
}
|
|
121
|
+
|
|
112
122
|
export interface CliLogInput {
|
|
113
123
|
phase: EvoDevLogPhase;
|
|
114
124
|
argv: string[];
|
|
@@ -538,6 +548,39 @@ export function resolveTraceTeamContext(input: {
|
|
|
538
548
|
}
|
|
539
549
|
|
|
540
550
|
export function resolveProjectLogKey(homeDir: string, repoRoot: string): string {
|
|
551
|
+
return resolveProjectLogIdentity(homeDir, repoRoot).projectKey;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
export function resolveProjectLogIdentity(homeDir: string, repoRoot: string): ProjectLogIdentity {
|
|
555
|
+
const identityHomeDir = realpathDirectoryOrFallback(homeDir);
|
|
556
|
+
const workspaceRoot = realpathDirectoryOrFallback(repoRoot);
|
|
557
|
+
const workspaceKey = resolvePathProjectLogKey(identityHomeDir, workspaceRoot);
|
|
558
|
+
const gitCommonDir = resolveGitCommonDir(workspaceRoot);
|
|
559
|
+
if (gitCommonDir === null) {
|
|
560
|
+
return {
|
|
561
|
+
projectKey: workspaceKey,
|
|
562
|
+
workspaceKey,
|
|
563
|
+
projectRoot: workspaceRoot,
|
|
564
|
+
workspaceRoot,
|
|
565
|
+
gitCommonDir: null,
|
|
566
|
+
linkedWorktree: false,
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const commonDirOwnsWorktree = basename(gitCommonDir) === ".git";
|
|
571
|
+
const projectIdentityPath = commonDirOwnsWorktree ? dirname(gitCommonDir) : gitCommonDir;
|
|
572
|
+
const projectRoot = commonDirOwnsWorktree ? projectIdentityPath : workspaceRoot;
|
|
573
|
+
return {
|
|
574
|
+
projectKey: resolvePathProjectLogKey(identityHomeDir, projectIdentityPath),
|
|
575
|
+
workspaceKey,
|
|
576
|
+
projectRoot,
|
|
577
|
+
workspaceRoot,
|
|
578
|
+
gitCommonDir,
|
|
579
|
+
linkedWorktree: workspaceKey !== resolvePathProjectLogKey(identityHomeDir, projectIdentityPath),
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
export function resolvePathProjectLogKey(homeDir: string, repoRoot: string): string {
|
|
541
584
|
const trimmedHome = stripTrailingSlash(homeDir);
|
|
542
585
|
const trimmedRepo = stripTrailingSlash(repoRoot);
|
|
543
586
|
const relativePath = relative(trimmedHome, trimmedRepo);
|
|
@@ -554,6 +597,58 @@ export function resolveProjectLogKey(homeDir: string, repoRoot: string): string
|
|
|
554
597
|
return sanitizePersistentIdentifier(projectKey, "project");
|
|
555
598
|
}
|
|
556
599
|
|
|
600
|
+
function realpathDirectoryOrFallback(path: string): string {
|
|
601
|
+
try {
|
|
602
|
+
return realpathSync(path);
|
|
603
|
+
} catch {
|
|
604
|
+
if (!isAbsolute(path)) return stripTrailingSlash(path);
|
|
605
|
+
const missingSegments: string[] = [];
|
|
606
|
+
let current = stripTrailingSlash(path);
|
|
607
|
+
for (;;) {
|
|
608
|
+
const parent = dirname(current);
|
|
609
|
+
if (parent === current) return stripTrailingSlash(path);
|
|
610
|
+
missingSegments.unshift(basename(current));
|
|
611
|
+
current = parent;
|
|
612
|
+
try {
|
|
613
|
+
return join(realpathSync(current), ...missingSegments);
|
|
614
|
+
} catch {
|
|
615
|
+
// Continue toward the nearest existing ancestor so deleted worktrees
|
|
616
|
+
// retain the same path identity across symlinked filesystem prefixes.
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function resolveGitCommonDir(workspaceRoot: string): string | null {
|
|
623
|
+
const markerPath = join(workspaceRoot, ".git");
|
|
624
|
+
let gitDir: string;
|
|
625
|
+
try {
|
|
626
|
+
const marker = lstatSync(markerPath);
|
|
627
|
+
if (marker.isDirectory()) {
|
|
628
|
+
gitDir = realpathSync(markerPath);
|
|
629
|
+
} else if (marker.isFile()) {
|
|
630
|
+
const value = readFileSync(markerPath, "utf8").trim();
|
|
631
|
+
const match = value.match(/^gitdir:\s*(.+)$/u);
|
|
632
|
+
if (match?.[1] === undefined || match[1].includes("\0")) return null;
|
|
633
|
+
gitDir = realpathSync(isAbsolute(match[1]) ? match[1] : resolve(workspaceRoot, match[1]));
|
|
634
|
+
} else {
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
} catch {
|
|
638
|
+
return null;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
try {
|
|
642
|
+
const commonDirValue = readFileSync(join(gitDir, "commondir"), "utf8").trim();
|
|
643
|
+
if (commonDirValue === "" || commonDirValue.includes("\0")) return gitDir;
|
|
644
|
+
return realpathSync(
|
|
645
|
+
isAbsolute(commonDirValue) ? commonDirValue : resolve(gitDir, commonDirValue),
|
|
646
|
+
);
|
|
647
|
+
} catch {
|
|
648
|
+
return gitDir;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
557
652
|
export function resolveTraceSessionKey(payload: unknown): string {
|
|
558
653
|
const record = isRecord(payload) ? payload : {};
|
|
559
654
|
const sessionId = optionalString(record.session_id ?? record.sessionId);
|