Promote AgentCompany-New to the repository root and retire the old app
The legacy application - its src, tests, landing site, promo assets, docs, release tooling, CI workflows, and root configs - leaves the tree; it stays reachable in history. Everything under AgentCompany-New moves up unchanged: same package name, so the production userData/database path is untouched, and e2e/build scripts already resolved paths relative to the project. The developer cred.txt stays gitignored at its new location. Full verify:ci passes from the new root.
This commit is contained in:
1 parent
2350f744e3
commit
07d0b4587d
1904 files changed
+1133
-282075
No files matched your search
@@ -0,0 +1,85 @@
|
||||
import { copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, statSync } from "node:fs";
|
||||
import { createHash } from "node:crypto";
|
||||
import { dirname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
||||
|
||||
export interface CopiedSkillFile {
|
||||
relativePath: string;
|
||||
objectKey: string;
|
||||
sha256: string;
|
||||
sizeBytes: number;
|
||||
}
|
||||
|
||||
export function copySkillRevision(sourceDir: string, artifactRoot: string, revisionId: string): CopiedSkillFile[] {
|
||||
const sourceRoot = resolve(sourceDir);
|
||||
if (!existsSync(sourceRoot) || !lstatSync(sourceRoot).isDirectory()) {
|
||||
throw new Error("Skill directory was not found.");
|
||||
}
|
||||
const targetRoot = join(artifactRoot, "skills", revisionId);
|
||||
const files = listSkillFiles(sourceRoot);
|
||||
mkdirSync(targetRoot, { recursive: true });
|
||||
return files.map((relativePath) => {
|
||||
const sourcePath = pathFromRelative(sourceRoot, relativePath);
|
||||
const targetPath = pathFromRelative(targetRoot, relativePath);
|
||||
mkdirSync(dirname(targetPath), { recursive: true });
|
||||
copyFileSync(sourcePath, targetPath);
|
||||
return {
|
||||
relativePath,
|
||||
objectKey: targetPath,
|
||||
sha256: fileChecksum(targetPath),
|
||||
sizeBytes: statSync(targetPath).size,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function recursiveSkillChecksum(sourceDir: string): string {
|
||||
const sourceRoot = resolve(sourceDir);
|
||||
const hash = createHash("sha256");
|
||||
for (const relativePath of listSkillFiles(sourceRoot)) {
|
||||
hash.update(relativePath);
|
||||
hash.update(readFileSync(pathFromRelative(sourceRoot, relativePath)));
|
||||
}
|
||||
return hash.digest("hex");
|
||||
}
|
||||
|
||||
export function assertSafeSkillPath(relativePath: string): string {
|
||||
const clean = relativePath.trim().replaceAll("\\", "/");
|
||||
if (!clean || isAbsolute(clean)) throw new Error(`Invalid skill artifact path: ${relativePath}`);
|
||||
const normalized = normalize(clean).replaceAll("\\", "/");
|
||||
if (normalized === "." || normalized.startsWith("../") || normalized.includes("/../")) {
|
||||
throw new Error(`Invalid skill artifact path: ${relativePath}`);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function listSkillFiles(root: string): string[] {
|
||||
const files: string[] = [];
|
||||
walk(root, root, files);
|
||||
return files.sort();
|
||||
}
|
||||
|
||||
function walk(root: string, currentDir: string, files: string[]): void {
|
||||
for (const name of readdirSync(currentDir).sort()) {
|
||||
if (name.startsWith(".")) continue;
|
||||
const path = join(currentDir, name);
|
||||
const stat = lstatSync(path);
|
||||
if (stat.isSymbolicLink()) throw new Error("Skill directories must not contain symbolic links.");
|
||||
if (stat.isDirectory()) {
|
||||
walk(root, path, files);
|
||||
continue;
|
||||
}
|
||||
if (stat.isFile()) files.push(relativePath(root, path));
|
||||
}
|
||||
}
|
||||
|
||||
function relativePath(root: string, path: string): string {
|
||||
return relative(root, path).split(sep).join("/");
|
||||
}
|
||||
|
||||
function pathFromRelative(root: string, relativePath: string): string {
|
||||
const safe = assertSafeSkillPath(relativePath);
|
||||
return join(root, ...safe.split("/"));
|
||||
}
|
||||
|
||||
function fileChecksum(path: string): string {
|
||||
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
||||
}
|
||||
Reference in new issue
Block a user