Build the current workspace snapshot on native CI runners
This branch snapshots the in-progress desktop workspace so GitHub-hosted Windows and Linux runners can package the same source tree that already passes local verification on macOS. Constraint: Local Apple Silicon Docker/Wine packaging crashes before Windows artifacts are produced Rejected: Publish from the incomplete base repo state | remote typecheck failed because current source additions were missing Confidence: medium Scope-risk: broad Directive: Treat this branch as a build snapshot only; do not merge it without reviewing the unrelated workspace changes it contains Tested: local typecheck, lint, workspace typecheck, unit tests, integration tests, e2e smoke, macOS signed release upload Not-tested: Native Windows/Linux artifacts before this CI run
This commit is contained in:
1 parent
0e497cd892
commit
b772e1c758
271 files changed
+35047
-22879
No files matched your search
@@ -0,0 +1,227 @@
|
||||
import { mkdtemp, rm } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { AppDatabase } from "../../src/main/database";
|
||||
import { buildTaskPrompt } from "../../src/main/prompt-builder";
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
async function createTempDir(prefix: string) {
|
||||
const dir = await mkdtemp(join(tmpdir(), prefix));
|
||||
tempDirs.push(dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })));
|
||||
});
|
||||
|
||||
describe("skill-aware capability registry", () => {
|
||||
it("autoAssignTask prefers an agent whose assigned skill matches the task, even when capability text is generic", async () => {
|
||||
const profileDir = await createTempDir("agentcompany-skill-assign-");
|
||||
const db = new AppDatabase(profileDir);
|
||||
db.init();
|
||||
|
||||
db.updateConnectorHealth({
|
||||
id: "codex_local",
|
||||
status: "ready",
|
||||
authState: "authenticated",
|
||||
version: "test",
|
||||
lastError: null,
|
||||
});
|
||||
|
||||
const companyId = db.saveCompany({
|
||||
name: "Skill Match Co",
|
||||
description: "Tests skill-aware assignment",
|
||||
status: "active",
|
||||
});
|
||||
const workspaceId = db.saveWorkspace({
|
||||
companyId,
|
||||
name: "Primary",
|
||||
localPath: profileDir,
|
||||
repoUrl: "",
|
||||
repoRef: "",
|
||||
isPrimary: true,
|
||||
});
|
||||
|
||||
db.saveAgent({
|
||||
companyId,
|
||||
name: "Generic Engineer",
|
||||
role: "Engineer",
|
||||
title: "Engineer",
|
||||
status: "active",
|
||||
reportsTo: null,
|
||||
connectorId: "codex_local",
|
||||
workspaceId,
|
||||
model: null,
|
||||
capabilities: "General software delivery",
|
||||
budgetMonthlyUsd: 200,
|
||||
});
|
||||
const styledEngineerId = db.saveAgent({
|
||||
companyId,
|
||||
name: "Frontend Specialist",
|
||||
role: "Engineer",
|
||||
title: "Frontend Specialist",
|
||||
status: "active",
|
||||
reportsTo: null,
|
||||
connectorId: "codex_local",
|
||||
workspaceId,
|
||||
model: null,
|
||||
capabilities: "General software delivery",
|
||||
budgetMonthlyUsd: 200,
|
||||
});
|
||||
|
||||
const skillId = randomUUID();
|
||||
const now = new Date().toISOString();
|
||||
db.upsertCompanySkill({
|
||||
id: skillId,
|
||||
companyId,
|
||||
key: "frontend/react-ui",
|
||||
slug: "react-ui",
|
||||
name: "React UI",
|
||||
description: "Build React components with hooks, Tailwind, and accessible layouts",
|
||||
markdown: "# React UI\nUse when building React components with hooks and Tailwind.",
|
||||
sourceType: "local_path",
|
||||
sourceLocator: null,
|
||||
sourceRef: null,
|
||||
trustLevel: "markdown_only",
|
||||
compatibility: "compatible",
|
||||
fileInventory: "[]",
|
||||
metadata: null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
});
|
||||
db.assignSkillToAgent(styledEngineerId, skillId);
|
||||
|
||||
const taskId = db.saveTask({
|
||||
companyId,
|
||||
title: "Build React dashboard widget",
|
||||
description: "Create an accessible React component with hooks and Tailwind styling.",
|
||||
workspaceId,
|
||||
priority: "high",
|
||||
status: "todo",
|
||||
});
|
||||
|
||||
const assignedId = db.autoAssignTask(taskId, companyId);
|
||||
expect(assignedId).toBe(styledEngineerId);
|
||||
|
||||
db.close();
|
||||
});
|
||||
|
||||
it("injects the company capability registry into the task prompt", async () => {
|
||||
const profileDir = await createTempDir("agentcompany-capability-prompt-");
|
||||
const db = new AppDatabase(profileDir);
|
||||
db.init();
|
||||
|
||||
db.updateConnectorHealth({
|
||||
id: "codex_local",
|
||||
status: "ready",
|
||||
authState: "authenticated",
|
||||
version: "test",
|
||||
lastError: null,
|
||||
});
|
||||
|
||||
const companyId = db.saveCompany({
|
||||
name: "Registry Co",
|
||||
description: "Tests capability registry prompt injection",
|
||||
status: "active",
|
||||
});
|
||||
const workspaceId = db.saveWorkspace({
|
||||
companyId,
|
||||
name: "Primary",
|
||||
localPath: profileDir,
|
||||
repoUrl: "",
|
||||
repoRef: "",
|
||||
isPrimary: true,
|
||||
});
|
||||
const agentId = db.saveAgent({
|
||||
companyId,
|
||||
name: "CEO",
|
||||
role: "CEO",
|
||||
title: "Chief Executive Officer",
|
||||
status: "active",
|
||||
reportsTo: null,
|
||||
connectorId: "codex_local",
|
||||
workspaceId,
|
||||
model: null,
|
||||
capabilities: "Lead the company",
|
||||
budgetMonthlyUsd: 250,
|
||||
});
|
||||
|
||||
const skillId = randomUUID();
|
||||
const now = new Date().toISOString();
|
||||
db.upsertCompanySkill({
|
||||
id: skillId,
|
||||
companyId,
|
||||
key: "frontend/react-ui",
|
||||
slug: "react-ui",
|
||||
name: "React UI",
|
||||
description: "Use when building React interfaces",
|
||||
markdown: "# React UI\nUse when building React interfaces.",
|
||||
sourceType: "local_path",
|
||||
sourceLocator: null,
|
||||
sourceRef: null,
|
||||
trustLevel: "markdown_only",
|
||||
compatibility: "compatible",
|
||||
fileInventory: "[]",
|
||||
metadata: null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
});
|
||||
|
||||
const snapshot = db.listSnapshot();
|
||||
const prompt = buildTaskPrompt({
|
||||
agent: db.getAgent(agentId),
|
||||
apiUrl: "http://127.0.0.1:3210",
|
||||
apiKey: "token",
|
||||
runId: "run-1",
|
||||
task: null,
|
||||
companyName: "Registry Co",
|
||||
companyDescription: "Tests capability registry prompt injection",
|
||||
goals: [],
|
||||
projects: [],
|
||||
directReports: [],
|
||||
chainOfCommand: [],
|
||||
assignedTasks: [],
|
||||
allAgents: snapshot.agents.filter((entry) => entry.companyId === companyId),
|
||||
pendingApprovals: [],
|
||||
tasksAwaitingReview: [],
|
||||
wakeReason: "assignment",
|
||||
allTasks: [],
|
||||
recentComments: [],
|
||||
socialAccounts: [],
|
||||
allConnectors: snapshot.connectors
|
||||
.filter((connector) => connector.id === "codex_local")
|
||||
.map((connector) => ({ id: connector.id, label: connector.label, status: connector.status, enabledModels: ["gpt-5.4"] })),
|
||||
companySkillCatalog: db.listCompanySkills(companyId).map((skill) => ({
|
||||
name: skill.name,
|
||||
slug: skill.slug,
|
||||
description: skill.description,
|
||||
})),
|
||||
companyWorkspaces: snapshot.workspaces
|
||||
.filter((workspace) => workspace.companyId === companyId)
|
||||
.map((workspace) => ({ name: workspace.name, localPath: workspace.localPath })),
|
||||
companyDocuments: [],
|
||||
skillEntries: [
|
||||
{
|
||||
name: "React Standards",
|
||||
whenToUse: "building React UI",
|
||||
allowedTools: ["read", "edit"],
|
||||
effort: "high",
|
||||
contextMode: "inline",
|
||||
},
|
||||
],
|
||||
skillNames: ["React Standards"],
|
||||
});
|
||||
|
||||
expect(prompt).toContain("# Company Capability Registry");
|
||||
expect(prompt).toContain("React UI (`react-ui`)");
|
||||
expect(prompt).toContain("Primary:");
|
||||
expect(prompt).toContain("Ready Connectors");
|
||||
expect(prompt).toContain("Your domain skills:");
|
||||
|
||||
db.close();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user