/** * Crewly Cross-Domain Constants * * This file contains constants shared across all Crewly domains: * - Backend (Express.js server) * - Frontend (React application) * - CLI (Command-line interface) * - MCP Server (Model Context Protocol server) * * Domain-specific constants should remain in their respective constants.ts files. */ /** * Crewly core system identifiers and names */ export declare const CREWLY_CONSTANTS: { /** * Session and orchestrator configuration */ readonly SESSIONS: { /** Default orchestrator session name used across all domains */ readonly ORCHESTRATOR_NAME: "crewly-orc"; /** Default timeout for agent initialization (2 minutes) */ readonly DEFAULT_TIMEOUT: 120000; /** Interval for checking agent registration status (5 seconds) */ readonly REGISTRATION_CHECK_INTERVAL: 5000; /** Cache timeout for Claude detection (30 seconds) */ readonly CLAUDE_DETECTION_CACHE_TIMEOUT: 30000; /** Default shell for terminal sessions, /bin/bash, /bin/zsh */ readonly DEFAULT_SHELL: "/bin/bash"; }; /** * File system paths and directory structure */ readonly PATHS: { /** Crewly home directory name */ readonly CREWLY_HOME: ".crewly"; /** Teams configuration file */ readonly TEAMS_FILE: "teams.json"; /** Projects configuration file */ readonly PROJECTS_FILE: "projects.json"; /** Runtime state file */ readonly RUNTIME_FILE: "runtime.json"; /** Scheduled messages file */ readonly SCHEDULED_MESSAGES_FILE: "scheduled-messages.json"; /** Message delivery logs file */ readonly MESSAGE_DELIVERY_LOGS_FILE: "message-delivery-logs.json"; /** Configuration directory */ readonly CONFIG_DIR: "config"; /** System prompts directory */ readonly PROMPTS_DIR: "prompts"; /** Tasks directory */ readonly TASKS_DIR: "tasks"; /** Specifications directory */ readonly SPECS_DIR: "specs"; /** Agent memory directory */ readonly MEMORY_DIR: "memory"; /** Knowledge documents directory */ readonly DOCS_DIR: "docs"; /** Knowledge documents index file */ readonly DOCS_INDEX_FILE: "docs-index.json"; /** Server logs directory */ readonly LOGS_DIR: "logs"; /** Session PTY logs subdirectory (under LOGS_DIR) */ readonly SESSION_LOGS_DIR: "sessions"; /** Bug reports directory */ readonly BUG_REPORTS_DIR: "bug-reports"; /** Skills directory (under CREWLY_HOME) */ readonly SKILLS_DIR: "skills"; /** Agent skills catalog file (under SKILLS_DIR) */ readonly SKILLS_CATALOG_FILE: "AGENT_SKILLS_CATALOG.md"; }; /** * Agent status enumeration - represents agent lifecycle states * Lifecycle: inactive -> starting -> started -> active */ readonly AGENT_STATUSES: { /** Agent is not running or has been stopped */ readonly INACTIVE: "inactive"; /** Terminal/PTY session is being created */ readonly STARTING: "starting"; /** Runtime (Claude Code, etc.) is running but agent hasn't registered yet */ readonly STARTED: "started"; /** Agent has registered and is fully operational */ readonly ACTIVE: "active"; /** Agent was active but has been suspended to free resources (idle timeout) */ readonly SUSPENDED: "suspended"; /** @deprecated Use STARTING instead - kept for backward compatibility */ readonly ACTIVATING: "activating"; }; /** * Working status enumeration - represents current agent activity */ readonly WORKING_STATUSES: { /** Agent is idle and available for tasks */ readonly IDLE: "idle"; /** Agent is currently processing a task */ readonly IN_PROGRESS: "in_progress"; }; /** * Agent roles available in the system */ readonly ROLES: { /** System orchestrator - coordinates all activities */ readonly ORCHESTRATOR: "orchestrator"; /** Project manager - handles project-level coordination */ readonly PROJECT_MANAGER: "pm"; /** Technical project manager - technical leadership */ readonly TECH_LEAD: "tpm"; /** Software developer - implements features */ readonly DEVELOPER: "developer"; /** Quality assurance engineer - testing and validation */ readonly QA: "qa"; /** DevOps engineer - deployment and infrastructure */ readonly DEVOPS: "devops"; }; /** * Special agent identifiers for system-level agents */ readonly AGENT_IDS: { /** Orchestrator agent identifier - used in teamAgentStatus.json */ readonly ORCHESTRATOR_ID: "orchestrator"; }; /** * Human-readable role display names */ readonly ROLE_DISPLAY_NAMES: { readonly orchestrator: "Orchestrator"; readonly pm: "Project Manager"; readonly tpm: "Technical Project Manager"; readonly developer: "Developer"; readonly qa: "Quality Assurance"; readonly devops: "DevOps Engineer"; }; /** * Orchestrator-specific configuration */ readonly ORCHESTRATOR: { /** Display name for the orchestrator role */ readonly DISPLAY_NAME: "Orchestrator"; /** Default orchestrator window name */ readonly WINDOW_NAME: "Crewly Orchestrator"; /** Crewly session name prefix pattern */ readonly SESSION_PREFIX: "crewly_"; }; }; /** * Convenient agent identity references combining multiple constants */ export declare const AGENT_IDENTITY_CONSTANTS: { /** * Orchestrator agent identity - combines ID, session name, and role */ readonly ORCHESTRATOR: { /** Agent identifier used in teamAgentStatus.json */ readonly ID: "orchestrator"; /** PTY session name */ readonly SESSION_NAME: "crewly-orc"; /** Agent role */ readonly ROLE: "orchestrator"; }; }; /** * Process exit codes used for inter-process communication between the CLI * parent process and the backend child process. */ export declare const PROCESS_EXIT_CODES: { /** Normal shutdown — do not respawn */ readonly SUCCESS: 0; /** Error — do not respawn */ readonly ERROR: 1; /** Graceful restart requested — CLI should respawn the backend */ readonly RESTART_REQUESTED: 120; }; /** * Safe-restart budget shared by the backend (which drains in-flight agent * turns on SIGTERM/SIGINT) and every supervisor that stops it (CLI `start` * parent, `crewly stop`, `crewly service`, the systemd unit). A supervisor * that escalates to SIGKILL sooner than the drain plus a margin would cut * off the very turns the drain is waiting for. */ export declare const SAFE_RESTART_CONSTANTS: { /** Default time the backend waits for agents to finish their current turn (ms) */ readonly DRAIN_TIMEOUT_MS: 120000; /** Env var overriding DRAIN_TIMEOUT_MS; `0` disables the wait */ readonly DRAIN_ENV_VAR: "CREWLY_RESTART_DRAIN_MS"; /** * Hard cap on the drain while an agent it waits on has a tool call or a * subagent / background task still running (ms). Such work routinely * outlasts DRAIN_TIMEOUT_MS (2026-10-02, Eve). */ readonly BACKGROUND_DRAIN_TIMEOUT_MS: 600000; /** Env var overriding BACKGROUND_DRAIN_TIMEOUT_MS */ readonly BACKGROUND_DRAIN_ENV_VAR: "CREWLY_RESTART_DRAIN_BACKGROUND_MS"; /** * Time allowed after the drain for the rest of the shutdown (session state * save, PTY teardown, queue flush) before a supervisor may SIGKILL (ms). * Must exceed the backend's own post-drain force-exit timer (10s). */ readonly SHUTDOWN_MARGIN_MS: 30000; /** Two signals closer together than this count as one (tty process-group delivery) */ readonly SIGNAL_DEDUP_WINDOW_MS: 1000; /** REST path an operator (or the CLI) polls before restarting */ readonly READINESS_ENDPOINT: "/api/system/restart-readiness"; /** * Shutdown marker: `/run/shutdown-requested`. Written when the * owner shuts Crewly down (not restarts it). A supervisor that relaunches * Crewly on exit (the macOS `crewly-start.command` loop) checks it first * and stays down; `crewly start` and a fresh supervisor launch clear it. */ readonly SHUTDOWN_MARKER_DIR: "run"; /** File name of the shutdown marker inside SHUTDOWN_MARKER_DIR */ readonly SHUTDOWN_MARKER_FILE: "shutdown-requested"; /** Wind-down grace before a restart, when the request names none (seconds) */ readonly WIND_DOWN_RESTART_GRACE_SECONDS: 180; /** Wind-down grace before a shutdown, when the request names none (seconds) */ readonly WIND_DOWN_SHUTDOWN_GRACE_SECONDS: 300; /** Longest wind-down grace a request may ask for (seconds) */ readonly WIND_DOWN_MAX_GRACE_SECONDS: 900; /** How often the wind-down re-checks which agents are still busy (ms) */ readonly WIND_DOWN_POLL_MS: 2000; /** Tag at the start of the harness note agents receive */ readonly WIND_DOWN_TAG: "[Crewly wind-down]"; }; /** * Web server and API configuration */ export declare const WEB_CONSTANTS: { /** * Default server ports */ readonly PORTS: { /** Backend API server default port */ readonly BACKEND: 8787; /** Frontend development server default port */ readonly FRONTEND: 8788; }; /** * API endpoint paths */ readonly ENDPOINTS: { /** Health check endpoint */ readonly HEALTH: "/health"; /** Base API path */ readonly API_BASE: "/api"; /** Teams management endpoints */ readonly TEAMS: "/api/teams"; /** Projects management endpoints */ readonly PROJECTS: "/api/projects"; /** Orchestrator control endpoints */ readonly ORCHESTRATOR: "/api/orchestrator"; /** Terminal operations endpoints */ readonly TERMINAL: "/api/terminal"; /** Live agent sessions (PTY): name, pid, cwd */ readonly SESSIONS: "/api/sessions"; /** Live terminal sessions including in-process (no PTY) agents */ readonly TERMINAL_SESSIONS: "/api/terminal/sessions"; /** Task management endpoints */ readonly TASKS: "/api/tasks"; /** Factory SSE endpoint */ readonly FACTORY_SSE: "/api/factory/sse"; }; /** * SSE (Server-Sent Events) configuration */ readonly SSE: { /** Backend polling interval in milliseconds (3 seconds) */ readonly POLL_INTERVAL: 3000; /** Heartbeat interval in milliseconds (30 seconds) */ readonly HEARTBEAT_INTERVAL: 30000; /** Maximum reconnection attempts before fallback to polling */ readonly MAX_RECONNECT_ATTEMPTS: 5; /** Base delay between reconnection attempts (1 second) */ readonly BASE_RECONNECT_DELAY: 1000; /** Maximum reconnection delay (30 seconds) */ readonly MAX_RECONNECT_DELAY: 30000; /** Fallback polling interval when SSE fails (5 seconds) */ readonly FALLBACK_POLL_INTERVAL: 5000; }; }; /** * Network exposure + API token authentication for the OSS server. * * The REST API and WebSocket endpoints are open to loopback callers (local * skills, the local dashboard) and require a shared API token from every * other address. See README "Securing a server install". */ export declare const API_SECURITY_CONSTANTS: { /** Environment variable names */ readonly ENV: { /** Host/interface the HTTP server binds to (default: all interfaces) */ readonly BIND_HOST: "CREWLY_BIND_HOST"; /** Pinned API token; when unset one is generated on first boot */ readonly API_TOKEN: "CREWLY_API_TOKEN"; /** Set to `1` to honour `X-Forwarded-For` when classifying loopback callers */ readonly TRUST_PROXY: "CREWLY_TRUST_PROXY"; /** Set to `1`/`true` to force headless (no display) detection */ readonly HEADLESS: "CREWLY_HEADLESS"; /** * Set to `1`/`true` to keep `GET /health` open to non-loopback callers * without the API token (#825). For deployments that monitor /health * from another machine or through a public reverse proxy. */ readonly PUBLIC_HEALTH: "CREWLY_PUBLIC_HEALTH"; }; /** * Backend-only secrets that agent PTYs must not inherit from the backend's * process.env. No agent, skill or runtime reads them (the Slack bridge runs * in the backend), and an agent that runs `env` would print them into * scrollback and its session log. */ readonly AGENT_ENV_DENYLIST: readonly string[]; /** Default bind host — every interface, for backward compatibility */ readonly DEFAULT_BIND_HOST: "0.0.0.0"; /** Loopback-only bind host suggested in the startup warning */ readonly LOOPBACK_BIND_HOST: "127.0.0.1"; /** File (relative to CREWLY_HOME) holding the generated API token */ readonly TOKEN_FILE_NAME: "api-token"; /** Random bytes in a generated token (hex-encoded → 64 chars) */ readonly TOKEN_BYTES: 32; /** POSIX mode for the token file (owner read/write only) */ readonly TOKEN_FILE_MODE: 384; /** Hex characters of sha256(token) recorded for audit purposes */ readonly FINGERPRINT_HEX_LENGTH: 8; /** Request header carrying the token */ readonly TOKEN_HEADER: "x-crewly-token"; /** Cookie name carrying the token (lets ``/asset/WS requests pass) */ readonly TOKEN_COOKIE: "crewly_token"; /** Query-string parameter carrying the token (WebSocket + dashboard deep link) */ readonly TOKEN_QUERY_PARAM: "token"; /** localStorage key the dashboard stores the token under */ readonly TOKEN_STORAGE_KEY: "crewly_api_token"; /** `WWW-Authenticate` scheme advertised on 401 so clients can detect the challenge */ readonly AUTH_SCHEME: "Crewly-Token"; /** Error codes returned in `{ success: false, error }` */ readonly ERRORS: { readonly UNAUTHORIZED: "unauthorized"; readonly OWNER_APPROVAL_REQUIRED: "owner_approval_required"; }; /** Actor recorded on approvals performed with the owner token */ readonly OWNER_ACTOR: "owner"; /** * Header the dashboard sets on owner-initiated actions (e.g. the per-member * Start button). Paired with the ABSENCE of `X-Agent-Session`, it marks a * request as a human action rather than an agent skill or an internal * server-to-server call, which send neither (issue #775). */ readonly CALLER_HEADER: "x-crewly-caller"; /** Value of {@link CALLER_HEADER} sent by the dashboard. */ readonly DASHBOARD_CALLER: "dashboard"; /** Header skills send to identify the calling agent session. */ readonly AGENT_SESSION_HEADER: "x-agent-session"; /** Legacy alias of {@link AGENT_SESSION_HEADER} still accepted by the backend. */ readonly AGENT_SESSION_HEADER_LEGACY: "x-crewly-agent-session"; /** Hint appended to 401 responses */ readonly UNAUTHORIZED_HINT: "Non-loopback callers must send the API token: `Authorization: Bearer `, `X-Crewly-Token: ` or a `crewly_token` cookie. Run `crewly token` on the server to print it."; /** Loopback addresses that bypass token auth */ readonly LOOPBACK_ADDRESSES: readonly ["127.0.0.1", "::1", "::ffff:127.0.0.1"]; }; /** * Owner authentication (#999, specs/2026-10-03-owner-auth.md). * * Who a caller is comes from credentials, never from a missing header: * - agents carry a per-session **agent badge** minted by the harness at launch; * - the dashboard holds an owner session cookie plus a CSRF token; * - the phone / portal relay and Cloud-forwarded Slack envelopes carry an * in-memory internal credential; * - remote dashboards, the phone on the LAN and the CLI present the owner API token. */ export declare const OWNER_AUTH_CONSTANTS: { /** * Environment variable holding the agent badge in every agent process. * Deliberately free of TOKEN / KEY / SECRET: Codex's default * `shell_environment_policy` strips variables whose names contain those * words from the shells it runs, so the skills would never see it. */ readonly AGENT_BADGE_ENV: "CREWLY_AGENT_BADGE"; /** Request header carrying the agent badge */ readonly AGENT_BADGE_HEADER: "x-agent-badge"; /** Version prefix of a badge (`cab1..`) */ readonly AGENT_BADGE_PREFIX: "cab1"; /** Owner session cookie name prefix; the backend port is appended (cookies ignore ports) */ readonly OWNER_SESSION_COOKIE_PREFIX: "crewly_owner_"; /** Version prefix of an owner session value */ readonly OWNER_SESSION_PREFIX: "cos1"; /** Lifetime of an owner session cookie (seconds). The signing secret is in memory, so a restart ends it sooner. */ readonly OWNER_SESSION_MAX_AGE_S: number; /** Header the dashboard sends the CSRF token in on every write */ readonly CSRF_HEADER: "x-crewly-csrf"; /** Header carrying the in-memory internal credential (relay / cloud) */ readonly INTERNAL_HEADER: "x-crewly-internal"; /** Header naming the scheduled command that sends (validated; shown as `scheduler:`) */ readonly SCHEDULER_NAME_HEADER: "x-crewly-scheduler"; /** Env var that carries the scheduler credential into a scheduled command's process */ readonly SCHEDULER_CREDENTIAL_ENV: "CREWLY_SCHEDULER_CREDENTIAL"; /** Env var that carries the scheduled command's entry name */ readonly SCHEDULER_NAME_ENV: "CREWLY_SCHEDULER_NAME"; /** Sender label prefix on a message a scheduled command delivers */ readonly SCHEDULER_SENDER_PREFIX: "scheduler:"; /** Path (under `/api`) that issues the owner session and returns the CSRF token */ readonly SESSION_ROUTE: "/auth/session"; /** HTTP methods that change state and therefore need CSRF / a header-borne token */ readonly MUTATING_METHODS: readonly string[]; /** * What a browser without a session (a dashboard tab opened before the * upgrade) is told in the 401's `error`, which that old tab shows as is. */ readonly RELOAD_MESSAGE: "Reload this page — Crewly was updated."; /** Response header naming the dashboard build the backend serves (its hashed entry script) */ readonly BUILD_HEADER: "x-crewly-dashboard-build"; /** socket.io event announcing the served dashboard build on each connection */ readonly BUILD_EVENT: "dashboard_build"; /** Error codes in `{ success: false, error }` */ readonly ERRORS: { /** No owner credential (401). The dashboard refreshes its session and retries once. */ readonly OWNER_AUTH_REQUIRED: "owner_auth_required"; /** An agent called an owner-only route (403) */ readonly OWNER_ONLY: "owner_only"; /** An agent without a valid badge (legacy header only) asked for something only a badge unlocks (403) */ readonly AGENT_BADGE_REQUIRED: "agent_badge_required"; /** A scheduled command asked for anything but a plain message to an agent (403) */ readonly SCHEDULER_MESSAGE_ONLY: "scheduler_message_only"; }; /** Give up looking up a local client's process after this long (fail open) */ readonly PEER_LOOKUP_TIMEOUT_MS: 3000; /** Longest parent chain walked from a client process */ readonly PEER_MAX_ANCESTRY_DEPTH: 64; /** `X-Agent-Session` without a badge (migration window) is logged at most this often per session */ readonly LEGACY_WARN_THROTTLE_MS: number; }; /** * Timing and interval configurations used across domains */ export declare const TIMING_CONSTANTS: { /** * Retry and timeout configurations */ readonly RETRIES: { /** Maximum retry attempts for failed operations */ readonly MAX_ATTEMPTS: 3; /** Base delay between retries (1 second) */ readonly BASE_DELAY: 1000; /** Maximum delay between retries (10 seconds) */ readonly MAX_DELAY: 10000; }; /** * Polling and monitoring intervals */ readonly INTERVALS: { /** Health check interval (30 seconds) */ readonly HEALTH_CHECK: 30000; /** Memory cleanup interval (5 minutes) */ readonly MEMORY_CLEANUP: number; /** Status update interval (10 seconds) */ readonly STATUS_UPDATE: 10000; /** Activity monitoring interval (15 seconds) */ readonly ACTIVITY_MONITOR: 15000; /** General cleanup interval (1 minute) */ readonly CLEANUP: 60000; /** Batch operation delay (500ms) */ readonly BATCH_DELAY: 500; /** Rate limit window for short bursts (1 second) */ readonly RATE_LIMIT_WINDOW: 1000; /** Task cleanup interval (5 minutes) */ readonly TASK_CLEANUP: 300000; }; /** * Timeout values for various operations */ readonly TIMEOUTS: { /** Claude initialization timeout (45 seconds) */ readonly CLAUDE_INIT: 45000; /** Agent setup timeout (90 seconds) */ readonly AGENT_SETUP: 90000; /** Task completion timeout (5 minutes) */ readonly TASK_COMPLETION: number; /** WebSocket connection timeout (30 seconds) */ readonly WEBSOCKET: 30000; /** Orchestrator setup timeout (30 seconds) */ readonly ORCHESTRATOR_SETUP: 30000; /** Task monitoring and polling intervals (2 seconds) */ readonly TASK_MONITOR_POLL: 2000; /** Health check timeout for individual checks (1 second) */ readonly HEALTH_CHECK_TIMEOUT: 1000; /** HTTP health check timeout for CLI commands (3 seconds) */ readonly HTTP_HEALTH_CHECK: 3000; /** API request timeout for quick calls (2 seconds) */ readonly API_REQUEST_QUICK: 2000; /** Shutdown wait timeout (2 seconds) */ readonly SHUTDOWN: 2000; /** Connection timeout for network requests (10 seconds) */ readonly CONNECTION: 10000; /** Agent default timeout for operations (5 minutes) */ readonly AGENT_DEFAULT: 300000; /** Context refresh interval (30 minutes) */ readonly CONTEXT_REFRESH: 1800000; /** WebSocket ping timeout (60 seconds) */ readonly WS_PING: 60000; /** WebSocket ping interval (25 seconds) */ readonly WS_PING_INTERVAL: 25000; /** Backup interval (1 hour) */ readonly BACKUP: 3600000; /** Rate limit window (15 minutes) */ readonly RATE_LIMIT_WINDOW: 900000; /** Command timestamp offset (5 minutes) */ readonly COMMAND_TIMESTAMP_OFFSET: 300000; /** Command timestamp offset long (10 minutes) */ readonly COMMAND_TIMESTAMP_OFFSET_LONG: 600000; }; }; /** * Message handling and communication constants */ export declare const MESSAGE_CONSTANTS: { /** * Message size and chunking limits */ readonly LIMITS: { /** Maximum message size before chunking (1500 characters) */ readonly CHUNK_SIZE: 1500; /** Small chunk size to avoid paste detection (200 characters) */ readonly SMALL_CHUNK_SIZE: 200; /** Maximum output buffer size for streaming */ readonly MAX_BUFFER_SIZE: 100; }; /** * Message types and categories */ readonly TYPES: { /** System-generated status messages */ readonly SYSTEM: "system"; /** User-initiated messages */ readonly USER: "user"; /** Agent-to-agent communications */ readonly AGENT: "agent"; /** Error and warning messages */ readonly ERROR: "error"; /** Broadcast messages to all agents */ readonly BROADCAST: "broadcast"; }; }; /** * Environment variable names used across domains */ export declare const ENV_CONSTANTS: { /** PTY session name used for agent identity and heartbeat tracking */ readonly CREWLY_SESSION_NAME: "CREWLY_SESSION_NAME"; /** Crewly role identifier */ readonly CREWLY_ROLE: "CREWLY_ROLE"; /** API server port */ readonly API_PORT: "API_PORT"; /** MCP server port */ readonly MCP_PORT: "CREWLY_MCP_PORT"; /** Project path */ readonly PROJECT_PATH: "PROJECT_PATH"; /** Agent role */ readonly AGENT_ROLE: "AGENT_ROLE"; /** Node environment */ readonly NODE_ENV: "NODE_ENV"; /** Development mode flag */ readonly DEV_MODE: "DEV_MODE"; }; /** * Backend-specific configuration constants * These constants are primarily used by the Express.js backend server */ export declare const BACKEND_CONSTANTS: { /** * File names and configurations */ readonly FILES: { /** Active projects tracking file name */ readonly ACTIVE_PROJECTS_FILE: "active_projects.json"; /** Task tracking file name */ readonly TASK_TRACKING_FILE: "in_progress_tasks.json"; /** Communication log file name */ readonly COMMUNICATION_LOG_FILE: "communication.log"; /** Configuration file names */ readonly CONFIG_FILE_NAMES: { readonly CONFIG_JSON: "config.json"; readonly APP_JSON: "app.json"; }; /** Log file naming patterns */ readonly LOG_FILE_PREFIX: "crewly-"; readonly LOG_FILE_EXTENSION: ".log"; }; /** * Additional directory names not covered in CREWLY_CONSTANTS.PATHS */ readonly ADDITIONAL_DIRS: { readonly LOGS: "logs"; readonly DATA: "data"; }; /** * HTTP and network configuration */ readonly NETWORK: { /** Default CORS origin */ readonly DEFAULT_CORS_ORIGIN: "http://localhost:8788"; /** Allowed HTTP methods */ readonly ALLOWED_HTTP_METHODS: readonly ["GET", "POST"]; /** HTTP status codes used in the application */ readonly HTTP_STATUS_CODES: { readonly OK: 200; readonly CREATED: 201; readonly BAD_REQUEST: 400; readonly NOT_FOUND: 404; readonly INTERNAL_SERVER_ERROR: 500; readonly SERVICE_UNAVAILABLE: 503; }; /** Maximum request body size (10MB) */ readonly MAX_REQUEST_BODY_SIZE: "10mb"; }; /** * API endpoint paths */ readonly API_ENDPOINTS: { readonly ORCHESTRATOR_SETUP: "/api/orchestrator/setup"; readonly TEAMS: "/api/teams"; readonly TEAM_START: "/api/teams/:id/start"; readonly HEALTH: "/health"; readonly API_BASE: "/api"; readonly PROJECTS: "/projects"; readonly MONITORING: "/monitoring"; readonly SYSTEM: "/system"; }; /** * Orchestrator command identifiers */ readonly ORCHESTRATOR_COMMANDS: { readonly GET_TEAM_STATUS: "get_team_status"; readonly LIST_PROJECTS: "list_projects"; readonly LIST_SESSIONS: "list_sessions"; readonly BROADCAST: "broadcast"; readonly HELP: "help"; }; /** * Session command templates (legacy - PTY backend now used) */ readonly SESSION_COMMANDS: { /** @deprecated PTY backend now manages sessions internally */ readonly LIST_SESSIONS: ""; }; /** * Special key names */ readonly SPECIAL_KEYS: { readonly ENTER: "Enter"; readonly CTRL_C: "C-c"; }; /** * Initialization script file names */ readonly INIT_SCRIPTS: { readonly CLAUDE: "initialize_claude.sh"; }; /** * Size and limit constants */ readonly LIMITS: { /** Maximum file size for context loading (1MB) */ readonly MAX_CONTEXT_FILE_SIZE_BYTES: 1048576; /** Default log entry limit */ readonly DEFAULT_LOG_LIMIT: 100; /** Maximum concurrent monitoring jobs */ readonly MAX_CONCURRENT_MONITORING_JOBS: 10; /** Default log file size limit */ readonly DEFAULT_LOG_FILE_SIZE: "10m"; }; /** * Frontend build directory path (relative to backend) */ readonly FRONTEND_DIST_PATH: "../../frontend/dist"; /** * Additional environment variable names */ readonly ADDITIONAL_ENV_VARS: { readonly WEB_PORT: "WEB_PORT"; readonly DEFAULT_CHECK_INTERVAL: "DEFAULT_CHECK_INTERVAL"; readonly AUTO_COMMIT_INTERVAL: "AUTO_COMMIT_INTERVAL"; readonly CREWLY_HOME: "CREWLY_HOME"; }; /** * Orchestrator help text */ readonly ORCHESTRATOR_HELP_TEXT: string; }; /** * Memory system configuration for the two-level memory architecture * Agent-level: ~/.crewly/agents/{agentId}/ * Project-level: project/.crewly/knowledge/ */ export declare const MEMORY_CONSTANTS: { /** * Storage paths for memory files */ readonly PATHS: { /** Agent memory directory (relative to CREWLY_HOME) */ readonly AGENTS_DIR: "agents"; /** Project knowledge directory (relative to project .crewly) */ readonly KNOWLEDGE_DIR: "knowledge"; /** Agent session archives directory name (under agent dir) */ readonly SESSIONS_DIR: "sessions"; /** Latest session summary file name */ readonly LATEST_SUMMARY: "latest-summary.md"; /** Daily log directory (under project .crewly) */ readonly DAILY_LOG_DIR: "logs/daily"; /** Goals directory (under project .crewly) */ readonly GOALS_DIR: "goals"; /** Goals file */ readonly GOALS_FILE: "goals.md"; /** Current focus file */ readonly FOCUS_FILE: "current_focus.md"; /** Decisions log file (with retrospective outcomes) */ readonly DECISIONS_LOG: "decisions_log.md"; /** Learning accumulation directory (under project .crewly) */ readonly LEARNING_DIR: "learning"; /** What worked file */ readonly WHAT_WORKED_FILE: "what_worked.md"; /** What failed file */ readonly WHAT_FAILED_FILE: "what_failed.md"; /** Global learning directory (under CREWLY_HOME) */ readonly GLOBAL_LEARNING_DIR: "learning"; /** Cross-project insights file */ readonly CROSS_PROJECT_INSIGHTS: "cross_project_insights.md"; /** Agents index file (under project .crewly) */ readonly AGENTS_INDEX: "agents-index.json"; }; /** * File names for agent-level memory */ readonly AGENT_FILES: { /** Main memory file */ readonly MEMORY: "memory.json"; /** Detailed role knowledge entries */ readonly ROLE_KNOWLEDGE: "role-knowledge.json"; /** Agent preferences */ readonly PREFERENCES: "preferences.json"; /** Performance metrics */ readonly PERFORMANCE: "performance.json"; /** Custom SOPs directory */ readonly SOP_CUSTOM_DIR: "sop-custom"; }; /** * File names for project-level memory */ readonly PROJECT_FILES: { /** Main index file */ readonly INDEX: "index.json"; /** Pattern entries */ readonly PATTERNS: "patterns.json"; /** Decision entries */ readonly DECISIONS: "decisions.json"; /** Gotcha entries */ readonly GOTCHAS: "gotchas.json"; /** Relationship entries */ readonly RELATIONSHIPS: "relationships.json"; /** Completed-task ledger (TaskHistoryEntry[]) */ readonly TASK_HISTORY: "task-history.json"; /** Human-readable learnings log */ readonly LEARNINGS: "learnings.md"; /** Archive directory (under knowledge/) for entries moved out of long-term memory */ readonly ARCHIVE_DIR: "archive"; /** Archived task-completion decisions (JSON array, #833) */ readonly ARCHIVED_TASK_DECISIONS: "task-completion-decisions.json"; /** Archived task-completion learnings (markdown, #833) */ readonly ARCHIVED_TASK_LEARNINGS: "task-completion-learnings.md"; }; /** * Task-completion summaries are episodic task logs, not durable knowledge * (#833). They live on the WorkItem and in task-history.json; these * patterns identify them so they are never written to — and are migrated * out of — decisions, learnings and role knowledge. */ readonly TASK_LOG: { /** Entry id returned by remember() when a task log is dropped instead of stored */ readonly SKIPPED_ENTRY_ID: "skipped-task-log"; /** * Wrappers that other writers put around the summary before it is * stored (decision → learning mirror, agent-scope coercion). */ readonly WRAPPER_PREFIXES: readonly [RegExp, RegExp]; /** * The summary itself, as written by the complete-task and report-status * skills (current and older versions). */ readonly CONTENT_PATTERNS: readonly [RegExp, RegExp]; }; /** * Storage limits to keep memory files performant */ readonly LIMITS: { /** Maximum entries per category in agent memory */ readonly MAX_ROLE_KNOWLEDGE_ENTRIES: 500; /** Maximum entries per category in project memory */ readonly MAX_PATTERN_ENTRIES: 200; readonly MAX_DECISION_ENTRIES: 100; readonly MAX_GOTCHA_ENTRIES: 200; readonly MAX_RELATIONSHIP_ENTRIES: 500; /** Maximum file size in bytes (1MB) */ readonly MAX_FILE_SIZE_BYTES: 1048576; /** Maximum entries returned in a single query */ readonly MAX_QUERY_RESULTS: 50; /** Minimum confidence to retain during pruning (0-1) */ readonly MIN_CONFIDENCE_THRESHOLD: 0.2; /** Days before low-confidence entries are pruned */ readonly PRUNE_AFTER_DAYS: 90; }; /** * Default values for memory entries */ readonly DEFAULTS: { /** Default confidence for new knowledge entries */ readonly INITIAL_CONFIDENCE: 0.5; /** Confidence increase when knowledge is reinforced */ readonly CONFIDENCE_REINFORCEMENT: 0.1; /** Maximum confidence value */ readonly MAX_CONFIDENCE: 1; /** Minimum confidence value */ readonly MIN_CONFIDENCE: 0; }; /** * Near-duplicate detection on write (#914 P1): a new role-knowledge entry * close enough to an existing one in the same scope merges its evidence * into it instead of being added. */ readonly DEDUP: { /** * Token-set Jaccard at or above which two entries are one fact restated * (numbers must agree, see knowledge-similarity). Set by replaying 3.7k * real entries (2026-10-25): at 0.8 the matches are the same claim with * another id, a re-check of the same item, or a correction of the same * assertion (166 entries, 4.5%); from 0.7 down, different items that * share a sentence frame ("Schedule X stops after 3 more runs" / "Schedule * Y stops …") start to collide. */ readonly NEAR_DUPLICATE_JACCARD: 0.8; /** Fewer tokens than this and only an exact match counts (short texts overlap by chance) */ readonly MIN_TOKENS_FOR_NEAR: 4; /** The legacy containment rule applies only to incoming texts longer than this */ readonly SUBSTRING_MIN_CHARS: 20; }; /** * Schema versioning for migrations */ readonly SCHEMA: { /** Current schema version */ readonly CURRENT_VERSION: 1; /** Minimum supported schema version */ readonly MIN_SUPPORTED_VERSION: 1; }; /** * Memory categories */ readonly CATEGORIES: { /** Role knowledge categories */ readonly ROLE_KNOWLEDGE: readonly ["best-practice", "anti-pattern", "tool-usage", "workflow"]; /** Pattern categories */ readonly PATTERN: readonly ["api", "component", "service", "testing", "styling", "database", "config", "other"]; /** Gotcha severity levels */ readonly GOTCHA_SEVERITY: readonly ["low", "medium", "high", "critical"]; /** Learning categories */ readonly LEARNING: readonly ["pattern", "decision", "gotcha", "insight", "improvement"]; /** Relationship types */ readonly RELATIONSHIP: readonly ["depends-on", "uses", "extends", "implements", "calls", "imported-by"]; }; }; /** * Continuation system configuration for automatic agent continuation */ export declare const CONTINUATION_CONSTANTS: { /** * Detection thresholds */ readonly DETECTION: { /** Number of idle poll cycles before triggering continuation check */ readonly IDLE_CYCLES_BEFORE_CHECK: 2; /** Minutes without MCP calls before heartbeat is considered stale */ readonly STALE_THRESHOLD_MINUTES: 20; /** Milliseconds between activity poll checks */ readonly ACTIVITY_POLL_INTERVAL_MS: 120000; }; /** * Event handling configuration */ readonly EVENTS: { /** Debounce time for events (ms) */ readonly DEBOUNCE_MS: 5000; /** Deduplication window (ms) */ readonly DEDUP_WINDOW_MS: 10000; /** Cleanup interval for recent events (ms) */ readonly CLEANUP_INTERVAL_MS: 60000; }; /** * Iteration limits */ readonly ITERATIONS: { /** Default maximum iterations per task */ readonly DEFAULT_MAX: 10; /** Absolute maximum iterations (hard limit) */ readonly ABSOLUTE_MAX: 50; /** Warning threshold (percentage of max) */ readonly WARNING_THRESHOLD: 0.8; }; /** * Timeouts */ readonly TIMEOUTS: { /** Timeout for output analysis (ms) */ readonly ANALYSIS_MS: 10000; /** Timeout for action execution (ms) */ readonly ACTION_MS: 30000; /** Timeout for prompt injection (ms) */ readonly PROMPT_INJECTION_MS: 15000; }; /** * Output analysis patterns */ readonly PATTERNS: { /** Patterns indicating task completion */ readonly COMPLETION: readonly ["task completed", "task done", "successfully completed", "implementation complete", "all tests pass", "ready for review"]; /** Patterns indicating agent is waiting */ readonly WAITING: readonly ["waiting for", "awaiting", "blocked by", "need input", "please provide", "let me know"]; /** Patterns indicating errors */ readonly ERROR: readonly ["error:", "failed:", "exception:", "cannot", "unable to", "permission denied"]; }; /** * Confidence thresholds for analysis */ readonly CONFIDENCE: { /** Minimum confidence to take action */ readonly ACTION_THRESHOLD: 0.6; /** High confidence threshold */ readonly HIGH: 0.8; /** Medium confidence threshold */ readonly MEDIUM: 0.5; /** Low confidence threshold */ readonly LOW: 0.3; }; }; /** * Orchestrator auto-restart configuration. * Used by OrchestratorRestartService to automatically restart the orchestrator * when it becomes unresponsive (child process dies inside PTY shell). */ export declare const ORCHESTRATOR_RESTART_CONSTANTS: { /** Maximum number of restarts allowed within the cooldown window */ readonly MAX_RESTARTS_PER_WINDOW: 3; /** Cooldown window in milliseconds (1 hour) */ readonly COOLDOWN_WINDOW_MS: 3600000; /** Delay before attempting restart (ms) - allows cleanup */ readonly RESTART_DELAY_MS: 5000; /** * Consecutive failed restarts after which auto-restart stops until the * orchestrator runs again (B8 D1: a missing runtime CLI looped every ~2.5 min * forever, because failed attempts never counted toward the cooldown). */ readonly MAX_CONSECUTIVE_FAILURES: 3; /** * After stopping, one quiet retry this often. The owner is usually away * from the machine: a network blip or a sign-in they later fix from their * phone must not leave the orchestrator down until someone walks up to it. * Equal to the cooldown window so the old attempts have aged out of it. */ readonly GAVE_UP_RETRY_MS: 3600000; }; /** * Orchestrator heartbeat monitoring configuration. * Used by OrchestratorHeartbeatMonitorService to detect unresponsive orchestrators, * send proactive heartbeat requests, and trigger auto-restart with resume. */ export declare const ORCHESTRATOR_HEARTBEAT_CONSTANTS: { /** Interval between heartbeat checks in milliseconds (30 seconds) */ readonly CHECK_INTERVAL_MS: 30000; /** Time without API activity before sending a heartbeat request when PTY is idle (5 minutes) */ readonly HEARTBEAT_REQUEST_THRESHOLD_MS: 300000; /** Time without API activity before sending a heartbeat request when PTY is active (15 minutes). * A longer threshold is used when the orchestrator's terminal is producing output * (e.g. running a build, tests, or other long commands) since that proves the * orchestrator is alive and working — just not making API calls. */ readonly HEARTBEAT_REQUEST_THRESHOLD_PTY_ACTIVE_MS: 900000; /** PTY idle time below which the orchestrator is considered "PTY active" (2 minutes). * If the orchestrator produced terminal output within this window, the longer * HEARTBEAT_REQUEST_THRESHOLD_PTY_ACTIVE_MS threshold is used instead. */ readonly PTY_ACTIVE_WINDOW_MS: 120000; /** Time after heartbeat request before triggering auto-restart (1 minute) */ readonly RESTART_THRESHOLD_MS: 60000; /** Message sent to orchestrator PTY to request a heartbeat */ readonly HEARTBEAT_REQUEST_MESSAGE: "Please run your heartbeat skill now: bash config/skills/orchestrator/heartbeat/execute.sh"; /** Grace period after server start before monitoring begins (120 seconds). * Increased from 30s to account for orchestrator boot time + first API call delay, * preventing false-positive heartbeat timeouts on slow starts or restarts. */ readonly STARTUP_GRACE_PERIOD_MS: 120000; /** Maximum time the orchestrator can stay in_progress before triggering * a heartbeat/restart (30 minutes). Spinner animation counts as "activity" * in the idle tracker, so a stuck orchestrator may appear active forever. * This timeout provides a hard upper bound. */ readonly IN_PROGRESS_TIMEOUT_MS: 1800000; }; /** * Agent heartbeat monitor configuration. * Used by AgentHeartbeatMonitorService to detect crashed/unresponsive agents * and auto-restart them with task re-delivery. */ export declare const AGENT_HEARTBEAT_MONITOR_CONSTANTS: { /** Interval between heartbeat checks in milliseconds (30 seconds) */ readonly CHECK_INTERVAL_MS: 30000; /** Time without activity (both PTY and API) before checking process liveness (5 minutes) */ readonly HEARTBEAT_REQUEST_THRESHOLD_MS: 300000; /** Grace period after server start before monitoring begins (1 minute) */ readonly STARTUP_GRACE_PERIOD_MS: 60000; /** Maximum restarts per cooldown window per agent */ readonly MAX_RESTARTS_PER_WINDOW: 3; /** Cooldown window for restart tracking (1 hour) */ readonly COOLDOWN_WINDOW_MS: 3600000; }; /** * Agent suspend/rehydrate configuration. * Used by AgentSuspendService, IdleDetectionService, and DiskCleanupService * to automatically suspend idle agents and transparently rehydrate them. */ export declare const AGENT_SUSPEND_CONSTANTS: { /** Default idle timeout in minutes before an agent is suspended (0 = disabled) */ readonly DEFAULT_IDLE_TIMEOUT_MINUTES: 30; /** Interval between idle checks in milliseconds (2 minutes) */ readonly IDLE_CHECK_INTERVAL_MS: 120000; /** Maximum age of debug log files eligible for cleanup on suspend (hours) */ readonly DEBUG_LOG_MAX_AGE_HOURS: 24; /** Timeout for rehydration to complete in milliseconds (45 seconds) */ readonly REHYDRATION_TIMEOUT_MS: 45000; /** Roles that are exempt from suspension */ readonly EXEMPT_ROLES: readonly ["orchestrator"]; /** Idle timeout for agents stuck in 'started' status (minutes) */ readonly STARTED_AGENT_IDLE_TIMEOUT_MINUTES: 15; /** * An idle agent is stopped only when memory is tight — at or above this * share of RAM in use, or below {@link IDLE_STOP_MIN_FREE_MB} free. An * idle agent costs no tokens; stopping it costs a full cold start (init * prompt plus rebuilding a context that is often 200k+ tokens) the next * time anyone speaks to it (owner, 2026-09-22). */ readonly IDLE_STOP_MEMORY_USED_PERCENT: 85; /** See {@link IDLE_STOP_MEMORY_USED_PERCENT}. */ readonly IDLE_STOP_MIN_FREE_MB: 1024; /** * Also tight when this share of swap is in use, or the OS reports memory * pressure: "free" counts reclaimable pages and stays high while the * machine swaps itself to a crawl (2026-09-23, load 117). */ readonly IDLE_STOP_SWAP_USED_PERCENT: 75; /** Roles that should never be auto-stopped (always-on) */ readonly ALWAYS_ON_ROLES: readonly ["orchestrator", "auditor"]; /** Idle timeout in ms before a worker agent is stopped (default 30 min) */ readonly AGENT_IDLE_STOP_TIMEOUT_MS: 1800000; /** * Do not idle-stop an agent whose next cron run is due within this many * minutes. Killing it only to respawn it for the cron costs a cold start * (init prompt + registration + recall, ~0.5-1M input tokens on Codex) * every single run — a 15-minute cron under a 10-minute idle timeout * paid that 50 times a day on steamfun-ops (2026-09-16). */ readonly CRON_KEEPALIVE_WINDOW_MINUTES: 30; /** * An idle member that is in a conversation with the owner (an owner thread * the sentinel watches: the owner wrote to it, or it promised the owner * something, in the last two hours) is kept at least this long before an * idle stop, whatever the configured or pressure timeout says. Under the * 10-minute pressure timeout the audit of 2026-10-16 counted 50 idle stops * in 9 h, many of them agents the owner was still talking to; every stop * costs a cold start and, past the fresh-start threshold, the conversation * (crewly#1344). Memory-pressure and critical stops still apply. */ readonly OWNER_THREAD_IDLE_TIMEOUT_MINUTES: 30; }; /** * Server process configuration for Node.js heap sizing and resource management. * Used by CLI start command to dynamically allocate memory based on system RAM. */ export declare const SERVER_CONSTANTS: { /** Minimum heap size in MB (floor for very low-RAM machines) */ readonly MIN_HEAP_SIZE_MB: 256; /** Maximum heap size in MB (cap for high-RAM machines) */ readonly MAX_HEAP_SIZE_MB: 2048; /** Fraction of total system RAM to allocate to Node.js heap */ readonly HEAP_MEMORY_RATIO: 0.4; }; /** * Auditor feature-flag configuration. * Controls whether the autonomous auditor agent (Claude Code PTY session) * is started at boot. Disabled by default to save memory on small machines. */ export declare const AUDITOR_CONSTANTS: { /** Whether the auditor is enabled by default (can be overridden by CREWLY_ENABLE_AUDITOR env) */ readonly ENABLED_BY_DEFAULT: false; /** Environment variable name to enable/disable the auditor */ readonly ENV_VAR: "CREWLY_ENABLE_AUDITOR"; }; /** * Version check configuration for CLI and web update notifications. * Used by VersionCheckService (backend) and version-check utilities (CLI) * to query the npm registry and cache the result. */ export declare const VERSION_CHECK_CONSTANTS: { /** npm registry URL for fetching the latest published version */ readonly NPM_REGISTRY_URL: "https://registry.npmjs.org/crewly/latest"; /** Cache file name stored under CREWLY_HOME */ readonly CHECK_CACHE_FILE: ".update-check"; /** Time-to-live for cached check result (24 hours) */ readonly CACHE_TTL_MS: number; /** HTTP request timeout for npm registry calls (5 seconds) */ readonly REQUEST_TIMEOUT_MS: 5000; }; /** * Automatic self-update (specs/auto-update.md). * * The backend's AutoUpdateService checks npm for a newer `crewly`, waits for * a quiet window, installs into the prefix the running copy lives in, * verifies the installed version and restarts gracefully. Shared with the * CLI (`crewly update-status`) and `crewly start` (which marks itself as the * restart supervisor for the backend it spawns). */ export declare const AUTO_UPDATE_CONSTANTS: { /** Interval between registry checks (ms) — 30 minutes (the update itself still waits for idle agents) */ readonly CHECK_INTERVAL_MS: number; /** First check after boot (ms) — 10 minutes */ readonly FIRST_CHECK_DELAY_MS: number; /** A registry answer older than this is re-fetched for the auto-update decision (ms) */ readonly REGISTRY_MAX_AGE_MS: number; /** Gap between the two quiet-window probes (ms) */ readonly QUIET_CONFIRM_MS: number; /** Retry interval while agents are busy (ms) — 5 minutes */ readonly BUSY_RETRY_MS: number; /** * After deferring this long, an agent whose workingStatus is stuck at * in_progress no longer blocks the update; only turns actually in flight * do (the restart drain handles those anyway) (ms) — 24 hours */ readonly MAX_BUSY_DEFER_MS: number; /** Back-off after a failed install or verify (ms) — 6 hours */ readonly FAILURE_BACKOFF_MS: number; /** Consecutive failures before the owner is told (once per target version) */ readonly FAILURE_NOTIFY_THRESHOLD: 2; /** Upper bound for one `npm install -g` (ms) — 10 minutes */ readonly INSTALL_TIMEOUT_MS: number; /** Sanitised npm output lines written to the backend log when an install fails */ readonly FAILURE_LOG_TAIL_LINES: 40; /** Longest error / trailer line quoted in the one-line failure reason (chars) */ readonly FAILURE_REASON_MAX_CHARS: 240; /** How long the post-restart notice waits for Slack to connect (ms) */ readonly NOTIFY_WAIT_MS: number; /** Poll interval while waiting for Slack (ms) */ readonly NOTIFY_POLL_MS: number; /** A pending-upgrade marker older than this is ignored at boot (ms) — 1 day */ readonly MARKER_MAX_AGE_MS: number; /** Env var: `0`/`false`/`off` forces auto-update off, `1`/`true`/`on` forces it on */ readonly ENV_VAR: "CREWLY_AUTO_UPDATE"; /** * Env var `crewly start` sets on the backend it spawns: the parent respawns * the backend when it exits with RESTART_REQUESTED, so an upgrade can come back. */ readonly SUPERVISOR_ENV_VAR: "CREWLY_RESTART_SUPERVISOR"; /** Value of SUPERVISOR_ENV_VAR set by `crewly start` */ readonly SUPERVISOR_CLI_START: "cli-start"; /** Log file under `/logs/` */ readonly LOG_FILE: "auto-update.log"; /** Status file under CREWLY_HOME (read by `crewly update-status`) */ readonly STATE_FILE: "auto-update-state.json"; /** Marker written before an upgrade restart, read (and removed) on the next boot */ readonly MARKER_FILE: "auto-update-pending.json"; /** npm package name */ readonly PACKAGE_NAME: "crewly"; }; /** * Constants for marketplace registry, installation, and submission management. * Used by marketplace services (backend + CLI) to resolve API endpoints, * cache settings, schema versions, and local file paths. */ export declare const MARKETPLACE_CONSTANTS: { /** GitHub raw content URL for the public skills registry index */ readonly PUBLIC_REGISTRY_URL: "https://raw.githubusercontent.com/stevehuang0115/crewly/main/config/skills/registry.json"; /** GitHub raw content base URL for downloading public skill files */ readonly PUBLIC_CDN_BASE: "https://raw.githubusercontent.com/stevehuang0115/crewly/main"; /** Base URL for the Crewly marketplace webapp (premium/private registry) */ readonly PREMIUM_BASE_URL: "https://crewlyai.com"; /** API endpoint for premium skills registry */ readonly PREMIUM_REGISTRY_ENDPOINT: "/api/registry/skills"; /** API endpoint for downloading marketplace assets */ readonly ASSETS_ENDPOINT: "/api/assets"; /** In-memory registry cache time-to-live (1 hour in ms) */ readonly CACHE_TTL: 3600000; /** Directory name under ~/.crewly/ for marketplace data */ readonly DIR_NAME: "marketplace"; /** File name for the installed-items manifest */ readonly MANIFEST_FILE: "manifest.json"; /** File name for the local registry of published skills */ readonly LOCAL_REGISTRY_FILE: "local-registry.json"; /** Subdirectory for skill submission archives */ readonly SUBMISSIONS_DIR: "submissions"; /** GitHub repository (owner/repo) for PR-based skill submissions */ readonly GITHUB_REPO: "stevehuang0115/crewly"; /** Registry schema version -- bump when the registry format changes */ readonly SCHEMA_VERSION: 2; /** Timeout for downloading archive assets from the CDN (30 seconds) */ readonly DOWNLOAD_TIMEOUT: 30000; /** Timeout for downloading individual skill files from GitHub (15 seconds) */ readonly GITHUB_FILE_TIMEOUT: 15000; /** Timeout for fetching the registry index from public or premium sources (10 seconds) */ readonly REGISTRY_FETCH_TIMEOUT: 10000; /** Category mapping from skill.json categories to marketplace display categories */ readonly CATEGORY_MAP: Record; }; /** * Template Marketplace constants for creating, versioning, and publishing * team configuration templates. Templates are stored as JSON files under * ~/.crewly/marketplace/templates/. */ export declare const TEMPLATE_MARKETPLACE_CONSTANTS: { /** Subdirectory under marketplace dir for template data */ readonly TEMPLATES_DIR: "templates"; /** File name for the template store index */ readonly STORE_FILE: "templates.json"; /** Subdirectory under each template for version files */ readonly VERSIONS_DIR: "versions"; /** File name for the version store within each template dir */ readonly VERSIONS_FILE: "versions.json"; /** Schema version for template store files */ readonly SCHEMA_VERSION: 1; /** Maximum template name length */ readonly MAX_NAME_LENGTH: 100; /** Maximum template description length */ readonly MAX_DESCRIPTION_LENGTH: 2000; /** Maximum changelog length per version */ readonly MAX_CHANGELOG_LENGTH: 5000; /** Maximum number of tags per template */ readonly MAX_TAGS: 20; /** Maximum tag length */ readonly MAX_TAG_LENGTH: 50; }; /** * Addon system configuration for loading and managing Crewly addons. * Addons are installed to ~/.crewly/addons/ and loaded on server startup. * Each addon has a manifest.json and a dist/ directory with compiled code. */ export declare const ADDON_CONSTANTS: { /** * File system paths for addon management */ readonly PATHS: { /** Directory name under ~/.crewly/ for installed addons */ readonly ADDONS_DIR: "addons"; /** Directory name for addon downloads/tarballs */ readonly DOWNLOADS_DIR: "downloads"; }; /** * Addon manifest configuration */ readonly MANIFEST_FILE: "manifest.json"; /** * Default entrypoint file within an addon's directory */ readonly DEFAULT_ENTRYPOINT: "dist/index.js"; /** * Cloud API configuration for downloading Pro addons */ readonly CLOUD_API: { /** Base URL for the Crewly Cloud API */ readonly BASE_URL: "https://api.crewlyai.com/v1"; /** Endpoint path for addon downloads */ readonly DOWNLOAD_ENDPOINT: "/addons"; }; /** * Crewly Pro addon identifiers */ readonly PRO_ADDON: { /** Pro addon package name */ readonly NAME: "crewly-pro"; /** Default tarball filename */ readonly DEFAULT_TARBALL: "crewly-pro.tar.gz"; }; /** * Addon loading timeouts */ readonly TIMEOUTS: { /** Maximum time to load a single addon (10 seconds) */ readonly LOAD_TIMEOUT_MS: 10000; }; }; /** Shorthand for debounce value */ export declare const EVENT_DEBOUNCE_MS: 5000; /** * Redis connection and caching configuration */ export declare const REDIS_CONSTANTS: { /** Redis connection settings */ readonly CONNECTION: { /** Default Redis host */ readonly HOST: "127.0.0.1"; /** Default Redis port */ readonly PORT: 6379; /** Connection timeout in milliseconds (5 seconds) */ readonly CONNECT_TIMEOUT: 5000; /** Maximum number of reconnect retries before giving up */ readonly MAX_RETRIES: 3; /** Delay between reconnect attempts in milliseconds */ readonly RETRY_DELAY: 1000; /** Base key prefix; RedisCacheService appends the per-instance home id (`crewly::`) */ readonly KEY_PREFIX: "crewly:"; }; /** Cache TTL (time-to-live) settings in seconds */ readonly TTL: { /** TTL for GET /api/teams list (60 seconds) */ readonly TEAMS_LIST: 60; /** TTL for GET /api/projects list (60 seconds) */ readonly PROJECTS_LIST: 60; /** Default TTL for unspecified cache entries (60 seconds) */ readonly DEFAULT: 60; }; /** Cache key patterns */ readonly KEYS: { /** Cache key for the teams list endpoint */ readonly TEAMS_LIST: "api:teams"; /** Cache key for the projects list endpoint */ readonly PROJECTS_LIST: "api:projects"; }; /** Environment variable names for Redis configuration */ readonly ENV: { /** Redis host override */ readonly REDIS_HOST: "CREWLY_REDIS_HOST"; /** Redis port override */ readonly REDIS_PORT: "CREWLY_REDIS_PORT"; /** Redis password */ readonly REDIS_PASSWORD: "CREWLY_REDIS_PASSWORD"; /** Redis URL (takes precedence over host/port) */ readonly REDIS_URL: "CREWLY_REDIS_URL"; }; }; /** * Device-code pairing with Crewly Cloud (crewly-auth `/api/cloud/device/*`). * * A machine signs in to the owner's Cloud account without anyone at it: it * shows a short code + link (`crewlyai.com/cloud/pair?code=ABCD-2345`), the * owner approves on their phone, and the machine polls until it receives its * token pair. Shared by `crewly cloud login` (CLI) and the backend's * background pairing used by `/setup` and Settings → Cloud. */ export declare const CLOUD_DEVICE_PAIRING_CONSTANTS: { /** crewly-auth endpoints (relative to the Cloud API URL) */ readonly CLOUD_ENDPOINTS: { readonly START: "/api/cloud/device/start"; readonly POLL: "/api/cloud/device/poll"; readonly REDEEM: "/api/cloud/device/redeem"; }; /** Local backend endpoints (owner-only; mounted under /api/cloud) */ readonly LOCAL_ENDPOINTS: { readonly START: "/api/cloud/device/start"; readonly STATUS: "/api/cloud/device/status"; readonly CANCEL: "/api/cloud/device/cancel"; }; /** Poll outcomes reported by crewly-auth (RFC 8628 names where one exists) */ readonly POLL_STATUS: { readonly PENDING: "authorization_pending"; readonly SLOW_DOWN: "slow_down"; readonly EXPIRED: "expired"; readonly DENIED: "denied"; readonly APPROVED: "approved"; }; /** Poll interval when the Cloud does not say (seconds) */ readonly DEFAULT_INTERVAL_S: 5; /** Added to the interval on slow_down / rate limiting (seconds) */ readonly SLOW_DOWN_INCREMENT_S: 5; /** Longest interval the client will back off to (seconds) */ readonly MAX_INTERVAL_S: 60; /** Pairing lifetime when the Cloud does not say (seconds) */ readonly DEFAULT_EXPIRES_IN_S: 900; /** Timeout for one start / poll request (ms) */ readonly REQUEST_TIMEOUT_MS: 15000; /** Consecutive network / server errors tolerated while polling */ readonly MAX_CONSECUTIVE_POLL_ERRORS: 10; /** `purpose` sent with a pairing (shown to the owner on the approve page) */ readonly PURPOSES: { readonly CLI: "cli"; readonly SETUP: "setup"; }; }; /** * Cloud disconnect notice: when a signed-in machine cannot talk to Crewly * Cloud for a sustained period (sign-in expired, Cloud unreachable), inbound * Slack messages for its agents queue in Cloud unseen. The notice DMs the * owner on Slack (outbound still works with the local bot tokens) with a * phone-friendly re-login link from `crewly cloud login`, run by Crewly. */ export declare const CLOUD_DISCONNECT_NOTICE_CONSTANTS: { /** Kill switch: `CREWLY_CLOUD_DISCONNECT_NOTICE=0` turns the notice off */ readonly ENV_SWITCH: "CREWLY_CLOUD_DISCONNECT_NOTICE"; /** No successful Cloud request for this long = disconnected (ms) — 15 min */ readonly DISCONNECT_THRESHOLD_MS: number; /** How often the monitor checks (ms) */ readonly CHECK_INTERVAL_MS: number; /** Repeat the notice at most this often while still disconnected (ms) — 6 h */ readonly REPEAT_INTERVAL_MS: number; /** * Relay queue registration failing (and no queue held) for this long = * disconnected (ms) — 2 min. Heartbeats can keep succeeding meanwhile, so * the 15-min "no contact" rule never sees it (2026-10-02). */ readonly QUEUE_FAILURE_THRESHOLD_MS: number; /** * When the owner was last told about a relay-queue failure (survives the * episode, so a flapping registration is reported at most every 6 h). */ readonly RELAY_QUEUE_NOTICE_FILE: "cloud/relay-queue-notice.json"; /** State file under the Crewly home (last notice, DM message, episode start) */ readonly STATE_FILE: "cloud/disconnect-notice.json"; /** Arguments for the CLI login run in a PTY (device pairing, no local browser) */ readonly CLI_LOGIN_ARGS: readonly ["cloud", "login", "--no-browser"]; /** CLI entry point relative to the package root */ readonly CLI_ENTRY: "dist/cli/cli/src/index.js"; /** How long to wait for the CLI to print its login link before sending the notice without one (ms) */ readonly LINK_WAIT_MS: number; /** Hard stop for one CLI login run (ms) — the pairing itself lasts 15 min */ readonly LOGIN_TIMEOUT_MS: number; /** Wait before starting another login run after one could not start (ms) */ readonly LOGIN_RETRY_MS: number; /** How often to read the owner's Slack DM for a reply the CLI asked for (ms) */ readonly REPLY_POLL_INTERVAL_MS: number; /** Stop reading replies after this long (ms) */ readonly REPLY_MAX_WAIT_MS: number; /** PTY size for the CLI login (wide so the link is never wrapped) */ readonly PTY_COLS: 500; readonly PTY_ROWS: 50; /** Largest PTY output kept for parsing (chars) */ readonly RAW_BUFFER_MAX_CHARS: number; /** Slack Web API base */ readonly SLACK_API_BASE: "https://slack.com/api"; /** Timeout for one Slack Web API call (ms) */ readonly SLACK_REQUEST_TIMEOUT_MS: number; }; /** * Project tickets (specs/2026-09-28-project-tickets.md): a project's own * backlog, one markdown file per ticket under `/.crewly/tickets/`, * tracked in git. Shared by the backend service, the CLI migration command * and (mirrored) the frontend board. */ export declare const PROJECT_TICKET_CONSTANTS: { /** Folder inside the project's `.crewly` data dir */ readonly DIR_NAME: "tickets"; /** Repo-relative folder, used for git tracking checks */ readonly REPO_RELATIVE_DIR: ".crewly/tickets"; /** Counter file (tracked): `{ "prefix": "CRW", "next": 13 }` */ readonly COUNTER_FILENAME: ".counter.json"; /** Cross-process lockfile (ignored by the folder's own .gitignore) */ readonly LOCK_FILENAME: ".lock"; /** The folder's own .gitignore (keeps the lock and temp files out of version control) */ readonly FOLDER_GITIGNORE_CONTENT: "# Crewly: transient files, never commit\n.lock\n*.tmp.*\n"; /** A lockfile older than this is considered left behind by a crashed writer (ms) */ readonly LOCK_STALE_MS: number; /** Wait between lock attempts (ms) */ readonly LOCK_RETRY_MS: 25; /** Give up acquiring the lock after this long (ms) */ readonly LOCK_TIMEOUT_MS: number; /** Ticket statuses, in board order */ readonly STATUSES: readonly ["backlog", "ready", "in_progress", "review", "done", "cancelled"]; /** Priorities, highest first */ readonly PRIORITIES: readonly ["P0", "P1", "P2", "P3"]; /** Priority of a ticket created without one */ readonly DEFAULT_PRIORITY: "P2"; /** Status of a ticket created without one (and of every worker-created ticket) */ readonly DEFAULT_STATUS: "backlog"; /** Fallback id prefix when the project name has no letters/digits */ readonly FALLBACK_PREFIX: "T"; /** Max characters of the id prefix derived from the project name */ readonly MAX_PREFIX_LENGTH: 4; /** Max characters of the slug in the file name */ readonly MAX_SLUG_LENGTH: 48; /** Section headings the service reads / writes */ readonly SECTIONS: { readonly DESCRIPTION: "Description"; readonly ACCEPTANCE: "Acceptance criteria"; readonly LOG: "Log"; }; /** `source` value stamped by the v1 migration */ readonly MIGRATION_SOURCE: "v1-migration"; /** v1 status folders whose files are imported (done/ and blocked/ are not) */ readonly MIGRATION_STATUS_FOLDERS: readonly ["open", "in_progress"]; /** v1 task root inside the project's `.crewly` data dir */ readonly MIGRATION_V1_DIR: "tasks"; /** Lines appended to the project's .gitignore when the tickets folder is ignored */ readonly GITIGNORE_BLOCK: readonly ["# Crewly project tickets are tracked (specs/2026-09-28-project-tickets.md)", "!.crewly/", ".crewly/*", "!.crewly/tickets/", "!.crewly/tickets/**"]; /** WorkItem metadata key linking a WorkItem to its project ticket */ readonly WORK_ITEM_METADATA_KEY: "projectTicket"; /** How often the sweep reconciles tickets with their WorkItems (ms) */ readonly SYNC_SWEEP_INTERVAL_MS: number; /** Successor hops followed from a ticket's WorkItem before giving up */ readonly MAX_SUCCESSOR_HOPS: 8; /** * Delegation through tickets (spec §11): the task-pool body field naming the * project ticket a delegated WorkItem works (`delegate-task --ticket`). */ readonly DELEGATION_TICKET_BODY_KEY: "projectTicketId"; /** WorkItem metadata key a delegating skill uses to name the delegator when no X-Agent-Session header is sent */ readonly DELEGATION_CALLER_METADATA_KEY: "delegatedBy"; /** WorkItem types that are delegations of work to someone (the only ones routed through tickets) */ readonly DELEGATION_WORK_ITEM_TYPES: readonly ["delegate"]; /** Max characters of a ticket title derived from a delegation's title */ readonly DELEGATION_TITLE_MAX_CHARS: 120; /** Error `code` of a task-pool add refused by the ticket rules (skills stop instead of delivering) */ readonly DELEGATION_REFUSED_CODE: "project_ticket_refused"; }; /** * Inputs to the OSS/Pro boundary check (issue #809). * * The rule "no premium/paid content in the OSS repo" (CLAUDE.md, Critical * Rule 10) is enforced by `backend/src/scripts/check-oss-boundary.ts`, which * runs in CI (`.github/workflows/oss-boundary.yml`) and inside the jest suite. * Every path here is relative to the repository root. */ /** * Rule metadata (issue #877): every SOP records the failure it prevents, the * model where that was seen, and a review date — so rules can be re-tested * and deleted when they stop making a difference. */ export declare const RULE_METADATA_CONSTANTS: { /** Directory of SOP files whose frontmatter is audited */ readonly SOPS_DIR: "config/sops"; /** The three frontmatter fields (plus the optional `source` link) */ readonly FIELDS: { readonly PREVENTS: "prevents"; readonly SEEN_ON: "seenOn"; readonly REVIEW_BY: "reviewBy"; readonly SOURCE: "source"; }; /** Share of SOPs that must carry all three fields for the check to pass */ readonly MIN_COVERAGE: 0.8; /** `prevents` starts with this when no failure was ever recorded for the rule */ readonly NO_RECORDED_FAILURE: "none recorded"; }; export declare const OSS_BOUNDARY_CONSTANTS: { /** Allowlist of explicit exceptions; every entry carries a one-line reason */ readonly ALLOWLIST_FILE: "config/oss-boundary-allowlist.json"; /** Directory whose JSON templates must stay free-tier (rules 1 and 2) */ readonly TEMPLATES_DIR: "config/templates"; /** Directory whose file paths must not look premium (rule 3) */ readonly CONFIG_DIR: "config"; /** Field that gates a template or skill behind a paid tier */ readonly TIER_FIELD: "requiredTier"; /** Tier values that mark content as paid — only allowed in crewly-pro */ readonly PAID_TIERS: readonly ["pro", "enterprise"]; /** Top-level template fields that are Pro-only features */ readonly PRO_ONLY_TEMPLATE_FIELDS: readonly ["workflows", "verificationPipeline", "qualityGates"]; /** A path segment starting with this prefix looks like Pro content */ readonly PRO_SEGMENT_PREFIX: "pro-"; /** A path segment containing this word looks like premium content */ readonly PREMIUM_SEGMENT_MARKER: "premium"; /** Package names OSS source must never import (also matches their subpaths) */ readonly FORBIDDEN_IMPORT_PACKAGES: readonly ["crewly-pro", "@crewly/pro"]; /** Source roots scanned for forbidden imports (rule 4); missing roots are skipped */ readonly SOURCE_ROOTS: readonly ["backend/src", "frontend/src", "cli/src", "mcp-server/src"]; /** Workspace packages directory; each `/src` is also scanned */ readonly PACKAGES_DIR: "packages"; /** Source directory name inside each workspace package */ readonly PACKAGE_SOURCE_SUBDIR: "src"; /** Directory names never descended into */ readonly SKIPPED_DIRS: readonly ["node_modules", "dist", ".git"]; /** File extensions treated as importable source */ readonly SOURCE_EXTENSIONS: readonly [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"]; /** File extension of template definitions */ readonly JSON_EXTENSION: ".json"; /** Rule identifiers used in reports and allowlist entries */ readonly RULES: { readonly PAID_TIER: "paid-tier"; readonly PRO_TEMPLATE_FIELD: "pro-template-field"; readonly PREMIUM_PATH: "premium-path"; readonly PRO_IMPORT: "pro-import"; }; }; /** * Type helpers for extracting literal types from constants */ export type AgentStatus = (typeof CREWLY_CONSTANTS.AGENT_STATUSES)[keyof typeof CREWLY_CONSTANTS.AGENT_STATUSES]; export type WorkingStatus = (typeof CREWLY_CONSTANTS.WORKING_STATUSES)[keyof typeof CREWLY_CONSTANTS.WORKING_STATUSES]; export type AgentRole = (typeof CREWLY_CONSTANTS.ROLES)[keyof typeof CREWLY_CONSTANTS.ROLES]; export type MessageType = (typeof MESSAGE_CONSTANTS.TYPES)[keyof typeof MESSAGE_CONSTANTS.TYPES]; export type OrchestratorCommand = (typeof BACKEND_CONSTANTS.ORCHESTRATOR_COMMANDS)[keyof typeof BACKEND_CONSTANTS.ORCHESTRATOR_COMMANDS]; export type HTTPStatusCode = (typeof BACKEND_CONSTANTS.NETWORK.HTTP_STATUS_CODES)[keyof typeof BACKEND_CONSTANTS.NETWORK.HTTP_STATUS_CODES]; export type AgentId = (typeof CREWLY_CONSTANTS.AGENT_IDS)[keyof typeof CREWLY_CONSTANTS.AGENT_IDS]; //# sourceMappingURL=constants.d.ts.map