fix(skills): pull upstream skill runtime resolution to stop event-loop starvation
Build: Production / build (push) Failing after 12m39s
Build: Production / build (push) Failing after 12m39s
The fork's listRuntimeSkillEntries rematerialized every skill's files from the DB on every heartbeat run dispatch — fs.rm + fs.mkdir + per-file readFile/writeFile, sequentially per skill. With 24 configured skills and 5 concurrent agents, this saturated the Node event loop badly enough that executeRun continuations couldn't reach activeRunExecutions.add() within the orphan-reaper's 5-min threshold, causing reaper to false-positive runs as "process_lost". Upstream's listRuntimeSkillEntries calls resolveRuntimeSkillSource, which checks if the materialized directory already exists on disk and short- circuits when it does. Fixes the symptom at the root. Replaces these files with upstream/master content: - server/src/services/company-skills.ts - server/src/services/heartbeat.ts - server/src/services/workspace-runtime.ts - server/src/services/company-portability.ts - server/src/routes/company-skills.ts - server/src/routes/agents.ts - packages/adapter-utils/src/server-utils.ts Pulls in supporting upstream files: - server/src/services/catalog-provenance.ts - server/src/services/skills-catalog.ts - server/src/services/github-fetch.ts - server/src/services/portable-path.ts - packages/skills-catalog/ (new package) - packages/db document_annotation_* schema + migration 0091 - packages/shared document-annotation types/validators Drops fork features (to be re-evaluated later): - Gitea/Forgejo git skill sources (server/src/services/git-source.ts deleted) - PAT support for private skill repos - Fork-specific secret-export portability extensions Adds agentId: null to acquireRunLease test-probe call in routes/agents.ts to satisfy the fork's environment-runtime agentId requirement (kept). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import catalogManifestJson from "../generated/catalog.json" with { type: "json" };
|
||||
import type { CatalogManifest, CatalogSkill } from "./types.js";
|
||||
|
||||
export type {
|
||||
CatalogCompatibility,
|
||||
CatalogManifest,
|
||||
CatalogSkill,
|
||||
CatalogSkillFile,
|
||||
CatalogSkillFileKind,
|
||||
CatalogSkillKind,
|
||||
CatalogTrustLevel,
|
||||
CatalogValidationResult,
|
||||
} from "./types.js";
|
||||
|
||||
export const catalogManifest = catalogManifestJson as CatalogManifest;
|
||||
|
||||
export const catalogSkills: CatalogSkill[] = catalogManifest.skills;
|
||||
|
||||
const skillsById = new Map(catalogSkills.map((skill) => [skill.id, skill]));
|
||||
const skillsByKey = new Map(catalogSkills.map((skill) => [skill.key, skill]));
|
||||
|
||||
export function getCatalogSkill(id: string): CatalogSkill | null {
|
||||
return skillsById.get(id) ?? null;
|
||||
}
|
||||
|
||||
export function resolveCatalogSkillRef(ref: string): CatalogSkill | null {
|
||||
const normalized = ref.trim();
|
||||
if (normalized.length === 0) return null;
|
||||
|
||||
const exactMatch = skillsById.get(normalized) ?? skillsByKey.get(normalized);
|
||||
if (exactMatch) return exactMatch;
|
||||
|
||||
const slugMatches = catalogSkills.filter((skill) => skill.slug === normalized);
|
||||
if (slugMatches.length === 1) return slugMatches[0]!;
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user