Add referenced last30days catalog entry

This commit is contained in:
Dotta
2026-06-04 20:01:25 +00:00
parent 1227bb8ead
commit bee2b25f5d
17 changed files with 1276 additions and 49 deletions
+53 -10
View File
@@ -44,7 +44,6 @@ import {
copyCatalogSkillFile,
getCatalogPackageMetadata,
getCatalogSkillOrThrow,
readCatalogSkillFile,
resolveCatalogSkillReference,
} from "./skills-catalog.js";
import {
@@ -2452,7 +2451,7 @@ export function companySkillService(db: Db) {
buildSkillRuntimeName(catalogSkill.key, skill.slug),
);
await copySkillDirectory(originSnapshotLocator, materializedDir);
const markdown = (await readCatalogSkillFile(catalogSkill.id, catalogSkill.entrypoint)).content;
const markdown = await fs.readFile(path.join(originSnapshotLocator, catalogSkill.entrypoint), "utf8");
const nextMetadata = buildCatalogSkillMetadata(catalogSkill, skill, originSnapshotLocator);
const nextValues = {
name: catalogSkill.name,
@@ -2942,6 +2941,7 @@ export function companySkillService(db: Db) {
catalogKind: catalogSkill.kind,
catalogCategory: catalogSkill.category,
catalogPath: catalogSkill.path,
catalogSource: catalogSkill.source ?? null,
packageName: packageMetadata.packageName,
packageVersion: packageMetadata.packageVersion,
originHash: catalogSkill.contentHash,
@@ -2956,11 +2956,36 @@ export function companySkillService(db: Db) {
if (catalogSkill.compatibility !== "compatible") {
throw unprocessable(`Catalog skill ${catalogSkill.id} is not compatible.`);
}
if (catalogSkill.trustLevel === "scripts_executables") {
throw unprocessable(
"Catalog skill contains executable scripts and cannot be force-installed until security review semantics allow it.",
);
}
}
async function auditCatalogSkillSnapshot(
companyId: string,
catalogSkill: CatalogSkill,
slug: string,
sourceDir: string,
) {
return auditInstalledSkillBytes({
id: randomUUID(),
companyId,
key: catalogSkill.key,
slug,
name: catalogSkill.name,
description: catalogSkill.description,
markdown: "",
sourceType: "catalog",
sourceLocator: sourceDir,
sourceRef: catalogSkill.contentHash,
trustLevel: catalogSkill.trustLevel,
compatibility: catalogSkill.compatibility,
fileInventory: catalogSkill.files.map((entry) => ({ path: entry.path, kind: entry.kind })),
metadata: {
sourceKind: "catalog",
catalogId: catalogSkill.id,
originHash: catalogSkill.contentHash,
},
createdAt: new Date(),
updatedAt: new Date(),
});
}
async function installFromCatalog(
@@ -3021,9 +3046,27 @@ export function companySkillService(db: Db) {
}
}
const materializedDir = await materializeCatalogManifestSkillFiles(companyId, catalogSkill, slug);
const originSnapshotLocator = await materializeCatalogOriginSnapshot(companyId, catalogSkill, slug);
const markdown = (await readCatalogSkillFile(catalogSkill.id, catalogSkill.entrypoint)).content;
let materializedDir: string | null = null;
let originSnapshotLocator: string | null = null;
try {
originSnapshotLocator = await materializeCatalogOriginSnapshot(companyId, catalogSkill, slug);
const candidateAudit = await auditCatalogSkillSnapshot(companyId, catalogSkill, slug, originSnapshotLocator);
if (candidateAudit.verdict === "fail") {
throw unprocessable("Catalog install is blocked by hard-stop audit findings.", {
updateHoldReason: "audit_hard_stop",
audit: candidateAudit,
});
}
materializedDir = await materializeCatalogManifestSkillFiles(companyId, catalogSkill, slug);
} catch (error) {
if (materializedDir) await fs.rm(materializedDir, { recursive: true, force: true }).catch(() => undefined);
if (originSnapshotLocator) await fs.rm(originSnapshotLocator, { recursive: true, force: true }).catch(() => undefined);
throw error;
}
if (!materializedDir || !originSnapshotLocator) {
throw unprocessable("Catalog install did not materialize pinned files.");
}
const markdown = await fs.readFile(path.join(originSnapshotLocator, catalogSkill.entrypoint), "utf8");
const metadata = buildCatalogSkillMetadata(catalogSkill, existingByKey, originSnapshotLocator);
const values = {
companyId,