Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions apps/web/src/lib/forkTypes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect, it } from "vitest";

import { FORK_TYPES, getForkType } from "./forkTypes";

describe("forkTypes", () => {
it("includes git as the only functional integration by default", () => {
const functional = FORK_TYPES.filter((entry) => entry.isFunctionalIntegration);
const nonGit = FORK_TYPES.filter((entry) => entry.id !== "git-fork");

expect(functional.map((entry) => entry.id)).toEqual(["git-fork"]);
expect(nonGit.every((entry) => !entry.isFunctionalIntegration)).toBe(true);
});

it("exposes at least four parody-only fork types", () => {
const parody = FORK_TYPES.filter((entry) => !entry.isFunctionalIntegration);
expect(parody.length).toBeGreaterThanOrEqual(4);
});

it("keeps entries complete and stable enough for lookup", () => {
expect(getForkType("git-fork")?.displayName).toBe("Git Fork");
expect(getForkType("spork")?.icon).toBe("🥄");
expect(getForkType("spork")?.isFunctionalIntegration).toBe(false);
});
});
63 changes: 63 additions & 0 deletions apps/web/src/lib/forkTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// FILE: forkTypes.ts
// Purpose: Reusable fork-type catalog for parody and Git-functional distinctions.
// Layer: Shared UI/data model
// Exports: Fork type metadata consumed by fork-related surfaces and future copy.

export interface ForkTypeEntry {
readonly id: string;
readonly displayName: string;
readonly description: string;
readonly icon: string;
readonly isFunctionalIntegration: boolean;
}

export const FORK_TYPES: readonly ForkTypeEntry[] = [
{
id: "git-fork",
displayName: "Git Fork",
description: "Functional repository-derived code branching workflow with full sync support.",
icon: "🍴",
isFunctionalIntegration: true,
},
{
id: "dinner-fork",
displayName: "Dinner Fork",
description: "Shared dish split for social rituals, not code synchronization.",
icon: "🍴",
isFunctionalIntegration: false,
},
{
id: "tuning-fork",
displayName: "Tuning Fork",
description: "Conceptual fork where two ideas vibrate in agreement or drift apart.",
icon: "🎵",
isFunctionalIntegration: false,
},
{
id: "pitchfork",
displayName: "Pitchfork",
description: "Provocative fork of support; sharp edges, no git remotes.",
icon: "🔥",
isFunctionalIntegration: false,
},
{
id: "spork",
displayName: "Spork",
description: "Pragmatic hybrid fork for improv tasks that still isn’t a repo clone.",
icon: "🥄",
isFunctionalIntegration: false,
},
{
id: "chess-fork",
displayName: "Chess Fork",
description: "A tactical forking moment where one move attacks multiple priorities.",
icon: "♟️",
isFunctionalIntegration: false,
},
] as const;

export type ForkTypeId = (typeof FORK_TYPES)[number]["id"];

export function getForkType(entryId: ForkTypeId): ForkTypeEntry | undefined {
return FORK_TYPES.find((entry) => entry.id === entryId);
}
Loading