This commit is contained in:
ZacharyZhang-NY committed 2026-04-05 20:14:48 -04:00
1 parent 09971cabc2
commit 9145572422
163 files changed
+3348 -2874

No files matched your search

+3 -14
View File
@@ -1,6 +1,6 @@
import type { DepartmentId } from "./types";
export const DEPARTMENT_LABELS: Record<string, string> = {
export const DEPARTMENT_LABELS: Record<DepartmentId, string> = {
executive: "Executive Suite",
engineering: "Engineering",
product: "Product & Design",
@@ -17,18 +17,7 @@ export const DEPARTMENT_LABELS: Record<string, string> = {
export const DEPARTMENT_OPTIONS: Array<{ value: DepartmentId | ""; label: string }> = [
{ value: "", label: "Any department" },
{ value: "executive", label: "Executive" },
{ value: "engineering", label: "Engineering" },
{ value: "product", label: "Product" },
{ value: "marketing", label: "Marketing" },
{ value: "sales", label: "Sales" },
{ value: "hr", label: "Human Resources" },
{ value: "finance", label: "Finance" },
{ value: "legal", label: "Legal" },
{ value: "operations", label: "Operations" },
{ value: "customer_support", label: "Customer Support" },
{ value: "research", label: "Research" },
{ value: "design", label: "Design" },
...(Object.entries(DEPARTMENT_LABELS) as [DepartmentId, string][]).map(([value, label]) => ({ value, label })),
];
export const DEPARTMENT_COLORS: Record<DepartmentId, string> = {
@@ -42,6 +31,6 @@ export const DEPARTMENT_COLORS: Record<DepartmentId, string> = {
legal: "#a78bfa",
operations: "#f97316",
customer_support: "#06b6d4",
research: "#8b5cf6",
research: "#0ea5e9",
design: "#f43f5e",
};
+45 -7
View File
@@ -116,6 +116,44 @@ export interface SaveTaskResult {
capabilityWarning?: string;
}
export interface ConfigRevisionSummary {
id: string;
agentId: string;
revisionNumber: number;
changedKeys: string[];
source: string;
rolledBackFromRevisionId: string | null;
createdByAgentId: string | null;
createdByUserId: string | null;
createdAt: string;
}
export interface ConfigRevisionDetail extends ConfigRevisionSummary {
configBefore: Record<string, unknown>;
configAfter: Record<string, unknown>;
}
export interface RunEventRecord {
id: number;
runId: string;
agentId: string;
seq: number;
eventType: string;
stream: string | null;
level: string | null;
message: string | null;
payload: Record<string, unknown> | null;
createdAt: string;
}
export interface HeartbeatPolicy {
enabled: boolean;
intervalSec: number;
cooldownSec: number;
maxConcurrentRuns: number;
wakeOnDemand: boolean;
}
export type DesktopApi = {
loadSnapshot: () => Promise<DesktopResult<ProfileSnapshot>>;
pickDirectory: () => Promise<DesktopResult<string | null>>;
@@ -214,15 +252,15 @@ export type DesktopApi = {
getAgent: (input: z.infer<typeof entityGetterSchema>) => Promise<DesktopResult<AgentRecord>>;
getRun: (input: z.infer<typeof entityGetterSchema>) => Promise<DesktopResult<RunRecord>>;
getApproval: (input: z.infer<typeof entityGetterSchema>) => Promise<DesktopResult<ApprovalRecord>>;
listConfigRevisions: (companyId: string, agentId: string) => Promise<DesktopResult<unknown[]>>;
getConfigRevision: (companyId: string, revisionId: string) => Promise<DesktopResult<unknown>>;
rollbackConfigRevision: (companyId: string, agentId: string, revisionId: string) => Promise<DesktopResult<boolean>>;
listRunEvents: (companyId: string, runId: string, opts?: { offset?: number; limit?: number }) => Promise<DesktopResult<unknown[]>>;
getAgentPermissions: (agentId: string) => Promise<DesktopResult<unknown>>;
listConfigRevisions: (companyId: string, agentId: string) => Promise<DesktopResult<ConfigRevisionSummary[]>>;
getConfigRevision: (companyId: string, revisionId: string) => Promise<DesktopResult<ConfigRevisionDetail>>;
rollbackConfigRevision: (companyId: string, agentId: string, revisionId: string) => Promise<DesktopResult<{ revisionId: string }>>;
listRunEvents: (companyId: string, runId: string, opts?: { offset?: number; limit?: number }) => Promise<DesktopResult<RunEventRecord[]>>;
getAgentPermissions: (agentId: string) => Promise<DesktopResult<Record<string, boolean>>>;
setAgentPermission: (companyId: string, agentId: string, permissionKey: string, enabled: boolean) => Promise<DesktopResult<boolean>>;
getHeartbeatPolicy: (agentId: string, companyId: string) => Promise<DesktopResult<unknown>>;
getHeartbeatPolicy: (agentId: string, companyId: string) => Promise<DesktopResult<HeartbeatPolicy>>;
setHeartbeatPolicy: (companyId: string, agentId: string, policy: Record<string, unknown>) => Promise<DesktopResult<boolean>>;
getRuntimeState: (agentId: string, companyId: string) => Promise<DesktopResult<unknown>>;
getRuntimeState: (agentId: string, companyId: string) => Promise<DesktopResult<Record<string, unknown>>>;
setRuntimeState: (companyId: string, agentId: string, state: Record<string, unknown>) => Promise<DesktopResult<boolean>>;
// Thread runtime
createThread: (input: z.infer<typeof createThreadSchema>) => Promise<DesktopResult<ConversationThreadRecord>>;
+11
View File
@@ -4,3 +4,14 @@ export const optionalId = z.preprocess(
(value) => (value === "" ? null : value),
z.string().uuid().nullable().optional(),
);
/** Canonical department identifiers shared across agent and automation schemas. */
export const DEPARTMENT_IDS = z.enum([
"executive", "engineering", "product", "marketing", "sales",
"hr", "finance", "legal", "operations", "customer_support", "research", "design",
]);
/** Canonical message channel types shared across messaging schemas. */
export const MESSAGE_CHANNELS = z.enum([
"direct", "department", "company", "project", "incident",
]);
+3 -3
View File
@@ -1,5 +1,5 @@
import { z } from "zod";
import { optionalId } from "./helpers";
import { DEPARTMENT_IDS, optionalId } from "./helpers";
import { connectorInputSchema } from "./schemas-company";
export const agentInputSchema = z.object({
@@ -8,7 +8,7 @@ export const agentInputSchema = z.object({
name: z.string().min(2).max(80),
role: z.string().min(2).max(80),
title: z.string().default(""),
department: z.enum(["executive", "engineering", "product", "marketing", "sales", "hr", "finance", "legal", "operations", "customer_support", "research", "design"]).nullable().optional(),
department: DEPARTMENT_IDS.nullable().optional(),
reportsTo: optionalId,
connectorId: connectorInputSchema.shape.id,
workspaceId: optionalId,
@@ -25,7 +25,7 @@ export const hireRequestSchema = z.object({
name: z.string().min(2).max(80),
role: z.string().min(2).max(80),
title: z.string().default(""),
department: z.enum(["executive", "engineering", "product", "marketing", "sales", "hr", "finance", "legal", "operations", "customer_support", "research", "design"]).nullable().optional(),
department: DEPARTMENT_IDS.nullable().optional(),
reportsTo: optionalId,
connectorId: connectorInputSchema.shape.id,
workspaceId: optionalId,
+1 -1
View File
@@ -51,7 +51,7 @@ export const bootstrapOnboardingSchema = z.object({
executionMode: z.enum(["ai_ceo", "ai_cofounder"]).default("ai_ceo"),
goalTitle: z.string().default(""),
goalDescription: z.string().default(""),
connectorId: z.enum(["codex_local", "claude_local", "claude_compatible", "claude_compat_2", "claude_compat_3", "claude_compat_4", "claude_compat_5", "claude_compat_6", "claude_compat_7", "claude_compat_8", "claude_compat_9", "claude_compat_10", "gemini_local"]).optional(),
connectorId: connectorInputSchema.shape.id.optional(),
connectorModel: z.string().default(""),
});
+13 -2
View File
@@ -106,7 +106,18 @@ export const listAgentSkillsSchema = z.object({
agentId: z.string().min(1),
});
export const terminalCommandKeys = [
"install_node_darwin",
"install_node_win32",
"install_node_linux",
"install_claude_unix",
"install_claude_win32",
"install_codex",
"install_gemini",
] as const;
export type TerminalCommandKey = (typeof terminalCommandKeys)[number];
export const openTerminalCommandSchema = z.object({
title: z.string().min(1).max(200),
command: z.string().min(1),
commandKey: z.enum(terminalCommandKeys),
});
+4 -4
View File
@@ -1,5 +1,5 @@
import { z } from "zod";
import { optionalId } from "./helpers";
import { MESSAGE_CHANNELS, optionalId } from "./helpers";
export const agentMessageInputSchema = z.object({
companyId: z.string().uuid(),
@@ -8,7 +8,7 @@ export const agentMessageInputSchema = z.object({
(v) => (v === "" ? null : v),
z.union([z.string().uuid(), z.literal("__board__")]).nullable().optional(),
),
channel: z.enum(["direct", "department", "company", "project", "incident"]).default("direct"),
channel: MESSAGE_CHANNELS.default("direct"),
channelTargetId: z.string().nullable().optional(),
subject: z.preprocess((v) => (v === "" ? "(no subject)" : v), z.string().min(1).max(200)),
body: z.string().min(1).max(8000),
@@ -46,7 +46,7 @@ export const agentMessageInputSchema = z.object({
export const messageQuerySchema = z.object({
companyId: z.string().uuid(),
agentId: z.string().uuid().optional(),
channel: z.enum(["direct", "department", "company", "project", "incident"]).optional(),
channel: MESSAGE_CHANNELS.optional(),
channelTargetId: z.string().nullable().optional(),
unreadOnly: z.boolean().optional(),
limit: z.number().int().min(1).max(500).default(200),
@@ -55,7 +55,7 @@ export const messageQuerySchema = z.object({
export const searchMessagesSchema = z.object({
companyId: z.string().uuid(),
query: z.string().min(1).max(200),
channel: z.enum(["direct", "department", "company", "project", "incident"]).optional(),
channel: MESSAGE_CHANNELS.optional(),
channelTargetId: z.string().nullable().optional(),
limit: z.number().int().min(1).max(100).default(50),
});
+3 -9
View File
@@ -1,5 +1,5 @@
import { z } from "zod";
import { optionalId } from "./helpers";
import { DEPARTMENT_IDS, optionalId } from "./helpers";
export const deleteEntitySchema = z.object({
id: z.string().uuid(),
@@ -35,14 +35,8 @@ export const automationRuleInputSchema = z.object({
"create_document", "auto_approve", "reassign_task", "run_task",
]),
actionConfigJson: z.string().default("{}"),
sourceDepartment: z.enum([
"executive", "engineering", "product", "marketing", "sales",
"hr", "finance", "legal", "operations", "customer_support", "research", "design",
]).nullable().optional(),
targetDepartment: z.enum([
"executive", "engineering", "product", "marketing", "sales",
"hr", "finance", "legal", "operations", "customer_support", "research", "design",
]).nullable().optional(),
sourceDepartment: DEPARTMENT_IDS.nullable().optional(),
targetDepartment: DEPARTMENT_IDS.nullable().optional(),
priority: z.number().int().min(0).max(100).default(50),
status: z.enum(["active", "paused", "disabled", "error"]).default("active"),
});
-7
View File
@@ -48,8 +48,6 @@ export type ConnectorStatus =
| "degraded"
| "error";
export type SenderKind = "agent" | "human" | "system";
export type TaskType = "code" | "research" | "content" | "management" | "general";
export type WorkspaceState = "ready" | "busy" | "blocked" | "missing" | "error";
@@ -110,8 +108,6 @@ export type DepartmentId =
| "research"
| "design";
export type BudgetAlertLevel = "warn" | "hard_stop";
export type SkillSourceType = "github" | "local_path" | "url" | "skills_sh" | "managed";
export type TrustLevel = "markdown_only" | "assets" | "scripts_executables";
@@ -232,9 +228,6 @@ export type MessagePriority = "urgent" | "normal" | "low";
export type WorkflowStatus = "draft" | "active" | "paused" | "completed" | "failed";
export type WorkProductType = "preview_url" | "pull_request" | "branch" | "commit" | "artifact" | "document" | "runtime_service";
export type WorkProductStatus = "active" | "ready_for_review" | "approved" | "changes_requested" | "merged" | "closed" | "failed" | "archived" | "draft";
export type WorkProductReviewState = "none" | "needs_board_review" | "approved" | "changes_requested";
export type InboxItemType = "pending_approval" | "failed_run" | "budget_warning" | "blocked_task" | "review_needed" | "agent_message";
+10 -1
View File
@@ -94,6 +94,14 @@ export interface ThreadWaitStateUpdatedEvent {
action: "created" | "resolved";
}
export interface RecoveryNeededEvent {
type: "recovery-needed";
interruptedRuns: Array<{
runId: string; taskId: string; taskTitle: string; agentId: string;
agentName: string; connectorId: string; interruptedAt: string;
}>;
}
export type DesktopEvent =
| LogChunkEvent
| DomainChangedEvent
@@ -109,4 +117,5 @@ export type DesktopEvent =
| ApprovalUpdatedEvent
| AgentUpdatedEvent
| BudgetChangedEvent
| ThreadWaitStateUpdatedEvent;
| ThreadWaitStateUpdatedEvent
| RecoveryNeededEvent;
+1
View File
@@ -131,6 +131,7 @@ export interface TaskRecord {
sessionJson: string | null;
sessionDisplayId: string | null;
costUsd: number;
taskType: string | null;
requiresUserReview: boolean;
startedAt: string | null;
completedAt: string | null;
-56
View File
@@ -16,9 +16,6 @@ import type {
MessageChannel,
MessagePriority,
WorkflowStatus,
WorkProductType,
WorkProductStatus,
WorkProductReviewState,
ThreadType,
ThreadActorType,
ThreadEventType,
@@ -100,59 +97,6 @@ export interface DocumentRecord {
updatedAt: string;
}
export interface DocumentRevisionRecord {
id: string;
companyId: string;
documentId: string;
revisionNumber: number;
body: string;
changeSummary: string | null;
createdByAgentId: string | null;
createdByUserId: string | null;
createdAt: string;
}
export interface ApprovalCommentRecord {
id: string;
companyId: string;
approvalId: string;
authorAgentId: string | null;
authorUserId: string | null;
body: string;
createdAt: string;
updatedAt: string;
}
export interface WorkProductRecord {
id: string;
companyId: string;
projectId: string | null;
taskId: string;
type: WorkProductType;
provider: string;
externalId: string | null;
title: string;
url: string | null;
status: WorkProductStatus;
reviewState: WorkProductReviewState;
isPrimary: boolean;
summary: string | null;
metadataJson: string | null;
createdByRunId: string | null;
createdAt: string;
updatedAt: string;
}
export interface TaskDocumentLink {
id: string;
companyId: string;
taskId: string;
documentId: string;
key: string;
createdAt: string;
updatedAt: string;
}
export interface KnowledgeEntryRecord {
id: string;
companyId: string;