export const COMPANY_STATUSES = ["active", "paused", "archived"] as const; export type CompanyStatus = (typeof COMPANY_STATUSES)[number]; export const DEPLOYMENT_MODES = ["local_trusted", "authenticated"] as const; export type DeploymentMode = (typeof DEPLOYMENT_MODES)[number]; export const DEPLOYMENT_EXPOSURES = ["private", "public"] as const; export type DeploymentExposure = (typeof DEPLOYMENT_EXPOSURES)[number]; export const AUTH_BASE_URL_MODES = ["auto", "explicit"] as const; export type AuthBaseUrlMode = (typeof AUTH_BASE_URL_MODES)[number]; export const AGENT_STATUSES = [ "active", "paused", "idle", "running", "error", "pending_approval", "terminated", ] as const; export type AgentStatus = (typeof AGENT_STATUSES)[number]; export const AGENT_ADAPTER_TYPES = [ "process", "http", "claude_local", "codex_local", "opencode_local", "pi_local", "cursor", "openclaw_gateway", "hermes_local", ] as const; export type AgentAdapterType = (typeof AGENT_ADAPTER_TYPES)[number]; export const AGENT_ROLES = [ "ceo", "cto", "cmo", "cfo", "engineer", "designer", "pm", "qa", "devops", "researcher", "general", ] as const; export type AgentRole = (typeof AGENT_ROLES)[number]; export const AGENT_ROLE_LABELS: Record = { ceo: "CEO", cto: "CTO", cmo: "CMO", cfo: "CFO", engineer: "Engineer", designer: "Designer", pm: "PM", qa: "QA", devops: "DevOps", researcher: "Researcher", general: "General", }; export const AGENT_ICON_NAMES = [ "bot", "cpu", "brain", "zap", "rocket", "code", "terminal", "shield", "eye", "search", "wrench", "hammer", "lightbulb", "sparkles", "star", "heart", "flame", "bug", "cog", "database", "globe", "lock", "mail", "message-square", "file-code", "git-branch", "package", "puzzle", "target", "wand", "atom", "circuit-board", "radar", "swords", "telescope", "microscope", "crown", "gem", "hexagon", "pentagon", "fingerprint", ] as const; export type AgentIconName = (typeof AGENT_ICON_NAMES)[number]; export const ISSUE_STATUSES = [ "backlog", "todo", "in_progress", "in_review", "done", "blocked", "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]; export const GOAL_STATUSES = ["planned", "active", "achieved", "cancelled"] as const; export type GoalStatus = (typeof GOAL_STATUSES)[number]; export const PROJECT_STATUSES = [ "backlog", "planned", "in_progress", "completed", "cancelled", ] as const; export type ProjectStatus = (typeof PROJECT_STATUSES)[number]; export const PAUSE_REASONS = ["manual", "budget", "system"] as const; export type PauseReason = (typeof PAUSE_REASONS)[number]; export const PROJECT_COLORS = [ "#6366f1", // indigo "#8b5cf6", // violet "#ec4899", // pink "#ef4444", // red "#f97316", // orange "#eab308", // yellow "#22c55e", // green "#14b8a6", // teal "#06b6d4", // cyan "#3b82f6", // blue ] as const; export const APPROVAL_TYPES = ["hire_agent", "approve_ceo_strategy", "budget_override_required"] as const; export type ApprovalType = (typeof APPROVAL_TYPES)[number]; export const APPROVAL_STATUSES = [ "pending", "revision_requested", "approved", "rejected", "cancelled", ] as const; export type ApprovalStatus = (typeof APPROVAL_STATUSES)[number]; export const SECRET_PROVIDERS = [ "local_encrypted", "aws_secrets_manager", "gcp_secret_manager", "vault", ] as const; export type SecretProvider = (typeof SECRET_PROVIDERS)[number]; export const STORAGE_PROVIDERS = ["local_disk", "s3"] as const; export type StorageProvider = (typeof STORAGE_PROVIDERS)[number]; export const BILLING_TYPES = [ "metered_api", "subscription_included", "subscription_overage", "credits", "fixed", "unknown", ] as const; export type BillingType = (typeof BILLING_TYPES)[number]; export const FINANCE_EVENT_KINDS = [ "inference_charge", "platform_fee", "credit_purchase", "credit_refund", "credit_expiry", "byok_fee", "gateway_overhead", "log_storage_charge", "logpush_charge", "provisioned_capacity_charge", "training_charge", "custom_model_import_charge", "custom_model_storage_charge", "manual_adjustment", ] as const; export type FinanceEventKind = (typeof FINANCE_EVENT_KINDS)[number]; export const FINANCE_DIRECTIONS = ["debit", "credit"] as const; export type FinanceDirection = (typeof FINANCE_DIRECTIONS)[number]; export const FINANCE_UNITS = [ "input_token", "output_token", "cached_input_token", "request", "credit_usd", "credit_unit", "model_unit_minute", "model_unit_hour", "gb_month", "train_token", "unknown", ] as const; export type FinanceUnit = (typeof FINANCE_UNITS)[number]; export const BUDGET_SCOPE_TYPES = ["company", "agent", "project"] as const; export type BudgetScopeType = (typeof BUDGET_SCOPE_TYPES)[number]; export const BUDGET_METRICS = ["billed_cents"] as const; export type BudgetMetric = (typeof BUDGET_METRICS)[number]; export const BUDGET_WINDOW_KINDS = ["calendar_month_utc", "lifetime"] as const; export type BudgetWindowKind = (typeof BUDGET_WINDOW_KINDS)[number]; export const BUDGET_THRESHOLD_TYPES = ["soft", "hard"] as const; export type BudgetThresholdType = (typeof BUDGET_THRESHOLD_TYPES)[number]; export const BUDGET_INCIDENT_STATUSES = ["open", "resolved", "dismissed"] as const; export type BudgetIncidentStatus = (typeof BUDGET_INCIDENT_STATUSES)[number]; export const BUDGET_INCIDENT_RESOLUTION_ACTIONS = [ "keep_paused", "raise_budget_and_resume", ] as const; export type BudgetIncidentResolutionAction = (typeof BUDGET_INCIDENT_RESOLUTION_ACTIONS)[number]; export const HEARTBEAT_INVOCATION_SOURCES = [ "timer", "assignment", "on_demand", "automation", ] as const; export type HeartbeatInvocationSource = (typeof HEARTBEAT_INVOCATION_SOURCES)[number]; export const WAKEUP_TRIGGER_DETAILS = ["manual", "ping", "callback", "system"] as const; export type WakeupTriggerDetail = (typeof WAKEUP_TRIGGER_DETAILS)[number]; export const WAKEUP_REQUEST_STATUSES = [ "queued", "deferred_issue_execution", "claimed", "coalesced", "skipped", "completed", "failed", "cancelled", ] as const; export type WakeupRequestStatus = (typeof WAKEUP_REQUEST_STATUSES)[number]; export const HEARTBEAT_RUN_STATUSES = [ "queued", "running", "succeeded", "failed", "cancelled", "timed_out", ] as const; export type HeartbeatRunStatus = (typeof HEARTBEAT_RUN_STATUSES)[number]; export const LIVE_EVENT_TYPES = [ "heartbeat.run.queued", "heartbeat.run.status", "heartbeat.run.event", "heartbeat.run.log", "agent.status", "activity.logged", "plugin.ui.updated", "plugin.worker.crashed", "plugin.worker.restarted", ] as const; export type LiveEventType = (typeof LIVE_EVENT_TYPES)[number]; export const PRINCIPAL_TYPES = ["user", "agent"] as const; export type PrincipalType = (typeof PRINCIPAL_TYPES)[number]; export const MEMBERSHIP_STATUSES = ["pending", "active", "suspended"] as const; export type MembershipStatus = (typeof MEMBERSHIP_STATUSES)[number]; export const INSTANCE_USER_ROLES = ["instance_admin"] as const; export type InstanceUserRole = (typeof INSTANCE_USER_ROLES)[number]; export const INVITE_TYPES = ["company_join", "bootstrap_ceo"] as const; export type InviteType = (typeof INVITE_TYPES)[number]; export const INVITE_JOIN_TYPES = ["human", "agent", "both"] as const; export type InviteJoinType = (typeof INVITE_JOIN_TYPES)[number]; export const JOIN_REQUEST_TYPES = ["human", "agent"] as const; export type JoinRequestType = (typeof JOIN_REQUEST_TYPES)[number]; export const JOIN_REQUEST_STATUSES = ["pending_approval", "approved", "rejected"] as const; export type JoinRequestStatus = (typeof JOIN_REQUEST_STATUSES)[number]; export const PERMISSION_KEYS = [ "agents:create", "users:invite", "users:manage_permissions", "tasks:assign", "tasks:assign_scope", "joins:approve", ] as const; export type PermissionKey = (typeof PERMISSION_KEYS)[number]; // --------------------------------------------------------------------------- // Plugin System — see doc/plugins/PLUGIN_SPEC.md for the full specification // --------------------------------------------------------------------------- /** * The current version of the Plugin API contract. * * Increment this value whenever a breaking change is made to the plugin API * so that the host can reject incompatible plugin manifests. * * @see PLUGIN_SPEC.md §4 — Versioning */ export const PLUGIN_API_VERSION = 1 as const; /** * Lifecycle statuses for an installed plugin. * * State machine: installed → ready | error, ready → disabled | error | upgrade_pending | uninstalled, * disabled → ready | uninstalled, error → ready | uninstalled, * upgrade_pending → ready | error | uninstalled, uninstalled → installed (reinstall). * * @see {@link PluginStatus} — inferred union type * @see PLUGIN_SPEC.md §21.3 `plugins.status` */ export const PLUGIN_STATUSES = [ "installed", "ready", "disabled", "error", "upgrade_pending", "uninstalled", ] as const; export type PluginStatus = (typeof PLUGIN_STATUSES)[number]; /** * Plugin classification categories. A plugin declares one or more categories * in its manifest to describe its primary purpose. * * @see PLUGIN_SPEC.md §6.2 */ export const PLUGIN_CATEGORIES = [ "connector", "workspace", "automation", "ui", ] as const; export type PluginCategory = (typeof PLUGIN_CATEGORIES)[number]; /** * Named permissions the host grants to a plugin. Plugins declare required * capabilities in their manifest; the host enforces them at runtime via the * plugin capability validator. * * Grouped into: Data Read, Data Write, Plugin State, Runtime/Integration, * Agent Tools, and UI. * * @see PLUGIN_SPEC.md §15 — Capability Model */ export const PLUGIN_CAPABILITIES = [ // Data Read "companies.read", "projects.read", "project.workspaces.read", "issues.read", "issue.comments.read", "agents.read", "goals.read", "goals.create", "goals.update", "activity.read", "costs.read", // Data Write "issues.create", "issues.update", "issue.comments.create", "agents.pause", "agents.resume", "agents.invoke", "agent.sessions.create", "agent.sessions.list", "agent.sessions.send", "agent.sessions.close", "activity.log.write", "metrics.write", // Plugin State "plugin.state.read", "plugin.state.write", // Runtime / Integration "events.subscribe", "events.emit", "jobs.schedule", "webhooks.receive", "http.outbound", "secrets.read-ref", // Agent Tools "agent.tools.register", // UI "instance.settings.register", "ui.sidebar.register", "ui.page.register", "ui.detailTab.register", "ui.dashboardWidget.register", "ui.commentAnnotation.register", "ui.action.register", ] as const; export type PluginCapability = (typeof PLUGIN_CAPABILITIES)[number]; /** * UI extension slot types. Each slot type corresponds to a mount point in the * Paperclip UI where plugin components can be rendered. * * @see PLUGIN_SPEC.md §19 — UI Extension Model */ export const PLUGIN_UI_SLOT_TYPES = [ "page", "detailTab", "taskDetailView", "dashboardWidget", "sidebar", "sidebarPanel", "projectSidebarItem", "globalToolbarButton", "toolbarButton", "contextMenuItem", "commentAnnotation", "commentContextMenuItem", "settingsPage", ] as const; export type PluginUiSlotType = (typeof PLUGIN_UI_SLOT_TYPES)[number]; /** * Reserved company-scoped route segments that plugin page routes may not claim. * * These map to first-class host pages under `/:companyPrefix/...`. */ export const PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS = [ "dashboard", "onboarding", "companies", "company", "settings", "plugins", "org", "agents", "projects", "issues", "goals", "approvals", "costs", "activity", "inbox", "design-guide", "tests", ] as const; export type PluginReservedCompanyRouteSegment = (typeof PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS)[number]; /** * Launcher placement zones describe where a plugin-owned launcher can appear * in the host UI. These are intentionally aligned with current slot surfaces * so manifest authors can describe launch intent without coupling to a single * component implementation detail. */ export const PLUGIN_LAUNCHER_PLACEMENT_ZONES = [ "page", "detailTab", "taskDetailView", "dashboardWidget", "sidebar", "sidebarPanel", "projectSidebarItem", "globalToolbarButton", "toolbarButton", "contextMenuItem", "commentAnnotation", "commentContextMenuItem", "settingsPage", ] as const; export type PluginLauncherPlacementZone = (typeof PLUGIN_LAUNCHER_PLACEMENT_ZONES)[number]; /** * Launcher action kinds describe what the launcher does when activated. */ export const PLUGIN_LAUNCHER_ACTIONS = [ "navigate", "openModal", "openDrawer", "openPopover", "performAction", "deepLink", ] as const; export type PluginLauncherAction = (typeof PLUGIN_LAUNCHER_ACTIONS)[number]; /** * Optional size hints the host can use when rendering plugin-owned launcher * destinations such as overlays, drawers, or full page handoffs. */ export const PLUGIN_LAUNCHER_BOUNDS = [ "inline", "compact", "default", "wide", "full", ] as const; export type PluginLauncherBounds = (typeof PLUGIN_LAUNCHER_BOUNDS)[number]; /** * Render environments describe the container a launcher expects after it is * activated. The current host may map these to concrete UI primitives. */ export const PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS = [ "hostInline", "hostOverlay", "hostRoute", "external", "iframe", ] as const; export type PluginLauncherRenderEnvironment = (typeof PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS)[number]; /** * Entity types that a `detailTab` UI slot can attach to. * * @see PLUGIN_SPEC.md §19.3 — Detail Tabs */ export const PLUGIN_UI_SLOT_ENTITY_TYPES = [ "project", "issue", "agent", "goal", "run", "comment", ] as const; export type PluginUiSlotEntityType = (typeof PLUGIN_UI_SLOT_ENTITY_TYPES)[number]; /** * Scope kinds for plugin state storage. Determines the granularity at which * a plugin stores key-value state data. * * @see PLUGIN_SPEC.md §21.3 `plugin_state.scope_kind` */ export const PLUGIN_STATE_SCOPE_KINDS = [ "instance", "company", "project", "project_workspace", "agent", "issue", "goal", "run", ] as const; export type PluginStateScopeKind = (typeof PLUGIN_STATE_SCOPE_KINDS)[number]; /** Statuses for a plugin's scheduled job definition. */ export const PLUGIN_JOB_STATUSES = [ "active", "paused", "failed", ] as const; export type PluginJobStatus = (typeof PLUGIN_JOB_STATUSES)[number]; /** Statuses for individual job run executions. */ export const PLUGIN_JOB_RUN_STATUSES = [ "pending", "queued", "running", "succeeded", "failed", "cancelled", ] as const; export type PluginJobRunStatus = (typeof PLUGIN_JOB_RUN_STATUSES)[number]; /** What triggered a particular job run. */ export const PLUGIN_JOB_RUN_TRIGGERS = [ "schedule", "manual", "retry", ] as const; export type PluginJobRunTrigger = (typeof PLUGIN_JOB_RUN_TRIGGERS)[number]; /** Statuses for inbound webhook deliveries. */ export const PLUGIN_WEBHOOK_DELIVERY_STATUSES = [ "pending", "success", "failed", ] as const; export type PluginWebhookDeliveryStatus = (typeof PLUGIN_WEBHOOK_DELIVERY_STATUSES)[number]; /** * Core domain event types that plugins can subscribe to via the * `events.subscribe` capability. * * @see PLUGIN_SPEC.md §16 — Event System */ export const PLUGIN_EVENT_TYPES = [ "company.created", "company.updated", "project.created", "project.updated", "project.workspace_created", "project.workspace_updated", "project.workspace_deleted", "issue.created", "issue.updated", "issue.comment.created", "agent.created", "agent.updated", "agent.status_changed", "agent.run.started", "agent.run.finished", "agent.run.failed", "agent.run.cancelled", "goal.created", "goal.updated", "approval.created", "approval.decided", "cost_event.created", "activity.logged", ] as const; export type PluginEventType = (typeof PLUGIN_EVENT_TYPES)[number]; /** * Error codes returned by the plugin bridge when a UI → worker call fails. * * @see PLUGIN_SPEC.md §19.7 — Error Propagation Through The Bridge */ export const PLUGIN_BRIDGE_ERROR_CODES = [ "WORKER_UNAVAILABLE", "CAPABILITY_DENIED", "WORKER_ERROR", "TIMEOUT", "UNKNOWN", ] as const; export type PluginBridgeErrorCode = (typeof PLUGIN_BRIDGE_ERROR_CODES)[number];