From b62fa4ad64105a3b62e7c5b2f9950069df8a464e Mon Sep 17 00:00:00 2001 From: Forgotten Date: Mon, 16 Feb 2026 13:31:47 -0600 Subject: [PATCH] Add shared types package Shared TypeScript types, Zod validators, API contract definitions, and constants used by both server and UI. Covers agents, goals, issues, projects, and activity entities. Co-Authored-By: Claude Opus 4.6 --- packages/shared/package.json | 19 +++++++++++ packages/shared/src/api.ts | 10 ++++++ packages/shared/src/constants.ts | 33 ++++++++++++++++++ packages/shared/src/index.ts | 41 +++++++++++++++++++++++ packages/shared/src/types/activity.ts | 9 +++++ packages/shared/src/types/agent.ts | 15 +++++++++ packages/shared/src/types/goal.ts | 12 +++++++ packages/shared/src/types/index.ts | 5 +++ packages/shared/src/types/issue.ts | 14 ++++++++ packages/shared/src/types/project.ts | 7 ++++ packages/shared/src/validators/agent.ts | 20 +++++++++++ packages/shared/src/validators/goal.ts | 16 +++++++++ packages/shared/src/validators/index.ts | 27 +++++++++++++++ packages/shared/src/validators/issue.ts | 18 ++++++++++ packages/shared/src/validators/project.ts | 12 +++++++ packages/shared/tsconfig.json | 8 +++++ 16 files changed, 266 insertions(+) create mode 100644 packages/shared/package.json create mode 100644 packages/shared/src/api.ts create mode 100644 packages/shared/src/constants.ts create mode 100644 packages/shared/src/index.ts create mode 100644 packages/shared/src/types/activity.ts create mode 100644 packages/shared/src/types/agent.ts create mode 100644 packages/shared/src/types/goal.ts create mode 100644 packages/shared/src/types/index.ts create mode 100644 packages/shared/src/types/issue.ts create mode 100644 packages/shared/src/types/project.ts create mode 100644 packages/shared/src/validators/agent.ts create mode 100644 packages/shared/src/validators/goal.ts create mode 100644 packages/shared/src/validators/index.ts create mode 100644 packages/shared/src/validators/issue.ts create mode 100644 packages/shared/src/validators/project.ts create mode 100644 packages/shared/tsconfig.json diff --git a/packages/shared/package.json b/packages/shared/package.json new file mode 100644 index 00000000..ba38b06a --- /dev/null +++ b/packages/shared/package.json @@ -0,0 +1,19 @@ +{ + "name": "@paperclip/shared", + "version": "0.0.1", + "private": true, + "type": "module", + "exports": { + ".": "./src/index.ts", + "./*": "./src/*.ts" + }, + "scripts": { + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "zod": "^3.24.2" + }, + "devDependencies": { + "typescript": "^5.7.3" + } +} diff --git a/packages/shared/src/api.ts b/packages/shared/src/api.ts new file mode 100644 index 00000000..89bbfcd0 --- /dev/null +++ b/packages/shared/src/api.ts @@ -0,0 +1,10 @@ +export const API_PREFIX = "/api"; + +export const API = { + health: `${API_PREFIX}/health`, + agents: `${API_PREFIX}/agents`, + projects: `${API_PREFIX}/projects`, + issues: `${API_PREFIX}/issues`, + goals: `${API_PREFIX}/goals`, + activity: `${API_PREFIX}/activity`, +} as const; diff --git a/packages/shared/src/constants.ts b/packages/shared/src/constants.ts new file mode 100644 index 00000000..9bfe0d8c --- /dev/null +++ b/packages/shared/src/constants.ts @@ -0,0 +1,33 @@ +export const AGENT_STATUSES = ["active", "idle", "offline", "error"] as const; +export type AgentStatus = (typeof AGENT_STATUSES)[number]; + +export const AGENT_ROLES = [ + "engineer", + "designer", + "pm", + "qa", + "devops", + "general", +] as const; +export type AgentRole = (typeof AGENT_ROLES)[number]; + +export const ISSUE_STATUSES = [ + "backlog", + "todo", + "in_progress", + "in_review", + "done", + "cancelled", +] as const; +export type IssueStatus = (typeof ISSUE_STATUSES)[number]; + +export const ISSUE_PRIORITIES = [ + "critical", + "high", + "medium", + "low", +] as const; +export type IssuePriority = (typeof ISSUE_PRIORITIES)[number]; + +export const GOAL_LEVELS = ["company", "team", "agent", "task"] as const; +export type GoalLevel = (typeof GOAL_LEVELS)[number]; diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts new file mode 100644 index 00000000..d306e7eb --- /dev/null +++ b/packages/shared/src/index.ts @@ -0,0 +1,41 @@ +export { + AGENT_STATUSES, + AGENT_ROLES, + ISSUE_STATUSES, + ISSUE_PRIORITIES, + GOAL_LEVELS, + type AgentStatus, + type AgentRole, + type IssueStatus, + type IssuePriority, + type GoalLevel, +} from "./constants.js"; + +export type { + Agent, + Project, + Issue, + Goal, + ActivityEvent, +} from "./types/index.js"; + +export { + createAgentSchema, + updateAgentSchema, + type CreateAgent, + type UpdateAgent, + createProjectSchema, + updateProjectSchema, + type CreateProject, + type UpdateProject, + createIssueSchema, + updateIssueSchema, + type CreateIssue, + type UpdateIssue, + createGoalSchema, + updateGoalSchema, + type CreateGoal, + type UpdateGoal, +} from "./validators/index.js"; + +export { API_PREFIX, API } from "./api.js"; diff --git a/packages/shared/src/types/activity.ts b/packages/shared/src/types/activity.ts new file mode 100644 index 00000000..b908d0e1 --- /dev/null +++ b/packages/shared/src/types/activity.ts @@ -0,0 +1,9 @@ +export interface ActivityEvent { + id: string; + action: string; + entityType: string; + entityId: string; + agentId: string | null; + details: Record | null; + createdAt: Date; +} diff --git a/packages/shared/src/types/agent.ts b/packages/shared/src/types/agent.ts new file mode 100644 index 00000000..84478ed4 --- /dev/null +++ b/packages/shared/src/types/agent.ts @@ -0,0 +1,15 @@ +import type { AgentRole, AgentStatus } from "../constants.js"; + +export interface Agent { + id: string; + name: string; + role: AgentRole; + status: AgentStatus; + budgetCents: number; + spentCents: number; + lastHeartbeat: Date | null; + reportsTo: string | null; + metadata: Record | null; + createdAt: Date; + updatedAt: Date; +} diff --git a/packages/shared/src/types/goal.ts b/packages/shared/src/types/goal.ts new file mode 100644 index 00000000..f50dd7ed --- /dev/null +++ b/packages/shared/src/types/goal.ts @@ -0,0 +1,12 @@ +import type { GoalLevel } from "../constants.js"; + +export interface Goal { + id: string; + title: string; + description: string | null; + level: GoalLevel; + parentId: string | null; + ownerId: string | null; + createdAt: Date; + updatedAt: Date; +} diff --git a/packages/shared/src/types/index.ts b/packages/shared/src/types/index.ts new file mode 100644 index 00000000..465a314f --- /dev/null +++ b/packages/shared/src/types/index.ts @@ -0,0 +1,5 @@ +export type { Agent } from "./agent.js"; +export type { Project } from "./project.js"; +export type { Issue } from "./issue.js"; +export type { Goal } from "./goal.js"; +export type { ActivityEvent } from "./activity.js"; diff --git a/packages/shared/src/types/issue.ts b/packages/shared/src/types/issue.ts new file mode 100644 index 00000000..e9053e6d --- /dev/null +++ b/packages/shared/src/types/issue.ts @@ -0,0 +1,14 @@ +import type { IssuePriority, IssueStatus } from "../constants.js"; + +export interface Issue { + id: string; + title: string; + description: string | null; + status: IssueStatus; + priority: IssuePriority; + projectId: string | null; + assigneeId: string | null; + goalId: string | null; + createdAt: Date; + updatedAt: Date; +} diff --git a/packages/shared/src/types/project.ts b/packages/shared/src/types/project.ts new file mode 100644 index 00000000..026629b6 --- /dev/null +++ b/packages/shared/src/types/project.ts @@ -0,0 +1,7 @@ +export interface Project { + id: string; + name: string; + description: string | null; + createdAt: Date; + updatedAt: Date; +} diff --git a/packages/shared/src/validators/agent.ts b/packages/shared/src/validators/agent.ts new file mode 100644 index 00000000..74199368 --- /dev/null +++ b/packages/shared/src/validators/agent.ts @@ -0,0 +1,20 @@ +import { z } from "zod"; +import { AGENT_ROLES, AGENT_STATUSES } from "../constants.js"; + +export const createAgentSchema = z.object({ + name: z.string().min(1), + role: z.enum(AGENT_ROLES), + budgetCents: z.number().int().nonnegative().optional().default(0), + reportsTo: z.string().uuid().optional().nullable(), + metadata: z.record(z.unknown()).optional().nullable(), +}); + +export type CreateAgent = z.infer; + +export const updateAgentSchema = createAgentSchema + .partial() + .extend({ + status: z.enum(AGENT_STATUSES).optional(), + }); + +export type UpdateAgent = z.infer; diff --git a/packages/shared/src/validators/goal.ts b/packages/shared/src/validators/goal.ts new file mode 100644 index 00000000..0ecc043d --- /dev/null +++ b/packages/shared/src/validators/goal.ts @@ -0,0 +1,16 @@ +import { z } from "zod"; +import { GOAL_LEVELS } from "../constants.js"; + +export const createGoalSchema = z.object({ + title: z.string().min(1), + description: z.string().optional().nullable(), + level: z.enum(GOAL_LEVELS), + parentId: z.string().uuid().optional().nullable(), + ownerId: z.string().uuid().optional().nullable(), +}); + +export type CreateGoal = z.infer; + +export const updateGoalSchema = createGoalSchema.partial(); + +export type UpdateGoal = z.infer; diff --git a/packages/shared/src/validators/index.ts b/packages/shared/src/validators/index.ts new file mode 100644 index 00000000..b92e1465 --- /dev/null +++ b/packages/shared/src/validators/index.ts @@ -0,0 +1,27 @@ +export { + createAgentSchema, + updateAgentSchema, + type CreateAgent, + type UpdateAgent, +} from "./agent.js"; + +export { + createProjectSchema, + updateProjectSchema, + type CreateProject, + type UpdateProject, +} from "./project.js"; + +export { + createIssueSchema, + updateIssueSchema, + type CreateIssue, + type UpdateIssue, +} from "./issue.js"; + +export { + createGoalSchema, + updateGoalSchema, + type CreateGoal, + type UpdateGoal, +} from "./goal.js"; diff --git a/packages/shared/src/validators/issue.ts b/packages/shared/src/validators/issue.ts new file mode 100644 index 00000000..07b05f8b --- /dev/null +++ b/packages/shared/src/validators/issue.ts @@ -0,0 +1,18 @@ +import { z } from "zod"; +import { ISSUE_PRIORITIES, ISSUE_STATUSES } from "../constants.js"; + +export const createIssueSchema = z.object({ + title: z.string().min(1), + description: z.string().optional().nullable(), + status: z.enum(ISSUE_STATUSES).optional().default("backlog"), + priority: z.enum(ISSUE_PRIORITIES).optional().default("medium"), + projectId: z.string().uuid().optional().nullable(), + assigneeId: z.string().uuid().optional().nullable(), + goalId: z.string().uuid().optional().nullable(), +}); + +export type CreateIssue = z.infer; + +export const updateIssueSchema = createIssueSchema.partial(); + +export type UpdateIssue = z.infer; diff --git a/packages/shared/src/validators/project.ts b/packages/shared/src/validators/project.ts new file mode 100644 index 00000000..ac929501 --- /dev/null +++ b/packages/shared/src/validators/project.ts @@ -0,0 +1,12 @@ +import { z } from "zod"; + +export const createProjectSchema = z.object({ + name: z.string().min(1), + description: z.string().optional().nullable(), +}); + +export type CreateProject = z.infer; + +export const updateProjectSchema = createProjectSchema.partial(); + +export type UpdateProject = z.infer; diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json new file mode 100644 index 00000000..a086b149 --- /dev/null +++ b/packages/shared/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +}