feat: company-prefixed routing, delete tests, docs favicon, and skills

Add company-prefix URL routing utilities and custom router wrapper.
Add CLI company delete confirmation tests. Add docs favicon and
para-memory-files skill.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-03-02 09:07:09 -06:00
parent cc2c724ad2
commit 97d4f6c622
6 changed files with 391 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
import { describe, expect, it } from "vitest";
import type { Company } from "@paperclip/shared";
import { assertDeleteConfirmation, resolveCompanyForDeletion } from "../commands/client/company.js";
function makeCompany(overrides: Partial<Company>): Company {
return {
id: "11111111-1111-1111-1111-111111111111",
name: "Alpha",
description: null,
status: "active",
issuePrefix: "ALP",
issueCounter: 1,
budgetMonthlyCents: 0,
spentMonthlyCents: 0,
requireBoardApprovalForNewAgents: false,
brandColor: null,
createdAt: new Date(),
updatedAt: new Date(),
...overrides,
};
}
describe("resolveCompanyForDeletion", () => {
const companies: Company[] = [
makeCompany({
id: "11111111-1111-1111-1111-111111111111",
name: "Alpha",
issuePrefix: "ALP",
}),
makeCompany({
id: "22222222-2222-2222-2222-222222222222",
name: "Paperclip",
issuePrefix: "PAP",
}),
];
it("resolves by ID in auto mode", () => {
const result = resolveCompanyForDeletion(companies, "22222222-2222-2222-2222-222222222222", "auto");
expect(result.issuePrefix).toBe("PAP");
});
it("resolves by prefix in auto mode", () => {
const result = resolveCompanyForDeletion(companies, "pap", "auto");
expect(result.id).toBe("22222222-2222-2222-2222-222222222222");
});
it("throws when selector is not found", () => {
expect(() => resolveCompanyForDeletion(companies, "MISSING", "auto")).toThrow(/No company found/);
});
it("respects explicit id mode", () => {
expect(() => resolveCompanyForDeletion(companies, "PAP", "id")).toThrow(/No company found by ID/);
});
it("respects explicit prefix mode", () => {
expect(() => resolveCompanyForDeletion(companies, "22222222-2222-2222-2222-222222222222", "prefix"))
.toThrow(/No company found by shortname/);
});
});
describe("assertDeleteConfirmation", () => {
const company = makeCompany({
id: "22222222-2222-2222-2222-222222222222",
issuePrefix: "PAP",
});
it("requires --yes", () => {
expect(() => assertDeleteConfirmation(company, { confirm: "PAP" })).toThrow(/requires --yes/);
});
it("accepts matching prefix confirmation", () => {
expect(() => assertDeleteConfirmation(company, { yes: true, confirm: "pap" })).not.toThrow();
});
it("accepts matching id confirmation", () => {
expect(() =>
assertDeleteConfirmation(company, {
yes: true,
confirm: "22222222-2222-2222-2222-222222222222",
})).not.toThrow();
});
it("rejects mismatched confirmation", () => {
expect(() => assertDeleteConfirmation(company, { yes: true, confirm: "nope" }))
.toThrow(/does not match target company/);
});
});