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 <noreply@anthropic.com>
This commit is contained in:
19
packages/shared/package.json
Normal file
19
packages/shared/package.json
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
10
packages/shared/src/api.ts
Normal file
10
packages/shared/src/api.ts
Normal file
@@ -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;
|
||||
33
packages/shared/src/constants.ts
Normal file
33
packages/shared/src/constants.ts
Normal file
@@ -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];
|
||||
41
packages/shared/src/index.ts
Normal file
41
packages/shared/src/index.ts
Normal file
@@ -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";
|
||||
9
packages/shared/src/types/activity.ts
Normal file
9
packages/shared/src/types/activity.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface ActivityEvent {
|
||||
id: string;
|
||||
action: string;
|
||||
entityType: string;
|
||||
entityId: string;
|
||||
agentId: string | null;
|
||||
details: Record<string, unknown> | null;
|
||||
createdAt: Date;
|
||||
}
|
||||
15
packages/shared/src/types/agent.ts
Normal file
15
packages/shared/src/types/agent.ts
Normal file
@@ -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<string, unknown> | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
12
packages/shared/src/types/goal.ts
Normal file
12
packages/shared/src/types/goal.ts
Normal file
@@ -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;
|
||||
}
|
||||
5
packages/shared/src/types/index.ts
Normal file
5
packages/shared/src/types/index.ts
Normal file
@@ -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";
|
||||
14
packages/shared/src/types/issue.ts
Normal file
14
packages/shared/src/types/issue.ts
Normal file
@@ -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;
|
||||
}
|
||||
7
packages/shared/src/types/project.ts
Normal file
7
packages/shared/src/types/project.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface Project {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
20
packages/shared/src/validators/agent.ts
Normal file
20
packages/shared/src/validators/agent.ts
Normal file
@@ -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<typeof createAgentSchema>;
|
||||
|
||||
export const updateAgentSchema = createAgentSchema
|
||||
.partial()
|
||||
.extend({
|
||||
status: z.enum(AGENT_STATUSES).optional(),
|
||||
});
|
||||
|
||||
export type UpdateAgent = z.infer<typeof updateAgentSchema>;
|
||||
16
packages/shared/src/validators/goal.ts
Normal file
16
packages/shared/src/validators/goal.ts
Normal file
@@ -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<typeof createGoalSchema>;
|
||||
|
||||
export const updateGoalSchema = createGoalSchema.partial();
|
||||
|
||||
export type UpdateGoal = z.infer<typeof updateGoalSchema>;
|
||||
27
packages/shared/src/validators/index.ts
Normal file
27
packages/shared/src/validators/index.ts
Normal file
@@ -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";
|
||||
18
packages/shared/src/validators/issue.ts
Normal file
18
packages/shared/src/validators/issue.ts
Normal file
@@ -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<typeof createIssueSchema>;
|
||||
|
||||
export const updateIssueSchema = createIssueSchema.partial();
|
||||
|
||||
export type UpdateIssue = z.infer<typeof updateIssueSchema>;
|
||||
12
packages/shared/src/validators/project.ts
Normal file
12
packages/shared/src/validators/project.ts
Normal file
@@ -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<typeof createProjectSchema>;
|
||||
|
||||
export const updateProjectSchema = createProjectSchema.partial();
|
||||
|
||||
export type UpdateProject = z.infer<typeof updateProjectSchema>;
|
||||
8
packages/shared/tsconfig.json
Normal file
8
packages/shared/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user