@rudderhq/cli 0.2.2-canary.7 → 0.2.2-canary.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/shared/src/constants.ts", "../../packages/shared/src/types/observability.ts", "../../packages/shared/src/types/workspace-backup.ts", "../../packages/shared/src/validators/instance.ts", "../../packages/shared/src/validators/budget.ts", "../../packages/shared/src/validators/organization.ts", "../../packages/shared/src/validators/resource.ts", "../../packages/shared/src/validators/chat.ts", "../../packages/shared/src/validators/organization-skill.ts", "../../packages/shared/src/validators/adapter-skills.ts", "../../packages/shared/src/validators/organization-portability.ts", "../../packages/shared/src/validators/secret.ts", "../../packages/shared/src/validators/model-fallbacks.ts", "../../packages/shared/src/validators/agent.ts", "../../packages/shared/src/validators/project.ts", "../../packages/shared/src/validators/issue.ts", "../../packages/shared/src/validators/work-product.ts", "../../packages/shared/src/validators/execution-workspace.ts", "../../packages/shared/src/validators/workspace-backup.ts", "../../packages/shared/src/validators/goal.ts", "../../packages/shared/src/validators/approval.ts", "../../packages/shared/src/validators/automation.ts", "../../packages/shared/src/validators/calendar.ts", "../../packages/shared/src/validators/cost.ts", "../../packages/shared/src/validators/finance.ts", "../../packages/shared/src/validators/asset.ts", "../../packages/shared/src/validators/access.ts", "../../packages/shared/src/validators/plugin.ts", "../../packages/shared/src/validators/index.ts", "../../packages/shared/src/api.ts", "../../packages/shared/src/agent-url-key.ts", "../../packages/shared/src/organization-url-key.ts", "../../packages/shared/src/project-url-key.ts", "../../packages/shared/src/messenger-preview.ts", "../../packages/shared/src/token-usage.ts", "../../packages/shared/src/organization-skill-reference.ts", "../../packages/shared/src/project-mentions.ts", "../../packages/shared/src/config-schema.ts", "../../packages/shared/src/index.ts", "../src/config/schema.ts", "../src/config/home.ts", "../src/config/store.ts", "../src/config/env.ts", "../src/utils/path-resolver.ts", "../src/config/secrets-key.ts", "../src/prompts/database.ts", "../src/prompts/llm.ts", "../src/prompts/logging.ts", "../src/prompts/secrets.ts", "../src/prompts/storage.ts", "../src/config/hostnames.ts", "../src/prompts/server.ts", "../src/runtime/install.ts", "../src/runtime/server-entry.ts", "../src/version.ts", "../src/commands/auth-bootstrap-ceo.ts", "../src/install.ts", "../src/runtime/database.ts", "../src/utils/banner.ts", "../src/checks/agent-jwt-secret-check.ts", "../src/checks/config-check.ts", "../src/checks/deployment-auth-check.ts", "../src/checks/path-resolver.ts", "../src/checks/database-check.ts", "../src/checks/llm-check.ts", "../src/checks/log-check.ts", "../src/utils/net.ts", "../src/checks/port-check.ts", "../src/checks/secrets-check.ts", "../src/checks/storage-check.ts", "../src/checks/index.ts", "../src/commands/doctor.ts", "../src/config/local-env.ts", "../src/commands/run.ts", "../src/commands/onboard.ts", "../src/program.ts", "../src/commands/env.ts", "../src/commands/configure.ts", "../src/commands/start.ts", "../src/utils/progress.ts", "../src/commands/allowed-hostname.ts", "../src/commands/heartbeat-run.ts", "../src/agent-runtimes/process/format-event.ts", "../src/agent-runtimes/process/index.ts", "../src/agent-runtimes/http/format-event.ts", "../src/agent-runtimes/http/index.ts", "../src/agent-runtimes/registry.ts", "../src/commands/client/common.ts", "../src/client/board-auth.ts", "../src/client/command-label.ts", "../src/client/context.ts", "../src/client/http.ts", "../src/commands/client/context.ts", "../src/commands/client/company.ts", "../src/commands/client/zip.ts", "../src/commands/client/issue.ts", "../src/agent-v1-registry.ts", "../src/commands/client/agent.ts", "../../packages/agent-runtime-utils/src/server-utils.ts", "../src/commands/client/approval.ts", "../src/commands/client/activity.ts", "../src/commands/client/dashboard.ts", "../src/commands/client/skill.ts", "../src/config/data-dir.ts", "../src/commands/client/plugin.ts", "../src/commands/client/auth.ts", "../src/index.ts"],
4
- "sourcesContent": ["export const ORGANIZATION_STATUSES = [\"active\", \"paused\", \"archived\"] as const;\nexport type OrganizationStatus = (typeof ORGANIZATION_STATUSES)[number];\n\nexport const DEPLOYMENT_MODES = [\"local_trusted\", \"authenticated\"] as const;\nexport type DeploymentMode = (typeof DEPLOYMENT_MODES)[number];\n\nexport const DEPLOYMENT_EXPOSURES = [\"private\", \"public\"] as const;\nexport type DeploymentExposure = (typeof DEPLOYMENT_EXPOSURES)[number];\n\nexport const AUTH_BASE_URL_MODES = [\"auto\", \"explicit\"] as const;\nexport type AuthBaseUrlMode = (typeof AUTH_BASE_URL_MODES)[number];\n\nexport const AGENT_STATUSES = [\n \"active\",\n \"paused\",\n \"idle\",\n \"running\",\n \"error\",\n \"pending_approval\",\n \"terminated\",\n] as const;\nexport type AgentStatus = (typeof AGENT_STATUSES)[number];\n\nexport const AGENT_RUN_CONCURRENCY_DEFAULT = 3;\nexport const AGENT_RUN_CONCURRENCY_MIN = 1;\nexport const AGENT_RUN_CONCURRENCY_MAX = 10;\n\nexport const AGENT_RUNTIME_TYPES = [\n \"process\",\n \"http\",\n \"claude_local\",\n \"codex_local\",\n \"gemini_local\",\n \"opencode_local\",\n \"pi_local\",\n \"cursor\",\n \"openclaw_gateway\",\n \"hermes_local\",\n] as const;\nexport type AgentRuntimeType = (typeof AGENT_RUNTIME_TYPES)[number];\n\nexport const AGENT_ROLES = [\n \"ceo\",\n \"cto\",\n \"cmo\",\n \"cfo\",\n \"engineer\",\n \"designer\",\n \"pm\",\n \"qa\",\n \"devops\",\n \"researcher\",\n \"general\",\n] as const;\nexport type AgentRole = (typeof AGENT_ROLES)[number];\n\nexport const AGENT_ROLE_LABELS: Record<AgentRole, string> = {\n ceo: \"CEO\",\n cto: \"CTO\",\n cmo: \"CMO\",\n cfo: \"CFO\",\n engineer: \"Engineer\",\n designer: \"Designer\",\n pm: \"PM\",\n qa: \"QA\",\n devops: \"DevOps\",\n researcher: \"Researcher\",\n general: \"General\",\n};\n\nexport const AGENT_ICON_NAMES = [\n \"bot\",\n \"cpu\",\n \"brain\",\n \"zap\",\n \"rocket\",\n \"code\",\n \"terminal\",\n \"shield\",\n \"eye\",\n \"search\",\n \"wrench\",\n \"hammer\",\n \"lightbulb\",\n \"sparkles\",\n \"star\",\n \"heart\",\n \"flame\",\n \"bug\",\n \"cog\",\n \"database\",\n \"globe\",\n \"lock\",\n \"mail\",\n \"message-square\",\n \"file-code\",\n \"git-branch\",\n \"package\",\n \"puzzle\",\n \"target\",\n \"wand\",\n \"atom\",\n \"circuit-board\",\n \"radar\",\n \"swords\",\n \"telescope\",\n \"microscope\",\n \"crown\",\n \"gem\",\n \"hexagon\",\n \"pentagon\",\n \"fingerprint\",\n] as const;\nexport type AgentIconName = (typeof AGENT_ICON_NAMES)[number];\n\nexport const ISSUE_STATUSES = [\n \"backlog\",\n \"todo\",\n \"in_progress\",\n \"in_review\",\n \"done\",\n \"blocked\",\n \"cancelled\",\n] as const;\nexport type IssueStatus = (typeof ISSUE_STATUSES)[number];\n\nexport const ISSUE_PRIORITIES = [\"critical\", \"high\", \"medium\", \"low\"] as const;\nexport type IssuePriority = (typeof ISSUE_PRIORITIES)[number];\n\nexport const ISSUE_ORIGIN_KINDS = [\"manual\", \"automation_execution\"] as const;\nexport type IssueOriginKind = (typeof ISSUE_ORIGIN_KINDS)[number];\n\nexport const CALENDAR_SOURCE_TYPES = [\"rudder_local\", \"google_calendar\", \"agent_work\", \"system\"] as const;\nexport type CalendarSourceType = (typeof CALENDAR_SOURCE_TYPES)[number];\n\nexport const CALENDAR_OWNER_TYPES = [\"user\", \"agent\", \"system\"] as const;\nexport type CalendarOwnerType = (typeof CALENDAR_OWNER_TYPES)[number];\n\nexport const CALENDAR_VISIBILITIES = [\"full\", \"busy_only\", \"private\"] as const;\nexport type CalendarVisibility = (typeof CALENDAR_VISIBILITIES)[number];\n\nexport const CALENDAR_SOURCE_STATUSES = [\"active\", \"paused\", \"disconnected\", \"error\"] as const;\nexport type CalendarSourceStatus = (typeof CALENDAR_SOURCE_STATUSES)[number];\n\nexport const CALENDAR_EVENT_KINDS = [\"human_event\", \"agent_work_block\", \"external_event\", \"system_event\"] as const;\nexport type CalendarEventKind = (typeof CALENDAR_EVENT_KINDS)[number];\n\nexport const CALENDAR_EVENT_STATUSES = [\"planned\", \"in_progress\", \"actual\", \"cancelled\", \"external\", \"projected\"] as const;\nexport type CalendarEventStatus = (typeof CALENDAR_EVENT_STATUSES)[number];\n\nexport const CALENDAR_SOURCE_MODES = [\"manual\", \"derived\", \"imported\"] as const;\nexport type CalendarSourceMode = (typeof CALENDAR_SOURCE_MODES)[number];\n\nexport const CHAT_CONVERSATION_STATUSES = [\"active\", \"resolved\", \"archived\"] as const;\nexport type ChatConversationStatus = (typeof CHAT_CONVERSATION_STATUSES)[number];\n\nexport const CHAT_ISSUE_CREATION_MODES = [\"manual_approval\", \"auto_create\"] as const;\nexport type ChatIssueCreationMode = (typeof CHAT_ISSUE_CREATION_MODES)[number];\n\nexport const CHAT_MESSAGE_ROLES = [\"user\", \"assistant\", \"system\"] as const;\nexport type ChatMessageRole = (typeof CHAT_MESSAGE_ROLES)[number];\n\nexport const CHAT_MESSAGE_KINDS = [\n \"message\",\n \"ask_user\",\n \"issue_proposal\",\n \"operation_proposal\",\n \"system_event\",\n] as const;\nexport type ChatMessageKind = (typeof CHAT_MESSAGE_KINDS)[number];\n\nexport const CHAT_MESSAGE_STATUSES = [\"streaming\", \"completed\", \"stopped\", \"failed\", \"interrupted\"] as const;\nexport type ChatMessageStatus = (typeof CHAT_MESSAGE_STATUSES)[number];\n\nexport const CHAT_CONTEXT_ENTITY_TYPES = [\"issue\", \"project\", \"agent\"] as const;\nexport type ChatContextEntityType = (typeof CHAT_CONTEXT_ENTITY_TYPES)[number];\n\nexport const MESSENGER_THREAD_KINDS = [\n \"chat\",\n \"issues\",\n \"approvals\",\n \"failed-runs\",\n \"budget-alerts\",\n \"join-requests\",\n] as const;\nexport type MessengerThreadKind = (typeof MESSENGER_THREAD_KINDS)[number];\n\nexport const MESSENGER_SYSTEM_THREAD_KINDS = [\n \"failed-runs\",\n \"budget-alerts\",\n \"join-requests\",\n] as const;\nexport type MessengerSystemThreadKind = (typeof MESSENGER_SYSTEM_THREAD_KINDS)[number];\n\nexport const GOAL_LEVELS = [\"organization\", \"team\", \"agent\", \"task\"] as const;\nexport type GoalLevel = (typeof GOAL_LEVELS)[number];\n\nexport const GOAL_STATUSES = [\"planned\", \"active\", \"achieved\", \"cancelled\"] as const;\nexport type GoalStatus = (typeof GOAL_STATUSES)[number];\n\nexport const PROJECT_STATUSES = [\n \"backlog\",\n \"planned\",\n \"in_progress\",\n \"completed\",\n \"cancelled\",\n] as const;\nexport type ProjectStatus = (typeof PROJECT_STATUSES)[number];\n\nexport const ORGANIZATION_RESOURCE_KINDS = [\n \"file\",\n \"directory\",\n \"url\",\n \"connector_object\",\n] as const;\nexport type OrganizationResourceKind = (typeof ORGANIZATION_RESOURCE_KINDS)[number];\n\nexport const PROJECT_RESOURCE_ATTACHMENT_ROLES = [\n \"working_set\",\n \"reference\",\n \"tracking\",\n \"deliverable\",\n \"background\",\n] as const;\nexport type ProjectResourceAttachmentRole = (typeof PROJECT_RESOURCE_ATTACHMENT_ROLES)[number];\n\nexport const AUTOMATION_STATUSES = [\"active\", \"paused\", \"archived\"] as const;\nexport type AutomationStatus = (typeof AUTOMATION_STATUSES)[number];\n\nexport const AUTOMATION_CONCURRENCY_POLICIES = [\"coalesce_if_active\", \"always_enqueue\", \"skip_if_active\"] as const;\nexport type AutomationConcurrencyPolicy = (typeof AUTOMATION_CONCURRENCY_POLICIES)[number];\n\nexport const AUTOMATION_CATCH_UP_POLICIES = [\"skip_missed\", \"enqueue_missed_with_cap\"] as const;\nexport type AutomationCatchUpPolicy = (typeof AUTOMATION_CATCH_UP_POLICIES)[number];\n\nexport const AUTOMATION_TRIGGER_KINDS = [\"schedule\", \"webhook\", \"api\"] as const;\nexport type AutomationTriggerKind = (typeof AUTOMATION_TRIGGER_KINDS)[number];\n\nexport const AUTOMATION_TRIGGER_SIGNING_MODES = [\"bearer\", \"hmac_sha256\"] as const;\nexport type AutomationTriggerSigningMode = (typeof AUTOMATION_TRIGGER_SIGNING_MODES)[number];\n\nexport const AUTOMATION_RUN_STATUSES = [\n \"received\",\n \"coalesced\",\n \"skipped\",\n \"issue_created\",\n \"completed\",\n \"failed\",\n ] as const;\nexport type AutomationRunStatus = (typeof AUTOMATION_RUN_STATUSES)[number];\n\nexport const AUTOMATION_RUN_SOURCES = [\"schedule\", \"manual\", \"api\", \"webhook\"] as const;\nexport type AutomationRunSource = (typeof AUTOMATION_RUN_SOURCES)[number];\n\nexport const PAUSE_REASONS = [\"manual\", \"budget\", \"system\"] as const;\nexport type PauseReason = (typeof PAUSE_REASONS)[number];\n\nexport const PROJECT_COLORS = [\n \"linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)\",\n \"linear-gradient(135deg, #7c3aed 0%, #d946ef 100%)\",\n \"linear-gradient(135deg, #db2777 0%, #f97316 100%)\",\n \"linear-gradient(135deg, #ef4444 0%, #f59e0b 100%)\",\n \"linear-gradient(135deg, #f97316 0%, #facc15 100%)\",\n \"linear-gradient(135deg, #10b981 0%, #84cc16 100%)\",\n \"linear-gradient(135deg, #059669 0%, #14b8a6 100%)\",\n \"linear-gradient(135deg, #0d9488 0%, #06b6d4 100%)\",\n \"linear-gradient(135deg, #0284c7 0%, #2563eb 100%)\",\n \"linear-gradient(135deg, #2563eb 0%, #4f46e5 100%)\",\n \"linear-gradient(135deg, #f43f5e 0%, #ec4899 100%)\",\n \"linear-gradient(135deg, #be123c 0%, #7c2d12 100%)\",\n \"linear-gradient(135deg, #a16207 0%, #ca8a04 100%)\",\n \"linear-gradient(135deg, #16a34a 0%, #0f766e 100%)\",\n \"linear-gradient(135deg, #0891b2 0%, #4338ca 100%)\",\n \"linear-gradient(135deg, #6d28d9 0%, #be185d 100%)\",\n \"linear-gradient(135deg, #475569 0%, #0f766e 100%)\",\n \"linear-gradient(135deg, #334155 0%, #7c3aed 100%)\",\n] as const;\n\nexport const APPROVAL_TYPES = [\n \"hire_agent\",\n \"approve_ceo_strategy\",\n \"budget_override_required\",\n \"chat_issue_creation\",\n \"chat_operation\",\n] as const;\nexport type ApprovalType = (typeof APPROVAL_TYPES)[number];\n\nexport const APPROVAL_STATUSES = [\n \"pending\",\n \"revision_requested\",\n \"approved\",\n \"rejected\",\n \"cancelled\",\n] as const;\nexport type ApprovalStatus = (typeof APPROVAL_STATUSES)[number];\n\nexport const SECRET_PROVIDERS = [\n \"local_encrypted\",\n \"aws_secrets_manager\",\n \"gcp_secret_manager\",\n \"vault\",\n] as const;\nexport type SecretProvider = (typeof SECRET_PROVIDERS)[number];\n\nexport const STORAGE_PROVIDERS = [\"local_disk\", \"s3\"] as const;\nexport type StorageProvider = (typeof STORAGE_PROVIDERS)[number];\n\nexport const BILLING_TYPES = [\n \"metered_api\",\n \"subscription_included\",\n \"subscription_overage\",\n \"credits\",\n \"fixed\",\n \"unknown\",\n] as const;\nexport type BillingType = (typeof BILLING_TYPES)[number];\n\nexport const FINANCE_EVENT_KINDS = [\n \"inference_charge\",\n \"platform_fee\",\n \"credit_purchase\",\n \"credit_refund\",\n \"credit_expiry\",\n \"byok_fee\",\n \"gateway_overhead\",\n \"log_storage_charge\",\n \"logpush_charge\",\n \"provisioned_capacity_charge\",\n \"training_charge\",\n \"custom_model_import_charge\",\n \"custom_model_storage_charge\",\n \"manual_adjustment\",\n] as const;\nexport type FinanceEventKind = (typeof FINANCE_EVENT_KINDS)[number];\n\nexport const FINANCE_DIRECTIONS = [\"debit\", \"credit\"] as const;\nexport type FinanceDirection = (typeof FINANCE_DIRECTIONS)[number];\n\nexport const FINANCE_UNITS = [\n \"input_token\",\n \"output_token\",\n \"cached_input_token\",\n \"request\",\n \"credit_usd\",\n \"credit_unit\",\n \"model_unit_minute\",\n \"model_unit_hour\",\n \"gb_month\",\n \"train_token\",\n \"unknown\",\n] as const;\nexport type FinanceUnit = (typeof FINANCE_UNITS)[number];\n\nexport const BUDGET_SCOPE_TYPES = [\"organization\", \"agent\", \"project\"] as const;\nexport type BudgetScopeType = (typeof BUDGET_SCOPE_TYPES)[number];\n\nexport const BUDGET_METRICS = [\"billed_cents\"] as const;\nexport type BudgetMetric = (typeof BUDGET_METRICS)[number];\n\nexport const BUDGET_WINDOW_KINDS = [\"calendar_month_utc\", \"lifetime\"] as const;\nexport type BudgetWindowKind = (typeof BUDGET_WINDOW_KINDS)[number];\n\nexport const BUDGET_THRESHOLD_TYPES = [\"soft\", \"hard\"] as const;\nexport type BudgetThresholdType = (typeof BUDGET_THRESHOLD_TYPES)[number];\n\nexport const BUDGET_INCIDENT_STATUSES = [\"open\", \"resolved\", \"dismissed\"] as const;\nexport type BudgetIncidentStatus = (typeof BUDGET_INCIDENT_STATUSES)[number];\n\nexport const BUDGET_INCIDENT_RESOLUTION_ACTIONS = [\n \"keep_paused\",\n \"raise_budget_and_resume\",\n] as const;\nexport type BudgetIncidentResolutionAction = (typeof BUDGET_INCIDENT_RESOLUTION_ACTIONS)[number];\n\nexport const HEARTBEAT_INVOCATION_SOURCES = [\n \"timer\",\n \"assignment\",\n \"review\",\n \"on_demand\",\n \"automation\",\n] as const;\nexport type HeartbeatInvocationSource = (typeof HEARTBEAT_INVOCATION_SOURCES)[number];\n\nexport const WAKEUP_TRIGGER_DETAILS = [\"manual\", \"ping\", \"callback\", \"system\"] as const;\nexport type WakeupTriggerDetail = (typeof WAKEUP_TRIGGER_DETAILS)[number];\n\nexport const WAKEUP_REQUEST_STATUSES = [\n \"queued\",\n \"deferred_issue_execution\",\n \"deferred_agent_paused\",\n \"claimed\",\n \"coalesced\",\n \"skipped\",\n \"completed\",\n \"failed\",\n \"cancelled\",\n] as const;\nexport type WakeupRequestStatus = (typeof WAKEUP_REQUEST_STATUSES)[number];\n\nexport const HEARTBEAT_RUN_STATUSES = [\n \"queued\",\n \"running\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n \"timed_out\",\n] as const;\nexport type HeartbeatRunStatus = (typeof HEARTBEAT_RUN_STATUSES)[number];\n\nexport const LIVE_EVENT_TYPES = [\n \"heartbeat.run.queued\",\n \"heartbeat.run.status\",\n \"heartbeat.run.event\",\n \"heartbeat.run.log\",\n \"agent.status\",\n \"activity.logged\",\n \"plugin.ui.updated\",\n \"plugin.worker.crashed\",\n \"plugin.worker.restarted\",\n] as const;\nexport type LiveEventType = (typeof LIVE_EVENT_TYPES)[number];\n\nexport const PRINCIPAL_TYPES = [\"user\", \"agent\"] as const;\nexport type PrincipalType = (typeof PRINCIPAL_TYPES)[number];\n\nexport const MEMBERSHIP_STATUSES = [\"pending\", \"active\", \"suspended\"] as const;\nexport type MembershipStatus = (typeof MEMBERSHIP_STATUSES)[number];\n\nexport const INSTANCE_USER_ROLES = [\"instance_admin\"] as const;\nexport type InstanceUserRole = (typeof INSTANCE_USER_ROLES)[number];\n\nexport const INVITE_TYPES = [\"company_join\", \"bootstrap_ceo\"] as const;\nexport type InviteType = (typeof INVITE_TYPES)[number];\n\nexport const INVITE_JOIN_TYPES = [\"human\", \"agent\", \"both\"] as const;\nexport type InviteJoinType = (typeof INVITE_JOIN_TYPES)[number];\n\nexport const JOIN_REQUEST_TYPES = [\"human\", \"agent\"] as const;\nexport type JoinRequestType = (typeof JOIN_REQUEST_TYPES)[number];\n\nexport const JOIN_REQUEST_STATUSES = [\"pending_approval\", \"approved\", \"rejected\"] as const;\nexport type JoinRequestStatus = (typeof JOIN_REQUEST_STATUSES)[number];\n\nexport const PERMISSION_KEYS = [\n \"agents:create\",\n \"users:invite\",\n \"users:manage_permissions\",\n \"tasks:assign\",\n \"tasks:assign_scope\",\n \"joins:approve\",\n] as const;\nexport type PermissionKey = (typeof PERMISSION_KEYS)[number];\n\n// ---------------------------------------------------------------------------\n// Plugin System \u2014 see doc/plugins/PLUGIN_SPEC.md for the full specification\n// ---------------------------------------------------------------------------\n\n/**\n * The current version of the Plugin API contract.\n *\n * Increment this value whenever a breaking change is made to the plugin API\n * so that the host can reject incompatible plugin manifests.\n *\n * @see PLUGIN_SPEC.md \u00A74 \u2014 Versioning\n */\nexport const PLUGIN_API_VERSION = 1 as const;\n\n/**\n * Lifecycle statuses for an installed plugin.\n *\n * State machine: installed \u2192 ready | error, ready \u2192 disabled | error | upgrade_pending | uninstalled,\n * disabled \u2192 ready | uninstalled, error \u2192 ready | uninstalled,\n * upgrade_pending \u2192 ready | error | uninstalled, uninstalled \u2192 installed (reinstall).\n *\n * @see {@link PluginStatus} \u2014 inferred union type\n * @see PLUGIN_SPEC.md \u00A721.3 `plugins.status`\n */\nexport const PLUGIN_STATUSES = [\n \"installed\",\n \"ready\",\n \"disabled\",\n \"error\",\n \"upgrade_pending\",\n \"uninstalled\",\n] as const;\nexport type PluginStatus = (typeof PLUGIN_STATUSES)[number];\n\n/**\n * Plugin classification categories. A plugin declares one or more categories\n * in its manifest to describe its primary purpose.\n *\n * @see PLUGIN_SPEC.md \u00A76.2\n */\nexport const PLUGIN_CATEGORIES = [\n \"connector\",\n \"workspace\",\n \"automation\",\n \"ui\",\n] as const;\nexport type PluginCategory = (typeof PLUGIN_CATEGORIES)[number];\n\n/**\n * Named permissions the host grants to a plugin. Plugins declare required\n * capabilities in their manifest; the host enforces them at runtime via the\n * plugin capability validator.\n *\n * Grouped into: Data Read, Data Write, Plugin State, Runtime/Integration,\n * Agent Tools, and UI.\n *\n * @see PLUGIN_SPEC.md \u00A715 \u2014 Capability Model\n */\nexport const PLUGIN_CAPABILITIES = [\n // Data Read\n \"organizations.read\",\n \"projects.read\",\n \"project.workspaces.read\",\n \"issues.read\",\n \"issue.comments.read\",\n \"issue.documents.read\",\n \"agents.read\",\n \"goals.read\",\n \"goals.create\",\n \"goals.update\",\n \"activity.read\",\n \"costs.read\",\n // Data Write\n \"issues.create\",\n \"issues.update\",\n \"issue.comments.create\",\n \"issue.documents.write\",\n \"agents.pause\",\n \"agents.resume\",\n \"agents.invoke\",\n \"agent.sessions.create\",\n \"agent.sessions.list\",\n \"agent.sessions.send\",\n \"agent.sessions.close\",\n \"activity.log.write\",\n \"metrics.write\",\n // Plugin State\n \"plugin.state.read\",\n \"plugin.state.write\",\n // Runtime / Integration\n \"events.subscribe\",\n \"events.emit\",\n \"jobs.schedule\",\n \"webhooks.receive\",\n \"http.outbound\",\n \"secrets.read-ref\",\n // Agent Tools\n \"agent.tools.register\",\n // UI\n \"instance.settings.register\",\n \"ui.sidebar.register\",\n \"ui.page.register\",\n \"ui.detailTab.register\",\n \"ui.dashboardWidget.register\",\n \"ui.commentAnnotation.register\",\n \"ui.action.register\",\n] as const;\nexport type PluginCapability = (typeof PLUGIN_CAPABILITIES)[number];\n\n/**\n * UI extension slot types. Each slot type corresponds to a mount point in the\n * Rudder UI where plugin components can be rendered.\n *\n * @see PLUGIN_SPEC.md \u00A719 \u2014 UI Extension Model\n */\nexport const PLUGIN_UI_SLOT_TYPES = [\n \"page\",\n \"detailTab\",\n \"taskDetailView\",\n \"dashboardWidget\",\n \"sidebar\",\n \"sidebarPanel\",\n \"projectSidebarItem\",\n \"globalToolbarButton\",\n \"toolbarButton\",\n \"contextMenuItem\",\n \"commentAnnotation\",\n \"commentContextMenuItem\",\n \"settingsPage\",\n] as const;\nexport type PluginUiSlotType = (typeof PLUGIN_UI_SLOT_TYPES)[number];\n\n/**\n * Reserved organization-scoped route segments that plugin page routes may not claim.\n *\n * These map to first-class host pages under `/:organizationPrefix/...`.\n */\nexport const PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS = [\n \"dashboard\",\n \"onboarding\",\n \"organizations\",\n \"organization\",\n \"settings\",\n \"plugins\",\n \"org\",\n \"agents\",\n \"projects\",\n \"issues\",\n \"goals\",\n \"approvals\",\n \"costs\",\n \"activity\",\n \"inbox\",\n \"design-guide\",\n \"tests\",\n] as const;\nexport type PluginReservedCompanyRouteSegment =\n (typeof PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS)[number];\n\n/**\n * Launcher placement zones describe where a plugin-owned launcher can appear\n * in the host UI. These are intentionally aligned with current slot surfaces\n * so manifest authors can describe launch intent without coupling to a single\n * component implementation detail.\n */\nexport const PLUGIN_LAUNCHER_PLACEMENT_ZONES = [\n \"page\",\n \"detailTab\",\n \"taskDetailView\",\n \"dashboardWidget\",\n \"sidebar\",\n \"sidebarPanel\",\n \"projectSidebarItem\",\n \"globalToolbarButton\",\n \"toolbarButton\",\n \"contextMenuItem\",\n \"commentAnnotation\",\n \"commentContextMenuItem\",\n \"settingsPage\",\n] as const;\nexport type PluginLauncherPlacementZone = (typeof PLUGIN_LAUNCHER_PLACEMENT_ZONES)[number];\n\n/**\n * Launcher action kinds describe what the launcher does when activated.\n */\nexport const PLUGIN_LAUNCHER_ACTIONS = [\n \"navigate\",\n \"openModal\",\n \"openDrawer\",\n \"openPopover\",\n \"performAction\",\n \"deepLink\",\n] as const;\nexport type PluginLauncherAction = (typeof PLUGIN_LAUNCHER_ACTIONS)[number];\n\n/**\n * Optional size hints the host can use when rendering plugin-owned launcher\n * destinations such as overlays, drawers, or full page handoffs.\n */\nexport const PLUGIN_LAUNCHER_BOUNDS = [\n \"inline\",\n \"compact\",\n \"default\",\n \"wide\",\n \"full\",\n] as const;\nexport type PluginLauncherBounds = (typeof PLUGIN_LAUNCHER_BOUNDS)[number];\n\n/**\n * Render environments describe the container a launcher expects after it is\n * activated. The current host may map these to concrete UI primitives.\n */\nexport const PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS = [\n \"hostInline\",\n \"hostOverlay\",\n \"hostRoute\",\n \"external\",\n \"iframe\",\n] as const;\nexport type PluginLauncherRenderEnvironment =\n (typeof PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS)[number];\n\n/**\n * Entity types that a `detailTab` UI slot can attach to.\n *\n * @see PLUGIN_SPEC.md \u00A719.3 \u2014 Detail Tabs\n */\nexport const PLUGIN_UI_SLOT_ENTITY_TYPES = [\n \"project\",\n \"issue\",\n \"agent\",\n \"goal\",\n \"run\",\n \"comment\",\n] as const;\nexport type PluginUiSlotEntityType = (typeof PLUGIN_UI_SLOT_ENTITY_TYPES)[number];\n\n/**\n * Scope kinds for plugin state storage. Determines the granularity at which\n * a plugin stores key-value state data.\n *\n * @see PLUGIN_SPEC.md \u00A721.3 `plugin_state.scope_kind`\n */\nexport const PLUGIN_STATE_SCOPE_KINDS = [\n \"instance\",\n \"organization\",\n \"project\",\n \"project_workspace\",\n \"agent\",\n \"issue\",\n \"goal\",\n \"run\",\n] as const;\nexport type PluginStateScopeKind = (typeof PLUGIN_STATE_SCOPE_KINDS)[number];\n\n/** Statuses for a plugin's scheduled job definition. */\nexport const PLUGIN_JOB_STATUSES = [\n \"active\",\n \"paused\",\n \"failed\",\n] as const;\nexport type PluginJobStatus = (typeof PLUGIN_JOB_STATUSES)[number];\n\n/** Statuses for individual job run executions. */\nexport const PLUGIN_JOB_RUN_STATUSES = [\n \"pending\",\n \"queued\",\n \"running\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n] as const;\nexport type PluginJobRunStatus = (typeof PLUGIN_JOB_RUN_STATUSES)[number];\n\n/** What triggered a particular job run. */\nexport const PLUGIN_JOB_RUN_TRIGGERS = [\n \"schedule\",\n \"manual\",\n \"retry\",\n] as const;\nexport type PluginJobRunTrigger = (typeof PLUGIN_JOB_RUN_TRIGGERS)[number];\n\n/** Statuses for inbound webhook deliveries. */\nexport const PLUGIN_WEBHOOK_DELIVERY_STATUSES = [\n \"pending\",\n \"success\",\n \"failed\",\n] as const;\nexport type PluginWebhookDeliveryStatus = (typeof PLUGIN_WEBHOOK_DELIVERY_STATUSES)[number];\n\n/**\n * Core domain event types that plugins can subscribe to via the\n * `events.subscribe` capability.\n *\n * @see PLUGIN_SPEC.md \u00A716 \u2014 Event System\n */\nexport const PLUGIN_EVENT_TYPES = [\n \"organization.created\",\n \"organization.updated\",\n \"project.created\",\n \"project.updated\",\n \"project.workspace_created\",\n \"project.workspace_updated\",\n \"project.workspace_deleted\",\n \"issue.created\",\n \"issue.updated\",\n \"issue.comment.created\",\n \"agent.created\",\n \"agent.updated\",\n \"agent.status_changed\",\n \"agent.run.started\",\n \"agent.run.finished\",\n \"agent.run.failed\",\n \"agent.run.cancelled\",\n \"goal.created\",\n \"goal.updated\",\n \"approval.created\",\n \"approval.decided\",\n \"cost_event.created\",\n \"activity.logged\",\n] as const;\nexport type PluginEventType = (typeof PLUGIN_EVENT_TYPES)[number];\n\n/**\n * Error codes returned by the plugin bridge when a UI \u2192 worker call fails.\n *\n * @see PLUGIN_SPEC.md \u00A719.7 \u2014 Error Propagation Through The Bridge\n */\nexport const PLUGIN_BRIDGE_ERROR_CODES = [\n \"WORKER_UNAVAILABLE\",\n \"CAPABILITY_DENIED\",\n \"WORKER_ERROR\",\n \"TIMEOUT\",\n \"UNKNOWN\",\n] as const;\nexport type PluginBridgeErrorCode = (typeof PLUGIN_BRIDGE_ERROR_CODES)[number];\n", "export const EXECUTION_OBSERVABILITY_SURFACES = [\n \"heartbeat_run\",\n \"issue_run\",\n \"plugin_job_run\",\n \"workspace_operation\",\n \"chat_turn\",\n \"chat_action\",\n \"messenger_action\",\n \"activity_mutation\",\n \"cost_event\",\n] as const;\n\nexport type ExecutionObservabilitySurface = (typeof EXECUTION_OBSERVABILITY_SURFACES)[number];\n\nexport interface ExecutionObservabilityContext {\n surface: ExecutionObservabilitySurface;\n rootExecutionId: string;\n orgId?: string | null;\n agentId?: string | null;\n issueId?: string | null;\n pluginId?: string | null;\n sessionKey?: string | null;\n runtime?: string | null;\n trigger?: string | null;\n status?: string | null;\n environment?: string | null;\n release?: string | null;\n instanceId?: string | null;\n deploymentMode?: string | null;\n localEnv?: string | null;\n metadata?: Record<string, unknown> | null;\n tags?: string[] | null;\n}\n\nexport interface ExecutionLangfuseLink {\n traceId: string | null;\n traceUrl: string | null;\n}\n", "import type {\n OrganizationWorkspaceFileDetail,\n OrganizationWorkspaceFileList,\n} from \"./organization.js\";\n\nexport const WORKSPACE_BACKUP_DEFAULT_INTERVAL_HOURS = 24;\nexport const WORKSPACE_BACKUP_DEFAULT_RETENTION_DAYS = 30;\n\nexport type WorkspaceBackupStatus = \"running\" | \"succeeded\" | \"failed\" | \"restored\" | \"deleted\";\nexport type WorkspaceBackupTriggerSource = \"manual\" | \"scheduled\" | \"pre_restore\";\n\nexport interface WorkspaceBackupSummary {\n id: string;\n orgId: string;\n status: WorkspaceBackupStatus;\n triggerSource: WorkspaceBackupTriggerSource;\n artifactProvider: \"local_file\";\n artifactRef: string;\n archiveSha256: string | null;\n treeSha256: string | null;\n fileCount: number;\n byteSize: number;\n compressedSize: number;\n manifest: Record<string, unknown> | null;\n warnings: string[];\n error: string | null;\n startedAt: string | null;\n finishedAt: string | null;\n expiresAt: string | null;\n restoredFromBackupId: string | null;\n createdByUserId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface WorkspaceBackupList {\n backups: WorkspaceBackupSummary[];\n}\n\nexport interface WorkspaceBackupCreateRequest {\n triggerSource?: WorkspaceBackupTriggerSource;\n}\n\nexport interface WorkspaceBackupRestoreRequest {\n confirm: boolean;\n}\n\nexport interface WorkspaceBackupRestoreResult {\n restoredBackup: WorkspaceBackupSummary;\n preRestoreBackup: WorkspaceBackupSummary;\n}\n\nexport type WorkspaceBackupFileList = OrganizationWorkspaceFileList;\nexport type WorkspaceBackupFileDetail = OrganizationWorkspaceFileDetail;\n", "import { z } from \"zod\";\n\nexport const instanceLocaleSchema = z.enum([\"en\", \"zh-CN\"]);\n\nexport const instanceGeneralSettingsSchema = z.object({\n censorUsernameInLogs: z.boolean().default(false),\n showDeveloperDiagnostics: z.boolean().default(false),\n locale: instanceLocaleSchema.default(\"en\"),\n}).strict();\n\nexport const patchInstanceGeneralSettingsSchema = instanceGeneralSettingsSchema.partial();\n\nexport const instanceNotificationSettingsSchema = z.object({\n desktopInboxNotifications: z.boolean().default(true),\n desktopDockBadge: z.boolean().default(true),\n desktopIssueNotifications: z.boolean().default(true),\n desktopChatNotifications: z.boolean().default(true),\n}).strict();\n\nexport const patchInstanceNotificationSettingsSchema = instanceNotificationSettingsSchema.partial();\n\nexport const instanceLangfuseSettingsSchema = z.object({\n enabled: z.boolean().default(false),\n baseUrl: z.string().url().default(\"http://localhost:3000\"),\n publicKey: z.string().default(\"\"),\n environment: z.string().default(\"\"),\n secretKeyConfigured: z.boolean().default(false),\n managedByEnv: z.boolean().default(false),\n}).strict();\n\nexport const patchInstanceLangfuseSettingsSchema = z.object({\n enabled: z.boolean().optional(),\n baseUrl: z.string().url().optional(),\n publicKey: z.string().optional(),\n secretKey: z.string().optional(),\n environment: z.string().optional(),\n clearSecretKey: z.boolean().optional(),\n}).strict();\n\nexport const OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH = 8000;\n\nexport const operatorProfileSettingsSchema = z.object({\n nickname: z.string().max(80).default(\"\"),\n moreAboutYou: z.string().max(OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH).default(\"\"),\n}).strict();\n\nexport const patchOperatorProfileSettingsSchema = operatorProfileSettingsSchema.partial();\n\nexport const instancePathPickerSelectionTypeSchema = z.enum([\"file\", \"directory\"]);\n\nexport const instancePathPickerRequestSchema = z.object({\n selectionType: instancePathPickerSelectionTypeSchema,\n}).strict();\n\nexport const instancePathPickerResultSchema = z.object({\n path: z.string().nullable(),\n cancelled: z.boolean(),\n}).strict();\n\nexport type InstanceGeneralSettings = z.infer<typeof instanceGeneralSettingsSchema>;\nexport type PatchInstanceGeneralSettings = z.infer<typeof patchInstanceGeneralSettingsSchema>;\nexport type InstanceLangfuseSettings = z.infer<typeof instanceLangfuseSettingsSchema>;\nexport type PatchInstanceLangfuseSettings = z.infer<typeof patchInstanceLangfuseSettingsSchema>;\nexport type InstanceLocale = z.infer<typeof instanceLocaleSchema>;\nexport type OperatorProfileSettings = z.infer<typeof operatorProfileSettingsSchema>;\nexport type PatchOperatorProfileSettings = z.infer<typeof patchOperatorProfileSettingsSchema>;\nexport type InstanceNotificationSettings = z.infer<typeof instanceNotificationSettingsSchema>;\nexport type PatchInstanceNotificationSettings = z.infer<typeof patchInstanceNotificationSettingsSchema>;\nexport type InstancePathPickerSelectionType = z.infer<typeof instancePathPickerSelectionTypeSchema>;\nexport type InstancePathPickerRequest = z.infer<typeof instancePathPickerRequestSchema>;\nexport type InstancePathPickerResult = z.infer<typeof instancePathPickerResultSchema>;\n", "import { z } from \"zod\";\nimport {\n BUDGET_INCIDENT_RESOLUTION_ACTIONS,\n BUDGET_METRICS,\n BUDGET_SCOPE_TYPES,\n BUDGET_WINDOW_KINDS,\n} from \"../constants.js\";\n\nexport const upsertBudgetPolicySchema = z.object({\n scopeType: z.enum(BUDGET_SCOPE_TYPES),\n scopeId: z.string().uuid(),\n metric: z.enum(BUDGET_METRICS).optional().default(\"billed_cents\"),\n windowKind: z.enum(BUDGET_WINDOW_KINDS).optional().default(\"calendar_month_utc\"),\n amount: z.number().int().nonnegative(),\n warnPercent: z.number().int().min(1).max(99).optional().default(80),\n hardStopEnabled: z.boolean().optional().default(true),\n notifyEnabled: z.boolean().optional().default(true),\n isActive: z.boolean().optional().default(true),\n});\n\nexport type UpsertBudgetPolicy = z.infer<typeof upsertBudgetPolicySchema>;\n\nexport const resolveBudgetIncidentSchema = z.object({\n action: z.enum(BUDGET_INCIDENT_RESOLUTION_ACTIONS),\n amount: z.number().int().nonnegative().optional(),\n decisionNote: z.string().optional().nullable(),\n}).superRefine((value, ctx) => {\n if (value.action === \"raise_budget_and_resume\" && typeof value.amount !== \"number\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"amount is required when raising a budget\",\n path: [\"amount\"],\n });\n }\n});\n\nexport type ResolveBudgetIncident = z.infer<typeof resolveBudgetIncidentSchema>;\n", "import { z } from \"zod\";\nimport { CHAT_ISSUE_CREATION_MODES, ORGANIZATION_STATUSES } from \"../constants.js\";\n\nconst logoAssetIdSchema = z.string().uuid().nullable().optional();\nconst brandColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/).nullable().optional();\nexport const createOrganizationSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n budgetMonthlyCents: z.number().int().nonnegative().optional().default(0),\n defaultChatIssueCreationMode: z.enum(CHAT_ISSUE_CREATION_MODES).optional().default(\"manual_approval\"),\n brandColor: brandColorSchema,\n requireBoardApprovalForNewAgents: z.boolean().optional(),\n});\n\nexport type CreateOrganization = z.infer<typeof createOrganizationSchema>;\n\nexport const updateOrganizationSchema = createOrganizationSchema\n .partial()\n .extend({\n status: z.enum(ORGANIZATION_STATUSES).optional(),\n spentMonthlyCents: z.number().int().nonnegative().optional(),\n requireBoardApprovalForNewAgents: z.boolean().optional(),\n defaultChatIssueCreationMode: z.enum(CHAT_ISSUE_CREATION_MODES).optional(),\n brandColor: brandColorSchema,\n logoAssetId: logoAssetIdSchema,\n });\n\nexport type UpdateOrganization = z.infer<typeof updateOrganizationSchema>;\n\nexport const updateOrganizationBrandingSchema = z\n .object({\n name: z.string().min(1).optional(),\n description: z.string().nullable().optional(),\n brandColor: brandColorSchema,\n logoAssetId: logoAssetIdSchema,\n })\n .strict()\n .refine(\n (value) =>\n value.name !== undefined\n || value.description !== undefined\n || value.brandColor !== undefined\n || value.logoAssetId !== undefined,\n \"At least one branding field must be provided\",\n );\n\nexport type UpdateOrganizationBranding = z.infer<typeof updateOrganizationBrandingSchema>;\n\nexport const updateOrganizationWorkspaceFileSchema = z.object({\n content: z.string(),\n});\n\nexport type UpdateOrganizationWorkspaceFile = z.infer<typeof updateOrganizationWorkspaceFileSchema>;\n", "import { z } from \"zod\";\nimport { ORGANIZATION_RESOURCE_KINDS, PROJECT_RESOURCE_ATTACHMENT_ROLES } from \"../constants.js\";\n\nexport const organizationResourceKindSchema = z.enum(ORGANIZATION_RESOURCE_KINDS);\nexport const projectResourceAttachmentRoleSchema = z.enum(PROJECT_RESOURCE_ATTACHMENT_ROLES);\n\nexport const createOrganizationResourceSchema = z.object({\n name: z.string().min(1),\n kind: organizationResourceKindSchema,\n locator: z.string().min(1),\n description: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n});\n\nexport type CreateOrganizationResource = z.infer<typeof createOrganizationResourceSchema>;\n\nexport const updateOrganizationResourceSchema = z.object({\n name: z.string().min(1).optional(),\n kind: organizationResourceKindSchema.optional(),\n locator: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n}).strict();\n\nexport type UpdateOrganizationResource = z.infer<typeof updateOrganizationResourceSchema>;\n\nexport const projectResourceAttachmentInputSchema = z.object({\n resourceId: z.string().uuid(),\n role: projectResourceAttachmentRoleSchema.optional(),\n note: z.string().optional().nullable(),\n sortOrder: z.number().int().nonnegative().optional(),\n}).strict();\n\nexport type ProjectResourceAttachmentInputPayload = z.infer<typeof projectResourceAttachmentInputSchema>;\n\nexport const updateProjectResourceAttachmentSchema = z.object({\n role: projectResourceAttachmentRoleSchema.optional(),\n note: z.string().optional().nullable(),\n sortOrder: z.number().int().nonnegative().optional(),\n}).strict();\n\nexport type UpdateProjectResourceAttachment = z.infer<typeof updateProjectResourceAttachmentSchema>;\n\nexport const createProjectInlineResourceSchema = createOrganizationResourceSchema.extend({\n role: projectResourceAttachmentRoleSchema.optional(),\n note: z.string().optional().nullable(),\n sortOrder: z.number().int().nonnegative().optional(),\n}).strict();\n\nexport type CreateProjectInlineResource = z.infer<typeof createProjectInlineResourceSchema>;\n", "import { z } from \"zod\";\nimport {\n CHAT_CONTEXT_ENTITY_TYPES,\n CHAT_CONVERSATION_STATUSES,\n CHAT_ISSUE_CREATION_MODES,\n CHAT_MESSAGE_KINDS,\n CHAT_MESSAGE_ROLES,\n CHAT_MESSAGE_STATUSES,\n} from \"../constants.js\";\n\nexport const chatConversationStatusSchema = z.enum(CHAT_CONVERSATION_STATUSES);\nexport const chatIssueCreationModeSchema = z.enum(CHAT_ISSUE_CREATION_MODES);\nexport const chatMessageRoleSchema = z.enum(CHAT_MESSAGE_ROLES);\nexport const chatMessageKindSchema = z.enum(CHAT_MESSAGE_KINDS);\nexport const chatMessageStatusSchema = z.enum(CHAT_MESSAGE_STATUSES);\nexport const chatContextEntityTypeSchema = z.enum(CHAT_CONTEXT_ENTITY_TYPES);\n\nexport const createChatContextLinkSchema = z.object({\n entityType: chatContextEntityTypeSchema,\n entityId: z.string().min(1),\n metadata: z.record(z.unknown()).optional().nullable(),\n});\n\nexport const createChatConversationSchema = z.object({\n title: z.string().trim().min(1).max(200).optional(),\n summary: z.string().trim().max(5000).optional().nullable(),\n preferredAgentId: z.string().uuid().optional().nullable(),\n issueCreationMode: chatIssueCreationModeSchema.optional(),\n planMode: z.boolean().optional(),\n contextLinks: z.array(createChatContextLinkSchema).optional().default([]),\n});\n\nexport const setChatProjectContextSchema = z.object({\n projectId: z.string().uuid().optional().nullable(),\n});\n\nexport const updateChatConversationSchema = createChatConversationSchema\n .partial()\n .extend({\n status: chatConversationStatusSchema.optional(),\n routedAgentId: z.string().uuid().optional().nullable(),\n primaryIssueId: z.string().uuid().optional().nullable(),\n resolvedAt: z.string().datetime().optional().nullable(),\n });\n\nexport const addChatMessageSchema = z.object({\n body: z.string().trim().min(1).max(20000),\n editUserMessageId: z.string().uuid().optional().nullable(),\n});\n\nconst chatRichReferenceDisplaySchema = z.enum([\"card\", \"inline\"]);\nconst chatIssueIdentifierSchema = z.string().trim().min(1).max(64).regex(/^[A-Z0-9][A-Z0-9-]*$/i);\nconst chatAskUserIdentifierSchema = z.string().trim().min(1).max(64).regex(/^[a-zA-Z0-9_-]+$/);\n\nexport const chatAskUserOptionSchema = z.object({\n id: chatAskUserIdentifierSchema,\n label: z.string().trim().min(1).max(80),\n description: z.string().trim().min(1).max(220).optional(),\n recommended: z.boolean().optional(),\n});\n\nexport const chatAskUserQuestionSchema = z.object({\n id: chatAskUserIdentifierSchema,\n header: z.string().trim().min(1).max(32).optional(),\n question: z.string().trim().min(1).max(240),\n options: z.array(chatAskUserOptionSchema).min(2).max(3),\n allowFreeform: z.boolean().optional(),\n});\n\nexport const chatAskUserRequestSchema = z.object({\n questions: z.array(chatAskUserQuestionSchema).min(1).max(3),\n});\n\nconst chatIssueRichReferenceSchema = z.object({\n type: z.literal(\"issue\"),\n issueId: z.string().uuid().optional(),\n identifier: chatIssueIdentifierSchema.optional(),\n display: chatRichReferenceDisplaySchema.optional(),\n}).refine((value) => Boolean(value.issueId || value.identifier), {\n message: \"issueId or identifier is required\",\n});\n\nconst chatIssueCommentRichReferenceSchema = z.object({\n type: z.literal(\"issue_comment\"),\n issueId: z.string().uuid().optional(),\n identifier: chatIssueIdentifierSchema.optional(),\n commentId: z.string().uuid(),\n display: chatRichReferenceDisplaySchema.optional(),\n}).refine((value) => Boolean(value.issueId || value.identifier), {\n message: \"issueId or identifier is required\",\n});\n\nexport const chatRichReferenceSchema = z.union([\n chatIssueRichReferenceSchema,\n chatIssueCommentRichReferenceSchema,\n]);\n\nexport const chatRichReferencesSchema = z.array(chatRichReferenceSchema).max(5);\n\nexport function chatRichReferencesFromStructuredPayload(payload: unknown) {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return [];\n const rawReferences = (payload as Record<string, unknown>).richReferences;\n if (!Array.isArray(rawReferences)) return [];\n\n return rawReferences\n .map((reference) => chatRichReferenceSchema.safeParse(reference))\n .filter((result): result is z.SafeParseSuccess<z.infer<typeof chatRichReferenceSchema>> => result.success)\n .map((result) => result.data)\n .slice(0, 5);\n}\n\nexport function chatAskUserRequestFromStructuredPayload(payload: unknown) {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return null;\n const rawRequest = (payload as Record<string, unknown>).requestUserInput;\n const parsed = chatAskUserRequestSchema.safeParse(rawRequest);\n return parsed.success ? parsed.data : null;\n}\n\nexport function sanitizeChatStructuredPayload(payload: Record<string, unknown> | null | undefined) {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return null;\n const next = { ...payload };\n const requestUserInput = chatAskUserRequestFromStructuredPayload(payload);\n if (requestUserInput) {\n next.requestUserInput = requestUserInput;\n } else {\n delete next.requestUserInput;\n }\n const richReferences = chatRichReferencesFromStructuredPayload(payload);\n if (richReferences.length > 0) {\n next.richReferences = richReferences;\n } else {\n delete next.richReferences;\n }\n return Object.keys(next).length > 0 ? next : null;\n}\n\nexport const createChatAttachmentMetadataSchema = z.object({\n messageId: z.string().uuid(),\n});\n\nconst chatIssueProposalSchema = z.object({\n title: z.string().trim().min(1).max(200),\n description: z.string().trim().min(1).max(20000),\n priority: z.enum([\"critical\", \"high\", \"medium\", \"low\"]).optional().default(\"medium\"),\n projectId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n parentId: z.string().uuid().optional().nullable(),\n assigneeAgentId: z.string().uuid().optional().nullable(),\n assigneeUserId: z.string().trim().optional().nullable(),\n reviewerAgentId: z.string().uuid().optional().nullable(),\n reviewerUserId: z.string().trim().optional().nullable(),\n});\n\nexport const convertChatToIssueSchema = z.object({\n messageId: z.string().uuid().optional().nullable(),\n proposal: chatIssueProposalSchema.optional(),\n});\n\nexport const chatOperationProposalSchema = z.object({\n targetType: z.enum([\"organization\", \"agent\"]),\n targetId: z.string().min(1),\n summary: z.string().trim().min(1).max(500),\n patch: z.record(z.unknown()),\n});\n\nexport const resolveChatOperationProposalSchema = z.object({\n action: z.enum([\"approve\", \"reject\", \"requestRevision\"]),\n decisionNote: z.string().trim().max(5000).optional().nullable(),\n});\n\nexport const updateChatConversationUserStateSchema = z.object({\n pinned: z.boolean().optional(),\n unread: z.boolean().optional(),\n});\n\nexport type ChatConversationStatus = z.infer<typeof chatConversationStatusSchema>;\nexport type ChatIssueCreationMode = z.infer<typeof chatIssueCreationModeSchema>;\nexport type ChatMessageRole = z.infer<typeof chatMessageRoleSchema>;\nexport type ChatMessageKind = z.infer<typeof chatMessageKindSchema>;\nexport type ChatMessageStatus = z.infer<typeof chatMessageStatusSchema>;\nexport type ChatContextEntityType = z.infer<typeof chatContextEntityTypeSchema>;\nexport type CreateChatContextLink = z.infer<typeof createChatContextLinkSchema>;\nexport type CreateChatConversation = z.infer<typeof createChatConversationSchema>;\nexport type SetChatProjectContext = z.infer<typeof setChatProjectContextSchema>;\nexport type UpdateChatConversation = z.infer<typeof updateChatConversationSchema>;\nexport type AddChatMessage = z.infer<typeof addChatMessageSchema>;\nexport type ChatAskUserOption = z.infer<typeof chatAskUserOptionSchema>;\nexport type ChatAskUserQuestion = z.infer<typeof chatAskUserQuestionSchema>;\nexport type ChatAskUserRequest = z.infer<typeof chatAskUserRequestSchema>;\nexport type ChatRichReference = z.infer<typeof chatRichReferenceSchema>;\nexport type CreateChatAttachmentMetadata = z.infer<typeof createChatAttachmentMetadataSchema>;\nexport type ConvertChatToIssue = z.infer<typeof convertChatToIssueSchema>;\nexport type ChatOperationProposal = z.infer<typeof chatOperationProposalSchema>;\nexport type ResolveChatOperationProposal = z.infer<typeof resolveChatOperationProposalSchema>;\nexport type UpdateChatConversationUserState = z.infer<typeof updateChatConversationUserStateSchema>;\n", "import { z } from \"zod\";\n\nexport const organizationSkillSourceTypeSchema = z.enum([\"local_path\", \"github\", \"url\", \"catalog\", \"skills_sh\"]);\nexport const organizationSkillTrustLevelSchema = z.enum([\"markdown_only\", \"assets\", \"scripts_executables\"]);\nexport const organizationSkillCompatibilitySchema = z.enum([\"compatible\", \"unknown\", \"invalid\"]);\nexport const organizationSkillSourceBadgeSchema = z.enum([\n \"rudder\",\n \"community\",\n \"github\",\n \"local\",\n \"url\",\n \"catalog\",\n \"skills_sh\",\n]);\n\nexport const organizationSkillFileInventoryEntrySchema = z.object({\n path: z.string().min(1),\n kind: z.enum([\"skill\", \"markdown\", \"reference\", \"script\", \"asset\", \"other\"]),\n});\n\nexport const organizationSkillSchema = z.object({\n id: z.string().uuid(),\n orgId: z.string().uuid(),\n key: z.string().min(1),\n slug: z.string().min(1),\n name: z.string().min(1),\n description: z.string().nullable(),\n markdown: z.string(),\n sourceType: organizationSkillSourceTypeSchema,\n sourceLocator: z.string().nullable(),\n sourceRef: z.string().nullable(),\n trustLevel: organizationSkillTrustLevelSchema,\n compatibility: organizationSkillCompatibilitySchema,\n fileInventory: z.array(organizationSkillFileInventoryEntrySchema).default([]),\n metadata: z.record(z.unknown()).nullable(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n});\n\nexport const organizationSkillListItemSchema = organizationSkillSchema.extend({\n attachedAgentCount: z.number().int().nonnegative(),\n editable: z.boolean(),\n editableReason: z.string().nullable(),\n sourceLabel: z.string().nullable(),\n sourceBadge: organizationSkillSourceBadgeSchema,\n sourcePath: z.string().nullable(),\n workspaceEditPath: z.string().nullable(),\n});\n\nexport const organizationSkillUsageAgentSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(1),\n urlKey: z.string().min(1),\n agentRuntimeType: z.string().min(1),\n desired: z.boolean(),\n actualState: z.string().nullable(),\n});\n\nexport const organizationSkillDetailSchema = organizationSkillSchema.extend({\n attachedAgentCount: z.number().int().nonnegative(),\n usedByAgents: z.array(organizationSkillUsageAgentSchema).default([]),\n editable: z.boolean(),\n editableReason: z.string().nullable(),\n sourceLabel: z.string().nullable(),\n sourceBadge: organizationSkillSourceBadgeSchema,\n sourcePath: z.string().nullable(),\n workspaceEditPath: z.string().nullable(),\n});\n\nexport const organizationSkillUpdateStatusSchema = z.object({\n supported: z.boolean(),\n reason: z.string().nullable(),\n trackingRef: z.string().nullable(),\n currentRef: z.string().nullable(),\n latestRef: z.string().nullable(),\n hasUpdate: z.boolean(),\n});\n\nexport const organizationSkillImportSchema = z.object({\n source: z.string().min(1),\n});\n\nexport const organizationSkillProjectScanRequestSchema = z.object({\n projectIds: z.array(z.string().uuid()).optional(),\n workspaceIds: z.array(z.string().uuid()).optional(),\n});\n\nexport const organizationSkillProjectScanSkippedSchema = z.object({\n projectId: z.string().uuid(),\n projectName: z.string().min(1),\n workspaceId: z.string().uuid().nullable(),\n workspaceName: z.string().nullable(),\n path: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillProjectScanConflictSchema = z.object({\n slug: z.string().min(1),\n key: z.string().min(1),\n projectId: z.string().uuid(),\n projectName: z.string().min(1),\n workspaceId: z.string().uuid(),\n workspaceName: z.string().min(1),\n path: z.string().min(1),\n existingSkillId: z.string().uuid(),\n existingSkillKey: z.string().min(1),\n existingSourceLocator: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillProjectScanResultSchema = z.object({\n scannedProjects: z.number().int().nonnegative(),\n scannedWorkspaces: z.number().int().nonnegative(),\n discovered: z.number().int().nonnegative(),\n imported: z.array(organizationSkillSchema),\n updated: z.array(organizationSkillSchema),\n skipped: z.array(organizationSkillProjectScanSkippedSchema),\n conflicts: z.array(organizationSkillProjectScanConflictSchema),\n warnings: z.array(z.string()),\n});\n\nexport const organizationSkillLocalScanRequestSchema = z.object({\n roots: z.array(z.string().min(1)).optional(),\n});\n\nexport const organizationSkillLocalScanSkippedSchema = z.object({\n root: z.string().min(1),\n path: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillLocalScanConflictSchema = z.object({\n root: z.string().min(1),\n path: z.string().min(1),\n slug: z.string().min(1),\n key: z.string().min(1),\n existingSkillId: z.string().uuid(),\n existingSkillKey: z.string().min(1),\n existingSourceLocator: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillLocalScanResultSchema = z.object({\n scannedRoots: z.number().int().nonnegative(),\n discovered: z.number().int().nonnegative(),\n imported: z.array(organizationSkillSchema),\n updated: z.array(organizationSkillSchema),\n skipped: z.array(organizationSkillLocalScanSkippedSchema),\n conflicts: z.array(organizationSkillLocalScanConflictSchema),\n warnings: z.array(z.string()),\n});\n\nexport const organizationSkillCreateSchema = z.object({\n name: z.string().min(1),\n slug: z.string().min(1).nullable().optional(),\n description: z.string().nullable().optional(),\n markdown: z.string().nullable().optional(),\n});\n\nexport const organizationSkillFileDetailSchema = z.object({\n skillId: z.string().uuid(),\n path: z.string().min(1),\n kind: z.enum([\"skill\", \"markdown\", \"reference\", \"script\", \"asset\", \"other\"]),\n content: z.string(),\n language: z.string().nullable(),\n markdown: z.boolean(),\n editable: z.boolean(),\n});\n\nexport const organizationSkillFileUpdateSchema = z.object({\n path: z.string().min(1),\n content: z.string(),\n});\n\nexport type OrganizationSkillImport = z.infer<typeof organizationSkillImportSchema>;\nexport type OrganizationSkillProjectScan = z.infer<typeof organizationSkillProjectScanRequestSchema>;\nexport type OrganizationSkillLocalScan = z.infer<typeof organizationSkillLocalScanRequestSchema>;\nexport type OrganizationSkillCreate = z.infer<typeof organizationSkillCreateSchema>;\nexport type OrganizationSkillFileUpdate = z.infer<typeof organizationSkillFileUpdateSchema>;\n", "import { z } from \"zod\";\n\nexport const agentSkillStateSchema = z.enum([\n \"available\",\n \"configured\",\n \"installed\",\n \"missing\",\n \"stale\",\n \"external\",\n]);\n\nexport const agentSkillOriginSchema = z.preprocess((value) => {\n if (value === \"company_managed\") return \"organization_managed\";\n return value;\n}, z.enum([\n \"organization_managed\",\n \"user_installed\",\n \"external_unknown\",\n]));\n\nexport const agentSkillSourceClassSchema = z.enum([\n \"bundled\",\n \"organization\",\n \"agent_home\",\n \"global\",\n \"adapter_home\",\n]);\n\nexport const agentSkillSyncModeSchema = z.enum([\n \"unsupported\",\n \"persistent\",\n \"ephemeral\",\n]);\n\nexport const agentSkillEntrySchema = z.object({\n key: z.string().min(1),\n selectionKey: z.string().min(1),\n runtimeName: z.string().min(1).nullable(),\n description: z.string().nullable().optional(),\n desired: z.boolean(),\n configurable: z.boolean(),\n alwaysEnabled: z.boolean(),\n managed: z.boolean(),\n state: agentSkillStateSchema,\n sourceClass: agentSkillSourceClassSchema,\n origin: agentSkillOriginSchema.optional(),\n originLabel: z.string().nullable().optional(),\n locationLabel: z.string().nullable().optional(),\n readOnly: z.boolean().optional(),\n sourcePath: z.string().nullable().optional(),\n targetPath: z.string().nullable().optional(),\n workspaceEditPath: z.string().nullable().optional(),\n detail: z.string().nullable().optional(),\n});\n\nexport const agentSkillSnapshotSchema = z.object({\n agentRuntimeType: z.string().min(1),\n supported: z.boolean(),\n mode: agentSkillSyncModeSchema,\n desiredSkills: z.array(z.string().min(1)),\n entries: z.array(agentSkillEntrySchema),\n warnings: z.array(z.string()),\n});\n\nexport const agentSkillSyncSchema = z.object({\n desiredSkills: z.array(z.string().min(1)),\n});\n\nexport const agentSkillEnableSchema = z.object({\n skills: z.array(z.string().min(1)).min(1),\n});\n\nexport type AgentSkillSync = z.infer<typeof agentSkillSyncSchema>;\nexport type AgentSkillEnable = z.infer<typeof agentSkillEnableSchema>;\n", "import { z } from \"zod\";\n\nexport const portabilityIncludeSchema = z\n .object({\n organization: z.boolean().optional(),\n agents: z.boolean().optional(),\n projects: z.boolean().optional(),\n issues: z.boolean().optional(),\n skills: z.boolean().optional(),\n })\n .partial();\n\nexport const portabilityEnvInputSchema = z.object({\n key: z.string().min(1),\n description: z.string().nullable(),\n agentSlug: z.string().min(1).nullable(),\n kind: z.enum([\"secret\", \"plain\"]),\n requirement: z.enum([\"required\", \"optional\"]),\n defaultValue: z.string().nullable(),\n portability: z.enum([\"portable\", \"system_dependent\"]),\n});\n\nexport const portabilityFileEntrySchema = z.union([\n z.string(),\n z.object({\n encoding: z.literal(\"base64\"),\n data: z.string(),\n contentType: z.string().min(1).optional().nullable(),\n }),\n]);\n\nexport const portabilityOrganizationManifestEntrySchema = z.object({\n path: z.string().min(1),\n name: z.string().min(1),\n description: z.string().nullable(),\n brandColor: z.string().nullable(),\n logoPath: z.string().nullable(),\n requireBoardApprovalForNewAgents: z.boolean(),\n});\n\nexport const portabilitySidebarOrderSchema = z.object({\n agents: z.array(z.string().min(1)).default([]),\n projects: z.array(z.string().min(1)).default([]),\n});\n\nexport const portabilityAgentManifestEntrySchema = z.object({\n slug: z.string().min(1),\n name: z.string().min(1),\n path: z.string().min(1),\n skills: z.array(z.string().min(1)).default([]),\n role: z.string().min(1),\n title: z.string().nullable(),\n icon: z.string().nullable(),\n capabilities: z.string().nullable(),\n reportsToSlug: z.string().min(1).nullable(),\n agentRuntimeType: z.string().min(1),\n agentRuntimeConfig: z.record(z.unknown()),\n runtimeConfig: z.record(z.unknown()),\n permissions: z.record(z.unknown()),\n budgetMonthlyCents: z.number().int().nonnegative(),\n metadata: z.record(z.unknown()).nullable(),\n});\n\nexport const portabilitySkillManifestEntrySchema = z.object({\n key: z.string().min(1),\n slug: z.string().min(1),\n name: z.string().min(1),\n path: z.string().min(1),\n description: z.string().nullable(),\n sourceType: z.string().min(1),\n sourceLocator: z.string().nullable(),\n sourceRef: z.string().nullable(),\n trustLevel: z.string().nullable(),\n compatibility: z.string().nullable(),\n metadata: z.record(z.unknown()).nullable(),\n fileInventory: z.array(z.object({\n path: z.string().min(1),\n kind: z.string().min(1),\n })).default([]),\n});\n\nexport const portabilityProjectManifestEntrySchema = z.object({\n slug: z.string().min(1),\n name: z.string().min(1),\n path: z.string().min(1),\n description: z.string().nullable(),\n ownerAgentSlug: z.string().min(1).nullable(),\n leadAgentSlug: z.string().min(1).nullable(),\n targetDate: z.string().nullable(),\n color: z.string().nullable(),\n status: z.string().nullable(),\n executionWorkspacePolicy: z.record(z.unknown()).nullable(),\n workspaces: z.array(z.object({\n key: z.string().min(1),\n name: z.string().min(1),\n sourceType: z.string().nullable(),\n repoUrl: z.string().nullable(),\n repoRef: z.string().nullable(),\n defaultRef: z.string().nullable(),\n visibility: z.string().nullable(),\n setupCommand: z.string().nullable(),\n cleanupCommand: z.string().nullable(),\n metadata: z.record(z.unknown()).nullable(),\n isPrimary: z.boolean(),\n })).default([]),\n metadata: z.record(z.unknown()).nullable(),\n});\n\nexport const portabilityIssueAutomationTriggerManifestEntrySchema = z.object({\n kind: z.string().min(1),\n label: z.string().nullable(),\n enabled: z.boolean(),\n cronExpression: z.string().nullable(),\n timezone: z.string().nullable(),\n signingMode: z.string().nullable(),\n replayWindowSec: z.number().int().nullable(),\n});\n\nexport const portabilityIssueAutomationManifestEntrySchema = z.object({\n concurrencyPolicy: z.string().nullable(),\n catchUpPolicy: z.string().nullable(),\n triggers: z.array(portabilityIssueAutomationTriggerManifestEntrySchema).default([]),\n});\n\nexport const portabilityIssueManifestEntrySchema = z.object({\n slug: z.string().min(1),\n identifier: z.string().min(1).nullable(),\n title: z.string().min(1),\n path: z.string().min(1),\n projectSlug: z.string().min(1).nullable(),\n projectWorkspaceKey: z.string().min(1).nullable(),\n assigneeAgentSlug: z.string().min(1).nullable(),\n description: z.string().nullable(),\n recurring: z.boolean().default(false),\n automation: portabilityIssueAutomationManifestEntrySchema.nullable(),\n legacyRecurrence: z.record(z.unknown()).nullable(),\n status: z.string().nullable(),\n priority: z.string().nullable(),\n labelIds: z.array(z.string().min(1)).default([]),\n billingCode: z.string().nullable(),\n executionWorkspaceSettings: z.record(z.unknown()).nullable(),\n assigneeAgentRuntimeOverrides: z.record(z.unknown()).nullable(),\n metadata: z.record(z.unknown()).nullable(),\n});\n\nexport const portabilityManifestSchema = z.object({\n schemaVersion: z.number().int().positive(),\n generatedAt: z.string().datetime(),\n source: z\n .object({\n orgId: z.string().uuid(),\n organizationName: z.string().min(1),\n })\n .nullable(),\n includes: z.object({\n organization: z.boolean(),\n agents: z.boolean(),\n projects: z.boolean(),\n issues: z.boolean(),\n skills: z.boolean(),\n }),\n organization: portabilityOrganizationManifestEntrySchema.nullable(),\n sidebar: portabilitySidebarOrderSchema.nullable(),\n agents: z.array(portabilityAgentManifestEntrySchema),\n skills: z.array(portabilitySkillManifestEntrySchema).default([]),\n projects: z.array(portabilityProjectManifestEntrySchema).default([]),\n issues: z.array(portabilityIssueManifestEntrySchema).default([]),\n envInputs: z.array(portabilityEnvInputSchema).default([]),\n});\n\nexport const portabilitySourceSchema = z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"inline\"),\n rootPath: z.string().min(1).optional().nullable(),\n files: z.record(portabilityFileEntrySchema),\n }),\n z.object({\n type: z.literal(\"github\"),\n url: z.string().url(),\n }),\n]);\n\nexport const portabilityTargetSchema = z.discriminatedUnion(\"mode\", [\n z.object({\n mode: z.literal(\"new_organization\"),\n newOrganizationName: z.string().min(1).optional().nullable(),\n }),\n z.object({\n mode: z.literal(\"existing_organization\"),\n orgId: z.string().uuid(),\n }),\n]);\n\nexport const portabilityAgentSelectionSchema = z.union([\n z.literal(\"all\"),\n z.array(z.string().min(1)),\n]);\n\nexport const portabilityCollisionStrategySchema = z.enum([\"rename\", \"skip\", \"replace\"]);\n\nexport const organizationPortabilityExportSchema = z.object({\n include: portabilityIncludeSchema.optional(),\n agents: z.array(z.string().min(1)).optional(),\n skills: z.array(z.string().min(1)).optional(),\n projects: z.array(z.string().min(1)).optional(),\n issues: z.array(z.string().min(1)).optional(),\n projectIssues: z.array(z.string().min(1)).optional(),\n selectedFiles: z.array(z.string().min(1)).optional(),\n expandReferencedSkills: z.boolean().optional(),\n sidebarOrder: portabilitySidebarOrderSchema.partial().optional(),\n});\n\nexport type OrganizationPortabilityExport = z.infer<typeof organizationPortabilityExportSchema>;\n\nexport const organizationPortabilityPreviewSchema = z.object({\n source: portabilitySourceSchema,\n include: portabilityIncludeSchema.optional(),\n target: portabilityTargetSchema,\n agents: portabilityAgentSelectionSchema.optional(),\n collisionStrategy: portabilityCollisionStrategySchema.optional(),\n nameOverrides: z.record(z.string().min(1), z.string().min(1)).optional(),\n selectedFiles: z.array(z.string().min(1)).optional(),\n});\n\nexport type OrganizationPortabilityPreview = z.infer<typeof organizationPortabilityPreviewSchema>;\n\nexport const portabilityAdapterOverrideSchema = z.object({\n agentRuntimeType: z.string().min(1),\n agentRuntimeConfig: z.record(z.unknown()).optional(),\n});\n\nexport const organizationPortabilityImportSchema = organizationPortabilityPreviewSchema.extend({\n agentRuntimeOverrides: z.record(z.string().min(1), portabilityAdapterOverrideSchema).optional(),\n});\n\nexport type OrganizationPortabilityImport = z.infer<typeof organizationPortabilityImportSchema>;\n", "import { z } from \"zod\";\nimport { SECRET_PROVIDERS } from \"../constants.js\";\n\nexport const envBindingPlainSchema = z.object({\n type: z.literal(\"plain\"),\n value: z.string(),\n});\n\nexport const envBindingSecretRefSchema = z.object({\n type: z.literal(\"secret_ref\"),\n secretId: z.string().uuid(),\n version: z.union([z.literal(\"latest\"), z.number().int().positive()]).optional(),\n});\n\n// Backward-compatible union that accepts legacy inline values.\nexport const envBindingSchema = z.union([\n z.string(),\n envBindingPlainSchema,\n envBindingSecretRefSchema,\n]);\n\nexport const envConfigSchema = z.record(envBindingSchema);\n\nexport const createSecretSchema = z.object({\n name: z.string().min(1),\n provider: z.enum(SECRET_PROVIDERS).optional(),\n value: z.string().min(1),\n description: z.string().optional().nullable(),\n externalRef: z.string().optional().nullable(),\n});\n\nexport type CreateSecret = z.infer<typeof createSecretSchema>;\n\nexport const rotateSecretSchema = z.object({\n value: z.string().min(1),\n externalRef: z.string().optional().nullable(),\n});\n\nexport type RotateSecret = z.infer<typeof rotateSecretSchema>;\n\nexport const updateSecretSchema = z.object({\n name: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n externalRef: z.string().optional().nullable(),\n});\n\nexport type UpdateSecret = z.infer<typeof updateSecretSchema>;\n", "import { z } from \"zod\";\nimport { AGENT_RUNTIME_TYPES } from \"../constants.js\";\nimport { envConfigSchema } from \"./secret.js\";\n\nconst agentRuntimeTypes = new Set<string>(AGENT_RUNTIME_TYPES);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function validateModelFallbacksConfig(\n value: Record<string, unknown>,\n ctx: z.RefinementCtx,\n pathPrefix: Array<string | number>,\n) {\n const fallbackModels = value.modelFallbacks;\n if (fallbackModels === undefined) return;\n\n if (!Array.isArray(fallbackModels)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks must be an array\",\n path: [...pathPrefix, \"modelFallbacks\"],\n });\n return;\n }\n\n fallbackModels.forEach((fallback, index) => {\n if (typeof fallback === \"string\") {\n if (fallback.trim().length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks string entries must be non-empty\",\n path: [...pathPrefix, \"modelFallbacks\", index],\n });\n }\n return;\n }\n\n if (!isRecord(fallback)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must be strings or runtime/model objects\",\n path: [...pathPrefix, \"modelFallbacks\", index],\n });\n return;\n }\n\n if (typeof fallback.agentRuntimeType !== \"string\" || fallback.agentRuntimeType.trim().length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must include agentRuntimeType\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"agentRuntimeType\"],\n });\n } else if (!agentRuntimeTypes.has(fallback.agentRuntimeType)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must include a valid agentRuntimeType\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"agentRuntimeType\"],\n });\n }\n if (typeof fallback.model !== \"string\" || fallback.model.trim().length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must include model\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"model\"],\n });\n }\n if (fallback.config !== undefined && !isRecord(fallback.config)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entry config must be an object\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"config\"],\n });\n } else if (isRecord(fallback.config) && fallback.config.env !== undefined) {\n const parsed = envConfigSchema.safeParse(fallback.config.env);\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entry config.env must be a map of valid env bindings\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"config\", \"env\"],\n });\n }\n }\n });\n}\n", "import { z } from \"zod\";\nimport {\n AGENT_RUNTIME_TYPES,\n AGENT_ICON_NAMES,\n AGENT_ROLES,\n AGENT_STATUSES,\n} from \"../constants.js\";\nimport { envConfigSchema } from \"./secret.js\";\nimport { validateModelFallbacksConfig } from \"./model-fallbacks.js\";\n\nexport const agentPermissionsSchema = z.object({\n canCreateAgents: z.boolean().optional().default(false),\n});\n\nexport const agentInstructionsBundleModeSchema = z.enum([\"managed\", \"external\"]);\n\nexport const updateAgentInstructionsBundleSchema = z.object({\n mode: agentInstructionsBundleModeSchema.optional(),\n rootPath: z.string().trim().min(1).nullable().optional(),\n entryFile: z.string().trim().min(1).optional(),\n clearLegacyPromptTemplate: z.boolean().optional().default(false),\n});\n\nexport type UpdateAgentInstructionsBundle = z.infer<typeof updateAgentInstructionsBundleSchema>;\n\nexport const upsertAgentInstructionsFileSchema = z.object({\n path: z.string().trim().min(1),\n content: z.string(),\n clearLegacyPromptTemplate: z.boolean().optional().default(false),\n});\n\nexport type UpsertAgentInstructionsFile = z.infer<typeof upsertAgentInstructionsFileSchema>;\n\nconst agentRuntimeConfigSchema = z.record(z.unknown()).superRefine((value, ctx) => {\n const envValue = value.env;\n if (envValue !== undefined) {\n const parsed = envConfigSchema.safeParse(envValue);\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"agentRuntimeConfig.env must be a map of valid env bindings\",\n path: [\"env\"],\n });\n }\n }\n\n validateModelFallbacksConfig(value, ctx, []);\n});\n\nconst optionalAgentNameSchema = z.preprocess(\n (value) => {\n if (typeof value !== \"string\") return value;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n },\n z.string().trim().min(1).optional(),\n);\n\nexport const uploadedAgentIconSchema = z.string().regex(\n /^asset:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n \"Invalid uploaded avatar reference\",\n);\n\nexport const customAgentIconSchema = z.string()\n .trim()\n .min(1)\n .max(24)\n .refine((value) => !value.toLowerCase().startsWith(\"asset:\"), \"Invalid uploaded avatar reference\")\n .refine((value) => !/[<>\\u0000-\\u001f\\u007f]/u.test(value), \"Icon cannot contain markup or control characters\");\n\nexport const agentIconSchema = z.preprocess(\n (value) => {\n if (typeof value !== \"string\") return value;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n },\n z.union([\n z.enum(AGENT_ICON_NAMES),\n uploadedAgentIconSchema,\n customAgentIconSchema,\n ]).nullable(),\n);\n\nexport const createAgentSchema = z.object({\n name: optionalAgentNameSchema,\n role: z.enum(AGENT_ROLES).optional().default(\"general\"),\n title: z.string().optional().nullable(),\n icon: agentIconSchema.optional(),\n reportsTo: z.string().uuid().optional().nullable(),\n capabilities: z.string().optional().nullable(),\n desiredSkills: z.array(z.string().min(1)).optional(),\n agentRuntimeType: z.enum(AGENT_RUNTIME_TYPES).optional().default(\"process\"),\n agentRuntimeConfig: agentRuntimeConfigSchema.optional().default({}),\n runtimeConfig: z.record(z.unknown()).optional().default({}),\n budgetMonthlyCents: z.number().int().nonnegative().optional().default(0),\n permissions: agentPermissionsSchema.optional(),\n metadata: z.record(z.unknown()).optional().nullable(),\n});\n\nexport type CreateAgent = z.infer<typeof createAgentSchema>;\n\nexport const createAgentHireSchema = createAgentSchema.extend({\n sourceIssueId: z.string().uuid().optional().nullable(),\n sourceIssueIds: z.array(z.string().uuid()).optional(),\n});\n\nexport type CreateAgentHire = z.infer<typeof createAgentHireSchema>;\n\nexport const updateAgentSchema = createAgentSchema\n .omit({ permissions: true })\n .partial()\n .extend({\n permissions: z.never().optional(),\n replaceAgentRuntimeConfig: z.boolean().optional(),\n status: z.enum(AGENT_STATUSES).optional(),\n spentMonthlyCents: z.number().int().nonnegative().optional(),\n });\n\nexport type UpdateAgent = z.infer<typeof updateAgentSchema>;\n\nexport const updateAgentInstructionsPathSchema = z.object({\n path: z.string().trim().min(1).nullable(),\n agentRuntimeConfigKey: z.string().trim().min(1).optional(),\n});\n\nexport type UpdateAgentInstructionsPath = z.infer<typeof updateAgentInstructionsPathSchema>;\n\nexport const createAgentKeySchema = z.object({\n name: z.string().min(1).default(\"default\"),\n});\n\nexport type CreateAgentKey = z.infer<typeof createAgentKeySchema>;\n\nexport const wakeAgentSchema = z.object({\n source: z.enum([\"timer\", \"assignment\", \"review\", \"on_demand\", \"automation\"]).optional().default(\"on_demand\"),\n triggerDetail: z.enum([\"manual\", \"ping\", \"callback\", \"system\"]).optional(),\n reason: z.string().optional().nullable(),\n payload: z.record(z.unknown()).optional().nullable(),\n idempotencyKey: z.string().optional().nullable(),\n forceFreshSession: z.preprocess(\n (value) => (value === null ? undefined : value),\n z.boolean().optional().default(false),\n ),\n});\n\nexport type WakeAgent = z.infer<typeof wakeAgentSchema>;\n\nexport const resetAgentSessionSchema = z.object({\n taskKey: z.string().min(1).optional().nullable(),\n});\n\nexport type ResetAgentSession = z.infer<typeof resetAgentSessionSchema>;\n\nexport const testAgentRuntimeEnvironmentSchema = z.object({\n agentRuntimeConfig: agentRuntimeConfigSchema.optional().default({}),\n});\n\nexport type TestAgentRuntimeEnvironment = z.infer<typeof testAgentRuntimeEnvironmentSchema>;\n\nexport const updateAgentPermissionsSchema = z.object({\n canCreateAgents: z.boolean(),\n canAssignTasks: z.boolean(),\n});\n\nexport type UpdateAgentPermissions = z.infer<typeof updateAgentPermissionsSchema>;\n", "import { z } from \"zod\";\nimport { PROJECT_COLORS, PROJECT_STATUSES } from \"../constants.js\";\nimport {\n createProjectInlineResourceSchema,\n projectResourceAttachmentInputSchema,\n} from \"./resource.js\";\n\nconst executionWorkspaceStrategySchema = z\n .object({\n type: z.enum([\"project_primary\", \"git_worktree\", \"adapter_managed\", \"cloud_sandbox\"]).optional(),\n baseRef: z.string().optional().nullable(),\n branchTemplate: z.string().optional().nullable(),\n worktreeParentDir: z.string().optional().nullable(),\n provisionCommand: z.string().optional().nullable(),\n teardownCommand: z.string().optional().nullable(),\n })\n .strict();\n\nexport const projectExecutionWorkspacePolicySchema = z\n .object({\n enabled: z.boolean(),\n defaultMode: z.enum([\"shared_workspace\", \"isolated_workspace\", \"operator_branch\", \"adapter_default\"]).optional(),\n allowIssueOverride: z.boolean().optional(),\n defaultProjectWorkspaceId: z.string().uuid().optional().nullable(),\n workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),\n workspaceRuntime: z.record(z.unknown()).optional().nullable(),\n branchPolicy: z.record(z.unknown()).optional().nullable(),\n pullRequestPolicy: z.record(z.unknown()).optional().nullable(),\n runtimePolicy: z.record(z.unknown()).optional().nullable(),\n cleanupPolicy: z.record(z.unknown()).optional().nullable(),\n })\n .strict();\n\nconst projectWorkspaceSourceTypeSchema = z.enum([\"local_path\", \"git_repo\", \"remote_managed\", \"non_git_path\"]);\nconst projectWorkspaceVisibilitySchema = z.enum([\"default\", \"advanced\"]);\n\nconst projectWorkspaceFields = {\n name: z.string().min(1).optional(),\n sourceType: projectWorkspaceSourceTypeSchema.optional(),\n cwd: z.string().min(1).optional().nullable(),\n repoUrl: z.string().url().optional().nullable(),\n repoRef: z.string().optional().nullable(),\n defaultRef: z.string().optional().nullable(),\n visibility: projectWorkspaceVisibilitySchema.optional(),\n setupCommand: z.string().optional().nullable(),\n cleanupCommand: z.string().optional().nullable(),\n remoteProvider: z.string().optional().nullable(),\n remoteWorkspaceRef: z.string().optional().nullable(),\n sharedWorkspaceKey: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n};\n\nconst projectColorValues = new Set<string>(PROJECT_COLORS);\nconst legacyProjectColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/);\nconst projectColorSchema = z.string().refine(\n (value) => legacyProjectColorSchema.safeParse(value).success || projectColorValues.has(value),\n \"Color must be a 6-digit hex value or a supported project gradient\",\n);\n\nfunction validateProjectWorkspace(value: Record<string, unknown>, ctx: z.RefinementCtx) {\n const sourceType = value.sourceType ?? \"local_path\";\n const hasCwd = typeof value.cwd === \"string\" && value.cwd.trim().length > 0;\n const hasRepo = typeof value.repoUrl === \"string\" && value.repoUrl.trim().length > 0;\n const hasRemoteRef = typeof value.remoteWorkspaceRef === \"string\" && value.remoteWorkspaceRef.trim().length > 0;\n\n if (sourceType === \"remote_managed\") {\n if (!hasRemoteRef && !hasRepo) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Remote-managed workspace requires remoteWorkspaceRef or repoUrl.\",\n path: [\"remoteWorkspaceRef\"],\n });\n }\n return;\n }\n\n if (!hasCwd && !hasRepo) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Workspace requires at least one of cwd or repoUrl.\",\n path: [\"cwd\"],\n });\n }\n}\n\nexport const createProjectWorkspaceSchema = z.object({\n ...projectWorkspaceFields,\n isPrimary: z.boolean().optional().default(false),\n}).superRefine(validateProjectWorkspace);\n\nexport type CreateProjectWorkspace = z.infer<typeof createProjectWorkspaceSchema>;\n\nexport const updateProjectWorkspaceSchema = z.object({\n ...projectWorkspaceFields,\n isPrimary: z.boolean().optional(),\n}).partial();\n\nexport type UpdateProjectWorkspace = z.infer<typeof updateProjectWorkspaceSchema>;\n\nconst projectFields = {\n /** @deprecated Use goalIds instead */\n goalId: z.string().uuid().optional().nullable(),\n goalIds: z.array(z.string().uuid()).optional(),\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n status: z.enum(PROJECT_STATUSES).optional().default(\"backlog\"),\n leadAgentId: z.string().uuid().optional().nullable(),\n targetDate: z.string().optional().nullable(),\n color: projectColorSchema.optional().nullable(),\n executionWorkspacePolicy: projectExecutionWorkspacePolicySchema.optional().nullable(),\n resourceAttachments: z.array(projectResourceAttachmentInputSchema).optional(),\n newResources: z.array(createProjectInlineResourceSchema).optional(),\n archivedAt: z.string().datetime().optional().nullable(),\n};\n\nexport const createProjectSchema = z.object({\n ...projectFields,\n});\n\nexport type CreateProject = z.infer<typeof createProjectSchema>;\n\nexport const updateProjectSchema = z.object(projectFields).partial();\n\nexport type UpdateProject = z.infer<typeof updateProjectSchema>;\n\nexport type ProjectExecutionWorkspacePolicy = z.infer<typeof projectExecutionWorkspacePolicySchema>;\n", "import { z } from \"zod\";\nimport { ISSUE_PRIORITIES, ISSUE_STATUSES } from \"../constants.js\";\n\nconst executionWorkspaceStrategySchema = z\n .object({\n type: z.enum([\"project_primary\", \"git_worktree\", \"adapter_managed\", \"cloud_sandbox\"]).optional(),\n baseRef: z.string().optional().nullable(),\n branchTemplate: z.string().optional().nullable(),\n worktreeParentDir: z.string().optional().nullable(),\n provisionCommand: z.string().optional().nullable(),\n teardownCommand: z.string().optional().nullable(),\n })\n .strict();\n\nexport const issueExecutionWorkspaceSettingsSchema = z\n .object({\n mode: z.enum([\"inherit\", \"shared_workspace\", \"isolated_workspace\", \"operator_branch\", \"reuse_existing\", \"agent_default\"]).optional(),\n workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),\n workspaceRuntime: z.record(z.unknown()).optional().nullable(),\n })\n .strict();\n\nexport const issueAssigneeAdapterOverridesSchema = z\n .object({\n agentRuntimeConfig: z.record(z.unknown()).optional(),\n useProjectWorkspace: z.boolean().optional(),\n })\n .strict();\n\nexport const createIssueSchema = z.object({\n projectId: z.string().uuid().optional().nullable(),\n projectWorkspaceId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n parentId: z.string().uuid().optional().nullable(),\n title: z.string().min(1),\n description: z.string().optional().nullable(),\n status: z.enum(ISSUE_STATUSES).optional().default(\"backlog\"),\n priority: z.enum(ISSUE_PRIORITIES).optional().default(\"medium\"),\n assigneeAgentId: z.string().uuid().optional().nullable(),\n assigneeUserId: z.string().optional().nullable(),\n reviewerAgentId: z.string().uuid().optional().nullable(),\n reviewerUserId: z.string().optional().nullable(),\n requestDepth: z.number().int().nonnegative().optional().default(0),\n billingCode: z.string().optional().nullable(),\n assigneeAgentRuntimeOverrides: issueAssigneeAdapterOverridesSchema.optional().nullable(),\n executionWorkspaceId: z.string().uuid().optional().nullable(),\n executionWorkspacePreference: z.enum([\n \"inherit\",\n \"shared_workspace\",\n \"isolated_workspace\",\n \"operator_branch\",\n \"reuse_existing\",\n \"agent_default\",\n ]).optional().nullable(),\n executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),\n labelIds: z.array(z.string().uuid()).optional(),\n});\n\nexport type CreateIssue = z.infer<typeof createIssueSchema>;\n\nexport const createIssueLabelSchema = z.object({\n name: z.string().trim().min(1).max(48),\n color: z.string().regex(/^#(?:[0-9a-fA-F]{6})$/, \"Color must be a 6-digit hex value\"),\n});\n\nexport type CreateIssueLabel = z.infer<typeof createIssueLabelSchema>;\n\nexport const updateIssueLabelSchema = createIssueLabelSchema.partial().refine(\n (value) => value.name !== undefined || value.color !== undefined,\n {\n message: \"At least one label field must be provided\",\n },\n);\n\nexport type UpdateIssueLabel = z.infer<typeof updateIssueLabelSchema>;\n\nexport const updateIssueSchema = createIssueSchema.partial().extend({\n comment: z.string().min(1).optional(),\n reopen: z.boolean().optional(),\n hiddenAt: z.string().datetime().nullable().optional(),\n reviewDecision: z.enum([\"approve\", \"request_changes\", \"needs_followup\", \"blocked\"]).optional(),\n});\n\nexport type UpdateIssue = z.infer<typeof updateIssueSchema>;\nexport type IssueExecutionWorkspaceSettings = z.infer<typeof issueExecutionWorkspaceSettingsSchema>;\n\nexport const reorderIssueSchema = z\n .object({\n issueId: z.string().uuid(),\n targetStatus: z.enum(ISSUE_STATUSES),\n previousIssueId: z.string().uuid().optional().nullable(),\n nextIssueId: z.string().uuid().optional().nullable(),\n position: z.enum([\"start\", \"end\"]).optional(),\n })\n .refine(\n (value) => !(value.previousIssueId && value.nextIssueId && value.previousIssueId === value.nextIssueId),\n {\n message: \"previousIssueId and nextIssueId must be different\",\n },\n );\n\nexport type ReorderIssue = z.infer<typeof reorderIssueSchema>;\n\nexport const checkoutIssueSchema = z.object({\n agentId: z.string().uuid(),\n expectedStatuses: z.array(z.enum(ISSUE_STATUSES)).nonempty(),\n});\n\nexport type CheckoutIssue = z.infer<typeof checkoutIssueSchema>;\n\nexport const addIssueCommentSchema = z.object({\n body: z.string().min(1),\n reopen: z.boolean().optional(),\n interrupt: z.boolean().optional(),\n});\n\nexport type AddIssueComment = z.infer<typeof addIssueCommentSchema>;\n\nexport const reportIssueCommitSchema = z.object({\n sha: z.string().trim().regex(/^[0-9a-f]{7,64}$/i, \"Commit SHA must be 7 to 64 hexadecimal characters\"),\n message: z.string().trim().min(1).max(500),\n branch: z.string().trim().min(1).max(255).optional().nullable(),\n repoPath: z.string().trim().min(1).max(2048).optional().nullable(),\n workspacePath: z.string().trim().min(1).max(2048).optional().nullable(),\n commitCount: z.number().int().positive().max(1000).optional(),\n});\n\nexport type ReportIssueCommit = z.infer<typeof reportIssueCommitSchema>;\n\nexport const linkIssueApprovalSchema = z.object({\n approvalId: z.string().uuid(),\n});\n\nexport type LinkIssueApproval = z.infer<typeof linkIssueApprovalSchema>;\n\nexport const createIssueAttachmentMetadataSchema = z.object({\n issueCommentId: z.string().uuid().optional().nullable(),\n usage: z.enum([\"issue\", \"description_inline\", \"document_inline\", \"comment_inline\", \"comment_attachment\"]).optional(),\n});\n\nexport type CreateIssueAttachmentMetadata = z.infer<typeof createIssueAttachmentMetadataSchema>;\n\nexport const createIssueWorkspaceAttachmentSchema = z.object({\n path: z.string().trim().min(1).max(2048),\n});\n\nexport type CreateIssueWorkspaceAttachment = z.infer<typeof createIssueWorkspaceAttachmentSchema>;\n\nexport const ISSUE_DOCUMENT_FORMATS = [\"markdown\"] as const;\n\nexport const issueDocumentFormatSchema = z.enum(ISSUE_DOCUMENT_FORMATS);\n\nexport const issueDocumentKeySchema = z\n .string()\n .trim()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9][a-z0-9_-]*$/, \"Document key must be lowercase letters, numbers, _ or -\");\n\nexport const upsertIssueDocumentSchema = z.object({\n title: z.string().trim().max(200).nullable().optional(),\n format: issueDocumentFormatSchema,\n body: z.string().max(524288),\n changeSummary: z.string().trim().max(500).nullable().optional(),\n baseRevisionId: z.string().uuid().nullable().optional(),\n});\n\nexport type IssueDocumentFormat = z.infer<typeof issueDocumentFormatSchema>;\nexport type UpsertIssueDocument = z.infer<typeof upsertIssueDocumentSchema>;\n", "import { z } from \"zod\";\n\nexport const issueWorkProductTypeSchema = z.enum([\n \"preview_url\",\n \"runtime_service\",\n \"pull_request\",\n \"branch\",\n \"commit\",\n \"artifact\",\n \"document\",\n]);\n\nexport const issueWorkProductStatusSchema = z.enum([\n \"active\",\n \"ready_for_review\",\n \"approved\",\n \"changes_requested\",\n \"merged\",\n \"closed\",\n \"failed\",\n \"archived\",\n \"draft\",\n]);\n\nexport const issueWorkProductReviewStateSchema = z.enum([\n \"none\",\n \"needs_board_review\",\n \"approved\",\n \"changes_requested\",\n]);\n\nexport const createIssueWorkProductSchema = z.object({\n projectId: z.string().uuid().optional().nullable(),\n executionWorkspaceId: z.string().uuid().optional().nullable(),\n runtimeServiceId: z.string().uuid().optional().nullable(),\n type: issueWorkProductTypeSchema,\n provider: z.string().min(1),\n externalId: z.string().optional().nullable(),\n title: z.string().min(1),\n url: z.string().url().optional().nullable(),\n status: issueWorkProductStatusSchema.default(\"active\"),\n reviewState: issueWorkProductReviewStateSchema.optional().default(\"none\"),\n isPrimary: z.boolean().optional().default(false),\n healthStatus: z.enum([\"unknown\", \"healthy\", \"unhealthy\"]).optional().default(\"unknown\"),\n summary: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n createdByRunId: z.string().uuid().optional().nullable(),\n});\n\nexport type CreateIssueWorkProduct = z.infer<typeof createIssueWorkProductSchema>;\n\nexport const updateIssueWorkProductSchema = createIssueWorkProductSchema.partial();\n\nexport type UpdateIssueWorkProduct = z.infer<typeof updateIssueWorkProductSchema>;\n", "import { z } from \"zod\";\n\nexport const executionWorkspaceStatusSchema = z.enum([\n \"active\",\n \"idle\",\n \"in_review\",\n \"archived\",\n \"cleanup_failed\",\n]);\n\nexport const updateExecutionWorkspaceSchema = z.object({\n status: executionWorkspaceStatusSchema.optional(),\n cleanupEligibleAt: z.string().datetime().optional().nullable(),\n cleanupReason: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n}).strict();\n\nexport type UpdateExecutionWorkspace = z.infer<typeof updateExecutionWorkspaceSchema>;\n", "import { z } from \"zod\";\n\nexport const workspaceBackupTriggerSourceSchema = z.enum([\"manual\", \"scheduled\", \"pre_restore\"]);\n\nexport const createWorkspaceBackupSchema = z.object({\n triggerSource: workspaceBackupTriggerSourceSchema.optional().default(\"manual\"),\n}).strict();\n\nexport const restoreWorkspaceBackupSchema = z.object({\n confirm: z.literal(true),\n}).strict();\n\nexport type CreateWorkspaceBackup = z.infer<typeof createWorkspaceBackupSchema>;\nexport type RestoreWorkspaceBackup = z.infer<typeof restoreWorkspaceBackupSchema>;\n", "import { z } from \"zod\";\nimport { GOAL_LEVELS, GOAL_STATUSES } from \"../constants.js\";\n\nexport const createGoalSchema = z.object({\n title: z.string().min(1),\n description: z.string().optional().nullable(),\n level: z.enum(GOAL_LEVELS).optional().default(\"task\"),\n status: z.enum(GOAL_STATUSES).optional().default(\"planned\"),\n parentId: z.string().uuid().optional().nullable(),\n ownerAgentId: z.string().uuid().optional().nullable(),\n});\n\nexport type CreateGoal = z.infer<typeof createGoalSchema>;\n\nexport const updateGoalSchema = createGoalSchema.partial();\n\nexport type UpdateGoal = z.infer<typeof updateGoalSchema>;\n", "import { z } from \"zod\";\nimport { APPROVAL_TYPES } from \"../constants.js\";\n\nexport const createApprovalSchema = z.object({\n type: z.enum(APPROVAL_TYPES),\n requestedByAgentId: z.string().uuid().optional().nullable(),\n payload: z.record(z.unknown()),\n issueIds: z.array(z.string().uuid()).optional(),\n});\n\nexport type CreateApproval = z.infer<typeof createApprovalSchema>;\n\nexport const resolveApprovalSchema = z.object({\n decisionNote: z.string().optional().nullable(),\n decidedByUserId: z.string().optional().default(\"board\"),\n});\n\nexport type ResolveApproval = z.infer<typeof resolveApprovalSchema>;\n\nexport const requestApprovalRevisionSchema = z.object({\n decisionNote: z.string().optional().nullable(),\n decidedByUserId: z.string().optional().default(\"board\"),\n});\n\nexport type RequestApprovalRevision = z.infer<typeof requestApprovalRevisionSchema>;\n\nexport const resubmitApprovalSchema = z.object({\n payload: z.record(z.unknown()).optional(),\n});\n\nexport type ResubmitApproval = z.infer<typeof resubmitApprovalSchema>;\n\nexport const addApprovalCommentSchema = z.object({\n body: z.string().min(1),\n});\n\nexport type AddApprovalComment = z.infer<typeof addApprovalCommentSchema>;\n", "import { z } from \"zod\";\nimport {\n ISSUE_PRIORITIES,\n AUTOMATION_CATCH_UP_POLICIES,\n AUTOMATION_CONCURRENCY_POLICIES,\n AUTOMATION_STATUSES,\n AUTOMATION_TRIGGER_SIGNING_MODES,\n} from \"../constants.js\";\n\nexport const createAutomationSchema = z.object({\n projectId: z.string().uuid().optional().nullable().default(null),\n goalId: z.string().uuid().optional().nullable(),\n parentIssueId: z.string().uuid().optional().nullable(),\n title: z.string().trim().min(1).max(200),\n description: z.string().optional().nullable(),\n assigneeAgentId: z.string().uuid(),\n priority: z.enum(ISSUE_PRIORITIES).optional().default(\"medium\"),\n status: z.enum(AUTOMATION_STATUSES).optional().default(\"active\"),\n concurrencyPolicy: z.enum(AUTOMATION_CONCURRENCY_POLICIES).optional().default(\"coalesce_if_active\"),\n catchUpPolicy: z.enum(AUTOMATION_CATCH_UP_POLICIES).optional().default(\"skip_missed\"),\n});\n\nexport type CreateAutomation = z.infer<typeof createAutomationSchema>;\n\nexport const updateAutomationSchema = createAutomationSchema.partial();\nexport type UpdateAutomation = z.infer<typeof updateAutomationSchema>;\n\nconst baseTriggerSchema = z.object({\n label: z.string().trim().max(120).optional().nullable(),\n enabled: z.boolean().optional().default(true),\n});\n\nexport const createAutomationTriggerSchema = z.discriminatedUnion(\"kind\", [\n baseTriggerSchema.extend({\n kind: z.literal(\"schedule\"),\n cronExpression: z.string().trim().min(1),\n timezone: z.string().trim().min(1).default(\"UTC\"),\n }),\n baseTriggerSchema.extend({\n kind: z.literal(\"webhook\"),\n signingMode: z.enum(AUTOMATION_TRIGGER_SIGNING_MODES).optional().default(\"bearer\"),\n replayWindowSec: z.number().int().min(30).max(86_400).optional().default(300),\n }),\n baseTriggerSchema.extend({\n kind: z.literal(\"api\"),\n }),\n]);\n\nexport type CreateAutomationTrigger = z.infer<typeof createAutomationTriggerSchema>;\n\nexport const updateAutomationTriggerSchema = z.object({\n label: z.string().trim().max(120).optional().nullable(),\n enabled: z.boolean().optional(),\n cronExpression: z.string().trim().min(1).optional().nullable(),\n timezone: z.string().trim().min(1).optional().nullable(),\n signingMode: z.enum(AUTOMATION_TRIGGER_SIGNING_MODES).optional().nullable(),\n replayWindowSec: z.number().int().min(30).max(86_400).optional().nullable(),\n});\n\nexport type UpdateAutomationTrigger = z.infer<typeof updateAutomationTriggerSchema>;\n\nexport const runAutomationSchema = z.object({\n triggerId: z.string().uuid().optional().nullable(),\n payload: z.record(z.unknown()).optional().nullable(),\n idempotencyKey: z.string().trim().max(255).optional().nullable(),\n source: z.enum([\"manual\", \"api\"]).optional().default(\"manual\"),\n});\n\nexport type RunAutomation = z.infer<typeof runAutomationSchema>;\n\nexport const rotateAutomationTriggerSecretSchema = z.object({});\nexport type RotateAutomationTriggerSecret = z.infer<typeof rotateAutomationTriggerSecretSchema>;\n", "import { z } from \"zod\";\nimport {\n CALENDAR_EVENT_KINDS,\n CALENDAR_EVENT_STATUSES,\n CALENDAR_OWNER_TYPES,\n CALENDAR_SOURCE_MODES,\n CALENDAR_SOURCE_STATUSES,\n CALENDAR_SOURCE_TYPES,\n CALENDAR_VISIBILITIES,\n} from \"../constants.js\";\n\nconst nullableUuid = z.string().uuid().optional().nullable();\n\nexport const createCalendarSourceSchema = z.object({\n type: z.enum(CALENDAR_SOURCE_TYPES).optional().default(\"rudder_local\"),\n name: z.string().trim().min(1).max(160),\n ownerType: z.enum(CALENDAR_OWNER_TYPES).optional().default(\"user\"),\n ownerUserId: z.string().trim().min(1).optional().nullable(),\n ownerAgentId: nullableUuid,\n externalProvider: z.string().trim().min(1).max(80).optional().nullable(),\n externalCalendarId: z.string().trim().min(1).max(512).optional().nullable(),\n visibilityDefault: z.enum(CALENDAR_VISIBILITIES).optional().default(\"full\"),\n status: z.enum(CALENDAR_SOURCE_STATUSES).optional().default(\"active\"),\n syncCursorJson: z.record(z.unknown()).optional().nullable(),\n});\n\nexport type CreateCalendarSource = z.infer<typeof createCalendarSourceSchema>;\n\nexport const updateCalendarSourceSchema = createCalendarSourceSchema.partial().extend({\n lastSyncedAt: z.coerce.date().optional().nullable(),\n});\n\nexport type UpdateCalendarSource = z.infer<typeof updateCalendarSourceSchema>;\n\nconst calendarEventBaseSchema = z.object({\n sourceId: nullableUuid,\n eventKind: z.enum(CALENDAR_EVENT_KINDS),\n eventStatus: z.enum(CALENDAR_EVENT_STATUSES).optional().default(\"planned\"),\n ownerType: z.enum(CALENDAR_OWNER_TYPES),\n ownerUserId: z.string().trim().min(1).optional().nullable(),\n ownerAgentId: nullableUuid,\n title: z.string().trim().min(1).max(240),\n description: z.string().optional().nullable(),\n startAt: z.coerce.date(),\n endAt: z.coerce.date(),\n timezone: z.string().trim().min(1).max(80).optional().default(\"UTC\"),\n allDay: z.boolean().optional().default(false),\n visibility: z.enum(CALENDAR_VISIBILITIES).optional().default(\"full\"),\n issueId: nullableUuid,\n projectId: nullableUuid,\n goalId: nullableUuid,\n approvalId: nullableUuid,\n heartbeatRunId: nullableUuid,\n activityId: nullableUuid,\n sourceMode: z.enum(CALENDAR_SOURCE_MODES).optional().default(\"manual\"),\n externalProvider: z.string().trim().min(1).max(80).optional().nullable(),\n externalCalendarId: z.string().trim().min(1).max(512).optional().nullable(),\n externalEventId: z.string().trim().min(1).max(512).optional().nullable(),\n externalEtag: z.string().trim().min(1).max(512).optional().nullable(),\n externalUpdatedAt: z.coerce.date().optional().nullable(),\n});\n\nexport const createCalendarEventSchema = calendarEventBaseSchema.refine(\n (value) => value.endAt.getTime() > value.startAt.getTime(),\n { path: [\"endAt\"], message: \"End time must be after start time\" },\n);\n\nexport type CreateCalendarEvent = z.infer<typeof createCalendarEventSchema>;\n\nexport const updateCalendarEventSchema = calendarEventBaseSchema\n .partial()\n .refine(\n (value) =>\n value.startAt === undefined ||\n value.endAt === undefined ||\n value.endAt.getTime() > value.startAt.getTime(),\n { path: [\"endAt\"], message: \"End time must be after start time\" },\n );\n\nexport type UpdateCalendarEvent = z.infer<typeof updateCalendarEventSchema>;\n\nexport const calendarEventListQuerySchema = z.object({\n start: z.coerce.date(),\n end: z.coerce.date(),\n agentIds: z.string().optional(),\n sourceIds: z.string().optional(),\n eventKinds: z.string().optional(),\n statuses: z.string().optional(),\n}).refine(\n (value) => value.end.getTime() > value.start.getTime(),\n { path: [\"end\"], message: \"End time must be after start time\" },\n);\n\nexport type CalendarEventListQuery = z.infer<typeof calendarEventListQuerySchema>;\n\nexport const googleCalendarSyncSchema = z.object({\n sourceId: z.string().uuid().optional().nullable(),\n});\n\nexport type GoogleCalendarSync = z.infer<typeof googleCalendarSyncSchema>;\n\nexport const updateGoogleCalendarOAuthConfigSchema = z.object({\n clientId: z.string().trim().min(1).max(512).optional(),\n clientSecret: z.string().trim().min(1).max(2048).optional(),\n clear: z.boolean().optional().default(false),\n}).refine(\n (value) => value.clear || value.clientId !== undefined || value.clientSecret !== undefined,\n { message: \"Provide credentials or clear the stored Google Calendar OAuth configuration\" },\n);\n\nexport type UpdateGoogleCalendarOAuthConfig = z.input<typeof updateGoogleCalendarOAuthConfigSchema>;\n", "import { z } from \"zod\";\nimport { BILLING_TYPES } from \"../constants.js\";\n\nexport const createCostEventSchema = z.object({\n agentId: z.string().uuid(),\n issueId: z.string().uuid().optional().nullable(),\n projectId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n heartbeatRunId: z.string().uuid().optional().nullable(),\n billingCode: z.string().optional().nullable(),\n provider: z.string().min(1),\n biller: z.string().min(1).optional(),\n billingType: z.enum(BILLING_TYPES).optional().default(\"unknown\"),\n model: z.string().min(1),\n inputTokens: z.number().int().nonnegative().optional().default(0),\n cachedInputTokens: z.number().int().nonnegative().optional().default(0),\n outputTokens: z.number().int().nonnegative().optional().default(0),\n costCents: z.number().int().nonnegative(),\n occurredAt: z.string().datetime(),\n}).transform((value) => ({\n ...value,\n biller: value.biller ?? value.provider,\n}));\n\nexport type CreateCostEvent = z.infer<typeof createCostEventSchema>;\n\nexport const updateBudgetSchema = z.object({\n budgetMonthlyCents: z.number().int().nonnegative(),\n});\n\nexport type UpdateBudget = z.infer<typeof updateBudgetSchema>;\n", "import { z } from \"zod\";\nimport { AGENT_RUNTIME_TYPES, FINANCE_DIRECTIONS, FINANCE_EVENT_KINDS, FINANCE_UNITS } from \"../constants.js\";\n\nexport const createFinanceEventSchema = z.object({\n agentId: z.string().uuid().optional().nullable(),\n issueId: z.string().uuid().optional().nullable(),\n projectId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n heartbeatRunId: z.string().uuid().optional().nullable(),\n costEventId: z.string().uuid().optional().nullable(),\n billingCode: z.string().optional().nullable(),\n description: z.string().max(500).optional().nullable(),\n eventKind: z.enum(FINANCE_EVENT_KINDS),\n direction: z.enum(FINANCE_DIRECTIONS).optional().default(\"debit\"),\n biller: z.string().min(1),\n provider: z.string().min(1).optional().nullable(),\n executionAgentRuntimeType: z.enum(AGENT_RUNTIME_TYPES).optional().nullable(),\n pricingTier: z.string().min(1).optional().nullable(),\n region: z.string().min(1).optional().nullable(),\n model: z.string().min(1).optional().nullable(),\n quantity: z.number().int().nonnegative().optional().nullable(),\n unit: z.enum(FINANCE_UNITS).optional().nullable(),\n amountCents: z.number().int().nonnegative(),\n currency: z.string().length(3).optional().default(\"USD\"),\n estimated: z.boolean().optional().default(false),\n externalInvoiceId: z.string().optional().nullable(),\n metadataJson: z.record(z.string(), z.unknown()).optional().nullable(),\n occurredAt: z.string().datetime(),\n}).transform((value) => ({\n ...value,\n currency: value.currency.toUpperCase(),\n}));\n\nexport type CreateFinanceEvent = z.infer<typeof createFinanceEventSchema>;\n", "import { z } from \"zod\";\n\nexport const createAssetImageMetadataSchema = z.object({\n namespace: z\n .string()\n .trim()\n .min(1)\n .max(120)\n .regex(/^[a-zA-Z0-9/_-]+$/)\n .optional(),\n});\n\nexport type CreateAssetImageMetadata = z.infer<typeof createAssetImageMetadataSchema>;\n\n", "import { z } from \"zod\";\nimport {\n AGENT_RUNTIME_TYPES,\n INVITE_JOIN_TYPES,\n JOIN_REQUEST_STATUSES,\n JOIN_REQUEST_TYPES,\n PERMISSION_KEYS,\n} from \"../constants.js\";\n\nexport const createCompanyInviteSchema = z.object({\n allowedJoinTypes: z.enum(INVITE_JOIN_TYPES).default(\"both\"),\n defaultsPayload: z.record(z.string(), z.unknown()).optional().nullable(),\n agentMessage: z.string().max(4000).optional().nullable(),\n});\n\nexport type CreateCompanyInvite = z.infer<typeof createCompanyInviteSchema>;\n\nexport const createOpenClawInvitePromptSchema = z.object({\n agentMessage: z.string().max(4000).optional().nullable(),\n});\n\nexport type CreateOpenClawInvitePrompt = z.infer<\n typeof createOpenClawInvitePromptSchema\n>;\n\nexport const acceptInviteSchema = z.object({\n requestType: z.enum(JOIN_REQUEST_TYPES),\n agentName: z.string().min(1).max(120).optional(),\n agentRuntimeType: z.enum(AGENT_RUNTIME_TYPES).optional(),\n capabilities: z.string().max(4000).optional().nullable(),\n agentDefaultsPayload: z.record(z.string(), z.unknown()).optional().nullable(),\n // OpenClaw join compatibility fields accepted at top level.\n responsesWebhookUrl: z.string().max(4000).optional().nullable(),\n responsesWebhookMethod: z.string().max(32).optional().nullable(),\n responsesWebhookHeaders: z.record(z.string(), z.unknown()).optional().nullable(),\n rudderApiUrl: z.string().max(4000).optional().nullable(),\n webhookAuthHeader: z.string().max(4000).optional().nullable(),\n});\n\nexport type AcceptInvite = z.infer<typeof acceptInviteSchema>;\n\nexport const listJoinRequestsQuerySchema = z.object({\n status: z.enum(JOIN_REQUEST_STATUSES).optional(),\n requestType: z.enum(JOIN_REQUEST_TYPES).optional(),\n});\n\nexport type ListJoinRequestsQuery = z.infer<typeof listJoinRequestsQuerySchema>;\n\nexport const claimJoinRequestApiKeySchema = z.object({\n claimSecret: z.string().min(16).max(256),\n});\n\nexport type ClaimJoinRequestApiKey = z.infer<typeof claimJoinRequestApiKeySchema>;\n\nexport const boardCliAuthAccessLevelSchema = z.enum([\n \"board\",\n \"instance_admin_required\",\n]);\n\nexport type BoardCliAuthAccessLevel = z.infer<typeof boardCliAuthAccessLevelSchema>;\n\nexport const createCliAuthChallengeSchema = z.object({\n command: z.string().min(1).max(240),\n clientName: z.string().max(120).optional().nullable(),\n requestedAccess: boardCliAuthAccessLevelSchema.default(\"board\"),\n requestedCompanyId: z.string().uuid().optional().nullable(),\n});\n\nexport type CreateCliAuthChallenge = z.infer<typeof createCliAuthChallengeSchema>;\n\nexport const resolveCliAuthChallengeSchema = z.object({\n token: z.string().min(16).max(256),\n});\n\nexport type ResolveCliAuthChallenge = z.infer<typeof resolveCliAuthChallengeSchema>;\n\nexport const updateMemberPermissionsSchema = z.object({\n grants: z.array(\n z.object({\n permissionKey: z.enum(PERMISSION_KEYS),\n scope: z.record(z.string(), z.unknown()).optional().nullable(),\n }),\n ),\n});\n\nexport type UpdateMemberPermissions = z.infer<typeof updateMemberPermissionsSchema>;\n\nexport const updateUserCompanyAccessSchema = z.object({\n orgIds: z.array(z.string().uuid()).default([]),\n});\n\nexport type UpdateUserCompanyAccess = z.infer<typeof updateUserCompanyAccessSchema>;\n", "import { z } from \"zod\";\nimport {\n PLUGIN_STATUSES,\n PLUGIN_CATEGORIES,\n PLUGIN_CAPABILITIES,\n PLUGIN_UI_SLOT_TYPES,\n PLUGIN_UI_SLOT_ENTITY_TYPES,\n PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS,\n PLUGIN_LAUNCHER_PLACEMENT_ZONES,\n PLUGIN_LAUNCHER_ACTIONS,\n PLUGIN_LAUNCHER_BOUNDS,\n PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS,\n PLUGIN_STATE_SCOPE_KINDS,\n} from \"../constants.js\";\n\n// ---------------------------------------------------------------------------\n// JSON Schema placeholder \u2013 a permissive validator for JSON Schema objects\n// ---------------------------------------------------------------------------\n\n/**\n * Permissive validator for JSON Schema objects. Accepts any `Record<string, unknown>`\n * that contains at least a `type`, `$ref`, or composition keyword (`oneOf`/`anyOf`/`allOf`).\n * Empty objects are also accepted.\n *\n * Used to validate `instanceConfigSchema` and `parametersSchema` fields in the\n * plugin manifest without fully parsing JSON Schema.\n *\n * @see PLUGIN_SPEC.md \u00A710.1 \u2014 Manifest shape\n */\nexport const jsonSchemaSchema = z.record(z.unknown()).refine(\n (val) => {\n // Must have a \"type\" field if non-empty, or be a valid JSON Schema object\n if (Object.keys(val).length === 0) return true;\n return typeof val.type === \"string\" || val.$ref !== undefined || val.oneOf !== undefined || val.anyOf !== undefined || val.allOf !== undefined;\n },\n { message: \"Must be a valid JSON Schema object (requires at least a 'type', '$ref', or composition keyword)\" },\n);\n\n// ---------------------------------------------------------------------------\n// Manifest sub-type schemas\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a {@link PluginJobDeclaration} \u2014 a scheduled job declared in the\n * plugin manifest. Requires `jobKey` and `displayName`; `description` and\n * `schedule` (cron expression) are optional.\n *\n * @see PLUGIN_SPEC.md \u00A717 \u2014 Scheduled Jobs\n */\n/**\n * Validates a cron expression has exactly 5 whitespace-separated fields,\n * each containing only valid cron characters (digits, *, /, -, ,).\n *\n * Valid tokens per field: *, N, N-M, N/S, * /S, N-M/S, and comma-separated lists.\n */\nconst CRON_FIELD_PATTERN = /^(\\*(?:\\/[0-9]+)?|[0-9]+(?:-[0-9]+)?(?:\\/[0-9]+)?)(?:,(\\*(?:\\/[0-9]+)?|[0-9]+(?:-[0-9]+)?(?:\\/[0-9]+)?))*$/;\n\nfunction isValidCronExpression(expression: string): boolean {\n const trimmed = expression.trim();\n if (!trimmed) return false;\n const fields = trimmed.split(/\\s+/);\n if (fields.length !== 5) return false;\n return fields.every((f) => CRON_FIELD_PATTERN.test(f));\n}\n\nexport const pluginJobDeclarationSchema = z.object({\n jobKey: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().optional(),\n schedule: z.string().refine(\n (val) => isValidCronExpression(val),\n { message: \"schedule must be a valid 5-field cron expression (e.g. '*/15 * * * *')\" },\n ).optional(),\n});\n\nexport type PluginJobDeclarationInput = z.infer<typeof pluginJobDeclarationSchema>;\n\n/**\n * Validates a {@link PluginWebhookDeclaration} \u2014 a webhook endpoint declared\n * in the plugin manifest. Requires `endpointKey` and `displayName`.\n *\n * @see PLUGIN_SPEC.md \u00A718 \u2014 Webhooks\n */\nexport const pluginWebhookDeclarationSchema = z.object({\n endpointKey: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().optional(),\n});\n\nexport type PluginWebhookDeclarationInput = z.infer<typeof pluginWebhookDeclarationSchema>;\n\n/**\n * Validates a {@link PluginToolDeclaration} \u2014 an agent tool contributed by the\n * plugin. Requires `name`, `displayName`, `description`, and a valid\n * `parametersSchema`. Requires the `agent.tools.register` capability.\n *\n * @see PLUGIN_SPEC.md \u00A711 \u2014 Agent Tools\n */\nexport const pluginToolDeclarationSchema = z.object({\n name: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().min(1),\n parametersSchema: jsonSchemaSchema,\n});\n\nexport type PluginToolDeclarationInput = z.infer<typeof pluginToolDeclarationSchema>;\n\n/**\n * Validates a {@link PluginUiSlotDeclaration} \u2014 a UI extension slot the plugin\n * fills with a React component. Includes `superRefine` checks for slot-specific\n * requirements such as `entityTypes` for context-sensitive slots.\n *\n * @see PLUGIN_SPEC.md \u00A719 \u2014 UI Extension Model\n */\nexport const pluginUiSlotDeclarationSchema = z.object({\n type: z.enum(PLUGIN_UI_SLOT_TYPES),\n id: z.string().min(1),\n displayName: z.string().min(1),\n exportName: z.string().min(1),\n entityTypes: z.array(z.enum(PLUGIN_UI_SLOT_ENTITY_TYPES)).optional(),\n routePath: z.string().regex(/^[a-z0-9][a-z0-9-]*$/, {\n message: \"routePath must be a lowercase single-segment slug (letters, numbers, hyphens)\",\n }).optional(),\n order: z.number().int().optional(),\n}).superRefine((value, ctx) => {\n // context-sensitive slots require explicit entity targeting.\n const entityScopedTypes = [\"detailTab\", \"taskDetailView\", \"contextMenuItem\", \"commentAnnotation\", \"commentContextMenuItem\", \"projectSidebarItem\"];\n if (\n entityScopedTypes.includes(value.type)\n && (!value.entityTypes || value.entityTypes.length === 0)\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `${value.type} slots require at least one entityType`,\n path: [\"entityTypes\"],\n });\n }\n // projectSidebarItem only makes sense for entityType \"project\".\n if (value.type === \"projectSidebarItem\" && value.entityTypes && !value.entityTypes.includes(\"project\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"projectSidebarItem slots require entityTypes to include \\\"project\\\"\",\n path: [\"entityTypes\"],\n });\n }\n // commentAnnotation only makes sense for entityType \"comment\".\n if (value.type === \"commentAnnotation\" && value.entityTypes && !value.entityTypes.includes(\"comment\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"commentAnnotation slots require entityTypes to include \\\"comment\\\"\",\n path: [\"entityTypes\"],\n });\n }\n // commentContextMenuItem only makes sense for entityType \"comment\".\n if (value.type === \"commentContextMenuItem\" && value.entityTypes && !value.entityTypes.includes(\"comment\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"commentContextMenuItem slots require entityTypes to include \\\"comment\\\"\",\n path: [\"entityTypes\"],\n });\n }\n if (value.routePath && value.type !== \"page\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"routePath is only supported for page slots\",\n path: [\"routePath\"],\n });\n }\n if (value.routePath && PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS.includes(value.routePath as (typeof PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS)[number])) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `routePath \"${value.routePath}\" is reserved by the host`,\n path: [\"routePath\"],\n });\n }\n});\n\nexport type PluginUiSlotDeclarationInput = z.infer<typeof pluginUiSlotDeclarationSchema>;\n\nconst entityScopedLauncherPlacementZones = [\n \"detailTab\",\n \"taskDetailView\",\n \"contextMenuItem\",\n \"commentAnnotation\",\n \"commentContextMenuItem\",\n \"projectSidebarItem\",\n] as const;\n\nconst launcherBoundsByEnvironment: Record<\n (typeof PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS)[number],\n readonly (typeof PLUGIN_LAUNCHER_BOUNDS)[number][]\n> = {\n hostInline: [\"inline\", \"compact\", \"default\"],\n hostOverlay: [\"compact\", \"default\", \"wide\", \"full\"],\n hostRoute: [\"default\", \"wide\", \"full\"],\n external: [],\n iframe: [\"compact\", \"default\", \"wide\", \"full\"],\n};\n\n/**\n * Validates the action payload for a declarative plugin launcher.\n */\nexport const pluginLauncherActionDeclarationSchema = z.object({\n type: z.enum(PLUGIN_LAUNCHER_ACTIONS),\n target: z.string().min(1),\n params: z.record(z.unknown()).optional(),\n}).superRefine((value, ctx) => {\n if (value.type === \"performAction\" && value.target.includes(\"/\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"performAction launchers must target an action key, not a route or URL\",\n path: [\"target\"],\n });\n }\n\n if (value.type === \"navigate\" && /^https?:\\/\\//.test(value.target)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"navigate launchers must target a host route, not an absolute URL\",\n path: [\"target\"],\n });\n }\n});\n\nexport type PluginLauncherActionDeclarationInput =\n z.infer<typeof pluginLauncherActionDeclarationSchema>;\n\n/**\n * Validates optional render hints for a plugin launcher destination.\n */\nexport const pluginLauncherRenderDeclarationSchema = z.object({\n environment: z.enum(PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS),\n bounds: z.enum(PLUGIN_LAUNCHER_BOUNDS).optional(),\n}).superRefine((value, ctx) => {\n if (!value.bounds) {\n return;\n }\n\n const supportedBounds = launcherBoundsByEnvironment[value.environment];\n if (!supportedBounds.includes(value.bounds)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `bounds \"${value.bounds}\" is not supported for render environment \"${value.environment}\"`,\n path: [\"bounds\"],\n });\n }\n});\n\nexport type PluginLauncherRenderDeclarationInput =\n z.infer<typeof pluginLauncherRenderDeclarationSchema>;\n\n/**\n * Validates declarative launcher metadata in a plugin manifest.\n */\nexport const pluginLauncherDeclarationSchema = z.object({\n id: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().optional(),\n placementZone: z.enum(PLUGIN_LAUNCHER_PLACEMENT_ZONES),\n exportName: z.string().min(1).optional(),\n entityTypes: z.array(z.enum(PLUGIN_UI_SLOT_ENTITY_TYPES)).optional(),\n order: z.number().int().optional(),\n action: pluginLauncherActionDeclarationSchema,\n render: pluginLauncherRenderDeclarationSchema.optional(),\n}).superRefine((value, ctx) => {\n if (\n entityScopedLauncherPlacementZones.some((zone) => zone === value.placementZone)\n && (!value.entityTypes || value.entityTypes.length === 0)\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `${value.placementZone} launchers require at least one entityType`,\n path: [\"entityTypes\"],\n });\n }\n\n if (\n value.placementZone === \"projectSidebarItem\"\n && value.entityTypes\n && !value.entityTypes.includes(\"project\")\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"projectSidebarItem launchers require entityTypes to include \\\"project\\\"\",\n path: [\"entityTypes\"],\n });\n }\n\n if (value.action.type === \"performAction\" && value.render) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"performAction launchers cannot declare render hints\",\n path: [\"render\"],\n });\n }\n\n if (\n [\"openModal\", \"openDrawer\", \"openPopover\"].includes(value.action.type)\n && !value.render\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `${value.action.type} launchers require render metadata`,\n path: [\"render\"],\n });\n }\n\n if (value.action.type === \"openModal\" && value.render?.environment === \"hostInline\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"openModal launchers cannot use the hostInline render environment\",\n path: [\"render\", \"environment\"],\n });\n }\n\n if (\n value.action.type === \"openDrawer\"\n && value.render\n && ![\"hostOverlay\", \"iframe\"].includes(value.render.environment)\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"openDrawer launchers must use hostOverlay or iframe render environments\",\n path: [\"render\", \"environment\"],\n });\n }\n\n if (value.action.type === \"openPopover\" && value.render?.environment === \"hostRoute\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"openPopover launchers cannot use the hostRoute render environment\",\n path: [\"render\", \"environment\"],\n });\n }\n});\n\nexport type PluginLauncherDeclarationInput = z.infer<typeof pluginLauncherDeclarationSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin Manifest V1 schema\n// ---------------------------------------------------------------------------\n\n/**\n * Zod schema for {@link PaperclipPluginManifestV1} \u2014 the complete runtime\n * validator for plugin manifests read at install time.\n *\n * Field-level constraints (see PLUGIN_SPEC.md \u00A710.1 for the normative rules):\n *\n * | Field | Type | Constraints |\n * |--------------------------|------------|----------------------------------------------|\n * | `id` | string | `^[a-z0-9][a-z0-9._-]*$` |\n * | `apiVersion` | literal 1 | must equal `PLUGIN_API_VERSION` |\n * | `version` | string | semver (`\\d+\\.\\d+\\.\\d+`) |\n * | `displayName` | string | 1\u2013100 chars |\n * | `description` | string | 1\u2013500 chars |\n * | `author` | string | 1\u2013200 chars |\n * | `categories` | enum[] | at least one; values from PLUGIN_CATEGORIES |\n * | `minimumHostVersion` | string? | semver lower bound if present, no leading `v`|\n * | `minimumPaperclipVersion`| string? | legacy alias of `minimumHostVersion` |\n * | `capabilities` | enum[] | at least one; values from PLUGIN_CAPABILITIES|\n * | `entrypoints.worker` | string | min 1 char |\n * | `entrypoints.ui` | string? | required when `ui.slots` is declared |\n *\n * Cross-field rules enforced via `superRefine`:\n * - `entrypoints.ui` required when `ui.slots` declared\n * - `agent.tools.register` capability required when `tools` declared\n * - `jobs.schedule` capability required when `jobs` declared\n * - `webhooks.receive` capability required when `webhooks` declared\n * - duplicate `jobs[].jobKey` values are rejected\n * - duplicate `webhooks[].endpointKey` values are rejected\n * - duplicate `tools[].name` values are rejected\n * - duplicate `ui.slots[].id` values are rejected\n *\n * @see PLUGIN_SPEC.md \u00A710.1 \u2014 Manifest shape\n * @see {@link PaperclipPluginManifestV1} \u2014 the inferred TypeScript type\n */\nexport const pluginManifestV1Schema = z.object({\n id: z.string().min(1).regex(\n /^[a-z0-9][a-z0-9._-]*$/,\n \"Plugin id must start with a lowercase alphanumeric and contain only lowercase letters, digits, dots, hyphens, or underscores\",\n ),\n apiVersion: z.literal(1),\n version: z.string().min(1).regex(\n /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$/,\n \"Version must follow semver (e.g. 1.0.0 or 1.0.0-beta.1)\",\n ),\n displayName: z.string().min(1).max(100),\n description: z.string().min(1).max(500),\n author: z.string().min(1).max(200),\n categories: z.array(z.enum(PLUGIN_CATEGORIES)).min(1),\n minimumHostVersion: z.string().regex(\n /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$/,\n \"minimumHostVersion must follow semver (e.g. 1.0.0)\",\n ).optional(),\n minimumPaperclipVersion: z.string().regex(\n /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$/,\n \"minimumPaperclipVersion must follow semver (e.g. 1.0.0)\",\n ).optional(),\n capabilities: z.array(z.enum(PLUGIN_CAPABILITIES)).min(1),\n entrypoints: z.object({\n worker: z.string().min(1),\n ui: z.string().min(1).optional(),\n }),\n instanceConfigSchema: jsonSchemaSchema.optional(),\n jobs: z.array(pluginJobDeclarationSchema).optional(),\n webhooks: z.array(pluginWebhookDeclarationSchema).optional(),\n tools: z.array(pluginToolDeclarationSchema).optional(),\n launchers: z.array(pluginLauncherDeclarationSchema).optional(),\n ui: z.object({\n slots: z.array(pluginUiSlotDeclarationSchema).min(1).optional(),\n launchers: z.array(pluginLauncherDeclarationSchema).optional(),\n }).optional(),\n}).superRefine((manifest, ctx) => {\n // \u2500\u2500 Entrypoint \u2194 UI slot consistency \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Plugins that declare UI slots must also declare a UI entrypoint so the\n // host knows where to load the bundle from (PLUGIN_SPEC.md \u00A710.1).\n const hasUiSlots = (manifest.ui?.slots?.length ?? 0) > 0;\n const hasUiLaunchers = (manifest.ui?.launchers?.length ?? 0) > 0;\n if ((hasUiSlots || hasUiLaunchers) && !manifest.entrypoints.ui) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"entrypoints.ui is required when ui.slots or ui.launchers are declared\",\n path: [\"entrypoints\", \"ui\"],\n });\n }\n\n if (\n manifest.minimumHostVersion\n && manifest.minimumPaperclipVersion\n && manifest.minimumHostVersion !== manifest.minimumPaperclipVersion\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"minimumHostVersion and minimumPaperclipVersion must match when both are declared\",\n path: [\"minimumHostVersion\"],\n });\n }\n\n // \u2500\u2500 Capability \u2194 feature declaration consistency \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The host enforces capabilities at install and runtime. A plugin must\n // declare every capability it needs up-front; silently having more features\n // than capabilities would cause runtime rejections.\n\n // tools require agent.tools.register (PLUGIN_SPEC.md \u00A711)\n if (manifest.tools && manifest.tools.length > 0) {\n if (!manifest.capabilities.includes(\"agent.tools.register\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Capability 'agent.tools.register' is required when tools are declared\",\n path: [\"capabilities\"],\n });\n }\n }\n\n // jobs require jobs.schedule (PLUGIN_SPEC.md \u00A717)\n if (manifest.jobs && manifest.jobs.length > 0) {\n if (!manifest.capabilities.includes(\"jobs.schedule\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Capability 'jobs.schedule' is required when jobs are declared\",\n path: [\"capabilities\"],\n });\n }\n }\n\n // webhooks require webhooks.receive (PLUGIN_SPEC.md \u00A718)\n if (manifest.webhooks && manifest.webhooks.length > 0) {\n if (!manifest.capabilities.includes(\"webhooks.receive\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Capability 'webhooks.receive' is required when webhooks are declared\",\n path: [\"capabilities\"],\n });\n }\n }\n\n // \u2500\u2500 Uniqueness checks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Duplicate keys within a plugin's own manifest are always a bug. The host\n // would not know which declaration takes precedence, so we reject early.\n\n // job keys must be unique within the plugin (used as identifiers in the DB)\n if (manifest.jobs) {\n const jobKeys = manifest.jobs.map((j) => j.jobKey);\n const duplicates = jobKeys.filter((key, i) => jobKeys.indexOf(key) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate job keys: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"jobs\"],\n });\n }\n }\n\n // webhook endpoint keys must be unique within the plugin (used in routes)\n if (manifest.webhooks) {\n const endpointKeys = manifest.webhooks.map((w) => w.endpointKey);\n const duplicates = endpointKeys.filter((key, i) => endpointKeys.indexOf(key) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate webhook endpoint keys: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"webhooks\"],\n });\n }\n }\n\n // tool names must be unique within the plugin (namespaced at runtime)\n if (manifest.tools) {\n const toolNames = manifest.tools.map((t) => t.name);\n const duplicates = toolNames.filter((name, i) => toolNames.indexOf(name) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate tool names: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"tools\"],\n });\n }\n }\n\n // UI slot ids must be unique within the plugin (namespaced at runtime)\n if (manifest.ui) {\n if (manifest.ui.slots) {\n const slotIds = manifest.ui.slots.map((s) => s.id);\n const duplicates = slotIds.filter((id, i) => slotIds.indexOf(id) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate UI slot ids: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"ui\", \"slots\"],\n });\n }\n }\n }\n\n // launcher ids must be unique within the plugin\n const allLaunchers = [\n ...(manifest.launchers ?? []),\n ...(manifest.ui?.launchers ?? []),\n ];\n if (allLaunchers.length > 0) {\n const launcherIds = allLaunchers.map((launcher) => launcher.id);\n const duplicates = launcherIds.filter((id, i) => launcherIds.indexOf(id) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate launcher ids: ${[...new Set(duplicates)].join(\", \")}`,\n path: manifest.ui?.launchers ? [\"ui\", \"launchers\"] : [\"launchers\"],\n });\n }\n }\n});\n\nexport type PluginManifestV1Input = z.infer<typeof pluginManifestV1Schema>;\n\n// ---------------------------------------------------------------------------\n// Plugin installation / registration request\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for installing (registering) a plugin.\n * The server receives the packageName and resolves the manifest from the\n * installed package.\n */\nexport const installPluginSchema = z.object({\n packageName: z.string().min(1),\n version: z.string().min(1).optional(),\n /** Set by loader for local-path installs so the worker can be resolved. */\n packagePath: z.string().min(1).optional(),\n});\n\nexport type InstallPlugin = z.infer<typeof installPluginSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin config (instance configuration) schemas\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for creating or updating a plugin's instance configuration.\n * configJson is validated permissively here; runtime validation against\n * the plugin's instanceConfigSchema is done at the service layer.\n */\nexport const upsertPluginConfigSchema = z.object({\n configJson: z.record(z.unknown()),\n});\n\nexport type UpsertPluginConfig = z.infer<typeof upsertPluginConfigSchema>;\n\n/**\n * Schema for partially updating a plugin's instance configuration.\n * Allows a partial merge of config values.\n */\nexport const patchPluginConfigSchema = z.object({\n configJson: z.record(z.unknown()),\n});\n\nexport type PatchPluginConfig = z.infer<typeof patchPluginConfigSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin status update\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for updating a plugin's lifecycle status. Used by the lifecycle\n * manager to persist state transitions.\n *\n * @see {@link PLUGIN_STATUSES} for the valid status values\n */\nexport const updatePluginStatusSchema = z.object({\n status: z.enum(PLUGIN_STATUSES),\n lastError: z.string().nullable().optional(),\n});\n\nexport type UpdatePluginStatus = z.infer<typeof updatePluginStatusSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin uninstall\n// ---------------------------------------------------------------------------\n\n/** Schema for the uninstall request. `removeData` controls hard vs soft delete. */\nexport const uninstallPluginSchema = z.object({\n removeData: z.boolean().optional().default(false),\n});\n\nexport type UninstallPlugin = z.infer<typeof uninstallPluginSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin state (key-value storage) schemas\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for a plugin state scope key \u2014 identifies the exact location where\n * state is stored. Used by the `ctx.state.get()`, `ctx.state.set()`, and\n * `ctx.state.delete()` SDK methods.\n *\n * @see PLUGIN_SPEC.md \u00A721.3 `plugin_state`\n */\nexport const pluginStateScopeKeySchema = z.object({\n scopeKind: z.enum(PLUGIN_STATE_SCOPE_KINDS),\n scopeId: z.string().min(1).optional(),\n namespace: z.string().min(1).optional(),\n stateKey: z.string().min(1),\n});\n\nexport type PluginStateScopeKey = z.infer<typeof pluginStateScopeKeySchema>;\n\n/**\n * Schema for setting a plugin state value.\n */\nexport const setPluginStateSchema = z.object({\n scopeKind: z.enum(PLUGIN_STATE_SCOPE_KINDS),\n scopeId: z.string().min(1).optional(),\n namespace: z.string().min(1).optional(),\n stateKey: z.string().min(1),\n /** JSON-serializable value to store. */\n value: z.unknown(),\n});\n\nexport type SetPluginState = z.infer<typeof setPluginStateSchema>;\n\n/**\n * Schema for querying plugin state entries. All fields are optional to allow\n * flexible list queries (e.g. all state for a plugin within a scope).\n */\nexport const listPluginStateSchema = z.object({\n scopeKind: z.enum(PLUGIN_STATE_SCOPE_KINDS).optional(),\n scopeId: z.string().min(1).optional(),\n namespace: z.string().min(1).optional(),\n});\n\nexport type ListPluginState = z.infer<typeof listPluginStateSchema>;\n", "export {\n instanceLocaleSchema,\n type InstanceLocale,\n instanceGeneralSettingsSchema,\n patchInstanceGeneralSettingsSchema,\n type InstanceGeneralSettings,\n type PatchInstanceGeneralSettings,\n instanceNotificationSettingsSchema,\n patchInstanceNotificationSettingsSchema,\n type InstanceNotificationSettings,\n type PatchInstanceNotificationSettings,\n instanceLangfuseSettingsSchema,\n patchInstanceLangfuseSettingsSchema,\n type InstanceLangfuseSettings,\n type PatchInstanceLangfuseSettings,\n OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH,\n operatorProfileSettingsSchema,\n patchOperatorProfileSettingsSchema,\n type OperatorProfileSettings,\n type PatchOperatorProfileSettings,\n instancePathPickerSelectionTypeSchema,\n instancePathPickerRequestSchema,\n instancePathPickerResultSchema,\n type InstancePathPickerSelectionType,\n type InstancePathPickerRequest,\n type InstancePathPickerResult,\n} from \"./instance.js\";\n\nexport {\n upsertBudgetPolicySchema,\n resolveBudgetIncidentSchema,\n type UpsertBudgetPolicy,\n type ResolveBudgetIncident,\n} from \"./budget.js\";\n\nexport {\n createOrganizationSchema,\n updateOrganizationSchema,\n updateOrganizationBrandingSchema,\n updateOrganizationWorkspaceFileSchema,\n type CreateOrganization,\n type UpdateOrganization,\n type UpdateOrganizationBranding,\n type UpdateOrganizationWorkspaceFile,\n} from \"./organization.js\";\nexport {\n organizationResourceKindSchema,\n projectResourceAttachmentRoleSchema,\n createOrganizationResourceSchema,\n updateOrganizationResourceSchema,\n projectResourceAttachmentInputSchema,\n updateProjectResourceAttachmentSchema,\n createProjectInlineResourceSchema,\n type CreateOrganizationResource,\n type UpdateOrganizationResource,\n type ProjectResourceAttachmentInputPayload,\n type UpdateProjectResourceAttachment,\n type CreateProjectInlineResource,\n} from \"./resource.js\";\nexport {\n chatConversationStatusSchema,\n chatIssueCreationModeSchema,\n chatMessageRoleSchema,\n chatMessageKindSchema,\n chatContextEntityTypeSchema,\n createChatContextLinkSchema,\n createChatConversationSchema,\n setChatProjectContextSchema,\n updateChatConversationSchema,\n updateChatConversationUserStateSchema,\n addChatMessageSchema,\n chatAskUserOptionSchema,\n chatAskUserQuestionSchema,\n chatAskUserRequestSchema,\n chatAskUserRequestFromStructuredPayload,\n chatRichReferenceSchema,\n chatRichReferencesSchema,\n chatRichReferencesFromStructuredPayload,\n sanitizeChatStructuredPayload,\n createChatAttachmentMetadataSchema,\n convertChatToIssueSchema,\n chatOperationProposalSchema,\n resolveChatOperationProposalSchema,\n type CreateChatContextLink,\n type CreateChatConversation,\n type SetChatProjectContext,\n type UpdateChatConversation,\n type UpdateChatConversationUserState,\n type AddChatMessage,\n type ChatAskUserOption,\n type ChatAskUserQuestion,\n type ChatAskUserRequest,\n type ChatRichReference,\n type CreateChatAttachmentMetadata,\n type ConvertChatToIssue,\n type ChatOperationProposal,\n type ResolveChatOperationProposal,\n} from \"./chat.js\";\nexport {\n organizationSkillSourceTypeSchema,\n organizationSkillTrustLevelSchema,\n organizationSkillCompatibilitySchema,\n organizationSkillSourceBadgeSchema,\n organizationSkillFileInventoryEntrySchema,\n organizationSkillSchema,\n organizationSkillListItemSchema,\n organizationSkillUsageAgentSchema,\n organizationSkillDetailSchema,\n organizationSkillUpdateStatusSchema,\n organizationSkillImportSchema,\n organizationSkillProjectScanRequestSchema,\n organizationSkillProjectScanSkippedSchema,\n organizationSkillProjectScanConflictSchema,\n organizationSkillProjectScanResultSchema,\n organizationSkillLocalScanRequestSchema,\n organizationSkillLocalScanSkippedSchema,\n organizationSkillLocalScanConflictSchema,\n organizationSkillLocalScanResultSchema,\n organizationSkillCreateSchema,\n organizationSkillFileDetailSchema,\n organizationSkillFileUpdateSchema,\n type OrganizationSkillImport,\n type OrganizationSkillProjectScan,\n type OrganizationSkillLocalScan,\n type OrganizationSkillCreate,\n type OrganizationSkillFileUpdate,\n} from \"./organization-skill.js\";\nexport {\n agentSkillStateSchema,\n agentSkillOriginSchema,\n agentSkillSourceClassSchema,\n agentSkillSyncModeSchema,\n agentSkillEntrySchema,\n agentSkillSnapshotSchema,\n agentSkillSyncSchema,\n agentSkillEnableSchema,\n type AgentSkillSync,\n type AgentSkillEnable,\n} from \"./adapter-skills.js\";\nexport {\n portabilityIncludeSchema,\n portabilityEnvInputSchema,\n portabilityOrganizationManifestEntrySchema,\n portabilitySidebarOrderSchema,\n portabilityAgentManifestEntrySchema,\n portabilitySkillManifestEntrySchema,\n portabilityManifestSchema,\n portabilitySourceSchema,\n portabilityTargetSchema,\n portabilityAgentSelectionSchema,\n portabilityCollisionStrategySchema,\n organizationPortabilityExportSchema,\n organizationPortabilityPreviewSchema,\n organizationPortabilityImportSchema,\n type OrganizationPortabilityExport,\n type OrganizationPortabilityPreview,\n type OrganizationPortabilityImport,\n} from \"./organization-portability.js\";\n\nexport {\n agentIconSchema,\n customAgentIconSchema,\n createAgentSchema,\n createAgentHireSchema,\n updateAgentSchema,\n uploadedAgentIconSchema,\n agentInstructionsBundleModeSchema,\n updateAgentInstructionsBundleSchema,\n upsertAgentInstructionsFileSchema,\n updateAgentInstructionsPathSchema,\n createAgentKeySchema,\n wakeAgentSchema,\n resetAgentSessionSchema,\n testAgentRuntimeEnvironmentSchema,\n agentPermissionsSchema,\n updateAgentPermissionsSchema,\n type CreateAgent,\n type CreateAgentHire,\n type UpdateAgent,\n type UpdateAgentInstructionsBundle,\n type UpsertAgentInstructionsFile,\n type UpdateAgentInstructionsPath,\n type CreateAgentKey,\n type WakeAgent,\n type ResetAgentSession,\n type TestAgentRuntimeEnvironment,\n type UpdateAgentPermissions,\n} from \"./agent.js\";\n\nexport {\n createProjectSchema,\n updateProjectSchema,\n projectExecutionWorkspacePolicySchema,\n type CreateProject,\n type UpdateProject,\n type ProjectExecutionWorkspacePolicy,\n} from \"./project.js\";\n\nexport {\n createIssueSchema,\n createIssueLabelSchema,\n updateIssueLabelSchema,\n updateIssueSchema,\n reorderIssueSchema,\n issueExecutionWorkspaceSettingsSchema,\n checkoutIssueSchema,\n addIssueCommentSchema,\n reportIssueCommitSchema,\n linkIssueApprovalSchema,\n createIssueAttachmentMetadataSchema,\n createIssueWorkspaceAttachmentSchema,\n issueDocumentFormatSchema,\n issueDocumentKeySchema,\n upsertIssueDocumentSchema,\n type CreateIssue,\n type CreateIssueLabel,\n type UpdateIssueLabel,\n type UpdateIssue,\n type ReorderIssue,\n type IssueExecutionWorkspaceSettings,\n type CheckoutIssue,\n type AddIssueComment,\n type ReportIssueCommit,\n type LinkIssueApproval,\n type CreateIssueAttachmentMetadata,\n type CreateIssueWorkspaceAttachment,\n type IssueDocumentFormat,\n type UpsertIssueDocument,\n} from \"./issue.js\";\n\nexport {\n createIssueWorkProductSchema,\n updateIssueWorkProductSchema,\n issueWorkProductTypeSchema,\n issueWorkProductStatusSchema,\n issueWorkProductReviewStateSchema,\n type CreateIssueWorkProduct,\n type UpdateIssueWorkProduct,\n} from \"./work-product.js\";\n\nexport {\n updateExecutionWorkspaceSchema,\n executionWorkspaceStatusSchema,\n type UpdateExecutionWorkspace,\n} from \"./execution-workspace.js\";\n\nexport {\n workspaceBackupTriggerSourceSchema,\n createWorkspaceBackupSchema,\n restoreWorkspaceBackupSchema,\n type CreateWorkspaceBackup,\n type RestoreWorkspaceBackup,\n} from \"./workspace-backup.js\";\n\nexport {\n createGoalSchema,\n updateGoalSchema,\n type CreateGoal,\n type UpdateGoal,\n} from \"./goal.js\";\n\nexport {\n createApprovalSchema,\n resolveApprovalSchema,\n requestApprovalRevisionSchema,\n resubmitApprovalSchema,\n addApprovalCommentSchema,\n type CreateApproval,\n type ResolveApproval,\n type RequestApprovalRevision,\n type ResubmitApproval,\n type AddApprovalComment,\n} from \"./approval.js\";\n\nexport {\n envBindingPlainSchema,\n envBindingSecretRefSchema,\n envBindingSchema,\n envConfigSchema,\n createSecretSchema,\n rotateSecretSchema,\n updateSecretSchema,\n type CreateSecret,\n type RotateSecret,\n type UpdateSecret,\n} from \"./secret.js\";\n\nexport {\n createAutomationSchema,\n updateAutomationSchema,\n createAutomationTriggerSchema,\n updateAutomationTriggerSchema,\n runAutomationSchema,\n rotateAutomationTriggerSecretSchema,\n type CreateAutomation,\n type UpdateAutomation,\n type CreateAutomationTrigger,\n type UpdateAutomationTrigger,\n type RunAutomation,\n type RotateAutomationTriggerSecret,\n} from \"./automation.js\";\n\nexport {\n createCalendarSourceSchema,\n updateCalendarSourceSchema,\n createCalendarEventSchema,\n updateCalendarEventSchema,\n calendarEventListQuerySchema,\n googleCalendarSyncSchema,\n updateGoogleCalendarOAuthConfigSchema,\n type CreateCalendarSource,\n type UpdateCalendarSource,\n type CreateCalendarEvent,\n type UpdateCalendarEvent,\n type CalendarEventListQuery,\n type GoogleCalendarSync,\n type UpdateGoogleCalendarOAuthConfig,\n} from \"./calendar.js\";\n\nexport {\n createCostEventSchema,\n updateBudgetSchema,\n type CreateCostEvent,\n type UpdateBudget,\n} from \"./cost.js\";\n\nexport {\n createFinanceEventSchema,\n type CreateFinanceEvent,\n} from \"./finance.js\";\n\nexport {\n createAssetImageMetadataSchema,\n type CreateAssetImageMetadata,\n} from \"./asset.js\";\n\nexport {\n createCompanyInviteSchema,\n createOpenClawInvitePromptSchema,\n acceptInviteSchema,\n listJoinRequestsQuerySchema,\n claimJoinRequestApiKeySchema,\n boardCliAuthAccessLevelSchema,\n createCliAuthChallengeSchema,\n resolveCliAuthChallengeSchema,\n updateMemberPermissionsSchema,\n updateUserCompanyAccessSchema,\n type CreateCompanyInvite,\n type CreateOpenClawInvitePrompt,\n type AcceptInvite,\n type ListJoinRequestsQuery,\n type ClaimJoinRequestApiKey,\n type BoardCliAuthAccessLevel,\n type CreateCliAuthChallenge,\n type ResolveCliAuthChallenge,\n type UpdateMemberPermissions,\n type UpdateUserCompanyAccess,\n} from \"./access.js\";\n\nexport {\n jsonSchemaSchema,\n pluginJobDeclarationSchema,\n pluginWebhookDeclarationSchema,\n pluginToolDeclarationSchema,\n pluginUiSlotDeclarationSchema,\n pluginLauncherActionDeclarationSchema,\n pluginLauncherRenderDeclarationSchema,\n pluginLauncherDeclarationSchema,\n pluginManifestV1Schema,\n installPluginSchema,\n upsertPluginConfigSchema,\n patchPluginConfigSchema,\n updatePluginStatusSchema,\n uninstallPluginSchema,\n pluginStateScopeKeySchema,\n setPluginStateSchema,\n listPluginStateSchema,\n type PluginJobDeclarationInput,\n type PluginWebhookDeclarationInput,\n type PluginToolDeclarationInput,\n type PluginUiSlotDeclarationInput,\n type PluginLauncherActionDeclarationInput,\n type PluginLauncherRenderDeclarationInput,\n type PluginLauncherDeclarationInput,\n type PluginManifestV1Input,\n type InstallPlugin,\n type UpsertPluginConfig,\n type PatchPluginConfig,\n type UpdatePluginStatus,\n type UninstallPlugin,\n type PluginStateScopeKey,\n type SetPluginState,\n type ListPluginState,\n} from \"./plugin.js\";\n", "export const API_PREFIX = \"/api\";\n\nexport const API = {\n health: `${API_PREFIX}/health`,\n organizations: `${API_PREFIX}/orgs`,\n agents: `${API_PREFIX}/agents`,\n projects: `${API_PREFIX}/projects`,\n issues: `${API_PREFIX}/issues`,\n chats: `${API_PREFIX}/chats`,\n messenger: `${API_PREFIX}/messenger`,\n calendar: `${API_PREFIX}/calendar`,\n goals: `${API_PREFIX}/goals`,\n approvals: `${API_PREFIX}/approvals`,\n secrets: `${API_PREFIX}/secrets`,\n costs: `${API_PREFIX}/costs`,\n activity: `${API_PREFIX}/activity`,\n dashboard: `${API_PREFIX}/dashboard`,\n sidebarBadges: `${API_PREFIX}/sidebar-badges`,\n invites: `${API_PREFIX}/invites`,\n joinRequests: `${API_PREFIX}/join-requests`,\n members: `${API_PREFIX}/members`,\n admin: `${API_PREFIX}/admin`,\n} as const;\n", "const AGENT_URL_KEY_DELIM_RE = /[^a-z0-9]+/g;\nconst AGENT_URL_KEY_TRIM_RE = /^-+|-+$/g;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport function isUuidLike(value: string | null | undefined): boolean {\n if (typeof value !== \"string\") return false;\n return UUID_RE.test(value.trim());\n}\n\nexport function normalizeAgentUrlKey(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(AGENT_URL_KEY_DELIM_RE, \"-\")\n .replace(AGENT_URL_KEY_TRIM_RE, \"\");\n return normalized.length > 0 ? normalized : null;\n}\n\nexport function deriveAgentUrlKey(name: string | null | undefined, fallback?: string | null): string {\n return normalizeAgentUrlKey(name) ?? normalizeAgentUrlKey(fallback) ?? \"agent\";\n}\n", "const ORGANIZATION_URL_KEY_DELIM_RE = /[^a-z0-9]+/g;\nconst ORGANIZATION_URL_KEY_TRIM_RE = /^-+|-+$/g;\n\nexport function normalizeOrganizationUrlKey(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(ORGANIZATION_URL_KEY_DELIM_RE, \"-\")\n .replace(ORGANIZATION_URL_KEY_TRIM_RE, \"\");\n return normalized.length > 0 ? normalized : null;\n}\n\nexport function deriveOrganizationUrlKey(name: string | null | undefined, fallback?: string | null): string {\n return normalizeOrganizationUrlKey(name) ?? normalizeOrganizationUrlKey(fallback) ?? \"organization\";\n}\n", "const PROJECT_URL_KEY_DELIM_RE = /[^a-z0-9]+/g;\nconst PROJECT_URL_KEY_TRIM_RE = /^-+|-+$/g;\n\nexport function normalizeProjectUrlKey(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(PROJECT_URL_KEY_DELIM_RE, \"-\")\n .replace(PROJECT_URL_KEY_TRIM_RE, \"\");\n return normalized.length > 0 ? normalized : null;\n}\n\nexport function deriveProjectUrlKey(name: string | null | undefined, fallback?: string | null): string {\n return normalizeProjectUrlKey(name) ?? normalizeProjectUrlKey(fallback) ?? \"project\";\n}\n", "export interface MessengerPreviewOptions {\n max?: number;\n}\n\nconst URL_PATTERN = /(?:https?:\\/\\/|www\\.)[^\\s<>()\\]]+/giu;\n\nconst NAMED_HTML_ENTITIES: Record<string, string> = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n nbsp: \" \",\n quot: '\"',\n};\n\nfunction truncateText(value: string, max: number) {\n if (value.length <= max) return value;\n return `${value.slice(0, Math.max(0, max - 1))}\u2026`;\n}\n\nfunction decodeHtmlEntities(value: string) {\n return value\n .replace(/&#x([\\da-f]+);/giu, (_entity, codePoint: string) => {\n const parsed = Number.parseInt(codePoint, 16);\n return Number.isFinite(parsed) ? String.fromCodePoint(parsed) : _entity;\n })\n .replace(/&#(\\d+);/gu, (_entity, codePoint: string) => {\n const parsed = Number.parseInt(codePoint, 10);\n return Number.isFinite(parsed) ? String.fromCodePoint(parsed) : _entity;\n })\n .replace(/&([a-z]+);/giu, (entity, name: string) => NAMED_HTML_ENTITIES[name.toLowerCase()] ?? entity);\n}\n\nfunction trimUrlToken(value: string) {\n return value.replace(/[\\].,!?;:\uFF0C\u3002\uFF01\uFF1F\uFF1B\uFF1A]+$/u, \"\");\n}\n\nfunction compactUrlLabel(value: string | null | undefined) {\n const raw = trimUrlToken(value?.trim() ?? \"\");\n if (!raw) return null;\n const normalized = raw.startsWith(\"www.\") ? `https://${raw}` : raw;\n\n try {\n const parsed = new URL(normalized);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") return null;\n const hostname = parsed.hostname.replace(/^www\\./iu, \"\");\n const pathParts = parsed.pathname.split(\"/\").map((part) => part.trim()).filter(Boolean);\n const lastPathPart = pathParts.at(-1)\n ?.replace(/[-_]+/gu, \" \")\n .replace(/\\.html?$/iu, \"\")\n .trim();\n return lastPathPart ? `${hostname} \u00B7 ${lastPathPart}` : hostname;\n } catch {\n return null;\n }\n}\n\nfunction stripBareUrlNoise(value: string) {\n const urls = Array.from(value.matchAll(URL_PATTERN), (match) => match[0]);\n if (urls.length === 0) return value;\n\n const withoutUrls = value\n .replace(URL_PATTERN, \" \")\n .replace(/\\[\\s*\\]/gu, \" \")\n .replace(/\\(\\s*\\)/gu, \" \")\n .replace(/\\s+/gu, \" \")\n .trim();\n if (withoutUrls) return withoutUrls;\n\n return compactUrlLabel(urls[0]) ?? \"\";\n}\n\nfunction markdownHeadingText(line: string) {\n const match = decodeHtmlEntities(line).match(/^#{1,6}\\s*(.*?)\\s*#*$/);\n const text = match?.[1]?.trim();\n return text ? text.replace(/[:\uFF1A]\\s*$/, \"\") : null;\n}\n\nfunction plainPreviewLine(line: string) {\n return stripBareUrlNoise(decodeHtmlEntities(line)\n .trim()\n .replace(/^#{1,6}\\s*(.*?)\\s*#*$/, \"$1\")\n .replace(/^>\\s*/, \"\")\n .replace(/^(?:[-*+]|\\d+[.)])\\s+/, \"\")\n .replace(/^\\[[ xX]\\]\\s+/, \"\")\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/\\[\\s*((?:https?:\\/\\/|www\\.)[^\\]\\s]+)\\s*\\]/giu, \"$1\")\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"$1\")\n .replace(/__([^_]+)__/g, \"$1\")\n .replace(/\\*([^*]+)\\*/g, \"$1\")\n .replace(/_([^_]+)_/g, \"$1\")\n .replace(/\\s+/g, \" \")\n .trim())\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function formatMessengerPreview(value: string | null | undefined, options: MessengerPreviewOptions = {}) {\n const max = options.max ?? 140;\n const lines = (value ?? \"\")\n .split(/\\r?\\n/)\n .map((part) => part.trim())\n .filter(Boolean);\n if (lines.length === 0) return null;\n\n const heading = markdownHeadingText(lines[0] ?? \"\");\n if (heading) {\n const detail = lines.slice(1).map(plainPreviewLine).find(Boolean);\n return truncateText(detail ? `${plainPreviewLine(heading)}: ${detail}` : plainPreviewLine(heading), max);\n }\n\n const first = plainPreviewLine(lines[0] ?? \"\");\n return first ? truncateText(first, max) : null;\n}\n\nexport function formatMessengerTitle(value: string | null | undefined, options: MessengerPreviewOptions = {}) {\n const max = options.max ?? 80;\n const lines = (value ?? \"\")\n .split(/\\r?\\n/)\n .map((part) => part.trim())\n .filter(Boolean);\n\n for (const line of lines) {\n const heading = markdownHeadingText(line);\n const title = plainPreviewLine(heading ?? line);\n if (title) return truncateText(title, max);\n }\n\n return null;\n}\n", "export type CachedInputTokenSemantics = \"included_in_input\" | \"additional_to_input\";\n\nexport const ADDITIONAL_CACHED_INPUT_TOKEN_PROVIDERS = [\"anthropic\", \"claude\"] as const;\n\nexport interface TokenUsageParts {\n inputTokens?: number | null;\n cachedInputTokens?: number | null;\n outputTokens?: number | null;\n cachedInputTokenSemantics?: CachedInputTokenSemantics | null;\n provider?: string | null;\n}\n\nexport interface TokenUsageSummary {\n inputTokens: number;\n cachedInputTokens: number;\n outputTokens: number;\n cachedInputTokenSemantics: CachedInputTokenSemantics;\n uncachedInputTokens: number;\n promptTokens: number;\n totalTokens: number;\n}\n\nfunction tokenCount(value: number | null | undefined): number {\n return Math.max(0, Math.floor(typeof value === \"number\" && Number.isFinite(value) ? value : 0));\n}\n\nexport function cachedInputTokenSemanticsForProvider(\n provider: string | null | undefined,\n): CachedInputTokenSemantics {\n const normalized = provider?.trim().toLowerCase();\n if (normalized && ADDITIONAL_CACHED_INPUT_TOKEN_PROVIDERS.some((value) => (\n normalized === value || normalized.startsWith(`${value}:`) || normalized.startsWith(`${value}/`)\n ))) {\n return \"additional_to_input\";\n }\n return \"included_in_input\";\n}\n\nexport function summarizeTokenUsage(parts: TokenUsageParts): TokenUsageSummary {\n const inputTokens = tokenCount(parts.inputTokens);\n const cachedInputTokens = tokenCount(parts.cachedInputTokens);\n const outputTokens = tokenCount(parts.outputTokens);\n const cacheSemantics =\n parts.cachedInputTokenSemantics ?? cachedInputTokenSemanticsForProvider(parts.provider);\n const cachedIsInputSubset = cacheSemantics === \"included_in_input\";\n const uncachedInputTokens = cachedIsInputSubset\n ? Math.max(0, inputTokens - cachedInputTokens)\n : inputTokens;\n const promptTokens = cachedIsInputSubset\n ? inputTokens\n : inputTokens + cachedInputTokens;\n\n return {\n inputTokens,\n cachedInputTokens,\n outputTokens,\n cachedInputTokenSemantics: cacheSemantics,\n uncachedInputTokens,\n promptTokens,\n totalTokens: promptTokens + outputTokens,\n };\n}\n\nexport function tokenUsageCacheRatio(parts: TokenUsageParts): number | null {\n const summary = summarizeTokenUsage(parts);\n if (summary.promptTokens <= 0) return null;\n return summary.cachedInputTokens / summary.promptTokens;\n}\n\nexport function hasTokenUsage(parts: TokenUsageParts): boolean {\n const summary = summarizeTokenUsage(parts);\n return summary.totalTokens > 0 || summary.cachedInputTokens > 0;\n}\n", "import { normalizeAgentUrlKey } from \"./agent-url-key.js\";\nimport { normalizeOrganizationUrlKey } from \"./organization-url-key.js\";\nimport type {\n OrganizationSkillListItem,\n OrganizationSkillSourceType,\n} from \"./types/organization-skill.js\";\n\ntype SkillReferenceSource = Pick<\n OrganizationSkillListItem,\n \"key\" | \"slug\" | \"name\" | \"sourceType\" | \"sourceLocator\"\n> & Partial<Pick<OrganizationSkillListItem, \"sourceBadge\" | \"sourceLabel\" | \"sourcePath\">>;\n\nexport type OrganizationSkillPublicRefScope = \"organization\" | \"agent\";\n\nexport interface OrganizationSkillPublicRefContext {\n orgUrlKey: string;\n agentUrlKey?: string | null;\n scope?: OrganizationSkillPublicRefScope;\n}\n\nexport type ParsedOrganizationSkillReferenceKind =\n | \"raw_slug\"\n | \"organization\"\n | \"rudder\"\n | \"github\"\n | \"url\"\n | \"other\";\n\nexport interface ParsedOrganizationSkillReference {\n kind: ParsedOrganizationSkillReferenceKind;\n normalized: string;\n slug: string | null;\n segments: string[];\n}\n\nexport interface ResolveOrganizationSkillReferenceContext {\n orgId: string;\n}\n\nexport interface ResolveOrganizationSkillReferenceResult<TSkill> {\n skill: TSkill | null;\n ambiguous: boolean;\n}\n\nfunction normalizeSkillSlug(value: string | null | undefined) {\n return value ? normalizeAgentUrlKey(value) ?? null : null;\n}\n\nexport const RUDDER_BUNDLED_SKILL_SLUGS = [\n \"para-memory-files\",\n \"rudder\",\n \"rudder-create-agent\",\n \"rudder-create-plugin\",\n \"skill-creator\",\n \"skill-optimizer\",\n \"conversation-to-skill\",\n] as const;\n\nconst RUDDER_BUNDLED_SKILL_KEYS = new Set(\n RUDDER_BUNDLED_SKILL_SLUGS.map((slug) => `rudder/${slug}`),\n);\n\nexport function getBundledRudderSkillSlug(value: string | null | undefined) {\n if (!value) return null;\n const segments = value\n .trim()\n .split(\"/\")\n .map((segment) => normalizeSkillSlug(segment))\n .filter((segment): segment is string => Boolean(segment));\n\n if (segments.length === 2 && segments[0] === \"rudder\") {\n return segments[1] ?? null;\n }\n\n if (segments.length === 3 && segments[0] === \"rudder\" && segments[1] === \"rudder\") {\n return segments[2] ?? null;\n }\n\n return null;\n}\n\nexport function toBundledRudderSkillKey(value: string | null | undefined) {\n const slug = normalizeSkillSlug(value);\n if (!slug) return null;\n return `rudder/${slug}`;\n}\n\nexport function isCanonicalBundledRudderSkillKey(value: string | null | undefined) {\n return RUDDER_BUNDLED_SKILL_KEYS.has(value ?? \"\");\n}\n\nexport function normalizeOrganizationSkillKey(value: string | null | undefined) {\n if (!value) return null;\n const normalized = value\n .trim()\n .split(\"/\")\n .map((segment) => normalizeSkillSlug(segment))\n .filter((segment): segment is string => Boolean(segment))\n .join(\"/\");\n return normalized.length > 0 ? normalized : null;\n}\n\nfunction isOrganizationScopedSkill(skill: { sourceType?: OrganizationSkillSourceType | null; key: string }) {\n return skill.sourceType !== \"github\" && skill.sourceType !== \"skills_sh\" && skill.sourceType !== \"url\";\n}\n\nfunction isRudderSkill(skill: SkillReferenceSource) {\n return getBundledRudderSkillSlug(skill.key) !== null || skill.sourceBadge === \"rudder\";\n}\n\nfunction normalizeSegmentList(reference: string) {\n return reference\n .trim()\n .split(\"/\")\n .map((segment) => normalizeSkillSlug(segment))\n .filter((segment): segment is string => Boolean(segment));\n}\n\nfunction parseRepositoryLocator(sourceLocator: string | null | undefined, sourceLabel: string | null | undefined) {\n const tryParse = (value: string | null | undefined) => {\n if (!value) return null;\n try {\n const url = new URL(value);\n const parts = url.pathname.split(\"/\").filter(Boolean);\n if (parts.length >= 2) {\n return {\n owner: normalizeSkillSlug(parts[0]) ?? parts[0]!,\n repo: normalizeSkillSlug(parts[1]) ?? parts[1]!,\n };\n }\n } catch {\n const parts = value.split(\"/\").map((part) => part.trim()).filter(Boolean);\n if (parts.length >= 2) {\n return {\n owner: normalizeSkillSlug(parts[0]) ?? parts[0]!,\n repo: normalizeSkillSlug(parts[1]) ?? parts[1]!,\n };\n }\n }\n return null;\n };\n\n return tryParse(sourceLocator) ?? tryParse(sourceLabel);\n}\n\nexport function formatOrganizationSkillPublicRef(\n skill: SkillReferenceSource,\n context: OrganizationSkillPublicRefContext,\n) {\n const normalizedKey = normalizeOrganizationSkillKey(skill.key) ?? skill.key.trim();\n const slug = (normalizeSkillSlug(skill.slug) ?? skill.slug.trim()) || \"skill\";\n const orgUrlKey = normalizeOrganizationUrlKey(context.orgUrlKey) ?? \"organization\";\n const agentUrlKey = normalizeAgentUrlKey(context.agentUrlKey ?? null);\n\n if (isRudderSkill(skill)) {\n return `rudder/${slug}`;\n }\n\n if (normalizedKey.startsWith(\"organization/\") || normalizedKey.startsWith(\"local/\") || normalizedKey.startsWith(\"catalog/\")) {\n if (context.scope === \"agent\" && agentUrlKey) {\n return `org/${orgUrlKey}/${agentUrlKey}/${slug}`;\n }\n return `org/${orgUrlKey}/${slug}`;\n }\n\n if (skill.sourceType === \"github\" || skill.sourceType === \"skills_sh\") {\n const repo = parseRepositoryLocator(skill.sourceLocator, skill.sourceLabel);\n if (repo) {\n return `${repo.owner}/${repo.repo}/${slug}`;\n }\n }\n\n if (normalizedKey.startsWith(\"url/\")) {\n return normalizedKey;\n }\n\n return normalizedKey;\n}\n\nexport function buildOrganizationSkillSearchText(\n skill: SkillReferenceSource,\n context: OrganizationSkillPublicRefContext,\n) {\n return [\n formatOrganizationSkillPublicRef(skill, context),\n skill.name,\n skill.slug,\n skill.sourceLabel ?? \"\",\n skill.sourceBadge ?? \"\",\n skill.sourcePath ?? \"\",\n ]\n .join(\" \")\n .toLowerCase();\n}\n\nexport function parseOrganizationSkillReference(reference: string): ParsedOrganizationSkillReference {\n const normalized = reference.trim();\n const segments = normalizeSegmentList(normalized);\n if (segments.length === 0) {\n return {\n kind: \"other\",\n normalized: \"\",\n slug: null,\n segments: [],\n };\n }\n\n if (segments[0] === \"org\" || segments[0] === \"organization\") {\n return {\n kind: \"organization\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments[0] === \"rudder\") {\n return {\n kind: \"rudder\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments[0] === \"url\" && segments.length >= 4) {\n return {\n kind: \"url\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments[0] === \"local\" && segments.length >= 3) {\n return {\n kind: \"other\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments.length >= 3) {\n return {\n kind: \"github\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n return {\n kind: \"raw_slug\",\n normalized: segments.join(\"/\"),\n slug: segments[0] ?? null,\n segments,\n };\n}\n\nexport function resolveOrganizationSkillReference<TSkill extends SkillReferenceSource>(\n skills: TSkill[],\n reference: string,\n context: ResolveOrganizationSkillReferenceContext,\n): ResolveOrganizationSkillReferenceResult<TSkill> {\n const trimmed = reference.trim();\n if (!trimmed) {\n return { skill: null, ambiguous: false };\n }\n\n const normalizedKey = normalizeOrganizationSkillKey(trimmed);\n if (normalizedKey) {\n const byKey = skills.find((skill) => normalizeOrganizationSkillKey(skill.key) === normalizedKey);\n if (byKey) {\n return { skill: byKey, ambiguous: false };\n }\n }\n\n const parsed = parseOrganizationSkillReference(trimmed);\n if (parsed.kind === \"organization\") {\n const slug = parsed.slug;\n if (!slug) return { skill: null, ambiguous: false };\n const exactKey = `organization/${context.orgId}/${slug}`;\n const byExactOrgKey = skills.find((skill) => skill.key === exactKey);\n if (byExactOrgKey) {\n return { skill: byExactOrgKey, ambiguous: false };\n }\n\n const orgScoped = skills.filter((skill) => isOrganizationScopedSkill(skill) && skill.slug === slug);\n if (orgScoped.length === 1) {\n return { skill: orgScoped[0] ?? null, ambiguous: false };\n }\n if (orgScoped.length > 1) {\n return { skill: null, ambiguous: true };\n }\n\n const bySlug = skills.filter((skill) => skill.slug === slug);\n if (bySlug.length === 1) {\n return { skill: bySlug[0] ?? null, ambiguous: false };\n }\n if (bySlug.length > 1) {\n return { skill: null, ambiguous: true };\n }\n return { skill: null, ambiguous: false };\n }\n\n if (parsed.kind === \"rudder\") {\n const slug = parsed.slug;\n if (!slug) return { skill: null, ambiguous: false };\n const canonicalKey = toBundledRudderSkillKey(slug);\n const legacyKey = canonicalKey ? `rudder/${canonicalKey}` : null;\n for (const exactKey of [canonicalKey, legacyKey]) {\n if (!exactKey) continue;\n const byExactKey = skills.find((skill) => skill.key === exactKey);\n if (byExactKey) {\n return { skill: byExactKey, ambiguous: false };\n }\n }\n\n const rudderSkills = skills.filter((skill) => isRudderSkill(skill) && skill.slug === slug);\n if (rudderSkills.length === 1) {\n return { skill: rudderSkills[0] ?? null, ambiguous: false };\n }\n if (rudderSkills.length > 1) {\n return { skill: null, ambiguous: true };\n }\n return { skill: null, ambiguous: false };\n }\n\n if (parsed.kind === \"raw_slug\") {\n const slug = parsed.slug;\n if (!slug) return { skill: null, ambiguous: false };\n const bySlug = skills.filter((skill) => skill.slug === slug);\n if (bySlug.length === 1) {\n return { skill: bySlug[0] ?? null, ambiguous: false };\n }\n if (bySlug.length > 1) {\n return { skill: null, ambiguous: true };\n }\n }\n\n return { skill: null, ambiguous: false };\n}\n", "import { PROJECT_COLORS } from \"./constants.js\";\n\nexport const PROJECT_MENTION_SCHEME = \"project://\";\nexport const AGENT_MENTION_SCHEME = \"agent://\";\nexport const ISSUE_MENTION_SCHEME = \"issue://\";\n\nconst HEX_COLOR_RE = /^[0-9a-f]{6}$/i;\nconst HEX_COLOR_SHORT_RE = /^[0-9a-f]{3}$/i;\nconst HEX_COLOR_WITH_HASH_RE = /^#[0-9a-f]{6}$/i;\nconst HEX_COLOR_SHORT_WITH_HASH_RE = /^#[0-9a-f]{3}$/i;\nconst PROJECT_MENTION_LINK_RE = /\\[[^\\]]*]\\((project:\\/\\/[^)\\s]+)\\)/gi;\nconst AGENT_MENTION_LINK_RE = /\\[[^\\]]*]\\((agent:\\/\\/[^)\\s]+)\\)/gi;\nconst ISSUE_MENTION_LINK_RE = /\\[[^\\]]*]\\((issue:\\/\\/[^)\\s]+)\\)/gi;\nconst AGENT_ICON_NAME_RE = /^[a-z0-9-]+$/i;\nconst PROJECT_COLOR_VALUES = new Set<string>(PROJECT_COLORS);\n\nexport interface ParsedProjectMention {\n projectId: string;\n color: string | null;\n}\n\nexport interface ParsedAgentMention {\n agentId: string;\n icon: string | null;\n}\n\nexport interface ParsedIssueMention {\n issueId: string;\n ref: string | null;\n}\n\nfunction normalizeHexColor(input: string | null | undefined): string | null {\n if (!input) return null;\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n if (HEX_COLOR_WITH_HASH_RE.test(trimmed)) {\n return trimmed.toLowerCase();\n }\n if (HEX_COLOR_RE.test(trimmed)) {\n return `#${trimmed.toLowerCase()}`;\n }\n if (HEX_COLOR_SHORT_WITH_HASH_RE.test(trimmed)) {\n const raw = trimmed.slice(1).toLowerCase();\n return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}`;\n }\n if (HEX_COLOR_SHORT_RE.test(trimmed)) {\n const raw = trimmed.toLowerCase();\n return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}`;\n }\n return null;\n}\n\nfunction normalizeProjectMentionColor(input: string | null | undefined): string | null {\n const hex = normalizeHexColor(input);\n if (hex) return hex;\n const trimmed = input?.trim();\n if (trimmed && PROJECT_COLOR_VALUES.has(trimmed)) return trimmed;\n return null;\n}\n\nfunction encodeMentionParam(value: string): string {\n return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);\n}\n\nexport function buildProjectMentionHref(projectId: string, color?: string | null): string {\n const trimmedProjectId = projectId.trim();\n const normalizedColor = normalizeProjectMentionColor(color ?? null);\n if (!normalizedColor) {\n return `${PROJECT_MENTION_SCHEME}${trimmedProjectId}`;\n }\n const colorParam = normalizedColor.startsWith(\"#\") ? normalizedColor.slice(1) : normalizedColor;\n return `${PROJECT_MENTION_SCHEME}${trimmedProjectId}?c=${encodeMentionParam(colorParam)}`;\n}\n\nexport function parseProjectMentionHref(href: string): ParsedProjectMention | null {\n if (!href.startsWith(PROJECT_MENTION_SCHEME)) return null;\n\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"project:\") return null;\n\n const projectId = `${url.hostname}${url.pathname}`.replace(/^\\/+/, \"\").trim();\n if (!projectId) return null;\n\n const color = normalizeProjectMentionColor(url.searchParams.get(\"c\") ?? url.searchParams.get(\"color\"));\n\n return {\n projectId,\n color,\n };\n}\n\nexport function buildAgentMentionHref(agentId: string, icon?: string | null): string {\n const trimmedAgentId = agentId.trim();\n const normalizedIcon = normalizeAgentIcon(icon ?? null);\n if (!normalizedIcon) {\n return `${AGENT_MENTION_SCHEME}${trimmedAgentId}`;\n }\n return `${AGENT_MENTION_SCHEME}${trimmedAgentId}?i=${encodeURIComponent(normalizedIcon)}`;\n}\n\nexport function parseAgentMentionHref(href: string): ParsedAgentMention | null {\n if (!href.startsWith(AGENT_MENTION_SCHEME)) return null;\n\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"agent:\") return null;\n\n const agentId = `${url.hostname}${url.pathname}`.replace(/^\\/+/, \"\").trim();\n if (!agentId) return null;\n\n return {\n agentId,\n icon: normalizeAgentIcon(url.searchParams.get(\"i\") ?? url.searchParams.get(\"icon\")),\n };\n}\n\nexport function buildIssueMentionHref(issueId: string, ref?: string | null): string {\n const trimmedIssueId = issueId.trim();\n const trimmedRef = ref?.trim();\n if (!trimmedRef) return `${ISSUE_MENTION_SCHEME}${trimmedIssueId}`;\n return `${ISSUE_MENTION_SCHEME}${trimmedIssueId}?r=${encodeURIComponent(trimmedRef)}`;\n}\n\nexport function parseIssueMentionHref(href: string): ParsedIssueMention | null {\n if (!href.startsWith(ISSUE_MENTION_SCHEME)) return null;\n\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"issue:\") return null;\n\n const issueId = `${url.hostname}${url.pathname}`.replace(/^\\/+/, \"\").trim();\n if (!issueId) return null;\n\n const ref = (url.searchParams.get(\"r\") ?? url.searchParams.get(\"ref\") ?? \"\").trim() || null;\n\n return {\n issueId,\n ref,\n };\n}\n\nexport function extractProjectMentionIds(markdown: string): string[] {\n if (!markdown) return [];\n const ids = new Set<string>();\n const re = new RegExp(PROJECT_MENTION_LINK_RE);\n let match: RegExpExecArray | null;\n while ((match = re.exec(markdown)) !== null) {\n const parsed = parseProjectMentionHref(match[1]);\n if (parsed) ids.add(parsed.projectId);\n }\n return [...ids];\n}\n\nexport function extractAgentMentionIds(markdown: string): string[] {\n if (!markdown) return [];\n const ids = new Set<string>();\n const re = new RegExp(AGENT_MENTION_LINK_RE);\n let match: RegExpExecArray | null;\n while ((match = re.exec(markdown)) !== null) {\n const parsed = parseAgentMentionHref(match[1]);\n if (parsed) ids.add(parsed.agentId);\n }\n return [...ids];\n}\n\nexport function extractIssueMentionIds(markdown: string): string[] {\n if (!markdown) return [];\n const ids = new Set<string>();\n const re = new RegExp(ISSUE_MENTION_LINK_RE);\n let match: RegExpExecArray | null;\n while ((match = re.exec(markdown)) !== null) {\n const parsed = parseIssueMentionHref(match[1]);\n if (parsed) ids.add(parsed.issueId);\n }\n return [...ids];\n}\n\nfunction normalizeAgentIcon(input: string | null | undefined): string | null {\n if (!input) return null;\n const trimmed = input.trim().toLowerCase();\n if (!trimmed || !AGENT_ICON_NAME_RE.test(trimmed)) return null;\n return trimmed;\n}\n", "import { z } from \"zod\";\nimport {\n AUTH_BASE_URL_MODES,\n DEPLOYMENT_EXPOSURES,\n DEPLOYMENT_MODES,\n SECRET_PROVIDERS,\n STORAGE_PROVIDERS,\n} from \"./constants.js\";\n\nexport const configMetaSchema = z.object({\n version: z.literal(1),\n updatedAt: z.string(),\n source: z.enum([\"onboard\", \"configure\", \"doctor\"]),\n});\n\nexport const llmConfigSchema = z.object({\n provider: z.enum([\"claude\", \"openai\"]),\n apiKey: z.string().optional(),\n});\n\nexport const databaseBackupConfigSchema = z.object({\n enabled: z.boolean().default(true),\n intervalMinutes: z.number().int().min(1).max(7 * 24 * 60).default(60),\n retentionDays: z.number().int().min(1).max(3650).default(30),\n dir: z.string().default(\"~/.rudder/instances/default/data/backups\"),\n});\n\nexport const databaseConfigSchema = z.object({\n mode: z.enum([\"embedded-postgres\", \"postgres\"]).default(\"embedded-postgres\"),\n connectionString: z.string().optional(),\n embeddedPostgresDataDir: z.string().default(\"~/.rudder/instances/default/db\"),\n embeddedPostgresPort: z.number().int().min(1).max(65535).default(54329),\n backup: databaseBackupConfigSchema.default({\n enabled: true,\n intervalMinutes: 60,\n retentionDays: 30,\n dir: \"~/.rudder/instances/default/data/backups\",\n }),\n});\n\nexport const loggingConfigSchema = z.object({\n mode: z.enum([\"file\", \"cloud\"]),\n logDir: z.string().default(\"~/.rudder/instances/default/logs\"),\n});\n\nexport const serverConfigSchema = z.object({\n deploymentMode: z.enum(DEPLOYMENT_MODES).default(\"local_trusted\"),\n exposure: z.enum(DEPLOYMENT_EXPOSURES).default(\"private\"),\n host: z.string().default(\"127.0.0.1\"),\n port: z.number().int().min(1).max(65535).default(3100),\n allowedHostnames: z.array(z.string().min(1)).default([]),\n serveUi: z.boolean().default(true),\n});\n\nexport const authConfigSchema = z.object({\n baseUrlMode: z.enum(AUTH_BASE_URL_MODES).default(\"auto\"),\n publicBaseUrl: z.string().url().optional(),\n disableSignUp: z.boolean().default(false),\n});\n\nexport const storageLocalDiskConfigSchema = z.object({\n baseDir: z.string().default(\"~/.rudder/instances/default/data/storage\"),\n});\n\nexport const storageS3ConfigSchema = z.object({\n bucket: z.string().min(1).default(\"rudder\"),\n region: z.string().min(1).default(\"us-east-1\"),\n endpoint: z.string().optional(),\n prefix: z.string().default(\"\"),\n forcePathStyle: z.boolean().default(false),\n});\n\nexport const storageConfigSchema = z.object({\n provider: z.enum(STORAGE_PROVIDERS).default(\"local_disk\"),\n localDisk: storageLocalDiskConfigSchema.default({\n baseDir: \"~/.rudder/instances/default/data/storage\",\n }),\n s3: storageS3ConfigSchema.default({\n bucket: \"rudder\",\n region: \"us-east-1\",\n prefix: \"\",\n forcePathStyle: false,\n }),\n});\n\nexport const secretsLocalEncryptedConfigSchema = z.object({\n keyFilePath: z.string().default(\"~/.rudder/instances/default/secrets/master.key\"),\n});\n\nexport const secretsConfigSchema = z.object({\n provider: z.enum(SECRET_PROVIDERS).default(\"local_encrypted\"),\n strictMode: z.boolean().default(false),\n localEncrypted: secretsLocalEncryptedConfigSchema.default({\n keyFilePath: \"~/.rudder/instances/default/secrets/master.key\",\n }),\n});\n\nexport const langfuseConfigSchema = z.object({\n enabled: z.boolean().default(false),\n baseUrl: z.string().url().default(\"http://localhost:3000\"),\n publicKey: z.string().optional(),\n secretKey: z.string().optional(),\n environment: z.string().optional(),\n});\n\nexport const rudderConfigSchema = z\n .object({\n $meta: configMetaSchema,\n llm: llmConfigSchema.optional(),\n database: databaseConfigSchema,\n logging: loggingConfigSchema,\n server: serverConfigSchema,\n auth: authConfigSchema.default({\n baseUrlMode: \"auto\",\n disableSignUp: false,\n }),\n storage: storageConfigSchema.default({\n provider: \"local_disk\",\n localDisk: {\n baseDir: \"~/.rudder/instances/default/data/storage\",\n },\n s3: {\n bucket: \"rudder\",\n region: \"us-east-1\",\n prefix: \"\",\n forcePathStyle: false,\n },\n }),\n secrets: secretsConfigSchema.default({\n provider: \"local_encrypted\",\n strictMode: false,\n localEncrypted: {\n keyFilePath: \"~/.rudder/instances/default/secrets/master.key\",\n },\n }),\n langfuse: langfuseConfigSchema.optional(),\n })\n .superRefine((value, ctx) => {\n if (value.server.deploymentMode === \"local_trusted\") {\n if (value.server.exposure !== \"private\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"server.exposure must be private when deploymentMode is local_trusted\",\n path: [\"server\", \"exposure\"],\n });\n }\n return;\n }\n\n if (value.auth.baseUrlMode === \"explicit\" && !value.auth.publicBaseUrl) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"auth.publicBaseUrl is required when auth.baseUrlMode is explicit\",\n path: [\"auth\", \"publicBaseUrl\"],\n });\n }\n\n if (value.server.exposure === \"public\" && value.auth.baseUrlMode !== \"explicit\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"auth.baseUrlMode must be explicit when deploymentMode=authenticated and exposure=public\",\n path: [\"auth\", \"baseUrlMode\"],\n });\n }\n\n if (value.server.exposure === \"public\" && !value.auth.publicBaseUrl) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"auth.publicBaseUrl is required when deploymentMode=authenticated and exposure=public\",\n path: [\"auth\", \"publicBaseUrl\"],\n });\n }\n });\n\nexport type RudderConfig = z.infer<typeof rudderConfigSchema>;\nexport type LlmConfig = z.infer<typeof llmConfigSchema>;\nexport type DatabaseConfig = z.infer<typeof databaseConfigSchema>;\nexport type LoggingConfig = z.infer<typeof loggingConfigSchema>;\nexport type ServerConfig = z.infer<typeof serverConfigSchema>;\nexport type StorageConfig = z.infer<typeof storageConfigSchema>;\nexport type StorageLocalDiskConfig = z.infer<typeof storageLocalDiskConfigSchema>;\nexport type StorageS3Config = z.infer<typeof storageS3ConfigSchema>;\nexport type SecretsConfig = z.infer<typeof secretsConfigSchema>;\nexport type SecretsLocalEncryptedConfig = z.infer<typeof secretsLocalEncryptedConfigSchema>;\nexport type LangfuseConfig = z.infer<typeof langfuseConfigSchema>;\nexport type AuthConfig = z.infer<typeof authConfigSchema>;\nexport type ConfigMeta = z.infer<typeof configMetaSchema>;\nexport type DatabaseBackupConfig = z.infer<typeof databaseBackupConfigSchema>;\n", "export {\n ORGANIZATION_STATUSES,\n DEPLOYMENT_MODES,\n DEPLOYMENT_EXPOSURES,\n AUTH_BASE_URL_MODES,\n AGENT_STATUSES,\n AGENT_RUN_CONCURRENCY_DEFAULT,\n AGENT_RUN_CONCURRENCY_MIN,\n AGENT_RUN_CONCURRENCY_MAX,\n AGENT_RUNTIME_TYPES,\n AGENT_ROLES,\n AGENT_ROLE_LABELS,\n AGENT_ICON_NAMES,\n ISSUE_STATUSES,\n ISSUE_PRIORITIES,\n ISSUE_ORIGIN_KINDS,\n CALENDAR_SOURCE_TYPES,\n CALENDAR_OWNER_TYPES,\n CALENDAR_VISIBILITIES,\n CALENDAR_SOURCE_STATUSES,\n CALENDAR_EVENT_KINDS,\n CALENDAR_EVENT_STATUSES,\n CALENDAR_SOURCE_MODES,\n CHAT_CONVERSATION_STATUSES,\n CHAT_ISSUE_CREATION_MODES,\n CHAT_MESSAGE_ROLES,\n CHAT_MESSAGE_KINDS,\n CHAT_MESSAGE_STATUSES,\n CHAT_CONTEXT_ENTITY_TYPES,\n MESSENGER_THREAD_KINDS,\n MESSENGER_SYSTEM_THREAD_KINDS,\n GOAL_LEVELS,\n GOAL_STATUSES,\n PROJECT_STATUSES,\n ORGANIZATION_RESOURCE_KINDS,\n PROJECT_RESOURCE_ATTACHMENT_ROLES,\n AUTOMATION_STATUSES,\n AUTOMATION_CONCURRENCY_POLICIES,\n AUTOMATION_CATCH_UP_POLICIES,\n AUTOMATION_TRIGGER_KINDS,\n AUTOMATION_TRIGGER_SIGNING_MODES,\n AUTOMATION_RUN_STATUSES,\n AUTOMATION_RUN_SOURCES,\n PAUSE_REASONS,\n PROJECT_COLORS,\n APPROVAL_TYPES,\n APPROVAL_STATUSES,\n SECRET_PROVIDERS,\n STORAGE_PROVIDERS,\n BILLING_TYPES,\n FINANCE_EVENT_KINDS,\n FINANCE_DIRECTIONS,\n FINANCE_UNITS,\n BUDGET_SCOPE_TYPES,\n BUDGET_METRICS,\n BUDGET_WINDOW_KINDS,\n BUDGET_THRESHOLD_TYPES,\n BUDGET_INCIDENT_STATUSES,\n BUDGET_INCIDENT_RESOLUTION_ACTIONS,\n HEARTBEAT_INVOCATION_SOURCES,\n HEARTBEAT_RUN_STATUSES,\n WAKEUP_TRIGGER_DETAILS,\n WAKEUP_REQUEST_STATUSES,\n LIVE_EVENT_TYPES,\n PRINCIPAL_TYPES,\n MEMBERSHIP_STATUSES,\n INSTANCE_USER_ROLES,\n INVITE_TYPES,\n INVITE_JOIN_TYPES,\n JOIN_REQUEST_TYPES,\n JOIN_REQUEST_STATUSES,\n PERMISSION_KEYS,\n PLUGIN_API_VERSION,\n PLUGIN_STATUSES,\n PLUGIN_CATEGORIES,\n PLUGIN_CAPABILITIES,\n PLUGIN_UI_SLOT_TYPES,\n PLUGIN_UI_SLOT_ENTITY_TYPES,\n PLUGIN_LAUNCHER_PLACEMENT_ZONES,\n PLUGIN_LAUNCHER_ACTIONS,\n PLUGIN_LAUNCHER_BOUNDS,\n PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS,\n PLUGIN_STATE_SCOPE_KINDS,\n PLUGIN_JOB_STATUSES,\n PLUGIN_JOB_RUN_STATUSES,\n PLUGIN_JOB_RUN_TRIGGERS,\n PLUGIN_WEBHOOK_DELIVERY_STATUSES,\n PLUGIN_EVENT_TYPES,\n PLUGIN_BRIDGE_ERROR_CODES,\n type OrganizationStatus,\n type DeploymentMode,\n type DeploymentExposure,\n type AuthBaseUrlMode,\n type AgentStatus,\n type AgentRuntimeType,\n type AgentRole,\n type AgentIconName,\n type IssueStatus,\n type IssuePriority,\n type IssueOriginKind,\n type CalendarSourceType,\n type CalendarOwnerType,\n type CalendarVisibility,\n type CalendarSourceStatus,\n type CalendarEventKind,\n type CalendarEventStatus,\n type CalendarSourceMode,\n type ChatConversationStatus,\n type ChatIssueCreationMode,\n type ChatMessageRole,\n type ChatMessageKind,\n type ChatMessageStatus,\n type ChatContextEntityType,\n type MessengerThreadKind,\n type MessengerSystemThreadKind,\n type GoalLevel,\n type GoalStatus,\n type ProjectStatus,\n type OrganizationResourceKind,\n type ProjectResourceAttachmentRole,\n type AutomationStatus,\n type AutomationConcurrencyPolicy,\n type AutomationCatchUpPolicy,\n type AutomationTriggerKind,\n type AutomationTriggerSigningMode,\n type AutomationRunStatus,\n type AutomationRunSource,\n type PauseReason,\n type ApprovalType,\n type ApprovalStatus,\n type SecretProvider,\n type StorageProvider,\n type BillingType,\n type FinanceEventKind,\n type FinanceDirection,\n type FinanceUnit,\n type BudgetScopeType,\n type BudgetMetric,\n type BudgetWindowKind,\n type BudgetThresholdType,\n type BudgetIncidentStatus,\n type BudgetIncidentResolutionAction,\n type HeartbeatInvocationSource,\n type HeartbeatRunStatus,\n type WakeupTriggerDetail,\n type WakeupRequestStatus,\n type LiveEventType,\n type PrincipalType,\n type MembershipStatus,\n type InstanceUserRole,\n type InviteType,\n type InviteJoinType,\n type JoinRequestType,\n type JoinRequestStatus,\n type PermissionKey,\n type PluginStatus,\n type PluginCategory,\n type PluginCapability,\n type PluginUiSlotType,\n type PluginUiSlotEntityType,\n type PluginLauncherPlacementZone,\n type PluginLauncherAction,\n type PluginLauncherBounds,\n type PluginLauncherRenderEnvironment,\n type PluginStateScopeKind,\n type PluginJobStatus,\n type PluginJobRunStatus,\n type PluginJobRunTrigger,\n type PluginWebhookDeliveryStatus,\n type PluginEventType,\n type PluginBridgeErrorCode,\n} from \"./constants.js\";\n\nexport { EXECUTION_OBSERVABILITY_SURFACES } from \"./types/observability.js\";\nexport {\n WORKSPACE_BACKUP_DEFAULT_INTERVAL_HOURS,\n WORKSPACE_BACKUP_DEFAULT_RETENTION_DAYS,\n} from \"./types/workspace-backup.js\";\n\n\nexport type {\n ExecutionObservabilityContext,\n ExecutionObservabilitySurface,\n ExecutionLangfuseLink,\n Organization,\n OrganizationWorkspace,\n OrganizationWorkspaceRootSource,\n OrganizationWorkspaceFileEntry,\n OrganizationWorkspaceFileList,\n OrganizationWorkspaceFileDetail,\n OrganizationWorkspaceFileUpdateRequest,\n ChatConversation,\n ChatMessage,\n ChatAttachment,\n ChatContextLink,\n ChatLinkedEntity,\n ChatPrimaryIssueSummary,\n ChatAskUserOption,\n ChatAskUserQuestion,\n ChatAskUserRequest,\n ChatRichReference,\n ChatRichReferenceDisplay,\n ChatRuntimeDescriptor,\n ChatOperationProposalDecision,\n ChatOperationProposalDecisionAction,\n ChatOperationProposalDecisionStatus,\n ChatStreamTranscriptEntry,\n ChatStreamTranscriptTodoItem,\n ChatStreamTranscriptTodoItemStatus,\n ChatStreamAckEvent,\n ChatStreamAssistantDeltaEvent,\n ChatStreamAssistantStateEvent,\n ChatStreamTranscriptEntryEvent,\n ChatStreamFinalEvent,\n ChatStreamErrorEvent,\n ChatStreamEvent,\n OrganizationSkillSourceType,\n OrganizationSkillTrustLevel,\n OrganizationSkillCompatibility,\n OrganizationSkillSourceBadge,\n OrganizationSkillFileInventoryEntry,\n OrganizationSkill,\n OrganizationSkillListItem,\n OrganizationSkillUsageAgent,\n OrganizationSkillDetail,\n OrganizationSkillUpdateStatus,\n OrganizationSkillImportRequest,\n OrganizationSkillImportResult,\n OrganizationSkillProjectScanRequest,\n OrganizationSkillProjectScanSkipped,\n OrganizationSkillProjectScanConflict,\n OrganizationSkillProjectScanResult,\n OrganizationSkillLocalScanRequest,\n OrganizationSkillLocalScanSkipped,\n OrganizationSkillLocalScanConflict,\n OrganizationSkillLocalScanResult,\n OrganizationSkillCreateRequest,\n OrganizationSkillFileDetail,\n OrganizationSkillFileUpdateRequest,\n OrganizationSkillWorkspaceEditPath,\n AgentSkillSyncMode,\n AgentSkillState,\n AgentSkillOrigin,\n AgentSkillSourceClass,\n AgentSkillEntry,\n AgentSkillSnapshot,\n AgentSkillSyncRequest,\n AgentSkillTelemetryEvidence,\n AgentSkillTelemetryEvidenceCounts,\n AgentSkillAnalyticsSkillTotal,\n AgentSkillAnalyticsDay,\n AgentSkillAnalytics,\n InstanceLocale,\n InstanceGeneralSettings,\n InstanceNotificationSettings,\n InstanceLangfuseSettings,\n OperatorProfileSettings,\n InstancePathPickerRequest,\n InstancePathPickerResult,\n InstancePathPickerSelectionType,\n InstanceSettings,\n Agent,\n AgentAccessState,\n AgentChainOfCommandEntry,\n AgentDetail,\n AgentPermissions,\n AgentInstructionsBundleMode,\n AgentInstructionsFileSummary,\n AgentInstructionsFileDetail,\n AgentInstructionsBundle,\n AgentKeyCreated,\n AgentConfigRevision,\n AgentRuntimeEnvironmentCheckLevel,\n AgentRuntimeEnvironmentTestStatus,\n AgentRuntimeEnvironmentCheck,\n AgentRuntimeEnvironmentTestResult,\n AssetImage,\n Project,\n ProjectCodebase,\n ProjectCodebaseOrigin,\n ProjectCodebaseScope,\n ProjectGoalRef,\n ProjectWorkspace,\n ProjectWorkspaceSourceType,\n ProjectWorkspaceVisibility,\n OrganizationResource,\n CreateOrganizationResourceRequest,\n UpdateOrganizationResourceRequest,\n ProjectResourceAttachment,\n ProjectResourceAttachmentInput,\n UpdateProjectResourceAttachmentRequest,\n CreateProjectInlineResourceInput,\n ExecutionWorkspace,\n WorkspaceRuntimeService,\n WorkspaceOperation,\n WorkspaceOperationPhase,\n WorkspaceOperationStatus,\n WorkspaceBackupStatus,\n WorkspaceBackupTriggerSource,\n WorkspaceBackupSummary,\n WorkspaceBackupList,\n WorkspaceBackupCreateRequest,\n WorkspaceBackupRestoreRequest,\n WorkspaceBackupRestoreResult,\n WorkspaceBackupFileList,\n WorkspaceBackupFileDetail,\n ExecutionWorkspaceStrategyType,\n ExecutionWorkspaceMode,\n ExecutionWorkspaceProviderType,\n ExecutionWorkspaceStatus,\n ExecutionWorkspaceStrategy,\n ProjectExecutionWorkspacePolicy,\n ProjectExecutionWorkspaceDefaultMode,\n IssueExecutionWorkspaceSettings,\n IssueWorkProduct,\n IssueWorkProductType,\n IssueWorkProductProvider,\n IssueWorkProductStatus,\n IssueWorkProductReviewState,\n Issue,\n IssueAssigneeAgentRuntimeOverrides,\n IssueSearchMatch,\n IssueComment,\n IssueCommitReport,\n IssueDocument,\n IssueDocumentSummary,\n DocumentRevision,\n DocumentFormat,\n LegacyPlanDocument,\n IssueAttachment,\n IssueLabel,\n Goal,\n GoalDependencies,\n GoalDependencyPreview,\n Approval,\n ApprovalComment,\n IssueLinkedApproval,\n MessengerThreadUserState,\n IssueFollow,\n IssueFollowEntry,\n MessengerEvent,\n MessengerThreadAction,\n MessengerThreadSummary,\n MessengerThreadDetail,\n MessengerThreadItem,\n MessengerChatThreadDetail,\n MessengerIssueThreadItem,\n MessengerApprovalThreadItem,\n MessengerBudgetThreadItem,\n MessengerJoinRequestThreadItem,\n MessengerHeartbeatRunThreadItem,\n BudgetPolicy,\n BudgetPolicySummary,\n BudgetIncident,\n BudgetOverview,\n BudgetPolicyUpsertInput,\n BudgetIncidentResolutionInput,\n CostEvent,\n CostSummary,\n CostTrendPoint,\n CostByAgent,\n CostByProviderModel,\n CostByBiller,\n CostByAgentModel,\n CostWindowSpendRow,\n CostByProject,\n FinanceEvent,\n FinanceSummary,\n FinanceByBiller,\n FinanceByKind,\n HeartbeatRecoveryMode,\n HeartbeatRecoveryTrigger,\n HeartbeatRun,\n HeartbeatRunContextSnapshot,\n HeartbeatRunEvent,\n HeartbeatRunRecoveryContext,\n AgentRuntimeState,\n AgentTaskSession,\n AgentWakeupRequest,\n InstanceSchedulerHeartbeatAgent,\n LiveEvent,\n DashboardSummary,\n ActivityEvent,\n SidebarBadges,\n OrganizationMembership,\n PrincipalPermissionGrant,\n Invite,\n JoinRequest,\n InstanceUserRoleGrant,\n OrganizationPortabilityInclude,\n OrganizationPortabilityEnvInput,\n OrganizationPortabilityFileEntry,\n OrganizationPortabilityOrganizationManifestEntry,\n OrganizationPortabilitySidebarOrder,\n OrganizationPortabilityAgentManifestEntry,\n OrganizationPortabilitySkillManifestEntry,\n OrganizationPortabilityProjectManifestEntry,\n OrganizationPortabilityProjectWorkspaceManifestEntry,\n OrganizationPortabilityIssueAutomationTriggerManifestEntry,\n OrganizationPortabilityIssueAutomationManifestEntry,\n OrganizationPortabilityIssueManifestEntry,\n OrganizationPortabilityManifest,\n OrganizationPortabilityExportResult,\n OrganizationPortabilityExportPreviewFile,\n OrganizationPortabilityExportPreviewResult,\n OrganizationExportJobStatus,\n OrganizationExportJobStage,\n OrganizationExportJobProgress,\n OrganizationExportJob,\n OrganizationExportJobCreateResult,\n OrganizationPortabilitySource,\n OrganizationPortabilityImportTarget,\n OrganizationPortabilityAgentSelection,\n OrganizationPortabilityCollisionStrategy,\n OrganizationPortabilityPreviewRequest,\n OrganizationPortabilityPreviewAgentPlan,\n OrganizationPortabilityPreviewProjectPlan,\n OrganizationPortabilityPreviewIssuePlan,\n OrganizationPortabilityPreviewResult,\n OrganizationPortabilityAgentRuntimeOverride,\n OrganizationPortabilityImportRequest,\n OrganizationPortabilityImportResult,\n OrganizationPortabilityExportRequest,\n EnvBinding,\n AgentEnvConfig,\n OrganizationSecret,\n SecretProviderDescriptor,\n Automation,\n AutomationTrigger,\n AutomationRun,\n AutomationTriggerSecretMaterial,\n AutomationDetail,\n AutomationRunSummary,\n AutomationExecutionIssueOrigin,\n AutomationListItem,\n CalendarSource,\n CalendarEvent,\n CalendarEventLinkedAgent,\n CalendarEventLinkedIssue,\n CalendarEventListResponse,\n GoogleCalendarConnectResponse,\n GoogleCalendarSyncResponse,\n GoogleCalendarOAuthConfig,\n JsonSchema,\n PluginJobDeclaration,\n PluginWebhookDeclaration,\n PluginToolDeclaration,\n PluginUiSlotDeclaration,\n PluginLauncherActionDeclaration,\n PluginLauncherRenderDeclaration,\n PluginLauncherRenderContextSnapshot,\n PluginLauncherDeclaration,\n PluginMinimumHostVersion,\n PluginUiDeclaration,\n PaperclipPluginManifestV1,\n PluginRecord,\n PluginStateRecord,\n PluginConfig,\n PluginEntityRecord,\n PluginEntityQuery,\n PluginJobRecord,\n PluginJobRunRecord,\n PluginWebhookDeliveryRecord,\n QuotaWindow,\n ProviderQuotaResult,\n} from \"./types/index.js\";\n\nexport {\n instanceLocaleSchema,\n instanceGeneralSettingsSchema,\n patchInstanceGeneralSettingsSchema,\n type PatchInstanceGeneralSettings,\n instanceNotificationSettingsSchema,\n patchInstanceNotificationSettingsSchema,\n type PatchInstanceNotificationSettings,\n instanceLangfuseSettingsSchema,\n patchInstanceLangfuseSettingsSchema,\n type PatchInstanceLangfuseSettings,\n OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH,\n operatorProfileSettingsSchema,\n patchOperatorProfileSettingsSchema,\n type PatchOperatorProfileSettings,\n instancePathPickerSelectionTypeSchema,\n instancePathPickerRequestSchema,\n instancePathPickerResultSchema,\n} from \"./validators/index.js\";\n\nexport {\n createOrganizationSchema,\n updateOrganizationSchema,\n updateOrganizationBrandingSchema,\n updateOrganizationWorkspaceFileSchema,\n organizationResourceKindSchema,\n projectResourceAttachmentRoleSchema,\n createOrganizationResourceSchema,\n updateOrganizationResourceSchema,\n projectResourceAttachmentInputSchema,\n updateProjectResourceAttachmentSchema,\n createProjectInlineResourceSchema,\n type CreateOrganization,\n type UpdateOrganization,\n type UpdateOrganizationBranding,\n type UpdateOrganizationWorkspaceFile,\n type CreateOrganizationResource,\n type UpdateOrganizationResource,\n type ProjectResourceAttachmentInputPayload,\n type UpdateProjectResourceAttachment,\n type CreateProjectInlineResource,\n chatConversationStatusSchema,\n chatIssueCreationModeSchema,\n chatMessageRoleSchema,\n chatMessageKindSchema,\n chatContextEntityTypeSchema,\n createChatContextLinkSchema,\n createChatConversationSchema,\n setChatProjectContextSchema,\n updateChatConversationSchema,\n addChatMessageSchema,\n chatAskUserOptionSchema,\n chatAskUserQuestionSchema,\n chatAskUserRequestSchema,\n chatAskUserRequestFromStructuredPayload,\n chatRichReferenceSchema,\n chatRichReferencesSchema,\n chatRichReferencesFromStructuredPayload,\n sanitizeChatStructuredPayload,\n createChatAttachmentMetadataSchema,\n convertChatToIssueSchema,\n chatOperationProposalSchema,\n resolveChatOperationProposalSchema,\n updateChatConversationUserStateSchema,\n type CreateChatContextLink,\n type CreateChatConversation,\n type SetChatProjectContext,\n type UpdateChatConversation,\n type AddChatMessage,\n type CreateChatAttachmentMetadata,\n type ConvertChatToIssue,\n type ChatOperationProposal,\n type ResolveChatOperationProposal,\n type UpdateChatConversationUserState,\n agentSkillStateSchema,\n agentSkillSyncModeSchema,\n agentSkillEntrySchema,\n agentSkillSnapshotSchema,\n agentSkillSyncSchema,\n agentSkillEnableSchema,\n type AgentSkillSync,\n type AgentSkillEnable,\n agentIconSchema,\n customAgentIconSchema,\n createAgentSchema,\n createAgentHireSchema,\n updateAgentSchema,\n uploadedAgentIconSchema,\n agentInstructionsBundleModeSchema,\n updateAgentInstructionsBundleSchema,\n upsertAgentInstructionsFileSchema,\n updateAgentInstructionsPathSchema,\n createAgentKeySchema,\n wakeAgentSchema,\n resetAgentSessionSchema,\n testAgentRuntimeEnvironmentSchema,\n agentPermissionsSchema,\n updateAgentPermissionsSchema,\n type CreateAgent,\n type CreateAgentHire,\n type UpdateAgent,\n type UpdateAgentInstructionsBundle,\n type UpsertAgentInstructionsFile,\n type UpdateAgentInstructionsPath,\n type CreateAgentKey,\n type WakeAgent,\n type ResetAgentSession,\n type TestAgentRuntimeEnvironment,\n type UpdateAgentPermissions,\n createProjectSchema,\n updateProjectSchema,\n type CreateProject,\n type UpdateProject,\n projectExecutionWorkspacePolicySchema,\n createIssueSchema,\n createIssueLabelSchema,\n updateIssueLabelSchema,\n updateIssueSchema,\n reorderIssueSchema,\n issueExecutionWorkspaceSettingsSchema,\n checkoutIssueSchema,\n addIssueCommentSchema,\n reportIssueCommitSchema,\n linkIssueApprovalSchema,\n createIssueAttachmentMetadataSchema,\n createIssueWorkspaceAttachmentSchema,\n createIssueWorkProductSchema,\n updateIssueWorkProductSchema,\n issueWorkProductTypeSchema,\n issueWorkProductStatusSchema,\n issueWorkProductReviewStateSchema,\n updateExecutionWorkspaceSchema,\n executionWorkspaceStatusSchema,\n issueDocumentFormatSchema,\n issueDocumentKeySchema,\n upsertIssueDocumentSchema,\n type CreateIssue,\n type CreateIssueLabel,\n type UpdateIssueLabel,\n type UpdateIssue,\n type ReorderIssue,\n type CheckoutIssue,\n type AddIssueComment,\n type ReportIssueCommit,\n type LinkIssueApproval,\n type CreateIssueAttachmentMetadata,\n type CreateIssueWorkspaceAttachment,\n type CreateIssueWorkProduct,\n type UpdateIssueWorkProduct,\n type UpdateExecutionWorkspace,\n type IssueDocumentFormat,\n type UpsertIssueDocument,\n workspaceBackupTriggerSourceSchema,\n createWorkspaceBackupSchema,\n restoreWorkspaceBackupSchema,\n type CreateWorkspaceBackup,\n type RestoreWorkspaceBackup,\n createGoalSchema,\n updateGoalSchema,\n type CreateGoal,\n type UpdateGoal,\n createApprovalSchema,\n upsertBudgetPolicySchema,\n resolveBudgetIncidentSchema,\n resolveApprovalSchema,\n requestApprovalRevisionSchema,\n resubmitApprovalSchema,\n addApprovalCommentSchema,\n type CreateApproval,\n type UpsertBudgetPolicy,\n type ResolveBudgetIncident,\n type ResolveApproval,\n type RequestApprovalRevision,\n type ResubmitApproval,\n type AddApprovalComment,\n envBindingPlainSchema,\n envBindingSecretRefSchema,\n envBindingSchema,\n envConfigSchema,\n createSecretSchema,\n rotateSecretSchema,\n updateSecretSchema,\n createAutomationSchema,\n updateAutomationSchema,\n createAutomationTriggerSchema,\n updateAutomationTriggerSchema,\n runAutomationSchema,\n rotateAutomationTriggerSecretSchema,\n createCalendarSourceSchema,\n updateCalendarSourceSchema,\n createCalendarEventSchema,\n updateCalendarEventSchema,\n calendarEventListQuerySchema,\n googleCalendarSyncSchema,\n updateGoogleCalendarOAuthConfigSchema,\n type CreateSecret,\n type RotateSecret,\n type UpdateSecret,\n type CreateAutomation,\n type UpdateAutomation,\n type CreateAutomationTrigger,\n type UpdateAutomationTrigger,\n type RunAutomation,\n type RotateAutomationTriggerSecret,\n type CreateCalendarSource,\n type UpdateCalendarSource,\n type CreateCalendarEvent,\n type UpdateCalendarEvent,\n type CalendarEventListQuery,\n type GoogleCalendarSync,\n type UpdateGoogleCalendarOAuthConfig,\n createCostEventSchema,\n createFinanceEventSchema,\n updateBudgetSchema,\n createAssetImageMetadataSchema,\n createCompanyInviteSchema,\n createOpenClawInvitePromptSchema,\n acceptInviteSchema,\n listJoinRequestsQuerySchema,\n claimJoinRequestApiKeySchema,\n boardCliAuthAccessLevelSchema,\n createCliAuthChallengeSchema,\n resolveCliAuthChallengeSchema,\n updateMemberPermissionsSchema,\n updateUserCompanyAccessSchema,\n type CreateCostEvent,\n type CreateFinanceEvent,\n type UpdateBudget,\n type CreateAssetImageMetadata,\n type CreateCompanyInvite,\n type CreateOpenClawInvitePrompt,\n type AcceptInvite,\n type ListJoinRequestsQuery,\n type ClaimJoinRequestApiKey,\n type BoardCliAuthAccessLevel,\n type CreateCliAuthChallenge,\n type ResolveCliAuthChallenge,\n type UpdateMemberPermissions,\n type UpdateUserCompanyAccess,\n organizationSkillSourceTypeSchema,\n organizationSkillTrustLevelSchema,\n organizationSkillCompatibilitySchema,\n organizationSkillSourceBadgeSchema,\n organizationSkillFileInventoryEntrySchema,\n organizationSkillSchema,\n organizationSkillListItemSchema,\n organizationSkillUsageAgentSchema,\n organizationSkillDetailSchema,\n organizationSkillUpdateStatusSchema,\n organizationSkillImportSchema,\n organizationSkillProjectScanRequestSchema,\n organizationSkillProjectScanSkippedSchema,\n organizationSkillProjectScanConflictSchema,\n organizationSkillProjectScanResultSchema,\n organizationSkillLocalScanRequestSchema,\n organizationSkillLocalScanSkippedSchema,\n organizationSkillLocalScanConflictSchema,\n organizationSkillLocalScanResultSchema,\n organizationSkillCreateSchema,\n organizationSkillFileDetailSchema,\n organizationSkillFileUpdateSchema,\n portabilityIncludeSchema,\n portabilityEnvInputSchema,\n portabilityOrganizationManifestEntrySchema,\n portabilitySidebarOrderSchema,\n portabilityAgentManifestEntrySchema,\n portabilityManifestSchema,\n portabilitySourceSchema,\n portabilityTargetSchema,\n portabilityAgentSelectionSchema,\n portabilityCollisionStrategySchema,\n organizationPortabilityExportSchema,\n organizationPortabilityPreviewSchema,\n organizationPortabilityImportSchema,\n type OrganizationPortabilityExport,\n type OrganizationPortabilityPreview,\n type OrganizationPortabilityImport,\n jsonSchemaSchema,\n pluginJobDeclarationSchema,\n pluginWebhookDeclarationSchema,\n pluginToolDeclarationSchema,\n pluginUiSlotDeclarationSchema,\n pluginLauncherActionDeclarationSchema,\n pluginLauncherRenderDeclarationSchema,\n pluginLauncherDeclarationSchema,\n pluginManifestV1Schema,\n installPluginSchema,\n upsertPluginConfigSchema,\n patchPluginConfigSchema,\n updatePluginStatusSchema,\n uninstallPluginSchema,\n pluginStateScopeKeySchema,\n setPluginStateSchema,\n listPluginStateSchema,\n type PluginJobDeclarationInput,\n type PluginWebhookDeclarationInput,\n type PluginToolDeclarationInput,\n type PluginUiSlotDeclarationInput,\n type PluginLauncherActionDeclarationInput,\n type PluginLauncherRenderDeclarationInput,\n type PluginLauncherDeclarationInput,\n type PluginManifestV1Input,\n type InstallPlugin,\n type UpsertPluginConfig,\n type PatchPluginConfig,\n type UpdatePluginStatus,\n type UninstallPlugin,\n type PluginStateScopeKey,\n type SetPluginState,\n type ListPluginState,\n} from \"./validators/index.js\";\n\nexport { API_PREFIX, API } from \"./api.js\";\nexport { normalizeAgentUrlKey, deriveAgentUrlKey, isUuidLike } from \"./agent-url-key.js\";\nexport { normalizeOrganizationUrlKey, deriveOrganizationUrlKey } from \"./organization-url-key.js\";\nexport { deriveProjectUrlKey, normalizeProjectUrlKey } from \"./project-url-key.js\";\nexport { formatMessengerPreview, formatMessengerTitle, type MessengerPreviewOptions } from \"./messenger-preview.js\";\nexport {\n summarizeTokenUsage,\n tokenUsageCacheRatio,\n hasTokenUsage,\n cachedInputTokenSemanticsForProvider,\n ADDITIONAL_CACHED_INPUT_TOKEN_PROVIDERS,\n type CachedInputTokenSemantics,\n type TokenUsageParts,\n type TokenUsageSummary,\n} from \"./token-usage.js\";\nexport {\n RUDDER_BUNDLED_SKILL_SLUGS,\n getBundledRudderSkillSlug,\n isCanonicalBundledRudderSkillKey,\n toBundledRudderSkillKey,\n normalizeOrganizationSkillKey,\n formatOrganizationSkillPublicRef,\n buildOrganizationSkillSearchText,\n parseOrganizationSkillReference,\n resolveOrganizationSkillReference,\n type OrganizationSkillPublicRefContext,\n type OrganizationSkillPublicRefScope,\n type ParsedOrganizationSkillReference,\n type ParsedOrganizationSkillReferenceKind,\n type ResolveOrganizationSkillReferenceContext,\n type ResolveOrganizationSkillReferenceResult,\n} from \"./organization-skill-reference.js\";\nexport {\n AGENT_MENTION_SCHEME,\n ISSUE_MENTION_SCHEME,\n PROJECT_MENTION_SCHEME,\n buildAgentMentionHref,\n buildIssueMentionHref,\n buildProjectMentionHref,\n extractAgentMentionIds,\n extractIssueMentionIds,\n parseAgentMentionHref,\n parseIssueMentionHref,\n parseProjectMentionHref,\n extractProjectMentionIds,\n type ParsedAgentMention,\n type ParsedIssueMention,\n type ParsedProjectMention,\n} from \"./project-mentions.js\";\n\nexport {\n rudderConfigSchema,\n configMetaSchema,\n llmConfigSchema,\n databaseBackupConfigSchema,\n databaseConfigSchema,\n loggingConfigSchema,\n serverConfigSchema,\n authConfigSchema,\n langfuseConfigSchema,\n secretsConfigSchema,\n storageConfigSchema,\n storageLocalDiskConfigSchema,\n storageS3ConfigSchema,\n secretsLocalEncryptedConfigSchema,\n type RudderConfig,\n type LlmConfig,\n type DatabaseBackupConfig,\n type DatabaseConfig,\n type LoggingConfig,\n type ServerConfig,\n type AuthConfig,\n type LangfuseConfig,\n type StorageConfig,\n type StorageLocalDiskConfig,\n type StorageS3Config,\n type SecretsConfig,\n type SecretsLocalEncryptedConfig,\n type ConfigMeta,\n} from \"./config-schema.js\";\n", "export {\n rudderConfigSchema,\n configMetaSchema,\n llmConfigSchema,\n databaseBackupConfigSchema,\n databaseConfigSchema,\n loggingConfigSchema,\n serverConfigSchema,\n authConfigSchema,\n storageConfigSchema,\n storageLocalDiskConfigSchema,\n storageS3ConfigSchema,\n secretsConfigSchema,\n secretsLocalEncryptedConfigSchema,\n type RudderConfig,\n type LlmConfig,\n type DatabaseBackupConfig,\n type DatabaseConfig,\n type LoggingConfig,\n type ServerConfig,\n type AuthConfig,\n type StorageConfig,\n type StorageLocalDiskConfig,\n type StorageS3Config,\n type SecretsConfig,\n type SecretsLocalEncryptedConfig,\n type ConfigMeta,\n} from \"@rudderhq/shared\";\n", "import os from \"node:os\";\nimport path from \"node:path\";\n\nconst DEFAULT_INSTANCE_ID = \"default\";\nconst INSTANCE_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nexport function resolveRudderHomeDir(): string {\n const envHome = process.env.RUDDER_HOME?.trim();\n if (envHome) return path.resolve(expandHomePrefix(envHome));\n return path.resolve(os.homedir(), \".rudder\");\n}\n\nexport function resolveRudderInstanceId(override?: string): string {\n const raw = override?.trim() || process.env.RUDDER_INSTANCE_ID?.trim() || DEFAULT_INSTANCE_ID;\n if (!INSTANCE_ID_RE.test(raw)) {\n throw new Error(\n `Invalid instance id '${raw}'. Allowed characters: letters, numbers, '_' and '-'.`,\n );\n }\n return raw;\n}\n\nexport function resolveRudderInstanceRoot(instanceId?: string): string {\n const id = resolveRudderInstanceId(instanceId);\n return path.resolve(resolveRudderHomeDir(), \"instances\", id);\n}\n\nexport function resolveDefaultConfigPath(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"config.json\");\n}\n\nexport function resolveDefaultContextPath(): string {\n return path.resolve(resolveRudderHomeDir(), \"context.json\");\n}\n\nexport function resolveDefaultCliAuthPath(): string {\n return path.resolve(resolveRudderHomeDir(), \"auth.json\");\n}\n\nexport function resolveDefaultEmbeddedPostgresDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"db\");\n}\n\nexport function resolveDefaultLogsDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"logs\");\n}\n\nexport function resolveDefaultSecretsKeyFilePath(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"secrets\", \"master.key\");\n}\n\nexport function resolveDefaultStorageDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"data\", \"storage\");\n}\n\nexport function resolveDefaultBackupDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"data\", \"backups\");\n}\n\nexport function expandHomePrefix(value: string): string {\n if (value === \"~\") return os.homedir();\n if (value.startsWith(\"~/\")) return path.resolve(os.homedir(), value.slice(2));\n return value;\n}\n\nexport function describeLocalInstancePaths(instanceId?: string) {\n const resolvedInstanceId = resolveRudderInstanceId(instanceId);\n const instanceRoot = resolveRudderInstanceRoot(resolvedInstanceId);\n return {\n homeDir: resolveRudderHomeDir(),\n instanceId: resolvedInstanceId,\n instanceRoot,\n configPath: resolveDefaultConfigPath(resolvedInstanceId),\n embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(resolvedInstanceId),\n backupDir: resolveDefaultBackupDir(resolvedInstanceId),\n logDir: resolveDefaultLogsDir(resolvedInstanceId),\n secretsKeyFilePath: resolveDefaultSecretsKeyFilePath(resolvedInstanceId),\n storageDir: resolveDefaultStorageDir(resolvedInstanceId),\n };\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { rudderConfigSchema, type RudderConfig } from \"./schema.js\";\nimport {\n resolveDefaultConfigPath,\n resolveRudderInstanceId,\n} from \"./home.js\";\n\nconst DEFAULT_CONFIG_BASENAME = \"config.json\";\n\nfunction findConfigFileFromAncestors(startDir: string): string | null {\n const absoluteStartDir = path.resolve(startDir);\n let currentDir = absoluteStartDir;\n\n while (true) {\n const candidate = path.resolve(currentDir, \".rudder\", DEFAULT_CONFIG_BASENAME);\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n\n const nextDir = path.resolve(currentDir, \"..\");\n if (nextDir === currentDir) break;\n currentDir = nextDir;\n }\n\n return null;\n}\n\nexport function resolveConfigPath(overridePath?: string): string {\n if (overridePath) return path.resolve(overridePath);\n if (process.env.RUDDER_CONFIG) return path.resolve(process.env.RUDDER_CONFIG);\n return findConfigFileFromAncestors(process.cwd()) ?? resolveDefaultConfigPath(resolveRudderInstanceId());\n}\n\nfunction parseJson(filePath: string): unknown {\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n } catch (err) {\n throw new Error(`Failed to parse JSON at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction migrateLegacyConfig(raw: unknown): unknown {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return raw;\n const config = { ...(raw as Record<string, unknown>) };\n const databaseRaw = config.database;\n if (typeof databaseRaw !== \"object\" || databaseRaw === null || Array.isArray(databaseRaw)) {\n return config;\n }\n\n const database = { ...(databaseRaw as Record<string, unknown>) };\n if (database.mode === \"pglite\") {\n database.mode = \"embedded-postgres\";\n\n if (typeof database.embeddedPostgresDataDir !== \"string\" && typeof database.pgliteDataDir === \"string\") {\n database.embeddedPostgresDataDir = database.pgliteDataDir;\n }\n if (\n typeof database.embeddedPostgresPort !== \"number\" &&\n typeof database.pglitePort === \"number\" &&\n Number.isFinite(database.pglitePort)\n ) {\n database.embeddedPostgresPort = database.pglitePort;\n }\n }\n\n config.database = database;\n return config;\n}\n\nfunction formatValidationError(err: unknown): string {\n const issues = (err as { issues?: Array<{ path?: unknown; message?: unknown }> })?.issues;\n if (Array.isArray(issues) && issues.length > 0) {\n return issues\n .map((issue) => {\n const pathParts = Array.isArray(issue.path) ? issue.path.map(String) : [];\n const issuePath = pathParts.length > 0 ? pathParts.join(\".\") : \"config\";\n const message = typeof issue.message === \"string\" ? issue.message : \"Invalid value\";\n return `${issuePath}: ${message}`;\n })\n .join(\"; \");\n }\n return err instanceof Error ? err.message : String(err);\n}\n\nexport function readConfig(configPath?: string): RudderConfig | null {\n const filePath = resolveConfigPath(configPath);\n if (!fs.existsSync(filePath)) return null;\n const raw = parseJson(filePath);\n const migrated = migrateLegacyConfig(raw);\n const parsed = rudderConfigSchema.safeParse(migrated);\n if (!parsed.success) {\n throw new Error(`Invalid config at ${filePath}: ${formatValidationError(parsed.error)}`);\n }\n return parsed.data;\n}\n\nexport function writeConfig(\n config: RudderConfig,\n configPath?: string,\n): void {\n const filePath = resolveConfigPath(configPath);\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n\n // Backup existing config before overwriting\n if (fs.existsSync(filePath)) {\n const backupPath = filePath + \".backup\";\n fs.copyFileSync(filePath, backupPath);\n fs.chmodSync(backupPath, 0o600);\n }\n\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\nexport function configExists(configPath?: string): boolean {\n return fs.existsSync(resolveConfigPath(configPath));\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { config as loadDotenv, parse as parseEnvFileContents } from \"dotenv\";\nimport { resolveConfigPath } from \"./store.js\";\n\nconst JWT_SECRET_ENV_KEY = \"RUDDER_AGENT_JWT_SECRET\";\nfunction resolveEnvFilePath(configPath?: string) {\n return path.resolve(path.dirname(resolveConfigPath(configPath)), \".env\");\n}\nconst loadedEnvFiles = new Set<string>();\n\nfunction isNonEmpty(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction parseEnvFile(contents: string) {\n try {\n return parseEnvFileContents(contents);\n } catch {\n return {};\n }\n}\n\nfunction formatEnvValue(value: string): string {\n if (/^[A-Za-z0-9_./:@-]+$/.test(value)) {\n return value;\n }\n return JSON.stringify(value);\n}\n\nfunction renderEnvFile(entries: Record<string, string>) {\n const lines = [\n \"# Rudder environment variables\",\n \"# Generated by Rudder CLI commands\",\n ...Object.entries(entries).map(([key, value]) => `${key}=${formatEnvValue(value)}`),\n \"\",\n ];\n return lines.join(\"\\n\");\n}\n\nexport function resolvePaperclipEnvFile(configPath?: string): string {\n return resolveEnvFilePath(configPath);\n}\n\nexport function resolveAgentJwtEnvFile(configPath?: string): string {\n return resolveEnvFilePath(configPath);\n}\n\nexport function loadRudderEnvFile(configPath?: string): void {\n loadAgentJwtEnvFile(resolveEnvFilePath(configPath));\n}\n\nexport function loadAgentJwtEnvFile(filePath = resolveEnvFilePath()): void {\n if (loadedEnvFiles.has(filePath)) return;\n\n if (!fs.existsSync(filePath)) return;\n loadedEnvFiles.add(filePath);\n loadDotenv({ path: filePath, override: false, quiet: true });\n}\n\nexport function readAgentJwtSecretFromEnv(configPath?: string): string | null {\n loadAgentJwtEnvFile(resolveEnvFilePath(configPath));\n const raw = process.env[JWT_SECRET_ENV_KEY];\n return isNonEmpty(raw) ? raw!.trim() : null;\n}\n\nexport function readAgentJwtSecretFromEnvFile(filePath = resolveEnvFilePath()): string | null {\n if (!fs.existsSync(filePath)) return null;\n\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const values = parseEnvFile(raw);\n const value = values[JWT_SECRET_ENV_KEY];\n return isNonEmpty(value) ? value!.trim() : null;\n}\n\nexport function ensureAgentJwtSecret(configPath?: string): { secret: string; created: boolean } {\n const existingEnv = readAgentJwtSecretFromEnv(configPath);\n if (existingEnv) {\n return { secret: existingEnv, created: false };\n }\n\n const envFilePath = resolveEnvFilePath(configPath);\n const existingFile = readAgentJwtSecretFromEnvFile(envFilePath);\n const secret = existingFile ?? randomBytes(32).toString(\"hex\");\n const created = !existingFile;\n\n if (!existingFile) {\n writeAgentJwtEnv(secret, envFilePath);\n }\n\n return { secret, created };\n}\n\nexport function writeAgentJwtEnv(secret: string, filePath = resolveEnvFilePath()): void {\n mergePaperclipEnvEntries({ [JWT_SECRET_ENV_KEY]: secret }, filePath);\n}\n\nexport function readPaperclipEnvEntries(filePath = resolveEnvFilePath()): Record<string, string> {\n if (!fs.existsSync(filePath)) return {};\n return parseEnvFile(fs.readFileSync(filePath, \"utf-8\"));\n}\n\nexport function writePaperclipEnvEntries(entries: Record<string, string>, filePath = resolveEnvFilePath()): void {\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(filePath, renderEnvFile(entries), {\n mode: 0o600,\n });\n}\n\nexport function mergePaperclipEnvEntries(\n entries: Record<string, string>,\n filePath = resolveEnvFilePath(),\n): Record<string, string> {\n const current = readPaperclipEnvEntries(filePath);\n const next = {\n ...current,\n ...Object.fromEntries(\n Object.entries(entries).filter(([, value]) => typeof value === \"string\" && value.trim().length > 0),\n ),\n };\n writePaperclipEnvEntries(next, filePath);\n return next;\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { expandHomePrefix } from \"../config/home.js\";\n\nfunction unique(items: string[]): string[] {\n return Array.from(new Set(items));\n}\n\nexport function resolveRuntimeLikePath(value: string, configPath?: string): string {\n const expanded = expandHomePrefix(value);\n if (path.isAbsolute(expanded)) return path.resolve(expanded);\n\n const cwd = process.cwd();\n const configDir = configPath ? path.dirname(configPath) : null;\n const workspaceRoot = configDir ? path.resolve(configDir, \"..\") : cwd;\n\n const candidates = unique([\n ...(configDir ? [path.resolve(configDir, expanded)] : []),\n path.resolve(workspaceRoot, \"server\", expanded),\n path.resolve(workspaceRoot, expanded),\n path.resolve(cwd, expanded),\n ]);\n\n return candidates.find((candidate) => fs.existsSync(candidate)) ?? candidates[0];\n}\n", "import { randomBytes } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RudderConfig } from \"./schema.js\";\nimport { resolveRuntimeLikePath } from \"../utils/path-resolver.js\";\n\nexport type EnsureSecretsKeyResult =\n | { status: \"created\"; path: string }\n | { status: \"existing\"; path: string }\n | { status: \"skipped_env\"; path: null }\n | { status: \"skipped_provider\"; path: null };\n\nexport function ensureLocalSecretsKeyFile(\n config: Pick<RudderConfig, \"secrets\">,\n configPath?: string,\n): EnsureSecretsKeyResult {\n if (config.secrets.provider !== \"local_encrypted\") {\n return { status: \"skipped_provider\", path: null };\n }\n\n const envMasterKey = process.env.RUDDER_SECRETS_MASTER_KEY;\n if (envMasterKey && envMasterKey.trim().length > 0) {\n return { status: \"skipped_env\", path: null };\n }\n\n const keyFileOverride = process.env.RUDDER_SECRETS_MASTER_KEY_FILE;\n const configuredPath =\n keyFileOverride && keyFileOverride.trim().length > 0\n ? keyFileOverride.trim()\n : config.secrets.localEncrypted.keyFilePath;\n const keyFilePath = resolveRuntimeLikePath(configuredPath, configPath);\n\n if (fs.existsSync(keyFilePath)) {\n return { status: \"existing\", path: keyFilePath };\n }\n\n fs.mkdirSync(path.dirname(keyFilePath), { recursive: true });\n fs.writeFileSync(keyFilePath, randomBytes(32).toString(\"base64\"), {\n encoding: \"utf8\",\n mode: 0o600,\n });\n try {\n fs.chmodSync(keyFilePath, 0o600);\n } catch {\n // best effort\n }\n return { status: \"created\", path: keyFilePath };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { DatabaseConfig } from \"../config/schema.js\";\nimport {\n resolveDefaultBackupDir,\n resolveDefaultEmbeddedPostgresDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\n\nfunction readEmbeddedPortFromEnv(): number {\n return Math.max(1, Number(process.env.RUDDER_EMBEDDED_POSTGRES_PORT) || 54329);\n}\n\nexport async function promptDatabase(current?: DatabaseConfig): Promise<DatabaseConfig> {\n const instanceId = resolveRudderInstanceId();\n const defaultEmbeddedDir = resolveDefaultEmbeddedPostgresDir(instanceId);\n const defaultBackupDir = resolveDefaultBackupDir(instanceId);\n const envEmbeddedPort = readEmbeddedPortFromEnv();\n const base: DatabaseConfig = current ?? {\n mode: \"embedded-postgres\",\n embeddedPostgresDataDir: defaultEmbeddedDir,\n embeddedPostgresPort: envEmbeddedPort,\n backup: {\n enabled: true,\n intervalMinutes: 60,\n retentionDays: 30,\n dir: defaultBackupDir,\n },\n };\n\n const mode = await p.select({\n message: \"Database mode\",\n options: [\n { value: \"embedded-postgres\" as const, label: \"Embedded PostgreSQL (managed locally)\", hint: \"recommended\" },\n { value: \"postgres\" as const, label: \"PostgreSQL (external server)\" },\n ],\n initialValue: base.mode,\n });\n\n if (p.isCancel(mode)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n let connectionString: string | undefined = base.connectionString;\n let embeddedPostgresDataDir = base.embeddedPostgresDataDir || defaultEmbeddedDir;\n let embeddedPostgresPort = base.embeddedPostgresPort || envEmbeddedPort;\n\n if (mode === \"postgres\") {\n const value = await p.text({\n message: \"PostgreSQL connection string\",\n defaultValue: base.connectionString ?? \"\",\n placeholder: \"postgres://user:pass@localhost:5432/rudder\",\n validate: (val) => {\n if (!val) return \"Connection string is required for PostgreSQL mode\";\n if (!val.startsWith(\"postgres\")) return \"Must be a postgres:// or postgresql:// URL\";\n },\n });\n\n if (p.isCancel(value)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n connectionString = value;\n } else {\n const dataDir = await p.text({\n message: \"Embedded PostgreSQL data directory\",\n defaultValue: base.embeddedPostgresDataDir || defaultEmbeddedDir,\n placeholder: defaultEmbeddedDir,\n });\n\n if (p.isCancel(dataDir)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n embeddedPostgresDataDir = dataDir || defaultEmbeddedDir;\n\n const portValue = await p.text({\n message: \"Embedded PostgreSQL port\",\n defaultValue: String(base.embeddedPostgresPort || envEmbeddedPort),\n placeholder: String(envEmbeddedPort),\n validate: (val) => {\n const n = Number(val);\n if (!Number.isInteger(n) || n < 1 || n > 65535) return \"Port must be an integer between 1 and 65535\";\n },\n });\n\n if (p.isCancel(portValue)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n embeddedPostgresPort = Number(portValue || String(envEmbeddedPort));\n connectionString = undefined;\n }\n\n const backupEnabled = await p.confirm({\n message: \"Enable automatic database backups?\",\n initialValue: base.backup.enabled,\n });\n if (p.isCancel(backupEnabled)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const backupDirInput = await p.text({\n message: \"Backup directory\",\n defaultValue: base.backup.dir || defaultBackupDir,\n placeholder: defaultBackupDir,\n validate: (val) => (!val || val.trim().length === 0 ? \"Backup directory is required\" : undefined),\n });\n if (p.isCancel(backupDirInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const backupIntervalInput = await p.text({\n message: \"Backup interval (minutes)\",\n defaultValue: String(base.backup.intervalMinutes || 60),\n placeholder: \"60\",\n validate: (val) => {\n const n = Number(val);\n if (!Number.isInteger(n) || n < 1) return \"Interval must be a positive integer\";\n if (n > 10080) return \"Interval must be 10080 minutes (7 days) or less\";\n return undefined;\n },\n });\n if (p.isCancel(backupIntervalInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const backupRetentionInput = await p.text({\n message: \"Backup retention (days)\",\n defaultValue: String(base.backup.retentionDays || 30),\n placeholder: \"30\",\n validate: (val) => {\n const n = Number(val);\n if (!Number.isInteger(n) || n < 1) return \"Retention must be a positive integer\";\n if (n > 3650) return \"Retention must be 3650 days or less\";\n return undefined;\n },\n });\n if (p.isCancel(backupRetentionInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return {\n mode,\n connectionString,\n embeddedPostgresDataDir,\n embeddedPostgresPort,\n backup: {\n enabled: backupEnabled,\n intervalMinutes: Number(backupIntervalInput || \"60\"),\n retentionDays: Number(backupRetentionInput || \"30\"),\n dir: backupDirInput || defaultBackupDir,\n },\n };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { LlmConfig } from \"../config/schema.js\";\n\nexport async function promptLlm(): Promise<LlmConfig | undefined> {\n const configureLlm = await p.confirm({\n message: \"Configure an LLM provider now?\",\n initialValue: false,\n });\n\n if (p.isCancel(configureLlm)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (!configureLlm) return undefined;\n\n const provider = await p.select({\n message: \"LLM provider\",\n options: [\n { value: \"claude\" as const, label: \"Claude (Anthropic)\" },\n { value: \"openai\" as const, label: \"OpenAI\" },\n ],\n });\n\n if (p.isCancel(provider)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const apiKey = await p.password({\n message: `${provider === \"claude\" ? \"Anthropic\" : \"OpenAI\"} API key`,\n validate: (val) => {\n if (!val) return \"API key is required\";\n },\n });\n\n if (p.isCancel(apiKey)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return { provider, apiKey };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { LoggingConfig } from \"../config/schema.js\";\nimport { resolveDefaultLogsDir, resolveRudderInstanceId } from \"../config/home.js\";\n\nexport async function promptLogging(): Promise<LoggingConfig> {\n const defaultLogDir = resolveDefaultLogsDir(resolveRudderInstanceId());\n const mode = await p.select({\n message: \"Logging mode\",\n options: [\n { value: \"file\" as const, label: \"File-based logging\", hint: \"recommended\" },\n { value: \"cloud\" as const, label: \"Cloud logging\", hint: \"coming soon\" },\n ],\n });\n\n if (p.isCancel(mode)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (mode === \"file\") {\n const logDir = await p.text({\n message: \"Log directory\",\n defaultValue: defaultLogDir,\n placeholder: defaultLogDir,\n });\n\n if (p.isCancel(logDir)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return { mode: \"file\", logDir: logDir || defaultLogDir };\n }\n\n p.note(\"Cloud logging is coming soon. Using file-based logging for now.\");\n return { mode: \"file\", logDir: defaultLogDir };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { SecretProvider } from \"@rudderhq/shared\";\nimport type { SecretsConfig } from \"../config/schema.js\";\nimport { resolveDefaultSecretsKeyFilePath, resolveRudderInstanceId } from \"../config/home.js\";\n\nfunction defaultKeyFilePath(): string {\n return resolveDefaultSecretsKeyFilePath(resolveRudderInstanceId());\n}\n\nexport function defaultSecretsConfig(): SecretsConfig {\n const keyFilePath = defaultKeyFilePath();\n return {\n provider: \"local_encrypted\",\n strictMode: false,\n localEncrypted: {\n keyFilePath,\n },\n };\n}\n\nexport async function promptSecrets(current?: SecretsConfig): Promise<SecretsConfig> {\n const base = current ?? defaultSecretsConfig();\n\n const provider = await p.select({\n message: \"Secrets provider\",\n options: [\n {\n value: \"local_encrypted\" as const,\n label: \"Local encrypted (recommended)\",\n hint: \"best for single-developer installs\",\n },\n {\n value: \"aws_secrets_manager\" as const,\n label: \"AWS Secrets Manager\",\n hint: \"requires external adapter integration\",\n },\n {\n value: \"gcp_secret_manager\" as const,\n label: \"GCP Secret Manager\",\n hint: \"requires external adapter integration\",\n },\n {\n value: \"vault\" as const,\n label: \"HashiCorp Vault\",\n hint: \"requires external adapter integration\",\n },\n ],\n initialValue: base.provider,\n });\n\n if (p.isCancel(provider)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const strictMode = await p.confirm({\n message: \"Require secret refs for sensitive env vars?\",\n initialValue: base.strictMode,\n });\n\n if (p.isCancel(strictMode)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const fallbackDefault = defaultKeyFilePath();\n let keyFilePath = base.localEncrypted.keyFilePath || fallbackDefault;\n if (provider === \"local_encrypted\") {\n const keyPath = await p.text({\n message: \"Local encrypted key file path\",\n defaultValue: keyFilePath,\n placeholder: fallbackDefault,\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Key file path is required\";\n },\n });\n\n if (p.isCancel(keyPath)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n keyFilePath = keyPath.trim();\n }\n\n if (provider !== \"local_encrypted\") {\n p.note(\n `${provider} is not fully wired in this build yet. Keep local_encrypted unless you are actively implementing that adapter.`,\n \"Heads up\",\n );\n }\n\n return {\n provider: provider as SecretProvider,\n strictMode,\n localEncrypted: {\n keyFilePath,\n },\n };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { StorageConfig } from \"../config/schema.js\";\nimport { resolveDefaultStorageDir, resolveRudderInstanceId } from \"../config/home.js\";\n\nfunction defaultStorageBaseDir(): string {\n return resolveDefaultStorageDir(resolveRudderInstanceId());\n}\n\nexport function defaultStorageConfig(): StorageConfig {\n return {\n provider: \"local_disk\",\n localDisk: {\n baseDir: defaultStorageBaseDir(),\n },\n s3: {\n bucket: \"rudder\",\n region: \"us-east-1\",\n endpoint: undefined,\n prefix: \"\",\n forcePathStyle: false,\n },\n };\n}\n\nexport async function promptStorage(current?: StorageConfig): Promise<StorageConfig> {\n const base = current ?? defaultStorageConfig();\n\n const provider = await p.select({\n message: \"Storage provider\",\n options: [\n {\n value: \"local_disk\" as const,\n label: \"Local disk (recommended)\",\n hint: \"best for single-user local deployments\",\n },\n {\n value: \"s3\" as const,\n label: \"S3 compatible\",\n hint: \"for cloud/object storage backends\",\n },\n ],\n initialValue: base.provider,\n });\n\n if (p.isCancel(provider)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (provider === \"local_disk\") {\n const baseDir = await p.text({\n message: \"Local storage base directory\",\n defaultValue: base.localDisk.baseDir || defaultStorageBaseDir(),\n placeholder: defaultStorageBaseDir(),\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Storage base directory is required\";\n },\n });\n\n if (p.isCancel(baseDir)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return {\n provider: \"local_disk\",\n localDisk: {\n baseDir: baseDir.trim(),\n },\n s3: base.s3,\n };\n }\n\n const bucket = await p.text({\n message: \"S3 bucket\",\n defaultValue: base.s3.bucket || \"rudder\",\n placeholder: \"rudder\",\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Bucket is required\";\n },\n });\n\n if (p.isCancel(bucket)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const region = await p.text({\n message: \"S3 region\",\n defaultValue: base.s3.region || \"us-east-1\",\n placeholder: \"us-east-1\",\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Region is required\";\n },\n });\n\n if (p.isCancel(region)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const endpoint = await p.text({\n message: \"S3 endpoint (optional for compatible backends)\",\n defaultValue: base.s3.endpoint ?? \"\",\n placeholder: \"https://s3.amazonaws.com\",\n });\n\n if (p.isCancel(endpoint)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const prefix = await p.text({\n message: \"Object key prefix (optional)\",\n defaultValue: base.s3.prefix ?? \"\",\n placeholder: \"rudder/\",\n });\n\n if (p.isCancel(prefix)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const forcePathStyle = await p.confirm({\n message: \"Use S3 path-style URLs?\",\n initialValue: base.s3.forcePathStyle ?? false,\n });\n\n if (p.isCancel(forcePathStyle)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return {\n provider: \"s3\",\n localDisk: base.localDisk,\n s3: {\n bucket: bucket.trim(),\n region: region.trim(),\n endpoint: endpoint.trim() || undefined,\n prefix: prefix.trim(),\n forcePathStyle,\n },\n };\n}\n\n", "export function normalizeHostnameInput(raw: string): string {\n const input = raw.trim();\n if (!input) {\n throw new Error(\"Hostname is required\");\n }\n\n try {\n const url = input.includes(\"://\") ? new URL(input) : new URL(`http://${input}`);\n const hostname = url.hostname.trim().toLowerCase();\n if (!hostname) throw new Error(\"Hostname is required\");\n return hostname;\n } catch {\n throw new Error(`Invalid hostname: ${raw}`);\n }\n}\n\nexport function parseHostnameCsv(raw: string): string[] {\n if (!raw.trim()) return [];\n const unique = new Set<string>();\n for (const part of raw.split(\",\")) {\n const hostname = normalizeHostnameInput(part);\n unique.add(hostname);\n }\n return Array.from(unique);\n}\n\n", "import * as p from \"@clack/prompts\";\nimport type { AuthConfig, ServerConfig } from \"../config/schema.js\";\nimport { parseHostnameCsv } from \"../config/hostnames.js\";\n\nexport async function promptServer(opts?: {\n currentServer?: Partial<ServerConfig>;\n currentAuth?: Partial<AuthConfig>;\n}): Promise<{ server: ServerConfig; auth: AuthConfig }> {\n const currentServer = opts?.currentServer;\n const currentAuth = opts?.currentAuth;\n\n const deploymentModeSelection = await p.select({\n message: \"Deployment mode\",\n options: [\n {\n value: \"local_trusted\",\n label: \"Local trusted\",\n hint: \"Easiest for local setup (no login, localhost-only)\",\n },\n {\n value: \"authenticated\",\n label: \"Authenticated\",\n hint: \"Login required; use for private network or public hosting\",\n },\n ],\n initialValue: currentServer?.deploymentMode ?? \"local_trusted\",\n });\n\n if (p.isCancel(deploymentModeSelection)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n const deploymentMode = deploymentModeSelection as ServerConfig[\"deploymentMode\"];\n\n let exposure: ServerConfig[\"exposure\"] = \"private\";\n if (deploymentMode === \"authenticated\") {\n const exposureSelection = await p.select({\n message: \"Exposure profile\",\n options: [\n {\n value: \"private\",\n label: \"Private network\",\n hint: \"Private access (for example Tailscale), lower setup friction\",\n },\n {\n value: \"public\",\n label: \"Public internet\",\n hint: \"Internet-facing deployment with stricter requirements\",\n },\n ],\n initialValue: currentServer?.exposure ?? \"private\",\n });\n if (p.isCancel(exposureSelection)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n exposure = exposureSelection as ServerConfig[\"exposure\"];\n }\n\n const hostDefault = deploymentMode === \"local_trusted\" ? \"127.0.0.1\" : \"0.0.0.0\";\n const hostStr = await p.text({\n message: \"Bind host\",\n defaultValue: currentServer?.host ?? hostDefault,\n placeholder: hostDefault,\n validate: (val) => {\n if (!val.trim()) return \"Host is required\";\n },\n });\n\n if (p.isCancel(hostStr)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const portStr = await p.text({\n message: \"Server port\",\n defaultValue: String(currentServer?.port ?? 3100),\n placeholder: \"3100\",\n validate: (val) => {\n const n = Number(val);\n if (isNaN(n) || n < 1 || n > 65535 || !Number.isInteger(n)) {\n return \"Must be an integer between 1 and 65535\";\n }\n },\n });\n\n if (p.isCancel(portStr)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n let allowedHostnames: string[] = [];\n if (deploymentMode === \"authenticated\" && exposure === \"private\") {\n const allowedHostnamesInput = await p.text({\n message: \"Allowed hostnames (comma-separated, optional)\",\n defaultValue: (currentServer?.allowedHostnames ?? []).join(\", \"),\n placeholder: \"dotta-macbook-pro, your-host.tailnet.ts.net\",\n validate: (val) => {\n try {\n parseHostnameCsv(val);\n return;\n } catch (err) {\n return err instanceof Error ? err.message : \"Invalid hostname list\";\n }\n },\n });\n\n if (p.isCancel(allowedHostnamesInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n allowedHostnames = parseHostnameCsv(allowedHostnamesInput);\n }\n\n const port = Number(portStr) || 3100;\n let auth: AuthConfig = { baseUrlMode: \"auto\", disableSignUp: false };\n if (deploymentMode === \"authenticated\" && exposure === \"public\") {\n const urlInput = await p.text({\n message: \"Public base URL\",\n defaultValue: currentAuth?.publicBaseUrl ?? \"\",\n placeholder: \"https://rudder.example.com\",\n validate: (val) => {\n const candidate = val.trim();\n if (!candidate) return \"Public base URL is required for public exposure\";\n try {\n const url = new URL(candidate);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return \"URL must start with http:// or https://\";\n }\n return;\n } catch {\n return \"Enter a valid URL\";\n }\n },\n });\n if (p.isCancel(urlInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n auth = {\n baseUrlMode: \"explicit\",\n disableSignUp: false,\n publicBaseUrl: urlInput.trim().replace(/\\/+$/, \"\"),\n };\n } else if (currentAuth?.baseUrlMode === \"explicit\" && currentAuth.publicBaseUrl) {\n auth = {\n baseUrlMode: \"explicit\",\n disableSignUp: false,\n publicBaseUrl: currentAuth.publicBaseUrl,\n };\n }\n\n return {\n server: {\n deploymentMode,\n exposure,\n host: hostStr.trim(),\n port,\n allowedHostnames,\n serveUi: currentServer?.serveUi ?? true,\n },\n auth,\n };\n}\n", "import { spawnSync } from \"node:child_process\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolveRudderHomeDir } from \"../config/home.js\";\n\nexport const RUNTIME_NPM_PACKAGE_NAME = \"@rudderhq/server\";\nexport const RUNTIME_METADATA_FILE = \"runtime.json\";\n\nexport interface RuntimeInstallMetadata {\n version: 1;\n packageName: string;\n packageVersion: string;\n installedAt: string;\n}\n\nexport interface RuntimeInstallResult {\n status: \"hit\" | \"installed\";\n cacheDir: string;\n packageSpec: string;\n command: string;\n output: string;\n}\n\nexport interface EnsureRuntimeInstalledOptions {\n version: string;\n homeDir?: string;\n packageName?: string;\n spawnSyncImpl?: typeof spawnSync;\n}\n\nexport class RuntimeInstallError extends Error {\n readonly cacheDir: string;\n readonly command: string;\n readonly output: string;\n\n constructor(message: string, options: { cacheDir: string; command: string; output?: string }) {\n super(message);\n this.name = \"RuntimeInstallError\";\n this.cacheDir = options.cacheDir;\n this.command = options.command;\n this.output = options.output ?? \"\";\n }\n}\n\ntype SpawnSyncResultLike = ReturnType<typeof spawnSync>;\n\nfunction sanitizeRuntimeCacheSegment(value: string): string {\n return encodeURIComponent(value.trim() || \"latest\").replaceAll(\"%\", \"_\");\n}\n\nexport function resolveRuntimePackageVersion(version: string): string {\n const normalized = version.trim();\n return normalized.length > 0 ? normalized : \"latest\";\n}\n\nexport function resolveRuntimeCacheDir(\n version: string,\n homeDir: string = resolveRudderHomeDir(),\n): string {\n return path.join(homeDir, \"runtimes\", sanitizeRuntimeCacheSegment(resolveRuntimePackageVersion(version)));\n}\n\nexport function resolveRuntimePackageSpec(\n version: string,\n packageName: string = RUNTIME_NPM_PACKAGE_NAME,\n): string {\n const packageVersion = resolveRuntimePackageVersion(version);\n return packageVersion === \"latest\" ? `${packageName}@latest` : `${packageName}@${packageVersion}`;\n}\n\nexport async function readRuntimeInstallMetadata(\n cacheDir: string,\n): Promise<RuntimeInstallMetadata | null> {\n try {\n const raw = await readFile(path.join(cacheDir, RUNTIME_METADATA_FILE), \"utf8\");\n const parsed = JSON.parse(raw) as RuntimeInstallMetadata;\n if (parsed.version !== 1) return null;\n if (typeof parsed.packageName !== \"string\" || typeof parsed.packageVersion !== \"string\") return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport async function isRuntimeCacheHit(options: {\n cacheDir: string;\n version: string;\n packageName?: string;\n}): Promise<boolean> {\n const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;\n const packageVersion = resolveRuntimePackageVersion(options.version);\n const metadata = await readRuntimeInstallMetadata(options.cacheDir);\n if (!metadata || metadata.packageName !== packageName || metadata.packageVersion !== packageVersion) {\n return false;\n }\n\n try {\n const packageJsonPath = path.join(options.cacheDir, \"node_modules\", ...packageName.split(\"/\"), \"package.json\");\n const packageJson = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as { version?: string };\n return packageVersion === \"latest\" || packageJson.version === packageVersion;\n } catch {\n return false;\n }\n}\n\nexport async function ensureRuntimeInstalled(\n options: EnsureRuntimeInstalledOptions,\n): Promise<RuntimeInstallResult> {\n const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;\n const packageVersion = resolveRuntimePackageVersion(options.version);\n const cacheDir = resolveRuntimeCacheDir(packageVersion, options.homeDir);\n const packageSpec = resolveRuntimePackageSpec(packageVersion, packageName);\n const command = `npm install --prefix ${cacheDir} --omit=dev --no-audit --no-fund ${packageSpec}`;\n\n if (await isRuntimeCacheHit({ cacheDir, version: packageVersion, packageName })) {\n return { status: \"hit\", cacheDir, packageSpec, command, output: \"\" };\n }\n\n await mkdir(cacheDir, { recursive: true });\n await writeFile(path.join(cacheDir, \"package.json\"), `${JSON.stringify({ private: true, type: \"module\" }, null, 2)}\\n`, \"utf8\");\n\n const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;\n const result = runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec);\n const output = collectSpawnOutput(result);\n if (result.status !== 0) {\n throw new RuntimeInstallError(\n `Rudder runtime installation failed. Re-run manually: ${command}`,\n { cacheDir, command, output },\n );\n }\n\n const metadata: RuntimeInstallMetadata = {\n version: 1,\n packageName,\n packageVersion,\n installedAt: new Date().toISOString(),\n };\n await writeFile(path.join(cacheDir, RUNTIME_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\\n`, \"utf8\");\n\n return { status: \"installed\", cacheDir, packageSpec, command, output };\n}\n\nexport function resolveRuntimeServerEntrypoint(cacheDir: string, packageName = RUNTIME_NPM_PACKAGE_NAME): string {\n return createRequire(path.join(cacheDir, \"package.json\")).resolve(packageName);\n}\n\nexport async function importRuntimeServerModule(cacheDir: string, packageName = RUNTIME_NPM_PACKAGE_NAME): Promise<unknown> {\n const entrypoint = resolveRuntimeServerEntrypoint(cacheDir, packageName);\n return await import(pathToFileURL(entrypoint).href);\n}\n\nfunction runNpmRuntimeInstall(\n spawnSyncImpl: typeof spawnSync,\n cacheDir: string,\n packageSpec: string,\n): SpawnSyncResultLike {\n return spawnSyncImpl(\n process.platform === \"win32\" ? \"npm.cmd\" : \"npm\",\n [\"install\", \"--prefix\", cacheDir, \"--omit=dev\", \"--no-audit\", \"--no-fund\", packageSpec],\n {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n ...(process.platform === \"win32\" ? { shell: true, windowsHide: true } : {}),\n },\n );\n}\n\nfunction collectSpawnOutput(result: SpawnSyncResultLike): string {\n return [result.stdout, result.stderr, result.error instanceof Error ? result.error.message : null]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport {\n ensureRuntimeInstalled,\n importRuntimeServerModule,\n type EnsureRuntimeInstalledOptions,\n} from \"./install.js\";\n\nexport interface StartedServer {\n apiUrl: string;\n databaseUrl: string | null;\n host: string;\n listenPort: number;\n runtime: {\n mode: \"owned\" | \"attached\";\n instanceId: string;\n localEnv: string | null;\n ownerKind: string | null;\n version: string;\n };\n stop(): Promise<void>;\n dispose(): Promise<void>;\n}\n\nexport interface LoadServerRuntimeOptions {\n version: string;\n homeDir?: string;\n onRuntimeInstalled?: (result: Awaited<ReturnType<typeof ensureRuntimeInstalled>>) => void;\n}\n\nfunction formatError(err: unknown): string {\n if (err instanceof Error) {\n if (err.message && err.message.trim().length > 0) return err.message;\n return err.name;\n }\n if (typeof err === \"string\") return err;\n try {\n return JSON.stringify(err);\n } catch {\n return String(err);\n }\n}\n\nfunction maybeEnableUiDevMiddleware(entrypoint: string): void {\n if (process.env.RUDDER_UI_DEV_MIDDLEWARE !== undefined) return;\n const normalized = entrypoint.replaceAll(\"\\\\\", \"/\");\n if (normalized.endsWith(\"/server/src/index.ts\") || normalized.endsWith(\"@rudderhq/server/src/index.ts\")) {\n process.env.RUDDER_UI_DEV_MIDDLEWARE = \"true\";\n }\n}\n\nfunction resolveDevServerEntry(): string {\n const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"../../..\");\n return path.resolve(projectRoot, \"server/src/index.ts\");\n}\n\nexport async function loadServerRuntimeModule(options: LoadServerRuntimeOptions): Promise<unknown> {\n const devEntry = resolveDevServerEntry();\n if (fs.existsSync(devEntry)) {\n maybeEnableUiDevMiddleware(devEntry);\n return await import(pathToFileURL(devEntry).href);\n }\n\n const installOptions: EnsureRuntimeInstalledOptions = {\n version: options.version,\n homeDir: options.homeDir,\n };\n const runtime = await ensureRuntimeInstalled(installOptions);\n options.onRuntimeInstalled?.(runtime);\n return await importRuntimeServerModule(runtime.cacheDir);\n}\n\nexport async function startManagedServerFromRuntime(\n options: LoadServerRuntimeOptions,\n): Promise<StartedServer> {\n try {\n const mod = await loadServerRuntimeModule(options);\n return await startServerFromModule(mod);\n } catch (err) {\n throw new Error(`Rudder server failed to start.\\n${formatError(err)}`);\n }\n}\n\nasync function startServerFromModule(mod: unknown): Promise<StartedServer> {\n const startManagedLocalServer = (mod as {\n startManagedLocalServer?: (options: {\n ownerKind: \"cli\";\n takeoverOnVersionMismatch?: boolean;\n }) => Promise<StartedServer>;\n }).startManagedLocalServer;\n if (typeof startManagedLocalServer !== \"function\") {\n throw new Error(\"Rudder server runtime did not export startManagedLocalServer().\");\n }\n return await startManagedLocalServer({\n ownerKind: \"cli\",\n takeoverOnVersionMismatch: true,\n });\n}\n", "import { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\ntype PackageJson = {\n name?: string;\n version?: string;\n};\n\nconst CLI_PACKAGE_NAME = \"@rudderhq/cli\";\nconst CLI_VERSION_MANIFEST = \"rudder-cli-package.json\";\n\nfunction readPackageVersion(packagePath: string, expectedName: string): string | null {\n if (!existsSync(packagePath)) return null;\n\n try {\n const parsed = JSON.parse(readFileSync(packagePath, \"utf8\")) as PackageJson;\n if (parsed.name === expectedName && parsed.version) return parsed.version;\n } catch {\n return null;\n }\n\n return null;\n}\n\nexport function resolveCliVersion(moduleUrl = import.meta.url, env: NodeJS.ProcessEnv = process.env): string {\n if (env.npm_package_name === CLI_PACKAGE_NAME && env.npm_package_version) {\n return env.npm_package_version;\n }\n\n const moduleDir = path.dirname(fileURLToPath(moduleUrl));\n const candidates = [\n path.resolve(moduleDir, CLI_VERSION_MANIFEST),\n path.resolve(moduleDir, \"package.json\"),\n path.resolve(moduleDir, \"../package.json\"),\n path.resolve(moduleDir, \"../../package.json\"),\n ];\n\n for (const candidate of candidates) {\n const version = readPackageVersion(candidate, CLI_PACKAGE_NAME);\n if (version) return version;\n }\n\n return \"0.0.0\";\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { loadRudderEnvFile } from \"../config/env.js\";\nimport { readConfig, resolveConfigPath } from \"../config/store.js\";\nimport { loadServerRuntimeModule } from \"../runtime/server-entry.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\ntype BootstrapCeoInviteRuntimeModule = {\n createBootstrapCeoInvite?: (options: {\n dbUrl: string;\n force?: boolean;\n expiresHours?: number;\n }) => Promise<{\n token: string;\n expiresAt: Date | string;\n } | null>;\n};\n\nfunction resolveDbUrl(configPath?: string, explicitDbUrl?: string) {\n if (explicitDbUrl) return explicitDbUrl;\n const config = readConfig(configPath);\n if (process.env.DATABASE_URL) return process.env.DATABASE_URL;\n if (config?.database.mode === \"postgres\" && config.database.connectionString) {\n return config.database.connectionString;\n }\n if (config?.database.mode === \"embedded-postgres\") {\n const port = config.database.embeddedPostgresPort ?? 54329;\n return `postgres://rudder:rudder@127.0.0.1:${port}/rudder`;\n }\n return null;\n}\n\nfunction resolveBaseUrl(configPath?: string, explicitBaseUrl?: string) {\n if (explicitBaseUrl) return explicitBaseUrl.replace(/\\/+$/, \"\");\n const fromEnv =\n process.env.RUDDER_PUBLIC_URL ??\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL ??\n process.env.BETTER_AUTH_URL ??\n process.env.BETTER_AUTH_BASE_URL;\n if (fromEnv?.trim()) return fromEnv.trim().replace(/\\/+$/, \"\");\n const config = readConfig(configPath);\n if (config?.auth.baseUrlMode === \"explicit\" && config.auth.publicBaseUrl) {\n return config.auth.publicBaseUrl.replace(/\\/+$/, \"\");\n }\n const host = config?.server.host ?? \"localhost\";\n const port = config?.server.port ?? 3100;\n const publicHost = host === \"0.0.0.0\" ? \"localhost\" : host;\n return `http://${publicHost}:${port}`;\n}\n\nexport async function bootstrapCeoInvite(opts: {\n config?: string;\n force?: boolean;\n expiresHours?: number;\n baseUrl?: string;\n dbUrl?: string;\n}) {\n const configPath = resolveConfigPath(opts.config);\n loadRudderEnvFile(configPath);\n const config = readConfig(configPath);\n if (!config) {\n p.log.error(`No config found at ${configPath}. Run ${pc.cyan(\"rudder onboard\")} first.`);\n return;\n }\n\n if (config.server.deploymentMode !== \"authenticated\") {\n p.log.info(\"Deployment mode is local_trusted. Bootstrap CEO invite is only required for authenticated mode.\");\n return;\n }\n\n const dbUrl = resolveDbUrl(configPath, opts.dbUrl);\n if (!dbUrl) {\n p.log.error(\n \"Could not resolve database connection for bootstrap.\",\n );\n return;\n }\n\n try {\n const runtimeModule = await loadBootstrapRuntimeModule();\n const createBootstrapCeoInvite = runtimeModule.createBootstrapCeoInvite;\n if (typeof createBootstrapCeoInvite !== \"function\") {\n throw new Error(\"Rudder server runtime did not export createBootstrapCeoInvite().\");\n }\n\n const created = await createBootstrapCeoInvite({\n dbUrl,\n force: opts.force,\n expiresHours: opts.expiresHours,\n });\n\n if (!created) {\n p.log.info(\"Instance already has an admin user. Use --force to generate a new bootstrap invite.\");\n return;\n }\n\n const baseUrl = resolveBaseUrl(configPath, opts.baseUrl);\n const inviteUrl = `${baseUrl}/invite/${created.token}`;\n const expiresAt = created.expiresAt instanceof Date\n ? created.expiresAt\n : new Date(created.expiresAt);\n p.log.success(\"Created bootstrap CEO invite.\");\n p.log.message(`Invite URL: ${pc.cyan(inviteUrl)}`);\n p.log.message(`Expires: ${pc.dim(expiresAt.toISOString())}`);\n } catch (err) {\n p.log.error(`Could not create bootstrap invite: ${err instanceof Error ? err.message : String(err)}`);\n p.log.info(\"If using embedded-postgres, start the Rudder server and run this command again.\");\n }\n}\n\nasync function loadBootstrapRuntimeModule(): Promise<BootstrapCeoInviteRuntimeModule> {\n const version = resolveCliVersion(import.meta.url);\n return await loadServerRuntimeModule({ version: version === \"0.0.0\" ? \"latest\" : version }) as BootstrapCeoInviteRuntimeModule;\n}\n", "import { execFileSync, spawnSync } from \"node:child_process\";\n\nexport const CLI_NPM_PACKAGE_NAME = \"@rudderhq/cli\";\nexport const CLI_BIN_NAME = \"rudder\";\n\ninterface PersistentCliStateOptions {\n entryPath?: string | null | undefined;\n env?: NodeJS.ProcessEnv;\n execFileSyncImpl?: typeof execFileSync;\n}\n\ninterface InstallPersistentCliOptions {\n installSpec: string;\n spawnSyncImpl?: typeof spawnSync;\n}\n\nexport interface PersistentCliState {\n usingNpx: boolean;\n alreadyInstalled: boolean;\n installSpec: string;\n installCommand: string;\n}\n\nexport interface PersistentCliInstallResult {\n ok: boolean;\n command: string;\n output: string;\n}\n\ntype SpawnSyncResultLike = ReturnType<typeof spawnSync>;\n\nfunction normalizePath(value: string | null | undefined): string {\n return (value ?? \"\").replaceAll(\"\\\\\", \"/\").toLowerCase();\n}\n\nexport function isLikelyNpxExecutionContext(\n entryPath: string | null | undefined = process.argv[1],\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n const normalizedEntry = normalizePath(entryPath);\n if (normalizedEntry.includes(\"/_npx/\")) return true;\n\n const npmCommand = env.npm_command?.trim().toLowerCase();\n if (npmCommand === \"exec\" || npmCommand === \"npx\") return true;\n\n return false;\n}\n\nexport function resolvePersistentCliInstallSpec(env: NodeJS.ProcessEnv = process.env): string {\n const pkgName = env.npm_package_name?.trim();\n const pkgVersion = env.npm_package_version?.trim();\n\n if (pkgName === CLI_NPM_PACKAGE_NAME && pkgVersion) {\n return `${pkgName}@${pkgVersion}`;\n }\n\n return CLI_NPM_PACKAGE_NAME;\n}\n\nfunction resolveCommandLookupExecutable(): { command: string; args: string[] } {\n if (process.platform === \"win32\") {\n return { command: \"where\", args: [CLI_BIN_NAME] };\n }\n return { command: \"which\", args: [CLI_BIN_NAME] };\n}\n\nexport function isTransientBinaryPath(candidatePath: string | null | undefined): boolean {\n const normalized = normalizePath(candidatePath);\n return normalized.includes(\"/_npx/\");\n}\n\nexport function hasGlobalInstalledPackage(\n packageName: string,\n execFileSyncImpl: typeof execFileSync = execFileSync,\n): boolean {\n return getGlobalInstalledPackageVersion(packageName, execFileSyncImpl) !== null;\n}\n\nexport function getGlobalInstalledPackageVersion(\n packageName: string,\n execFileSyncImpl: typeof execFileSync = execFileSync,\n): string | null {\n try {\n const output = execFileSyncImpl(\n process.platform === \"win32\" ? \"npm.cmd\" : \"npm\",\n [\"list\", \"--global\", \"--depth=0\", \"--json\", packageName],\n {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n },\n );\n const parsed = JSON.parse(output) as {\n dependencies?: Record<string, { version?: string }>;\n };\n return parsed.dependencies?.[packageName]?.version ?? null;\n } catch {\n return null;\n }\n}\n\nexport function hasPersistentBinaryOnPath(\n execFileSyncImpl: typeof execFileSync = execFileSync,\n): boolean {\n const { command, args } = resolveCommandLookupExecutable();\n\n try {\n const output = execFileSyncImpl(command, args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n const candidate = output\n .split(/\\r?\\n/)\n .map((value) => value.trim())\n .find((value) => value.length > 0);\n return Boolean(candidate) && !isTransientBinaryPath(candidate);\n } catch {\n return false;\n }\n}\n\nexport function detectPersistentCliState(options: PersistentCliStateOptions = {}): PersistentCliState {\n const env = options.env ?? process.env;\n const execFileSyncImpl = options.execFileSyncImpl ?? execFileSync;\n const installSpec = resolvePersistentCliInstallSpec(env);\n const usingNpx = isLikelyNpxExecutionContext(options.entryPath ?? process.argv[1], env);\n\n if (!usingNpx) {\n return {\n usingNpx,\n alreadyInstalled: true,\n installSpec,\n installCommand: `npm install --global ${installSpec}`,\n };\n }\n\n const alreadyInstalled =\n hasGlobalInstalledPackage(CLI_NPM_PACKAGE_NAME, execFileSyncImpl) ||\n hasPersistentBinaryOnPath(execFileSyncImpl);\n\n return {\n usingNpx,\n alreadyInstalled,\n installSpec,\n installCommand: `npm install --global ${installSpec}`,\n };\n}\n\nexport function installPersistentCli(\n options: InstallPersistentCliOptions,\n): PersistentCliInstallResult {\n const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;\n const command = `npm install --global ${options.installSpec}`;\n const initialResult = runNpmGlobalInstall(spawnSyncImpl, [\"install\", \"--global\", options.installSpec]);\n const initialOutput = collectSpawnOutput(initialResult);\n\n if (initialResult.status === 0 || !isRudderBinConflict(initialOutput)) {\n return {\n ok: initialResult.status === 0,\n command,\n output: initialOutput,\n };\n }\n\n const forcedCommand = `npm install --global --force ${options.installSpec}`;\n const forcedResult = runNpmGlobalInstall(spawnSyncImpl, [\"install\", \"--global\", \"--force\", options.installSpec]);\n const forcedOutput = collectSpawnOutput(forcedResult);\n\n return {\n ok: forcedResult.status === 0,\n command: forcedCommand,\n output: forcedOutput || initialOutput,\n };\n}\n\nfunction runNpmGlobalInstall(\n spawnSyncImpl: typeof spawnSync,\n args: string[],\n): SpawnSyncResultLike {\n return spawnSyncImpl(process.platform === \"win32\" ? \"npm.cmd\" : \"npm\", args, {\n encoding: \"utf8\",\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n ...(process.platform === \"win32\" ? { shell: true, windowsHide: true } : {}),\n });\n}\n\nfunction collectSpawnOutput(result: SpawnSyncResultLike): string {\n return [result.stdout, result.stderr, result.error instanceof Error ? result.error.message : null]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n}\n\nfunction isRudderBinConflict(output: string): boolean {\n const normalized = output.toLowerCase().replaceAll(\"\\\\\", \"/\");\n return (\n normalized.includes(\"eexist\") &&\n (normalized.includes(`/${CLI_BIN_NAME}`) ||\n normalized.includes(`/${CLI_BIN_NAME}.cmd`) ||\n normalized.includes(`/${CLI_BIN_NAME}.ps1`))\n );\n}\n", "import { loadServerRuntimeModule } from \"./server-entry.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\ntype DatabaseRuntimeModule = {\n checkDatabaseConnection?: (dbUrl: string) => Promise<void>;\n};\n\nexport async function checkPostgresConnection(connectionString: string): Promise<void> {\n const version = resolveCliVersion(import.meta.url);\n const runtimeModule = await loadServerRuntimeModule({\n version: version === \"0.0.0\" ? \"latest\" : version,\n }) as DatabaseRuntimeModule;\n if (typeof runtimeModule.checkDatabaseConnection !== \"function\") {\n throw new Error(\"Rudder server runtime did not export checkDatabaseConnection().\");\n }\n await runtimeModule.checkDatabaseConnection(connectionString);\n}\n", "import pc from \"picocolors\";\n\nconst RUDDER_ART = [\n \"\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \",\n \"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\",\n \"\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\",\n \"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\",\n \"\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\",\n \"\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\",\n] as const;\n\nconst TAGLINE = \"Orchestration and control platform for agent work\";\nconst DESCRIPTION = [\n \"Operating layer for agent teams\",\n \"Goals, tasks, knowledge, and workflows in an executable structure\",\n] as const;\n\nexport function printRudderCliBanner(): void {\n const lines = [\n \"\",\n ...RUDDER_ART.map((line) => pc.cyan(line)),\n pc.blue(\" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\"),\n pc.bold(pc.white(` ${TAGLINE}`)),\n ...DESCRIPTION.map((line) => pc.white(` ${line}`)),\n \"\",\n ];\n\n console.log(lines.join(\"\\n\"));\n}\n", "import {\n ensureAgentJwtSecret,\n readAgentJwtSecretFromEnv,\n readAgentJwtSecretFromEnvFile,\n resolveAgentJwtEnvFile,\n} from \"../config/env.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport function agentJwtSecretCheck(configPath?: string): CheckResult {\n if (readAgentJwtSecretFromEnv(configPath)) {\n return {\n name: \"Agent JWT secret\",\n status: \"pass\",\n message: \"RUDDER_AGENT_JWT_SECRET is set in environment\",\n };\n }\n\n const envPath = resolveAgentJwtEnvFile(configPath);\n const fileSecret = readAgentJwtSecretFromEnvFile(envPath);\n\n if (fileSecret) {\n return {\n name: \"Agent JWT secret\",\n status: \"warn\",\n message: `RUDDER_AGENT_JWT_SECRET is present in ${envPath} but not loaded into environment`,\n repairHint: `Set the value from ${envPath} in your shell before starting the Rudder server`,\n };\n }\n\n return {\n name: \"Agent JWT secret\",\n status: \"fail\",\n message: `RUDDER_AGENT_JWT_SECRET missing from environment and ${envPath}`,\n canRepair: true,\n repair: () => {\n ensureAgentJwtSecret(configPath);\n },\n repairHint: `Run with --repair to create ${envPath} containing RUDDER_AGENT_JWT_SECRET`,\n };\n}\n", "import { readConfig, configExists, resolveConfigPath } from \"../config/store.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport function configCheck(configPath?: string): CheckResult {\n const filePath = resolveConfigPath(configPath);\n\n if (!configExists(configPath)) {\n return {\n name: \"Config file\",\n status: \"fail\",\n message: `Config file not found at ${filePath}`,\n canRepair: false,\n repairHint: \"Run `rudder onboard` to create one\",\n };\n }\n\n try {\n readConfig(configPath);\n return {\n name: \"Config file\",\n status: \"pass\",\n message: `Valid config at ${filePath}`,\n };\n } catch (err) {\n return {\n name: \"Config file\",\n status: \"fail\",\n message: `Invalid config: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section database` (or `rudder onboard` to recreate)\",\n };\n }\n}\n", "import type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\n\nfunction isLoopbackHost(host: string) {\n const normalized = host.trim().toLowerCase();\n return normalized === \"127.0.0.1\" || normalized === \"localhost\" || normalized === \"::1\";\n}\n\nexport function deploymentAuthCheck(config: RudderConfig): CheckResult {\n const mode = config.server.deploymentMode;\n const exposure = config.server.exposure;\n const auth = config.auth;\n\n if (mode === \"local_trusted\") {\n if (!isLoopbackHost(config.server.host)) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: `local_trusted requires loopback host binding (found ${config.server.host})`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and set host to 127.0.0.1\",\n };\n }\n return {\n name: \"Deployment/auth mode\",\n status: \"pass\",\n message: \"local_trusted mode is configured for loopback-only access\",\n };\n }\n\n const secret =\n process.env.BETTER_AUTH_SECRET?.trim() ??\n process.env.RUDDER_AGENT_JWT_SECRET?.trim();\n if (!secret) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"authenticated mode requires BETTER_AUTH_SECRET (or RUDDER_AGENT_JWT_SECRET)\",\n canRepair: false,\n repairHint: \"Set BETTER_AUTH_SECRET before starting Rudder\",\n };\n }\n\n if (auth.baseUrlMode === \"explicit\" && !auth.publicBaseUrl) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"auth.baseUrlMode=explicit requires auth.publicBaseUrl\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and provide a base URL\",\n };\n }\n\n if (exposure === \"public\") {\n if (auth.baseUrlMode !== \"explicit\" || !auth.publicBaseUrl) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"authenticated/public requires explicit auth.publicBaseUrl\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and select public exposure\",\n };\n }\n try {\n const url = new URL(auth.publicBaseUrl);\n if (url.protocol !== \"https:\") {\n return {\n name: \"Deployment/auth mode\",\n status: \"warn\",\n message: \"Public exposure should use an https:// auth.publicBaseUrl\",\n canRepair: false,\n repairHint: \"Use HTTPS in production for secure session cookies\",\n };\n }\n } catch {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"auth.publicBaseUrl is not a valid URL\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and provide a valid URL\",\n };\n }\n }\n\n return {\n name: \"Deployment/auth mode\",\n status: \"pass\",\n message: `Mode ${mode}/${exposure} with auth URL mode ${auth.baseUrlMode}`,\n };\n}\n", "export { resolveRuntimeLikePath } from \"../utils/path-resolver.js\";\n", "import fs from \"node:fs\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\nimport { checkPostgresConnection } from \"../runtime/database.js\";\n\nexport async function databaseCheck(config: RudderConfig, configPath?: string): Promise<CheckResult> {\n if (config.database.mode === \"postgres\") {\n if (!config.database.connectionString) {\n return {\n name: \"Database\",\n status: \"fail\",\n message: \"PostgreSQL mode selected but no connection string configured\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section database`\",\n };\n }\n\n try {\n await checkPostgresConnection(config.database.connectionString);\n return {\n name: \"Database\",\n status: \"pass\",\n message: \"PostgreSQL connection successful\",\n };\n } catch (err) {\n return {\n name: \"Database\",\n status: \"fail\",\n message: `Cannot connect to PostgreSQL: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Check your connection string and ensure PostgreSQL is running\",\n };\n }\n }\n\n if (config.database.mode === \"embedded-postgres\") {\n const dataDir = resolveRuntimeLikePath(config.database.embeddedPostgresDataDir, configPath);\n const reportedPath = dataDir;\n if (!fs.existsSync(dataDir)) {\n fs.mkdirSync(reportedPath, { recursive: true });\n }\n\n return {\n name: \"Database\",\n status: \"pass\",\n message: `Embedded PostgreSQL configured at ${dataDir} (port ${config.database.embeddedPostgresPort})`,\n };\n }\n\n return {\n name: \"Database\",\n status: \"fail\",\n message: `Unknown database mode: ${String(config.database.mode)}`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section database`\",\n };\n}\n", "import type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport async function llmCheck(config: RudderConfig): Promise<CheckResult> {\n if (!config.llm) {\n return {\n name: \"LLM provider\",\n status: \"pass\",\n message: \"No LLM provider configured (optional)\",\n };\n }\n\n if (!config.llm.apiKey) {\n return {\n name: \"LLM provider\",\n status: \"pass\",\n message: `${config.llm.provider} configured but no API key set (optional)`,\n };\n }\n\n try {\n if (config.llm.provider === \"claude\") {\n const res = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"x-api-key\": config.llm.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n model: \"claude-sonnet-4-5-20250929\",\n max_tokens: 1,\n messages: [{ role: \"user\", content: \"hi\" }],\n }),\n });\n if (res.ok || res.status === 400) {\n return { name: \"LLM provider\", status: \"pass\", message: \"Claude API key is valid\" };\n }\n if (res.status === 401) {\n return {\n name: \"LLM provider\",\n status: \"fail\",\n message: \"Claude API key is invalid (401)\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section llm`\",\n };\n }\n return {\n name: \"LLM provider\",\n status: \"warn\",\n message: `Claude API returned status ${res.status}`,\n };\n } else {\n const res = await fetch(\"https://api.openai.com/v1/models\", {\n headers: { Authorization: `Bearer ${config.llm.apiKey}` },\n });\n if (res.ok) {\n return { name: \"LLM provider\", status: \"pass\", message: \"OpenAI API key is valid\" };\n }\n if (res.status === 401) {\n return {\n name: \"LLM provider\",\n status: \"fail\",\n message: \"OpenAI API key is invalid (401)\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section llm`\",\n };\n }\n return {\n name: \"LLM provider\",\n status: \"warn\",\n message: `OpenAI API returned status ${res.status}`,\n };\n }\n } catch {\n return {\n name: \"LLM provider\",\n status: \"warn\",\n message: \"Could not reach API to validate key\",\n };\n }\n}\n", "import fs from \"node:fs\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\n\nexport function logCheck(config: RudderConfig, configPath?: string): CheckResult {\n const logDir = resolveRuntimeLikePath(config.logging.logDir, configPath);\n const reportedDir = logDir;\n\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(reportedDir, { recursive: true });\n }\n\n try {\n fs.accessSync(reportedDir, fs.constants.W_OK);\n return {\n name: \"Log directory\",\n status: \"pass\",\n message: `Log directory is writable: ${reportedDir}`,\n };\n } catch {\n return {\n name: \"Log directory\",\n status: \"fail\",\n message: `Log directory is not writable: ${logDir}`,\n canRepair: false,\n repairHint: \"Check file permissions on the log directory\",\n };\n }\n}\n", "import net from \"node:net\";\n\nexport function checkPort(port: number): Promise<{ available: boolean; error?: string }> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n resolve({ available: false, error: `Port ${port} is already in use` });\n } else {\n resolve({ available: false, error: err.message });\n }\n });\n server.once(\"listening\", () => {\n server.close(() => resolve({ available: true }));\n });\n server.listen(port, \"127.0.0.1\");\n });\n}\n", "import type { RudderConfig } from \"../config/schema.js\";\nimport { checkPort } from \"../utils/net.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport async function portCheck(config: RudderConfig): Promise<CheckResult> {\n const port = config.server.port;\n const result = await checkPort(port);\n\n if (result.available) {\n return {\n name: \"Server port\",\n status: \"pass\",\n message: `Port ${port} is available`,\n };\n }\n\n return {\n name: \"Server port\",\n status: \"warn\",\n message: result.error ?? `Port ${port} is not available`,\n canRepair: false,\n repairHint: `Check what's using port ${port} with: lsof -i :${port}`,\n };\n}\n", "import { randomBytes } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\n\nfunction decodeMasterKey(raw: string): Buffer | null {\n const trimmed = raw.trim();\n if (!trimmed) return null;\n\n if (/^[A-Fa-f0-9]{64}$/.test(trimmed)) {\n return Buffer.from(trimmed, \"hex\");\n }\n\n try {\n const decoded = Buffer.from(trimmed, \"base64\");\n if (decoded.length === 32) return decoded;\n } catch {\n // ignored\n }\n\n if (Buffer.byteLength(trimmed, \"utf8\") === 32) {\n return Buffer.from(trimmed, \"utf8\");\n }\n return null;\n}\n\nfunction withStrictModeNote(\n base: Pick<CheckResult, \"name\" | \"status\" | \"message\" | \"canRepair\" | \"repair\" | \"repairHint\">,\n config: RudderConfig,\n): CheckResult {\n const strictModeDisabledInDeployedSetup =\n config.database.mode === \"postgres\" && config.secrets.strictMode === false;\n if (!strictModeDisabledInDeployedSetup) return base;\n\n if (base.status === \"fail\") return base;\n return {\n ...base,\n status: \"warn\",\n message: `${base.message}; strict secret mode is disabled for postgres deployment`,\n repairHint: base.repairHint\n ? `${base.repairHint}. Consider enabling secrets.strictMode`\n : \"Consider enabling secrets.strictMode\",\n };\n}\n\nexport function secretsCheck(config: RudderConfig, configPath?: string): CheckResult {\n const provider = config.secrets.provider;\n if (provider !== \"local_encrypted\") {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message: `${provider} is configured, but this build only supports local_encrypted`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section secrets` and set provider to local_encrypted\",\n };\n }\n\n const envMasterKey = process.env.RUDDER_SECRETS_MASTER_KEY;\n if (envMasterKey && envMasterKey.trim().length > 0) {\n if (!decodeMasterKey(envMasterKey)) {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message:\n \"RUDDER_SECRETS_MASTER_KEY is invalid (expected 32-byte base64, 64-char hex, or raw 32-char string)\",\n canRepair: false,\n repairHint: \"Set RUDDER_SECRETS_MASTER_KEY to a valid key or unset it to use a key file\",\n };\n }\n\n return withStrictModeNote(\n {\n name: \"Secrets adapter\",\n status: \"pass\",\n message: \"Local encrypted provider configured via RUDDER_SECRETS_MASTER_KEY\",\n },\n config,\n );\n }\n\n const keyFileOverride = process.env.RUDDER_SECRETS_MASTER_KEY_FILE;\n const configuredPath =\n keyFileOverride && keyFileOverride.trim().length > 0\n ? keyFileOverride.trim()\n : config.secrets.localEncrypted.keyFilePath;\n const keyFilePath = resolveRuntimeLikePath(configuredPath, configPath);\n\n if (!fs.existsSync(keyFilePath)) {\n return withStrictModeNote(\n {\n name: \"Secrets adapter\",\n status: \"warn\",\n message: `Secrets key file does not exist yet: ${keyFilePath}`,\n canRepair: true,\n repair: () => {\n fs.mkdirSync(path.dirname(keyFilePath), { recursive: true });\n fs.writeFileSync(keyFilePath, randomBytes(32).toString(\"base64\"), {\n encoding: \"utf8\",\n mode: 0o600,\n });\n try {\n fs.chmodSync(keyFilePath, 0o600);\n } catch {\n // best effort\n }\n },\n repairHint: \"Run with --repair to create a local encrypted secrets key file\",\n },\n config,\n );\n }\n\n let raw: string;\n try {\n raw = fs.readFileSync(keyFilePath, \"utf8\");\n } catch (err) {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message: `Could not read secrets key file: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Check file permissions or set RUDDER_SECRETS_MASTER_KEY\",\n };\n }\n\n if (!decodeMasterKey(raw)) {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message: `Invalid key material in ${keyFilePath}`,\n canRepair: false,\n repairHint: \"Replace with valid key material or delete it and run doctor --repair\",\n };\n }\n\n return withStrictModeNote(\n {\n name: \"Secrets adapter\",\n status: \"pass\",\n message: `Local encrypted provider configured with key file ${keyFilePath}`,\n },\n config,\n );\n}\n", "import fs from \"node:fs\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\n\nexport function storageCheck(config: RudderConfig, configPath?: string): CheckResult {\n if (config.storage.provider === \"local_disk\") {\n const baseDir = resolveRuntimeLikePath(config.storage.localDisk.baseDir, configPath);\n if (!fs.existsSync(baseDir)) {\n fs.mkdirSync(baseDir, { recursive: true });\n }\n\n try {\n fs.accessSync(baseDir, fs.constants.W_OK);\n return {\n name: \"Storage\",\n status: \"pass\",\n message: `Local disk storage is writable: ${baseDir}`,\n };\n } catch {\n return {\n name: \"Storage\",\n status: \"fail\",\n message: `Local storage directory is not writable: ${baseDir}`,\n canRepair: false,\n repairHint: \"Check file permissions for storage.localDisk.baseDir\",\n };\n }\n }\n\n const bucket = config.storage.s3.bucket.trim();\n const region = config.storage.s3.region.trim();\n if (!bucket || !region) {\n return {\n name: \"Storage\",\n status: \"fail\",\n message: \"S3 storage requires non-empty bucket and region\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section storage`\",\n };\n }\n\n return {\n name: \"Storage\",\n status: \"warn\",\n message: `S3 storage configured (bucket=${bucket}, region=${region}). Reachability check is skipped in doctor.`,\n canRepair: false,\n repairHint: \"Verify credentials and endpoint in deployment environment\",\n };\n}\n\n", "export interface CheckResult {\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n message: string;\n canRepair?: boolean;\n repair?: () => void | Promise<void>;\n repairHint?: string;\n}\n\nexport { agentJwtSecretCheck } from \"./agent-jwt-secret-check.js\";\nexport { configCheck } from \"./config-check.js\";\nexport { deploymentAuthCheck } from \"./deployment-auth-check.js\";\nexport { databaseCheck } from \"./database-check.js\";\nexport { llmCheck } from \"./llm-check.js\";\nexport { logCheck } from \"./log-check.js\";\nexport { portCheck } from \"./port-check.js\";\nexport { secretsCheck } from \"./secrets-check.js\";\nexport { storageCheck } from \"./storage-check.js\";\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { readConfig, resolveConfigPath } from \"../config/store.js\";\nimport {\n agentJwtSecretCheck,\n configCheck,\n databaseCheck,\n deploymentAuthCheck,\n llmCheck,\n logCheck,\n portCheck,\n secretsCheck,\n storageCheck,\n type CheckResult,\n} from \"../checks/index.js\";\nimport { loadRudderEnvFile } from \"../config/env.js\";\nimport { printRudderCliBanner } from \"../utils/banner.js\";\n\nconst STATUS_ICON = {\n pass: pc.green(\"\u2713\"),\n warn: pc.yellow(\"!\"),\n fail: pc.red(\"\u2717\"),\n} as const;\n\nexport async function doctor(opts: {\n config?: string;\n repair?: boolean;\n yes?: boolean;\n}): Promise<{ passed: number; warned: number; failed: number }> {\n printRudderCliBanner();\n p.intro(pc.bgCyan(pc.black(\" rudder doctor \")));\n\n const configPath = resolveConfigPath(opts.config);\n loadRudderEnvFile(configPath);\n const results: CheckResult[] = [];\n\n // 1. Config check (must pass before others)\n const cfgResult = configCheck(opts.config);\n results.push(cfgResult);\n printResult(cfgResult);\n\n if (cfgResult.status === \"fail\") {\n return printSummary(results);\n }\n\n let config: RudderConfig;\n try {\n config = readConfig(opts.config)!;\n } catch (err) {\n const readResult: CheckResult = {\n name: \"Config file\",\n status: \"fail\",\n message: `Could not read config: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section database` or `rudder onboard`\",\n };\n results.push(readResult);\n printResult(readResult);\n return printSummary(results);\n }\n\n // 2. Deployment/auth mode check\n const deploymentAuthResult = deploymentAuthCheck(config);\n results.push(deploymentAuthResult);\n printResult(deploymentAuthResult);\n\n // 3. Agent JWT check\n results.push(\n await runRepairableCheck({\n run: () => agentJwtSecretCheck(opts.config),\n configPath,\n opts,\n }),\n );\n\n // 4. Secrets adapter check\n results.push(\n await runRepairableCheck({\n run: () => secretsCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 5. Storage check\n results.push(\n await runRepairableCheck({\n run: () => storageCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 6. Database check\n results.push(\n await runRepairableCheck({\n run: () => databaseCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 7. LLM check\n const llmResult = await llmCheck(config);\n results.push(llmResult);\n printResult(llmResult);\n\n // 8. Log directory check\n results.push(\n await runRepairableCheck({\n run: () => logCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 9. Port check\n const portResult = await portCheck(config);\n results.push(portResult);\n printResult(portResult);\n\n // Summary\n return printSummary(results);\n}\n\nfunction printResult(result: CheckResult): void {\n const icon = STATUS_ICON[result.status];\n p.log.message(`${icon} ${pc.bold(result.name)}: ${result.message}`);\n if (result.status !== \"pass\" && result.repairHint) {\n p.log.message(` ${pc.dim(result.repairHint)}`);\n }\n}\n\nasync function maybeRepair(\n result: CheckResult,\n opts: { repair?: boolean; yes?: boolean },\n): Promise<boolean> {\n if (result.status === \"pass\" || !result.canRepair || !result.repair) return false;\n if (!opts.repair) return false;\n\n let shouldRepair = opts.yes;\n if (!shouldRepair) {\n const answer = await p.confirm({\n message: `Repair \"${result.name}\"?`,\n initialValue: true,\n });\n if (p.isCancel(answer)) return false;\n shouldRepair = answer;\n }\n\n if (shouldRepair) {\n try {\n await result.repair();\n p.log.success(`Repaired: ${result.name}`);\n return true;\n } catch (err) {\n p.log.error(`Repair failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n return false;\n}\n\nasync function runRepairableCheck(input: {\n run: () => CheckResult | Promise<CheckResult>;\n configPath: string;\n opts: { repair?: boolean; yes?: boolean };\n}): Promise<CheckResult> {\n let result = await input.run();\n printResult(result);\n\n const repaired = await maybeRepair(result, input.opts);\n if (!repaired) return result;\n\n // Repairs may create/update the adjacent .env file or other local resources.\n loadRudderEnvFile(input.configPath);\n result = await input.run();\n printResult(result);\n return result;\n}\n\nfunction printSummary(results: CheckResult[]): { passed: number; warned: number; failed: number } {\n const passed = results.filter((r) => r.status === \"pass\").length;\n const warned = results.filter((r) => r.status === \"warn\").length;\n const failed = results.filter((r) => r.status === \"fail\").length;\n\n const parts: string[] = [];\n parts.push(pc.green(`${passed} passed`));\n if (warned) parts.push(pc.yellow(`${warned} warnings`));\n if (failed) parts.push(pc.red(`${failed} failed`));\n\n p.note(parts.join(\", \"), \"Summary\");\n\n if (failed > 0) {\n p.outro(pc.red(\"Some checks failed. Fix the issues above and re-run doctor.\"));\n } else if (warned > 0) {\n p.outro(pc.yellow(\"All critical checks passed with some warnings.\"));\n } else {\n p.outro(pc.green(\"All checks passed!\"));\n }\n\n return { passed, warned, failed };\n}\n", "export const LOCAL_ENV_NAMES = [\"dev\", \"prod_local\", \"e2e\"] as const;\n\nexport type LocalEnvName = (typeof LOCAL_ENV_NAMES)[number];\n\nexport type LocalEnvProfile = {\n name: LocalEnvName;\n instanceId: string;\n port: number;\n embeddedPostgresPort: number;\n resettable: boolean;\n description: string;\n};\n\nconst LOCAL_ENV_PROFILES: Record<LocalEnvName, LocalEnvProfile> = {\n dev: {\n name: \"dev\",\n instanceId: \"dev\",\n port: 3100,\n embeddedPostgresPort: 54329,\n resettable: true,\n description: \"Disposable local development instance\",\n },\n prod_local: {\n name: \"prod_local\",\n instanceId: \"default\",\n port: 3200,\n embeddedPostgresPort: 54339,\n resettable: false,\n description: \"Persistent local instance\",\n },\n e2e: {\n name: \"e2e\",\n instanceId: \"e2e\",\n port: 3300,\n embeddedPostgresPort: 54349,\n resettable: true,\n description: \"Isolated end-to-end test instance\",\n },\n};\n\nexport function parseLocalEnvName(value: string | null | undefined): LocalEnvName | null {\n if (!value) return null;\n const normalized = value.trim().toLowerCase().replace(/-/g, \"_\");\n return (LOCAL_ENV_NAMES as readonly string[]).includes(normalized)\n ? (normalized as LocalEnvName)\n : null;\n}\n\nexport function resolveLocalEnvProfile(value: string | null | undefined): LocalEnvProfile | null {\n const name = parseLocalEnvName(value);\n return name ? LOCAL_ENV_PROFILES[name] : null;\n}\n\nexport function resolveActiveLocalEnvProfile(): LocalEnvProfile | null {\n return resolveLocalEnvProfile(process.env.RUDDER_LOCAL_ENV);\n}\n\nexport function applyLocalEnvProfile(input: {\n localEnv?: string | null;\n instance?: string | null;\n}): LocalEnvProfile | null {\n const profile = resolveLocalEnvProfile(input.localEnv ?? process.env.RUDDER_LOCAL_ENV);\n if (!profile) return null;\n\n process.env.RUDDER_LOCAL_ENV = profile.name;\n if (!input.instance?.trim()) {\n process.env.RUDDER_INSTANCE_ID = profile.instanceId;\n }\n if (!process.env.PORT?.trim()) {\n process.env.PORT = String(profile.port);\n }\n if (!process.env.RUDDER_EMBEDDED_POSTGRES_PORT?.trim()) {\n process.env.RUDDER_EMBEDDED_POSTGRES_PORT = String(profile.embeddedPostgresPort);\n }\n return profile;\n}\n\nexport function getDisposableLocalEnvProfiles(): LocalEnvProfile[] {\n return Object.values(LOCAL_ENV_PROFILES).filter((profile) => profile.resettable);\n}\n", "import fs from \"node:fs\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { bootstrapCeoInvite } from \"./auth-bootstrap-ceo.js\";\nimport { onboard } from \"./onboard.js\";\nimport { doctor } from \"./doctor.js\";\nimport { loadRudderEnvFile } from \"../config/env.js\";\nimport { configExists, resolveConfigPath } from \"../config/store.js\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { readConfig } from \"../config/store.js\";\nimport { applyLocalEnvProfile, resolveActiveLocalEnvProfile } from \"../config/local-env.js\";\nimport {\n describeLocalInstancePaths,\n resolveRudderHomeDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\nimport { startManagedServerFromRuntime, type StartedServer } from \"../runtime/server-entry.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\ninterface RunOptions {\n config?: string;\n instance?: string;\n repair?: boolean;\n yes?: boolean;\n}\n\nexport async function runCommand(opts: RunOptions): Promise<void> {\n let localEnvProfile = resolveActiveLocalEnvProfile();\n if (!localEnvProfile && !opts.instance?.trim() && !process.env.RUDDER_INSTANCE_ID?.trim()) {\n localEnvProfile = applyLocalEnvProfile({ localEnv: \"prod_local\" });\n }\n const instanceId = resolveRudderInstanceId(opts.instance);\n process.env.RUDDER_INSTANCE_ID = instanceId;\n\n const homeDir = resolveRudderHomeDir();\n fs.mkdirSync(homeDir, { recursive: true });\n\n const paths = describeLocalInstancePaths(instanceId);\n fs.mkdirSync(paths.instanceRoot, { recursive: true });\n\n const configPath = resolveConfigPath(opts.config);\n process.env.RUDDER_CONFIG = configPath;\n loadRudderEnvFile(configPath);\n\n p.intro(pc.bgCyan(pc.black(\" rudder run \")));\n if (localEnvProfile) {\n p.log.message(pc.dim(`Local env: ${localEnvProfile.name} (${localEnvProfile.description})`));\n }\n p.log.message(pc.dim(`Home: ${paths.homeDir}`));\n p.log.message(pc.dim(`Instance: ${paths.instanceId}`));\n p.log.message(pc.dim(`Config: ${configPath}`));\n\n if (!configExists(configPath)) {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n p.log.error(\"No config found and terminal is non-interactive.\");\n p.log.message(`Run ${pc.cyan(\"rudder onboard\")} once, then retry ${pc.cyan(\"rudder run\")}.`);\n process.exit(1);\n }\n\n p.log.step(\"No config found. Starting onboarding...\");\n await onboard({ config: configPath, invokedByRun: true });\n }\n\n p.log.step(\"Running doctor checks...\");\n const summary = await doctor({\n config: configPath,\n repair: opts.repair ?? true,\n yes: opts.yes ?? true,\n });\n\n if (summary.failed > 0) {\n p.log.error(\"Doctor found blocking issues. Not starting server.\");\n process.exit(1);\n }\n\n const config = readConfig(configPath);\n if (!config) {\n p.log.error(`No config found at ${configPath}.`);\n process.exit(1);\n }\n\n p.log.step(\"Starting Rudder server...\");\n const startedServer = await startManagedServerFromRuntime({ version: resolveRunRuntimeVersion() });\n if (startedServer.runtime.mode === \"attached\") {\n p.log.message(\n pc.dim(\n `Attached to existing ${startedServer.runtime.localEnv ?? startedServer.runtime.instanceId} runtime ` +\n `(${startedServer.runtime.ownerKind ?? \"unknown-owner\"}, v${startedServer.runtime.version}) at ${startedServer.apiUrl.replace(/\\/api$/, \"\")}`,\n ),\n );\n return;\n }\n\n if (startedServer.databaseUrl && shouldGenerateBootstrapInviteAfterStart(config)) {\n p.log.step(\"Generating bootstrap CEO invite\");\n await bootstrapCeoInvite({\n config: configPath,\n dbUrl: startedServer.databaseUrl,\n baseUrl: resolveBootstrapInviteBaseUrl(config, startedServer),\n });\n }\n\n // Keep running until the server is stopped\n await new Promise<void>((resolve) => {\n const checkInterval = setInterval(() => {\n // Server will be stopped via SIGTERM/SIGINT which triggers dispose()\n // We keep this promise pending until explicitly resolved via signal handler\n }, 1000);\n\n const cleanup = () => {\n clearInterval(checkInterval);\n resolve();\n };\n\n process.once(\"SIGINT\", cleanup);\n process.once(\"SIGTERM\", cleanup);\n });\n\n p.log.step(\"Shutting down...\");\n await startedServer.dispose();\n}\n\nfunction resolveBootstrapInviteBaseUrl(\n config: RudderConfig,\n startedServer: StartedServer,\n): string {\n const explicitBaseUrl =\n process.env.RUDDER_PUBLIC_URL ??\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL ??\n process.env.BETTER_AUTH_URL ??\n process.env.BETTER_AUTH_BASE_URL ??\n (config.auth.baseUrlMode === \"explicit\" ? config.auth.publicBaseUrl : undefined);\n\n if (typeof explicitBaseUrl === \"string\" && explicitBaseUrl.trim().length > 0) {\n return explicitBaseUrl.trim().replace(/\\/+$/, \"\");\n }\n\n return startedServer.apiUrl.replace(/\\/api$/, \"\");\n}\n\nfunction shouldGenerateBootstrapInviteAfterStart(config: RudderConfig): boolean {\n return config.server.deploymentMode === \"authenticated\" && config.database.mode === \"embedded-postgres\";\n}\n\nfunction resolveRunRuntimeVersion(): string {\n const version = resolveCliVersion(import.meta.url);\n return version === \"0.0.0\" ? \"latest\" : version;\n}\n", "import * as p from \"@clack/prompts\";\nimport path from \"node:path\";\nimport pc from \"picocolors\";\nimport {\n AUTH_BASE_URL_MODES,\n DEPLOYMENT_EXPOSURES,\n DEPLOYMENT_MODES,\n SECRET_PROVIDERS,\n STORAGE_PROVIDERS,\n type AuthBaseUrlMode,\n type DeploymentExposure,\n type DeploymentMode,\n type SecretProvider,\n type StorageProvider,\n} from \"@rudderhq/shared\";\nimport { configExists, readConfig, resolveConfigPath, writeConfig } from \"../config/store.js\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { ensureAgentJwtSecret, resolveAgentJwtEnvFile } from \"../config/env.js\";\nimport { ensureLocalSecretsKeyFile } from \"../config/secrets-key.js\";\nimport { promptDatabase } from \"../prompts/database.js\";\nimport { promptLlm } from \"../prompts/llm.js\";\nimport { promptLogging } from \"../prompts/logging.js\";\nimport { defaultSecretsConfig } from \"../prompts/secrets.js\";\nimport { defaultStorageConfig, promptStorage } from \"../prompts/storage.js\";\nimport { promptServer } from \"../prompts/server.js\";\nimport {\n describeLocalInstancePaths,\n expandHomePrefix,\n resolveDefaultBackupDir,\n resolveDefaultEmbeddedPostgresDir,\n resolveDefaultLogsDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\nimport { bootstrapCeoInvite } from \"./auth-bootstrap-ceo.js\";\nimport { detectPersistentCliState, installPersistentCli } from \"../install.js\";\nimport { checkPostgresConnection } from \"../runtime/database.js\";\nimport { printRudderCliBanner } from \"../utils/banner.js\";\n\ntype SetupMode = \"quickstart\" | \"advanced\";\n\ntype OnboardOptions = {\n config?: string;\n run?: boolean;\n yes?: boolean;\n invokedByRun?: boolean;\n};\n\ntype OnboardDefaults = Pick<RudderConfig, \"database\" | \"logging\" | \"server\" | \"auth\" | \"storage\" | \"secrets\">;\n\nconst ONBOARD_ENV_KEYS = [\n \"RUDDER_PUBLIC_URL\",\n \"DATABASE_URL\",\n \"RUDDER_DB_BACKUP_ENABLED\",\n \"RUDDER_DB_BACKUP_INTERVAL_MINUTES\",\n \"RUDDER_DB_BACKUP_RETENTION_DAYS\",\n \"RUDDER_DB_BACKUP_DIR\",\n \"RUDDER_DEPLOYMENT_MODE\",\n \"RUDDER_DEPLOYMENT_EXPOSURE\",\n \"HOST\",\n \"PORT\",\n \"RUDDER_EMBEDDED_POSTGRES_PORT\",\n \"SERVE_UI\",\n \"RUDDER_ALLOWED_HOSTNAMES\",\n \"RUDDER_AUTH_BASE_URL_MODE\",\n \"RUDDER_AUTH_PUBLIC_BASE_URL\",\n \"BETTER_AUTH_URL\",\n \"BETTER_AUTH_BASE_URL\",\n \"RUDDER_STORAGE_PROVIDER\",\n \"RUDDER_STORAGE_LOCAL_DIR\",\n \"RUDDER_STORAGE_S3_BUCKET\",\n \"RUDDER_STORAGE_S3_REGION\",\n \"RUDDER_STORAGE_S3_ENDPOINT\",\n \"RUDDER_STORAGE_S3_PREFIX\",\n \"RUDDER_STORAGE_S3_FORCE_PATH_STYLE\",\n \"RUDDER_SECRETS_PROVIDER\",\n \"RUDDER_SECRETS_STRICT_MODE\",\n \"RUDDER_SECRETS_MASTER_KEY_FILE\",\n] as const;\n\nfunction parseBooleanFromEnv(rawValue: string | undefined): boolean | null {\n if (rawValue === undefined) return null;\n const lower = rawValue.trim().toLowerCase();\n if (lower === \"true\" || lower === \"1\" || lower === \"yes\") return true;\n if (lower === \"false\" || lower === \"0\" || lower === \"no\") return false;\n return null;\n}\n\nfunction parseNumberFromEnv(rawValue: string | undefined): number | null {\n if (!rawValue) return null;\n const parsed = Number(rawValue);\n if (!Number.isFinite(parsed)) return null;\n return parsed;\n}\n\nfunction parseEnumFromEnv<T extends string>(rawValue: string | undefined, allowedValues: readonly T[]): T | null {\n if (!rawValue) return null;\n return allowedValues.includes(rawValue as T) ? (rawValue as T) : null;\n}\n\nfunction resolvePathFromEnv(rawValue: string | undefined): string | null {\n if (!rawValue || rawValue.trim().length === 0) return null;\n return path.resolve(expandHomePrefix(rawValue.trim()));\n}\n\nfunction quickstartDefaultsFromEnv(): {\n defaults: OnboardDefaults;\n usedEnvKeys: string[];\n ignoredEnvKeys: Array<{ key: string; reason: string }>;\n} {\n const instanceId = resolveRudderInstanceId();\n const defaultStorage = defaultStorageConfig();\n const defaultSecrets = defaultSecretsConfig();\n const databaseUrl = process.env.DATABASE_URL?.trim() || undefined;\n const publicUrl =\n process.env.RUDDER_PUBLIC_URL?.trim() ||\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL?.trim() ||\n process.env.BETTER_AUTH_URL?.trim() ||\n process.env.BETTER_AUTH_BASE_URL?.trim() ||\n undefined;\n const deploymentMode =\n parseEnumFromEnv<DeploymentMode>(process.env.RUDDER_DEPLOYMENT_MODE, DEPLOYMENT_MODES) ?? \"local_trusted\";\n const deploymentExposureFromEnv = parseEnumFromEnv<DeploymentExposure>(\n process.env.RUDDER_DEPLOYMENT_EXPOSURE,\n DEPLOYMENT_EXPOSURES,\n );\n const deploymentExposure =\n deploymentMode === \"local_trusted\" ? \"private\" : (deploymentExposureFromEnv ?? \"private\");\n const authPublicBaseUrl = publicUrl;\n const authBaseUrlModeFromEnv = parseEnumFromEnv<AuthBaseUrlMode>(\n process.env.RUDDER_AUTH_BASE_URL_MODE,\n AUTH_BASE_URL_MODES,\n );\n const authBaseUrlMode = authBaseUrlModeFromEnv ?? (authPublicBaseUrl ? \"explicit\" : \"auto\");\n const allowedHostnamesFromEnv = process.env.RUDDER_ALLOWED_HOSTNAMES\n ? process.env.RUDDER_ALLOWED_HOSTNAMES\n .split(\",\")\n .map((value) => value.trim().toLowerCase())\n .filter((value) => value.length > 0)\n : [];\n const hostnameFromPublicUrl = publicUrl\n ? (() => {\n try {\n return new URL(publicUrl).hostname.trim().toLowerCase();\n } catch {\n return null;\n }\n })()\n : null;\n const storageProvider =\n parseEnumFromEnv<StorageProvider>(process.env.RUDDER_STORAGE_PROVIDER, STORAGE_PROVIDERS) ??\n defaultStorage.provider;\n const secretsProvider =\n parseEnumFromEnv<SecretProvider>(process.env.RUDDER_SECRETS_PROVIDER, SECRET_PROVIDERS) ??\n defaultSecrets.provider;\n const databaseBackupEnabled = parseBooleanFromEnv(process.env.RUDDER_DB_BACKUP_ENABLED) ?? true;\n const databaseBackupIntervalMinutes = Math.max(\n 1,\n parseNumberFromEnv(process.env.RUDDER_DB_BACKUP_INTERVAL_MINUTES) ?? 60,\n );\n const databaseBackupRetentionDays = Math.max(\n 1,\n parseNumberFromEnv(process.env.RUDDER_DB_BACKUP_RETENTION_DAYS) ?? 30,\n );\n const defaults: OnboardDefaults = {\n database: {\n mode: databaseUrl ? \"postgres\" : \"embedded-postgres\",\n ...(databaseUrl ? { connectionString: databaseUrl } : {}),\n embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(instanceId),\n embeddedPostgresPort: Math.max(\n 1,\n parseNumberFromEnv(process.env.RUDDER_EMBEDDED_POSTGRES_PORT) ?? 54329,\n ),\n backup: {\n enabled: databaseBackupEnabled,\n intervalMinutes: databaseBackupIntervalMinutes,\n retentionDays: databaseBackupRetentionDays,\n dir: resolvePathFromEnv(process.env.RUDDER_DB_BACKUP_DIR) ?? resolveDefaultBackupDir(instanceId),\n },\n },\n logging: {\n mode: \"file\",\n logDir: resolveDefaultLogsDir(instanceId),\n },\n server: {\n deploymentMode,\n exposure: deploymentExposure,\n host: process.env.HOST ?? \"127.0.0.1\",\n port: Number(process.env.PORT) || 3100,\n allowedHostnames: Array.from(new Set([...allowedHostnamesFromEnv, ...(hostnameFromPublicUrl ? [hostnameFromPublicUrl] : [])])),\n serveUi: parseBooleanFromEnv(process.env.SERVE_UI) ?? true,\n },\n auth: {\n baseUrlMode: authBaseUrlMode,\n disableSignUp: false,\n ...(authPublicBaseUrl ? { publicBaseUrl: authPublicBaseUrl } : {}),\n },\n storage: {\n provider: storageProvider,\n localDisk: {\n baseDir:\n resolvePathFromEnv(process.env.RUDDER_STORAGE_LOCAL_DIR) ?? defaultStorage.localDisk.baseDir,\n },\n s3: {\n bucket: process.env.RUDDER_STORAGE_S3_BUCKET ?? defaultStorage.s3.bucket,\n region: process.env.RUDDER_STORAGE_S3_REGION ?? defaultStorage.s3.region,\n endpoint: process.env.RUDDER_STORAGE_S3_ENDPOINT ?? defaultStorage.s3.endpoint,\n prefix: process.env.RUDDER_STORAGE_S3_PREFIX ?? defaultStorage.s3.prefix,\n forcePathStyle:\n parseBooleanFromEnv(process.env.RUDDER_STORAGE_S3_FORCE_PATH_STYLE) ??\n defaultStorage.s3.forcePathStyle,\n },\n },\n secrets: {\n provider: secretsProvider,\n strictMode: parseBooleanFromEnv(process.env.RUDDER_SECRETS_STRICT_MODE) ?? defaultSecrets.strictMode,\n localEncrypted: {\n keyFilePath:\n resolvePathFromEnv(process.env.RUDDER_SECRETS_MASTER_KEY_FILE) ??\n defaultSecrets.localEncrypted.keyFilePath,\n },\n },\n };\n const ignoredEnvKeys: Array<{ key: string; reason: string }> = [];\n if (deploymentMode === \"local_trusted\" && process.env.RUDDER_DEPLOYMENT_EXPOSURE !== undefined) {\n ignoredEnvKeys.push({\n key: \"RUDDER_DEPLOYMENT_EXPOSURE\",\n reason: \"Ignored because deployment mode local_trusted always forces private exposure\",\n });\n }\n\n const ignoredKeySet = new Set(ignoredEnvKeys.map((entry) => entry.key));\n const usedEnvKeys = ONBOARD_ENV_KEYS.filter(\n (key) => process.env[key] !== undefined && !ignoredKeySet.has(key),\n );\n return { defaults, usedEnvKeys, ignoredEnvKeys };\n}\n\nfunction canCreateBootstrapInviteImmediately(config: Pick<RudderConfig, \"database\" | \"server\">): boolean {\n return config.server.deploymentMode === \"authenticated\" && config.database.mode !== \"embedded-postgres\";\n}\n\nexport async function onboard(opts: OnboardOptions): Promise<void> {\n printRudderCliBanner();\n p.intro(pc.bgCyan(pc.black(\" rudder onboard \")));\n const configPath = resolveConfigPath(opts.config);\n const instance = describeLocalInstancePaths(resolveRudderInstanceId());\n p.log.message(\n pc.dim(\n `Local home: ${instance.homeDir} | instance: ${instance.instanceId} | config: ${configPath}`,\n ),\n );\n\n if (configExists(opts.config)) {\n p.log.message(pc.dim(`${configPath} exists, updating config`));\n\n try {\n readConfig(opts.config);\n } catch (err) {\n p.log.message(\n pc.yellow(\n `Existing config appears invalid and will be updated.\\n${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n }\n }\n\n let setupMode: SetupMode = \"quickstart\";\n if (opts.yes) {\n p.log.message(pc.dim(\"`--yes` enabled: using Quickstart defaults.\"));\n } else {\n const setupModeChoice = await p.select({\n message: \"Choose setup path\",\n options: [\n {\n value: \"quickstart\" as const,\n label: \"Quickstart\",\n hint: \"Recommended: local defaults + ready to run\",\n },\n {\n value: \"advanced\" as const,\n label: \"Advanced setup\",\n hint: \"Customize database, server, storage, and more\",\n },\n ],\n initialValue: \"quickstart\",\n });\n if (p.isCancel(setupModeChoice)) {\n p.cancel(\"Setup cancelled.\");\n return;\n }\n setupMode = setupModeChoice as SetupMode;\n }\n\n let llm: RudderConfig[\"llm\"] | undefined;\n const { defaults: derivedDefaults, usedEnvKeys, ignoredEnvKeys } = quickstartDefaultsFromEnv();\n let {\n database,\n logging,\n server,\n auth,\n storage,\n secrets,\n } = derivedDefaults;\n\n if (setupMode === \"advanced\") {\n p.log.step(pc.bold(\"Database\"));\n database = await promptDatabase(database);\n\n if (database.mode === \"postgres\" && database.connectionString) {\n const s = p.spinner();\n s.start(\"Testing database connection...\");\n try {\n await checkPostgresConnection(database.connectionString);\n s.stop(\"Database connection successful\");\n } catch {\n s.stop(pc.yellow(\"Could not connect to database \u2014 you can fix this later with `rudder doctor`\"));\n }\n }\n\n p.log.step(pc.bold(\"LLM Provider\"));\n llm = await promptLlm();\n\n if (llm?.apiKey) {\n const s = p.spinner();\n s.start(\"Validating API key...\");\n try {\n if (llm.provider === \"claude\") {\n const res = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"x-api-key\": llm.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n model: \"claude-sonnet-4-5-20250929\",\n max_tokens: 1,\n messages: [{ role: \"user\", content: \"hi\" }],\n }),\n });\n if (res.ok || res.status === 400) {\n s.stop(\"API key is valid\");\n } else if (res.status === 401) {\n s.stop(pc.yellow(\"API key appears invalid \u2014 you can update it later\"));\n } else {\n s.stop(pc.yellow(\"Could not validate API key \u2014 continuing anyway\"));\n }\n } else {\n const res = await fetch(\"https://api.openai.com/v1/models\", {\n headers: { Authorization: `Bearer ${llm.apiKey}` },\n });\n if (res.ok) {\n s.stop(\"API key is valid\");\n } else if (res.status === 401) {\n s.stop(pc.yellow(\"API key appears invalid \u2014 you can update it later\"));\n } else {\n s.stop(pc.yellow(\"Could not validate API key \u2014 continuing anyway\"));\n }\n }\n } catch {\n s.stop(pc.yellow(\"Could not reach API \u2014 continuing anyway\"));\n }\n }\n\n p.log.step(pc.bold(\"Logging\"));\n logging = await promptLogging();\n\n p.log.step(pc.bold(\"Server\"));\n ({ server, auth } = await promptServer({ currentServer: server, currentAuth: auth }));\n\n p.log.step(pc.bold(\"Storage\"));\n storage = await promptStorage(storage);\n\n p.log.step(pc.bold(\"Secrets\"));\n const secretsDefaults = defaultSecretsConfig();\n secrets = {\n provider: secrets.provider ?? secretsDefaults.provider,\n strictMode: secrets.strictMode ?? secretsDefaults.strictMode,\n localEncrypted: {\n keyFilePath: secrets.localEncrypted?.keyFilePath ?? secretsDefaults.localEncrypted.keyFilePath,\n },\n };\n p.log.message(\n pc.dim(\n `Using defaults: provider=${secrets.provider}, strictMode=${secrets.strictMode}, keyFile=${secrets.localEncrypted.keyFilePath}`,\n ),\n );\n } else {\n p.log.step(pc.bold(\"Quickstart\"));\n p.log.message(pc.dim(\"Using quickstart defaults.\"));\n if (usedEnvKeys.length > 0) {\n p.log.message(pc.dim(`Environment-aware defaults active (${usedEnvKeys.length} env var(s) detected).`));\n } else {\n p.log.message(\n pc.dim(\"No environment overrides detected: embedded database, file storage, local encrypted secrets.\"),\n );\n }\n for (const ignored of ignoredEnvKeys) {\n p.log.message(pc.dim(`Ignored ${ignored.key}: ${ignored.reason}`));\n }\n }\n\n const jwtSecret = ensureAgentJwtSecret(configPath);\n const envFilePath = resolveAgentJwtEnvFile(configPath);\n if (jwtSecret.created) {\n p.log.success(`Created ${pc.cyan(\"RUDDER_AGENT_JWT_SECRET\")} in ${pc.dim(envFilePath)}`);\n } else if (process.env.RUDDER_AGENT_JWT_SECRET?.trim()) {\n p.log.info(`Using existing ${pc.cyan(\"RUDDER_AGENT_JWT_SECRET\")} from environment`);\n } else {\n p.log.info(`Using existing ${pc.cyan(\"RUDDER_AGENT_JWT_SECRET\")} in ${pc.dim(envFilePath)}`);\n }\n\n const config: RudderConfig = {\n $meta: {\n version: 1,\n updatedAt: new Date().toISOString(),\n source: \"onboard\",\n },\n ...(llm && { llm }),\n database,\n logging,\n server,\n auth,\n storage,\n secrets,\n };\n\n const keyResult = ensureLocalSecretsKeyFile(config, configPath);\n if (keyResult.status === \"created\") {\n p.log.success(`Created local secrets key file at ${pc.dim(keyResult.path)}`);\n } else if (keyResult.status === \"existing\") {\n p.log.message(pc.dim(`Using existing local secrets key file at ${keyResult.path}`));\n }\n\n writeConfig(config, opts.config);\n\n const persistentCliState = detectPersistentCliState();\n let persistentCliAvailable = !persistentCliState.usingNpx || persistentCliState.alreadyInstalled;\n\n p.note(\n [\n `Database: ${database.mode}`,\n llm ? `LLM: ${llm.provider}` : \"LLM: not configured\",\n `Logging: ${logging.mode} -> ${logging.logDir}`,\n `Server: ${server.deploymentMode}/${server.exposure} @ ${server.host}:${server.port}`,\n `Allowed hosts: ${server.allowedHostnames.length > 0 ? server.allowedHostnames.join(\", \") : \"(loopback only)\"}`,\n `Auth URL mode: ${auth.baseUrlMode}${auth.publicBaseUrl ? ` (${auth.publicBaseUrl})` : \"\"}`,\n `Storage: ${storage.provider}`,\n `Secrets: ${secrets.provider} (strict mode ${secrets.strictMode ? \"on\" : \"off\"})`,\n \"Agent auth: RUDDER_AGENT_JWT_SECRET configured\",\n ].join(\"\\n\"),\n \"Configuration saved\",\n );\n\n if (persistentCliState.usingNpx && !persistentCliState.alreadyInstalled) {\n p.log.step(\"Persistent CLI install\");\n\n let shouldInstallPersistentCli = Boolean(opts.yes);\n\n if (opts.yes) {\n p.log.message(pc.dim(\"`--yes` enabled: installing the persistent Rudder CLI.\"));\n } else if (process.stdin.isTTY && process.stdout.isTTY) {\n const answer = await p.confirm({\n message: `Install ${pc.cyan(\"rudder\")} globally now so you can use ${pc.cyan(\"rudder ...\")} next time?`,\n initialValue: true,\n });\n if (!p.isCancel(answer)) {\n shouldInstallPersistentCli = answer;\n }\n }\n\n if (shouldInstallPersistentCli) {\n p.log.message(pc.dim(`Running: ${persistentCliState.installCommand}`));\n const installResult = installPersistentCli({ installSpec: persistentCliState.installSpec });\n if (installResult.ok) {\n persistentCliAvailable = true;\n p.log.success(\n `${pc.cyan(\"rudder\")} is now installed. Open a new shell if the command is not visible immediately.`,\n );\n } else {\n p.log.error(\"Global CLI installation failed.\");\n if (installResult.output) {\n p.log.message(pc.dim(installResult.output));\n }\n p.log.message(`Install later with: ${pc.cyan(installResult.command)}`);\n }\n } else {\n p.log.message(`Install later with: ${pc.cyan(persistentCliState.installCommand)}`);\n }\n }\n\n p.note(\n [\n `Run: ${pc.cyan(persistentCliAvailable ? \"rudder run\" : \"npx @rudderhq/cli run\")}`,\n persistentCliAvailable\n ? `Fallback without install context: ${pc.cyan(\"npx @rudderhq/cli run\")}`\n : `Install later for direct use: ${pc.cyan(persistentCliState.installCommand)}`,\n `Reconfigure later: ${pc.cyan(persistentCliAvailable ? \"rudder configure\" : \"npx @rudderhq/cli configure\")}`,\n `Diagnose setup: ${pc.cyan(persistentCliAvailable ? \"rudder doctor\" : \"npx @rudderhq/cli doctor\")}`,\n ].join(\"\\n\"),\n \"Next commands\",\n );\n\n if (canCreateBootstrapInviteImmediately({ database, server })) {\n p.log.step(\"Generating bootstrap CEO invite\");\n await bootstrapCeoInvite({ config: configPath });\n }\n\n let shouldRunNow = opts.run === true || opts.yes === true;\n if (!shouldRunNow && !opts.invokedByRun && process.stdin.isTTY && process.stdout.isTTY) {\n const answer = await p.confirm({\n message: \"Start Rudder now?\",\n initialValue: true,\n });\n if (!p.isCancel(answer)) {\n shouldRunNow = answer;\n }\n }\n\n if (shouldRunNow && !opts.invokedByRun) {\n process.env.RUDDER_OPEN_ON_LISTEN = \"true\";\n const { runCommand } = await import(\"./run.js\");\n await runCommand({ config: configPath, repair: true, yes: true });\n return;\n }\n\n if (server.deploymentMode === \"authenticated\" && database.mode === \"embedded-postgres\") {\n p.log.info(\n [\n \"Bootstrap CEO invite will be created after the server starts.\",\n `Next: ${pc.cyan(\"rudder run\")}`,\n `Then: ${pc.cyan(\"rudder auth bootstrap-ceo\")}`,\n ].join(\"\\n\"),\n );\n }\n\n p.outro(\"You're all set!\");\n}\n", "import { Command, CommanderError } from \"commander\";\nimport { onboard } from \"./commands/onboard.js\";\nimport { doctor } from \"./commands/doctor.js\";\nimport { envCommand } from \"./commands/env.js\";\nimport { configure } from \"./commands/configure.js\";\nimport { startCommand } from \"./commands/start.js\";\nimport { addAllowedHostname } from \"./commands/allowed-hostname.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { heartbeatRun } from \"./commands/heartbeat-run.js\";\nimport { bootstrapCeoInvite } from \"./commands/auth-bootstrap-ceo.js\";\nimport { registerContextCommands } from \"./commands/client/context.js\";\nimport { registerCompanyCommands } from \"./commands/client/company.js\";\nimport { registerIssueCommands } from \"./commands/client/issue.js\";\nimport { registerAgentCommands } from \"./commands/client/agent.js\";\nimport { registerApprovalCommands } from \"./commands/client/approval.js\";\nimport { registerActivityCommands } from \"./commands/client/activity.js\";\nimport { registerDashboardCommands } from \"./commands/client/dashboard.js\";\nimport { registerSkillCommands } from \"./commands/client/skill.js\";\nimport { applyDataDirOverride, type DataDirOptionLike } from \"./config/data-dir.js\";\nimport { loadRudderEnvFile } from \"./config/env.js\";\nimport { applyLocalEnvProfile } from \"./config/local-env.js\";\nimport { registerPluginCommands } from \"./commands/client/plugin.js\";\nimport { registerClientAuthCommands } from \"./commands/client/auth.js\";\nimport { resolveCliVersion } from \"./version.js\";\n\nconst DATA_DIR_OPTION_HELP =\n \"Rudder data directory root (isolates state from ~/.rudder)\";\nconst LOCAL_ENV_OPTION_HELP =\n \"Local environment profile (dev, prod_local, e2e)\";\nconst DEFAULT_WORKTREE_HOME = \"~/.rudder-worktrees\";\n\nasync function importLazyCommandModule<T>(specifier: string, commandName: string): Promise<T> {\n try {\n return await import(specifier) as T;\n } catch (error) {\n if (isMissingLazyCommandModule(error, specifier)) {\n throw new Error(\n `${commandName} is not bundled in the thin Rudder CLI. Run it from a Rudder source checkout or a full runtime install.`,\n );\n }\n throw error;\n }\n}\n\nfunction isMissingLazyCommandModule(error: unknown, specifier: string): boolean {\n if (!(error instanceof Error)) return false;\n const code = (error as { code?: unknown }).code;\n return code === \"ERR_MODULE_NOT_FOUND\" && error.message.includes(specifier);\n}\n\nfunction numberOption(value: string): number {\n return Number(value);\n}\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"rudder\")\n .description(\"Rudder CLI \u2014 setup, diagnose, and configure your instance\")\n .version(resolveCliVersion());\n\n program.option(\"--local-env <name>\", LOCAL_ENV_OPTION_HELP);\n\n program.hook(\"preAction\", (_thisCommand, actionCommand) => {\n const options = actionCommand.optsWithGlobals() as DataDirOptionLike;\n applyLocalEnvProfile(options);\n const optionNames = new Set(actionCommand.options.map((option) => option.attributeName()));\n applyDataDirOverride(options, {\n hasConfigOption: optionNames.has(\"config\"),\n hasContextOption: optionNames.has(\"context\"),\n });\n loadRudderEnvFile(options.config);\n });\n\n program\n .command(\"start\")\n .description(\"Start Rudder Desktop and prepare the matching persistent CLI\")\n .option(\"--no-cli\", \"Skip persistent CLI installation\")\n .option(\"--no-runtime\", \"Skip Rudder runtime installation\")\n .option(\"--no-desktop\", \"Skip desktop app installation\")\n .option(\"--version <version>\", \"Rudder version to start (default: current CLI version)\")\n .option(\"--target-version <version>\", \"Rudder version to start; avoids the root CLI version flag\")\n .option(\"--repo <owner/repo>\", \"GitHub repository that hosts desktop releases\")\n .option(\"--output-dir <path>\", \"Directory for downloaded desktop release assets\")\n .option(\"--desktop-install-dir <path>\", \"Directory for the portable Desktop install\")\n .option(\"--no-open\", \"Install Desktop without launching it\")\n .option(\"--wait-for-active-runs\", \"Wait for active Rudder runs to finish before replacing Desktop\", false)\n .option(\"--desktop-progress-json\", \"Emit newline-delimited Desktop update progress events\")\n .option(\"--desktop-wait-for-apply\", \"Wait for an apply signal after downloading and verifying the Desktop update\", false)\n .option(\"--no-version-check\", \"Skip checking npm for a newer Rudder CLI version\")\n .option(\"--dry-run\", \"Print the start actions without changing the machine\", false)\n .action(startCommand);\n\n program\n .command(\"onboard\")\n .description(\"Interactive first-run setup wizard\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"-y, --yes\", \"Accept defaults (quickstart + start immediately)\", false)\n .option(\"--run\", \"Start Rudder immediately after saving config\", false)\n .action(onboard);\n\n program\n .command(\"doctor\")\n .description(\"Run diagnostic checks on your Rudder setup\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--repair\", \"Attempt to repair issues automatically\")\n .alias(\"--fix\")\n .option(\"-y, --yes\", \"Skip repair confirmation prompts\")\n .action(async (opts) => {\n await doctor(opts);\n });\n\n program\n .command(\"env\")\n .description(\"Print environment variables for deployment\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .action(envCommand);\n\n program\n .command(\"configure\")\n .description(\"Update configuration sections\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"-s, --section <section>\", \"Section to configure (llm, database, logging, server, storage, secrets)\")\n .action(configure);\n\n program\n .command(\"db:backup\")\n .description(\"Create a one-off database backup using current config\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--dir <path>\", \"Backup output directory (overrides config)\")\n .option(\"--retention-days <days>\", \"Retention window used for pruning\", (value) => Number(value))\n .option(\"--filename-prefix <prefix>\", \"Backup filename prefix\", \"rudder\")\n .option(\"--json\", \"Print backup metadata as JSON\")\n .action(async (opts) => {\n const { dbBackupCommand } = await importLazyCommandModule<typeof import(\"./commands/db-backup.js\")>(\n \"./commands/db-backup.js\",\n \"rudder db:backup\",\n );\n await dbBackupCommand(opts);\n });\n\n program\n .command(\"allowed-hostname\")\n .description(\"Allow a hostname for authenticated/private mode access\")\n .argument(\"<host>\", \"Hostname to allow (for example dotta-macbook-pro)\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .action(addAllowedHostname);\n\n program\n .command(\"run\")\n .description(\"Bootstrap local setup (onboard + doctor) and run Rudder\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"-i, --instance <id>\", \"Local instance id (default: default)\")\n .option(\"--repair\", \"Attempt automatic repairs during doctor\", true)\n .option(\"--no-repair\", \"Disable automatic repairs during doctor\")\n .action(runCommand);\n\n const heartbeat = program.command(\"heartbeat\").description(\"Heartbeat utilities\");\n\n heartbeat\n .command(\"run\")\n .description(\"Run one agent heartbeat and stream live logs\")\n .requiredOption(\"-a, --agent-id <agentId>\", \"Agent ID to invoke\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"CLI context profile name\")\n .option(\"--api-base <url>\", \"Base URL for the Rudder server API\")\n .option(\"--api-key <token>\", \"Bearer token for agent-authenticated calls\")\n .option(\n \"--source <source>\",\n \"Invocation source (timer | assignment | on_demand | automation)\",\n \"on_demand\",\n )\n .option(\"--trigger <trigger>\", \"Trigger detail (manual | ping | callback | system)\", \"manual\")\n .option(\"--timeout-ms <ms>\", \"Max time to wait before giving up\", \"0\")\n .option(\"--json\", \"Output raw JSON where applicable\")\n .option(\"--debug\", \"Show raw adapter stdout/stderr JSON chunks\")\n .action(heartbeatRun);\n\n registerContextCommands(program);\n registerCompanyCommands(program);\n registerIssueCommands(program);\n registerAgentCommands(program);\n registerApprovalCommands(program);\n registerActivityCommands(program);\n registerDashboardCommands(program);\n registerSkillCommands(program);\n registerLazyWorktreeCommands(program);\n registerPluginCommands(program);\n registerLazyBenchmarkCommands(program);\n\n const auth = program.command(\"auth\").description(\"Authentication and bootstrap utilities\");\n\n auth\n .command(\"bootstrap-ceo\")\n .description(\"Create a one-time bootstrap invite URL for first instance admin\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--force\", \"Create new invite even if admin already exists\", false)\n .option(\"--expires-hours <hours>\", \"Invite expiration window in hours\", numberOption)\n .option(\"--base-url <url>\", \"Public base URL used to print invite link\")\n .action(bootstrapCeoInvite);\n\n registerClientAuthCommands(auth);\n\n return program;\n}\n\nfunction registerLazyWorktreeCommands(program: Command): void {\n const load = () => importLazyCommandModule<typeof import(\"./commands/worktree.js\")>(\n \"./commands/worktree.js\",\n \"rudder worktree\",\n );\n const worktree = program.command(\"worktree\").description(\"Worktree-local Rudder instance helpers\");\n\n program\n .command(\"worktree:make\")\n .description(\"Create ~/NAME as a git worktree, then initialize an isolated Rudder instance inside it\")\n .argument(\"<name>\", \"Worktree name \u2014 auto-prefixed with rudder- if needed (created at ~/rudder-NAME)\")\n .option(\"--start-point <ref>\", \"Remote ref to base the new branch on (env: RUDDER_WORKTREE_START_POINT)\")\n .option(\"--instance <id>\", \"Explicit isolated instance id\")\n .option(\"--home <path>\", `Home root for worktree instances (env: RUDDER_WORKTREES_DIR, default: ${DEFAULT_WORKTREE_HOME})`)\n .option(\"--from-config <path>\", \"Source config.json to seed from\")\n .option(\"--from-data-dir <path>\", \"Source RUDDER_HOME used when deriving the source config\")\n .option(\"--from-instance <id>\", \"Source instance id when deriving the source config\", \"default\")\n .option(\"--server-port <port>\", \"Preferred server port\", numberOption)\n .option(\"--db-port <port>\", \"Preferred embedded Postgres port\", numberOption)\n .option(\"--seed-mode <mode>\", \"Seed profile: minimal or full (default: minimal)\", \"minimal\")\n .option(\"--no-seed\", \"Skip database seeding from the source instance\")\n .option(\"--force\", \"Replace existing repo-local config and isolated instance data\", false)\n .action(async (nameArg: string, opts) => (await load()).worktreeMakeCommand(nameArg, opts));\n\n worktree\n .command(\"init\")\n .description(\"Create repo-local config/env and an isolated instance for this worktree\")\n .option(\"--name <name>\", \"Display name used to derive the instance id\")\n .option(\"--instance <id>\", \"Explicit isolated instance id\")\n .option(\"--home <path>\", `Home root for worktree instances (env: RUDDER_WORKTREES_DIR, default: ${DEFAULT_WORKTREE_HOME})`)\n .option(\"--from-config <path>\", \"Source config.json to seed from\")\n .option(\"--from-data-dir <path>\", \"Source RUDDER_HOME used when deriving the source config\")\n .option(\"--from-instance <id>\", \"Source instance id when deriving the source config\", \"default\")\n .option(\"--server-port <port>\", \"Preferred server port\", numberOption)\n .option(\"--db-port <port>\", \"Preferred embedded Postgres port\", numberOption)\n .option(\"--seed-mode <mode>\", \"Seed profile: minimal or full (default: minimal)\", \"minimal\")\n .option(\"--no-seed\", \"Skip database seeding from the source instance\")\n .option(\"--force\", \"Replace existing repo-local config and isolated instance data\", false)\n .action(async (opts) => (await load()).worktreeInitCommand(opts));\n\n worktree\n .command(\"env\")\n .description(\"Print shell exports for the current worktree-local Rudder instance\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"--json\", \"Print JSON instead of shell exports\")\n .action(async (opts) => (await load()).worktreeEnvCommand(opts));\n\n program\n .command(\"worktree:list\")\n .description(\"List git worktrees visible from this repo and whether they look like Rudder worktrees\")\n .option(\"--json\", \"Print JSON instead of text output\")\n .action(async (opts) => (await load()).worktreeListCommand(opts));\n\n program\n .command(\"worktree:merge-history\")\n .description(\"Preview or import issue/comment history from another worktree into the current instance\")\n .argument(\"[source]\", \"Optional source worktree path, directory name, or branch name (back-compat alias for --from)\")\n .option(\"--from <worktree>\", \"Source worktree path, directory name, branch name, or current\")\n .option(\"--to <worktree>\", \"Target worktree path, directory name, branch name, or current (defaults to current)\")\n .option(\"--company <id-or-prefix>\", \"Shared company id or issue prefix inside the chosen source/target instances\")\n .option(\"--scope <items>\", \"Comma-separated scopes to import (issues, comments)\", \"issues,comments\")\n .option(\"--apply\", \"Apply the import after previewing the plan\", false)\n .option(\"--dry\", \"Preview only and do not import anything\", false)\n .option(\"--yes\", \"Skip the interactive confirmation prompt when applying\", false)\n .action(async (sourceArg: string | undefined, opts) => (await load()).worktreeMergeHistoryCommand(sourceArg, opts));\n\n program\n .command(\"worktree:cleanup\")\n .description(\"Safely remove a worktree, its branch, and its isolated instance data\")\n .argument(\"<name>\", \"Worktree name \u2014 auto-prefixed with rudder- if needed\")\n .option(\"--instance <id>\", \"Explicit instance id (if different from the worktree name)\")\n .option(\"--home <path>\", `Home root for worktree instances (env: RUDDER_WORKTREES_DIR, default: ${DEFAULT_WORKTREE_HOME})`)\n .option(\"--force\", \"Bypass safety checks (uncommitted changes, unique commits)\", false)\n .action(async (nameArg: string, opts) => (await load()).worktreeCleanupCommand(nameArg, opts));\n}\n\nfunction registerLazyBenchmarkCommands(program: Command): void {\n const benchmark = program.command(\"benchmark\").description(\"Benchmark and evaluation utilities\");\n benchmark\n .command(\"create-agent\")\n .description(\"Run create-agent benchmark cases\")\n .action(() => {\n throw new Error(\"Benchmark commands require a Rudder source checkout because they use development-only evaluation dependencies.\");\n });\n}\n\nexport async function runCli(argv: string[] = process.argv): Promise<number> {\n const program = createProgram();\n program.exitOverride();\n\n try {\n await program.parseAsync(argv);\n return 0;\n } catch (error) {\n if (error instanceof CommanderError) {\n if (error.code === \"commander.helpDisplayed\" || error.code === \"commander.version\") {\n return error.exitCode;\n }\n if (error.code === \"commander.executeSubCommandAsync\") {\n return error.exitCode;\n }\n if (error.exitCode > 0 && error.message) {\n console.error(error.message);\n return error.exitCode;\n }\n return error.exitCode;\n }\n\n console.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { configExists, readConfig, resolveConfigPath } from \"../config/store.js\";\nimport {\n readAgentJwtSecretFromEnv,\n readAgentJwtSecretFromEnvFile,\n resolveAgentJwtEnvFile,\n} from \"../config/env.js\";\nimport {\n resolveDefaultSecretsKeyFilePath,\n resolveDefaultStorageDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\n\ntype EnvSource = \"env\" | \"config\" | \"file\" | \"default\" | \"missing\";\n\ntype EnvVarRow = {\n key: string;\n value: string;\n source: EnvSource;\n required: boolean;\n note: string;\n};\n\nconst DEFAULT_AGENT_JWT_TTL_SECONDS = \"172800\";\nconst DEFAULT_AGENT_JWT_ISSUER = \"rudder\";\nconst DEFAULT_AGENT_JWT_AUDIENCE = \"rudder-api\";\nconst DEFAULT_HEARTBEAT_SCHEDULER_INTERVAL_MS = \"30000\";\nconst DEFAULT_SECRETS_PROVIDER = \"local_encrypted\";\nconst DEFAULT_STORAGE_PROVIDER = \"local_disk\";\nfunction defaultSecretsKeyFilePath(): string {\n return resolveDefaultSecretsKeyFilePath(resolveRudderInstanceId());\n}\nfunction defaultStorageBaseDir(): string {\n return resolveDefaultStorageDir(resolveRudderInstanceId());\n}\n\nexport async function envCommand(opts: { config?: string }): Promise<void> {\n p.intro(pc.bgCyan(pc.black(\" rudder env \")));\n\n const configPath = resolveConfigPath(opts.config);\n let config: RudderConfig | null = null;\n let configReadError: string | null = null;\n\n if (configExists(opts.config)) {\n p.log.message(pc.dim(`Config file: ${configPath}`));\n try {\n config = readConfig(opts.config);\n } catch (err) {\n configReadError = err instanceof Error ? err.message : String(err);\n p.log.message(pc.yellow(`Could not parse config: ${configReadError}`));\n }\n } else {\n p.log.message(pc.dim(`Config file missing: ${configPath}`));\n }\n\n const rows = collectDeploymentEnvRows(config, configPath);\n const missingRequired = rows.filter((row) => row.required && row.source === \"missing\");\n const sortedRows = rows.sort((a, b) => Number(b.required) - Number(a.required) || a.key.localeCompare(b.key));\n\n const requiredRows = sortedRows.filter((row) => row.required);\n const optionalRows = sortedRows.filter((row) => !row.required);\n\n const formatSection = (title: string, entries: EnvVarRow[]) => {\n if (entries.length === 0) return;\n\n p.log.message(pc.bold(title));\n for (const entry of entries) {\n const status = entry.source === \"missing\" ? pc.red(\"missing\") : entry.source === \"default\" ? pc.yellow(\"default\") : pc.green(\"set\");\n const sourceNote = {\n env: \"environment\",\n config: \"config\",\n file: \"file\",\n default: \"default\",\n missing: \"missing\",\n }[entry.source];\n p.log.message(\n `${pc.cyan(entry.key)} ${status.padEnd(7)} ${pc.dim(`[${sourceNote}] ${entry.note}`)}${entry.source === \"missing\" ? \"\" : ` ${pc.dim(\"=>\")} ${pc.white(quoteShellValue(entry.value))}`}`,\n );\n }\n };\n\n formatSection(\"Required environment variables\", requiredRows);\n formatSection(\"Optional environment variables\", optionalRows);\n\n const exportRows = rows.map((row) => (row.source === \"missing\" ? { ...row, value: \"<set-this-value>\" } : row));\n const uniqueRows = uniqueByKey(exportRows);\n const exportBlock = uniqueRows.map((row) => `export ${row.key}=${quoteShellValue(row.value)}`).join(\"\\n\");\n\n if (configReadError) {\n p.log.error(`Could not load config cleanly: ${configReadError}`);\n }\n\n p.note(\n exportBlock || \"No values detected. Set required variables manually.\",\n \"Deployment export block\",\n );\n\n if (missingRequired.length > 0) {\n p.log.message(\n pc.yellow(\n `Missing required values: ${missingRequired.map((row) => row.key).join(\", \")}. Set these before deployment.`,\n ),\n );\n } else {\n p.log.message(pc.green(\"All required deployment variables are present.\"));\n }\n p.outro(\"Done\");\n}\n\nfunction collectDeploymentEnvRows(config: RudderConfig | null, configPath: string): EnvVarRow[] {\n const agentJwtEnvFile = resolveAgentJwtEnvFile(configPath);\n const jwtEnv = readAgentJwtSecretFromEnv(configPath);\n const jwtFile = jwtEnv ? null : readAgentJwtSecretFromEnvFile(agentJwtEnvFile);\n const jwtSource = jwtEnv ? \"env\" : jwtFile ? \"file\" : \"missing\";\n\n const dbUrl = process.env.DATABASE_URL ?? config?.database?.connectionString ?? \"\";\n const databaseMode = config?.database?.mode ?? \"embedded-postgres\";\n const dbUrlSource: EnvSource = process.env.DATABASE_URL ? \"env\" : config?.database?.connectionString ? \"config\" : \"missing\";\n const publicUrl =\n process.env.RUDDER_PUBLIC_URL ??\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL ??\n process.env.BETTER_AUTH_URL ??\n process.env.BETTER_AUTH_BASE_URL ??\n config?.auth?.publicBaseUrl ??\n \"\";\n const publicUrlSource: EnvSource =\n process.env.RUDDER_PUBLIC_URL\n ? \"env\"\n : process.env.RUDDER_AUTH_PUBLIC_BASE_URL || process.env.BETTER_AUTH_URL || process.env.BETTER_AUTH_BASE_URL\n ? \"env\"\n : config?.auth?.publicBaseUrl\n ? \"config\"\n : \"missing\";\n let trustedOriginsDefault = \"\";\n if (publicUrl) {\n try {\n trustedOriginsDefault = new URL(publicUrl).origin;\n } catch {\n trustedOriginsDefault = \"\";\n }\n }\n\n const heartbeatInterval = process.env.HEARTBEAT_SCHEDULER_INTERVAL_MS ?? DEFAULT_HEARTBEAT_SCHEDULER_INTERVAL_MS;\n const heartbeatEnabled = process.env.HEARTBEAT_SCHEDULER_ENABLED ?? \"true\";\n const secretsProvider =\n process.env.RUDDER_SECRETS_PROVIDER ??\n config?.secrets?.provider ??\n DEFAULT_SECRETS_PROVIDER;\n const secretsStrictMode =\n process.env.RUDDER_SECRETS_STRICT_MODE ??\n String(config?.secrets?.strictMode ?? false);\n const secretsKeyFilePath =\n process.env.RUDDER_SECRETS_MASTER_KEY_FILE ??\n config?.secrets?.localEncrypted?.keyFilePath ??\n defaultSecretsKeyFilePath();\n const storageProvider =\n process.env.RUDDER_STORAGE_PROVIDER ??\n config?.storage?.provider ??\n DEFAULT_STORAGE_PROVIDER;\n const storageLocalDir =\n process.env.RUDDER_STORAGE_LOCAL_DIR ??\n config?.storage?.localDisk?.baseDir ??\n defaultStorageBaseDir();\n const storageS3Bucket =\n process.env.RUDDER_STORAGE_S3_BUCKET ??\n config?.storage?.s3?.bucket ??\n \"rudder\";\n const storageS3Region =\n process.env.RUDDER_STORAGE_S3_REGION ??\n config?.storage?.s3?.region ??\n \"us-east-1\";\n const storageS3Endpoint =\n process.env.RUDDER_STORAGE_S3_ENDPOINT ??\n config?.storage?.s3?.endpoint ??\n \"\";\n const storageS3Prefix =\n process.env.RUDDER_STORAGE_S3_PREFIX ??\n config?.storage?.s3?.prefix ??\n \"\";\n const storageS3ForcePathStyle =\n process.env.RUDDER_STORAGE_S3_FORCE_PATH_STYLE ??\n String(config?.storage?.s3?.forcePathStyle ?? false);\n\n const rows: EnvVarRow[] = [\n {\n key: \"RUDDER_LOCAL_ENV\",\n value: process.env.RUDDER_LOCAL_ENV ?? \"\",\n source: process.env.RUDDER_LOCAL_ENV ? \"env\" : \"missing\",\n required: false,\n note: \"Local environment profile selector (dev, prod_local, e2e)\",\n },\n {\n key: \"RUDDER_INSTANCE_ID\",\n value: process.env.RUDDER_INSTANCE_ID ?? resolveRudderInstanceId(),\n source: process.env.RUDDER_INSTANCE_ID ? \"env\" : \"default\",\n required: false,\n note: \"Local instance identifier used for per-instance config and storage paths\",\n },\n {\n key: \"RUDDER_AGENT_JWT_SECRET\",\n value: jwtEnv ?? jwtFile ?? \"\",\n source: jwtSource,\n required: true,\n note:\n jwtSource === \"missing\"\n ? \"Generate during onboard or set manually (required for local adapter authentication)\"\n : jwtSource === \"env\"\n ? \"Set in process environment\"\n : `Set in ${agentJwtEnvFile}`,\n },\n {\n key: \"DATABASE_URL\",\n value: dbUrl,\n source: dbUrlSource,\n required: true,\n note:\n databaseMode === \"postgres\"\n ? \"Configured for postgres mode (required)\"\n : \"Required for live deployment with managed PostgreSQL\",\n },\n {\n key: \"PORT\",\n value:\n process.env.PORT ??\n (config?.server?.port !== undefined ? String(config.server.port) : \"3100\"),\n source: process.env.PORT ? \"env\" : config?.server?.port !== undefined ? \"config\" : \"default\",\n required: false,\n note: \"HTTP listen port\",\n },\n {\n key: \"RUDDER_EMBEDDED_POSTGRES_PORT\",\n value:\n process.env.RUDDER_EMBEDDED_POSTGRES_PORT ??\n (config?.database?.embeddedPostgresPort !== undefined\n ? String(config.database.embeddedPostgresPort)\n : \"54329\"),\n source:\n process.env.RUDDER_EMBEDDED_POSTGRES_PORT\n ? \"env\"\n : config?.database?.embeddedPostgresPort !== undefined\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Embedded PostgreSQL listen port\",\n },\n {\n key: \"RUDDER_PUBLIC_URL\",\n value: publicUrl,\n source: publicUrlSource,\n required: false,\n note: \"Canonical public URL for auth/callback/invite origin wiring\",\n },\n {\n key: \"BETTER_AUTH_TRUSTED_ORIGINS\",\n value: process.env.BETTER_AUTH_TRUSTED_ORIGINS ?? trustedOriginsDefault,\n source: process.env.BETTER_AUTH_TRUSTED_ORIGINS\n ? \"env\"\n : trustedOriginsDefault\n ? \"default\"\n : \"missing\",\n required: false,\n note: \"Comma-separated auth origin allowlist (auto-derived from RUDDER_PUBLIC_URL when possible)\",\n },\n {\n key: \"RUDDER_AGENT_JWT_TTL_SECONDS\",\n value: process.env.RUDDER_AGENT_JWT_TTL_SECONDS ?? DEFAULT_AGENT_JWT_TTL_SECONDS,\n source: process.env.RUDDER_AGENT_JWT_TTL_SECONDS ? \"env\" : \"default\",\n required: false,\n note: \"JWT lifetime in seconds\",\n },\n {\n key: \"RUDDER_AGENT_JWT_ISSUER\",\n value: process.env.RUDDER_AGENT_JWT_ISSUER ?? DEFAULT_AGENT_JWT_ISSUER,\n source: process.env.RUDDER_AGENT_JWT_ISSUER ? \"env\" : \"default\",\n required: false,\n note: \"JWT issuer\",\n },\n {\n key: \"RUDDER_AGENT_JWT_AUDIENCE\",\n value: process.env.RUDDER_AGENT_JWT_AUDIENCE ?? DEFAULT_AGENT_JWT_AUDIENCE,\n source: process.env.RUDDER_AGENT_JWT_AUDIENCE ? \"env\" : \"default\",\n required: false,\n note: \"JWT audience\",\n },\n {\n key: \"HEARTBEAT_SCHEDULER_INTERVAL_MS\",\n value: heartbeatInterval,\n source: process.env.HEARTBEAT_SCHEDULER_INTERVAL_MS ? \"env\" : \"default\",\n required: false,\n note: \"Heartbeat worker interval in ms\",\n },\n {\n key: \"HEARTBEAT_SCHEDULER_ENABLED\",\n value: heartbeatEnabled,\n source: process.env.HEARTBEAT_SCHEDULER_ENABLED ? \"env\" : \"default\",\n required: false,\n note: \"Set to `false` to disable timer scheduling\",\n },\n {\n key: \"RUDDER_SECRETS_PROVIDER\",\n value: secretsProvider,\n source: process.env.RUDDER_SECRETS_PROVIDER\n ? \"env\"\n : config?.secrets?.provider\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Default provider for new secrets\",\n },\n {\n key: \"RUDDER_SECRETS_STRICT_MODE\",\n value: secretsStrictMode,\n source: process.env.RUDDER_SECRETS_STRICT_MODE\n ? \"env\"\n : config?.secrets?.strictMode !== undefined\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Require secret refs for sensitive env keys\",\n },\n {\n key: \"RUDDER_SECRETS_MASTER_KEY_FILE\",\n value: secretsKeyFilePath,\n source: process.env.RUDDER_SECRETS_MASTER_KEY_FILE\n ? \"env\"\n : config?.secrets?.localEncrypted?.keyFilePath\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Path to local encrypted secrets key file\",\n },\n {\n key: \"RUDDER_STORAGE_PROVIDER\",\n value: storageProvider,\n source: process.env.RUDDER_STORAGE_PROVIDER\n ? \"env\"\n : config?.storage?.provider\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Storage provider (local_disk or s3)\",\n },\n {\n key: \"RUDDER_STORAGE_LOCAL_DIR\",\n value: storageLocalDir,\n source: process.env.RUDDER_STORAGE_LOCAL_DIR\n ? \"env\"\n : config?.storage?.localDisk?.baseDir\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Local storage base directory for local_disk provider\",\n },\n {\n key: \"RUDDER_STORAGE_S3_BUCKET\",\n value: storageS3Bucket,\n source: process.env.RUDDER_STORAGE_S3_BUCKET\n ? \"env\"\n : config?.storage?.s3?.bucket\n ? \"config\"\n : \"default\",\n required: false,\n note: \"S3 bucket name for s3 provider\",\n },\n {\n key: \"RUDDER_STORAGE_S3_REGION\",\n value: storageS3Region,\n source: process.env.RUDDER_STORAGE_S3_REGION\n ? \"env\"\n : config?.storage?.s3?.region\n ? \"config\"\n : \"default\",\n required: false,\n note: \"S3 region for s3 provider\",\n },\n {\n key: \"RUDDER_STORAGE_S3_ENDPOINT\",\n value: storageS3Endpoint,\n source: process.env.RUDDER_STORAGE_S3_ENDPOINT\n ? \"env\"\n : config?.storage?.s3?.endpoint\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Optional custom endpoint for S3-compatible providers\",\n },\n {\n key: \"RUDDER_STORAGE_S3_PREFIX\",\n value: storageS3Prefix,\n source: process.env.RUDDER_STORAGE_S3_PREFIX\n ? \"env\"\n : config?.storage?.s3?.prefix\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Optional object key prefix\",\n },\n {\n key: \"RUDDER_STORAGE_S3_FORCE_PATH_STYLE\",\n value: storageS3ForcePathStyle,\n source: process.env.RUDDER_STORAGE_S3_FORCE_PATH_STYLE\n ? \"env\"\n : config?.storage?.s3?.forcePathStyle !== undefined\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Set true for path-style access on compatible providers\",\n },\n ];\n\n const defaultConfigPath = resolveConfigPath();\n if (process.env.RUDDER_CONFIG || configPath !== defaultConfigPath) {\n rows.push({\n key: \"RUDDER_CONFIG\",\n value: process.env.RUDDER_CONFIG ?? configPath,\n source: process.env.RUDDER_CONFIG ? \"env\" : \"default\",\n required: false,\n note: \"Optional path override for config file\",\n });\n }\n\n return rows;\n}\n\nfunction uniqueByKey(rows: EnvVarRow[]): EnvVarRow[] {\n const seen = new Set<string>();\n const result: EnvVarRow[] = [];\n for (const row of rows) {\n if (seen.has(row.key)) continue;\n seen.add(row.key);\n result.push(row);\n }\n return result;\n}\n\nfunction quoteShellValue(value: string): string {\n if (value === \"\") return \"\\\"\\\"\";\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { readConfig, writeConfig, configExists, resolveConfigPath } from \"../config/store.js\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { ensureLocalSecretsKeyFile } from \"../config/secrets-key.js\";\nimport { promptDatabase } from \"../prompts/database.js\";\nimport { promptLlm } from \"../prompts/llm.js\";\nimport { promptLogging } from \"../prompts/logging.js\";\nimport { defaultSecretsConfig, promptSecrets } from \"../prompts/secrets.js\";\nimport { defaultStorageConfig, promptStorage } from \"../prompts/storage.js\";\nimport { promptServer } from \"../prompts/server.js\";\nimport {\n resolveDefaultBackupDir,\n resolveDefaultEmbeddedPostgresDir,\n resolveDefaultLogsDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\nimport { printRudderCliBanner } from \"../utils/banner.js\";\n\ntype Section = \"llm\" | \"database\" | \"logging\" | \"server\" | \"storage\" | \"secrets\";\n\nconst SECTION_LABELS: Record<Section, string> = {\n llm: \"LLM Provider\",\n database: \"Database\",\n logging: \"Logging\",\n server: \"Server\",\n storage: \"Storage\",\n secrets: \"Secrets\",\n};\n\nfunction defaultConfig(): RudderConfig {\n const instanceId = resolveRudderInstanceId();\n const embeddedPostgresPort = Math.max(1, Number(process.env.RUDDER_EMBEDDED_POSTGRES_PORT) || 54329);\n const serverPort = Math.max(1, Number(process.env.PORT) || 3100);\n return {\n $meta: {\n version: 1,\n updatedAt: new Date().toISOString(),\n source: \"configure\",\n },\n database: {\n mode: \"embedded-postgres\",\n embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(instanceId),\n embeddedPostgresPort,\n backup: {\n enabled: true,\n intervalMinutes: 60,\n retentionDays: 30,\n dir: resolveDefaultBackupDir(instanceId),\n },\n },\n logging: {\n mode: \"file\",\n logDir: resolveDefaultLogsDir(instanceId),\n },\n server: {\n deploymentMode: \"local_trusted\",\n exposure: \"private\",\n host: \"127.0.0.1\",\n port: serverPort,\n allowedHostnames: [],\n serveUi: true,\n },\n auth: {\n baseUrlMode: \"auto\",\n disableSignUp: false,\n },\n storage: defaultStorageConfig(),\n secrets: defaultSecretsConfig(),\n };\n}\n\nexport async function configure(opts: {\n config?: string;\n section?: string;\n}): Promise<void> {\n printRudderCliBanner();\n p.intro(pc.bgCyan(pc.black(\" rudder configure \")));\n const configPath = resolveConfigPath(opts.config);\n\n if (!configExists(opts.config)) {\n p.log.error(\"No config file found. Run `rudder onboard` first.\");\n p.outro(\"\");\n return;\n }\n\n let config: RudderConfig;\n try {\n config = readConfig(opts.config) ?? defaultConfig();\n } catch (err) {\n p.log.message(\n pc.yellow(\n `Existing config is invalid. Loading defaults so you can repair it now.\\n${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n config = defaultConfig();\n }\n\n let section: Section | undefined = opts.section as Section | undefined;\n\n if (section && !SECTION_LABELS[section]) {\n p.log.error(`Unknown section: ${section}. Choose from: ${Object.keys(SECTION_LABELS).join(\", \")}`);\n p.outro(\"\");\n return;\n }\n\n // Section selection loop\n let continueLoop = true;\n while (continueLoop) {\n if (!section) {\n const choice = await p.select({\n message: \"Which section do you want to configure?\",\n options: Object.entries(SECTION_LABELS).map(([value, label]) => ({\n value: value as Section,\n label,\n })),\n });\n\n if (p.isCancel(choice)) {\n p.cancel(\"Configuration cancelled.\");\n return;\n }\n\n section = choice;\n }\n\n p.log.step(pc.bold(SECTION_LABELS[section]));\n\n switch (section) {\n case \"database\":\n config.database = await promptDatabase(config.database);\n break;\n case \"llm\": {\n const llm = await promptLlm();\n if (llm) {\n config.llm = llm;\n } else {\n delete config.llm;\n }\n break;\n }\n case \"logging\":\n config.logging = await promptLogging();\n break;\n case \"server\":\n {\n const { server, auth } = await promptServer({\n currentServer: config.server,\n currentAuth: config.auth,\n });\n config.server = server;\n config.auth = auth;\n }\n break;\n case \"storage\":\n config.storage = await promptStorage(config.storage);\n break;\n case \"secrets\":\n config.secrets = await promptSecrets(config.secrets);\n {\n const keyResult = ensureLocalSecretsKeyFile(config, configPath);\n if (keyResult.status === \"created\") {\n p.log.success(`Created local secrets key file at ${pc.dim(keyResult.path)}`);\n } else if (keyResult.status === \"existing\") {\n p.log.message(pc.dim(`Using existing local secrets key file at ${keyResult.path}`));\n } else if (keyResult.status === \"skipped_provider\") {\n p.log.message(pc.dim(\"Skipping local key file management for non-local provider\"));\n } else {\n p.log.message(pc.dim(\"Skipping local key file management because RUDDER_SECRETS_MASTER_KEY is set\"));\n }\n }\n break;\n }\n\n config.$meta.updatedAt = new Date().toISOString();\n config.$meta.source = \"configure\";\n\n writeConfig(config, opts.config);\n p.log.success(`${SECTION_LABELS[section]} configuration updated.`);\n\n // If section was provided via CLI flag, don't loop\n if (opts.section) {\n continueLoop = false;\n } else {\n const another = await p.confirm({\n message: \"Configure another section?\",\n initialValue: false,\n });\n\n if (p.isCancel(another) || !another) {\n continueLoop = false;\n } else {\n section = undefined; // Reset to show picker again\n }\n }\n }\n\n p.outro(\"Configuration saved.\");\n}\n", "import { spawn, spawnSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { constants as fsConstants, createWriteStream, mkdirSync, readFileSync } from \"node:fs\";\nimport { access, chmod, copyFile, cp, mkdtemp, mkdir, readFile, readdir, rm, writeFile } from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { Readable, Transform } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport {\n CLI_NPM_PACKAGE_NAME,\n getGlobalInstalledPackageVersion,\n installPersistentCli,\n resolvePersistentCliInstallSpec,\n} from \"../install.js\";\nimport { ensureRuntimeInstalled, RuntimeInstallError } from \"../runtime/install.js\";\nimport { createByteProgress, type ByteProgressReporter } from \"../utils/progress.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\nexport const DEFAULT_DESKTOP_RELEASE_REPO = \"Undertone0809/rudder\";\nexport const DESKTOP_UPDATE_QUIT_ARG = \"--rudder-update-quit\";\n\ntype SupportedPlatform = \"macos\" | \"windows\" | \"linux\";\n\nexport interface DesktopAssetTarget {\n platform: SupportedPlatform;\n arch: \"x64\" | \"arm64\";\n extension: \".zip\" | \".AppImage\";\n}\n\nexport interface DesktopInstallPaths {\n installRoot: string;\n appPath: string;\n executablePath: string;\n metadataPath: string;\n}\n\nexport interface GithubReleaseAsset {\n name: string;\n browser_download_url: string;\n url?: string;\n}\n\ninterface GithubRelease {\n tag_name: string;\n assets: GithubReleaseAsset[];\n}\n\ninterface StartCommandOptions {\n cli?: boolean;\n desktop?: boolean;\n runtime?: boolean;\n version?: string;\n targetVersion?: string;\n repo?: string;\n outputDir?: string;\n desktopInstallDir?: string;\n open?: boolean;\n waitForActiveRuns?: boolean;\n desktopProgressJson?: boolean;\n desktopWaitForApply?: boolean;\n dryRun?: boolean;\n versionCheck?: boolean;\n}\n\nexport interface DesktopInstallMetadata {\n version: 1;\n releaseTag: string;\n assetName: string;\n assetChecksum: string;\n installedAt: string;\n}\n\ntype UpdateQuitResponse =\n | { ok: true; status: \"quitting\" | \"not_running\" }\n | { ok: false; status: \"active_runs\"; totalRuns: number }\n | { ok: false; status: \"failed\"; message: string };\n\nexport type ProgressReporterFactory = (label: string) => ByteProgressReporter;\n\ntype DesktopUpdateProgressPhase =\n | \"starting\"\n | \"resolving_release\"\n | \"downloading_checksums\"\n | \"downloading_asset\"\n | \"verifying_checksum\"\n | \"ready_to_install\"\n | \"waiting_for_active_runs\"\n | \"preparing_restart\"\n | \"closing\"\n | \"failed\";\n\ntype DesktopUpdateProgressEvent = {\n source: \"rudder-desktop-update\";\n phase: DesktopUpdateProgressPhase;\n message: string;\n percent?: number;\n transferredBytes?: number;\n totalBytes?: number;\n error?: string;\n at: string;\n};\n\nconst STABLE_SEMVER_RE = /^[0-9]+\\.[0-9]+\\.[0-9]+$/;\nconst CANARY_SEMVER_RE = /^[0-9]+\\.[0-9]+\\.[0-9]+-canary\\.[0-9]+$/;\nconst CLI_REGISTRY_LATEST_URL = \"https://registry.npmjs.org/@rudderhq%2fcli/latest\";\nconst DESKTOP_APP_NAME = \"Rudder\";\nconst DESKTOP_METADATA_FILE = \".rudder-desktop-install.json\";\nconst DESKTOP_CHECKSUM_ASSET_NAME = \"SHASUMS256.txt\";\nconst GITHUB_ASSET_DOWNLOAD_ACCEPT = \"application/octet-stream\";\n\nfunction normalizeProgressTotal(totalBytes: number | null | undefined): number | null {\n return typeof totalBytes === \"number\" && Number.isFinite(totalBytes) && totalBytes > 0 ? totalBytes : null;\n}\n\nfunction writeDesktopProgress(event: Omit<DesktopUpdateProgressEvent, \"source\" | \"at\">): void {\n const payload: DesktopUpdateProgressEvent = {\n source: \"rudder-desktop-update\",\n ...event,\n at: new Date().toISOString(),\n };\n try {\n process.stdout.write(`${JSON.stringify(payload)}\\n`);\n } catch (error) {\n const code = typeof error === \"object\" && error && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : \"\";\n if (code !== \"EPIPE\") throw error;\n }\n}\n\nfunction desktopDownloadPhase(label: string): DesktopUpdateProgressPhase {\n return label.toLowerCase().includes(\"shasums\")\n ? \"downloading_checksums\"\n : \"downloading_asset\";\n}\n\nfunction createDesktopProgressFactory(): ProgressReporterFactory {\n return (label: string) => {\n const phase = desktopDownloadPhase(label);\n let latestReceivedBytes = 0;\n let latestTotalBytes: number | null | undefined = null;\n\n function emitByteProgress(\n message: string,\n receivedBytes: number,\n totalBytes: number | null | undefined,\n ): void {\n const total = normalizeProgressTotal(totalBytes);\n writeDesktopProgress({\n phase,\n message,\n transferredBytes: Math.max(0, receivedBytes),\n ...(total === null\n ? {}\n : {\n totalBytes: total,\n percent: Math.max(0, Math.min(100, Math.floor((Math.max(0, receivedBytes) / total) * 100))),\n }),\n });\n }\n\n return {\n start(totalBytes?: number | null) {\n latestReceivedBytes = 0;\n latestTotalBytes = totalBytes;\n emitByteProgress(label, 0, totalBytes);\n },\n update(receivedBytes: number, totalBytes?: number | null) {\n latestReceivedBytes = receivedBytes;\n latestTotalBytes = totalBytes;\n emitByteProgress(label, receivedBytes, totalBytes);\n },\n finish(receivedBytes = latestReceivedBytes, totalBytes = latestTotalBytes) {\n latestReceivedBytes = receivedBytes;\n latestTotalBytes = totalBytes;\n emitByteProgress(`${label} complete`, receivedBytes, totalBytes);\n },\n fail() {\n writeDesktopProgress({\n phase,\n message: `${label} failed`,\n transferredBytes: Math.max(0, latestReceivedBytes),\n error: `${label} failed`,\n });\n },\n };\n };\n}\n\nasync function waitForDesktopApplySignal(): Promise<void> {\n process.stdin.setEncoding(\"utf8\");\n process.stdin.resume();\n\n await new Promise<void>((resolve, reject) => {\n let buffer = \"\";\n const cleanup = () => {\n process.stdin.off(\"data\", onData);\n process.stdin.off(\"end\", onEnd);\n process.stdin.off(\"error\", onError);\n };\n const onData = (chunk: string) => {\n buffer += chunk;\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n if (lines.some((line) => line.trim() === \"apply\")) {\n cleanup();\n resolve();\n }\n };\n const onEnd = () => {\n cleanup();\n reject(new Error(\"Desktop update apply signal ended before confirmation.\"));\n };\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n process.stdin.on(\"data\", onData);\n process.stdin.on(\"end\", onEnd);\n process.stdin.on(\"error\", onError);\n });\n}\n\nexport function resolveCurrentCliVersion(env: NodeJS.ProcessEnv = process.env): string {\n const version = resolveCliVersion(import.meta.url, env);\n return version === \"0.0.0\" ? \"latest\" : version;\n}\n\nexport function resolveCliInstallSpec(version: string, env: NodeJS.ProcessEnv = process.env): string {\n if (version && version !== \"latest\") return `${CLI_NPM_PACKAGE_NAME}@${version}`;\n return resolvePersistentCliInstallSpec(env);\n}\n\nexport function isPersistentCliVersionCurrent(version: string, installedVersion: string | null): boolean {\n return Boolean(version && version !== \"latest\" && installedVersion === version);\n}\n\nexport function compareStableSemver(a: string, b: string): number {\n const aMatch = a.match(/^([0-9]+)\\.([0-9]+)\\.([0-9]+)$/);\n const bMatch = b.match(/^([0-9]+)\\.([0-9]+)\\.([0-9]+)$/);\n if (!aMatch || !bMatch) return 0;\n\n for (let index = 1; index <= 3; index += 1) {\n const diff = Number(aMatch[index]) - Number(bMatch[index]);\n if (diff !== 0) return diff;\n }\n\n return 0;\n}\n\nasync function fetchLatestCliVersion(): Promise<string | null> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2_000);\n\n try {\n const response = await fetch(CLI_REGISTRY_LATEST_URL, {\n signal: controller.signal,\n headers: { \"User-Agent\": \"rudder-cli-version-check\" },\n });\n if (!response.ok) return null;\n const parsed = (await response.json()) as { version?: string };\n return parsed.version?.trim() || null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nexport async function getCliUpdateNotice(currentVersion: string): Promise<string | null> {\n if (!STABLE_SEMVER_RE.test(currentVersion)) return null;\n const latestVersion = await fetchLatestCliVersion();\n if (!latestVersion || !STABLE_SEMVER_RE.test(latestVersion)) return null;\n if (compareStableSemver(latestVersion, currentVersion) <= 0) return null;\n\n return `Rudder ${latestVersion} is available. Update with ${pc.cyan(`npx ${CLI_NPM_PACKAGE_NAME}@latest start`)}.`;\n}\n\nexport function resolveDesktopReleaseTag(version: string): string {\n if (!version || version === \"latest\") return \"latest\";\n if (STABLE_SEMVER_RE.test(version)) return `v${version}`;\n if (CANARY_SEMVER_RE.test(version)) return `canary/v${version}`;\n\n throw new Error(\n `Desktop release lookup requires a release version like 0.1.0 or 0.1.0-canary.0. Received ${version}.`,\n );\n}\n\nexport function resolveDesktopAssetTarget(\n platform: NodeJS.Platform = process.platform,\n arch: NodeJS.Architecture = process.arch,\n): DesktopAssetTarget {\n if (platform === \"darwin\") {\n if (arch !== \"x64\" && arch !== \"arm64\") {\n throw new Error(`Rudder Desktop does not publish portable assets for ${platform}/${arch}.`);\n }\n return { platform: \"macos\", arch, extension: \".zip\" };\n }\n if (platform === \"win32\") return { platform: \"windows\", arch: \"x64\", extension: \".zip\" };\n if (platform === \"linux\") {\n if (arch !== \"x64\") {\n throw new Error(`Rudder Desktop does not publish portable assets for ${platform}/${arch}.`);\n }\n return { platform: \"linux\", arch: \"x64\", extension: \".AppImage\" };\n }\n\n throw new Error(`Rudder Desktop does not publish portable assets for ${platform}.`);\n}\n\nexport function resolveDefaultDesktopInstallRoot(\n target: DesktopAssetTarget,\n env: NodeJS.ProcessEnv = process.env,\n homeDir: string = homedir(),\n): string {\n if (target.platform === \"macos\") return path.join(homeDir, \"Applications\");\n if (target.platform === \"windows\") {\n const localAppData = env.LOCALAPPDATA?.trim() || path.join(homeDir, \"AppData\", \"Local\");\n return path.join(localAppData, \"Programs\", DESKTOP_APP_NAME);\n }\n return path.join(homeDir, \".local\", \"share\", \"rudder\");\n}\n\nexport function resolveDesktopInstallPaths(\n target: DesktopAssetTarget,\n installRoot: string,\n): DesktopInstallPaths {\n const root = path.resolve(installRoot);\n if (target.platform === \"macos\") {\n const appPath = path.join(root, `${DESKTOP_APP_NAME}.app`);\n return {\n installRoot: root,\n appPath,\n executablePath: path.join(appPath, \"Contents\", \"MacOS\", DESKTOP_APP_NAME),\n metadataPath: path.join(root, DESKTOP_METADATA_FILE),\n };\n }\n if (target.platform === \"windows\") {\n return {\n installRoot: root,\n appPath: root,\n executablePath: path.join(root, `${DESKTOP_APP_NAME}.exe`),\n metadataPath: path.join(root, DESKTOP_METADATA_FILE),\n };\n }\n const appPath = path.join(root, `${DESKTOP_APP_NAME}.AppImage`);\n return {\n installRoot: root,\n appPath,\n executablePath: appPath,\n metadataPath: path.join(root, DESKTOP_METADATA_FILE),\n };\n}\n\nfunction normalizeAssetName(name: string): string {\n return name.toLowerCase().replaceAll(\"_\", \"-\").replaceAll(\" \", \"-\");\n}\n\nfunction scoreDesktopAsset(asset: GithubReleaseAsset, target: DesktopAssetTarget): number {\n const normalized = normalizeAssetName(asset.name);\n const expectedExtension = target.extension.toLowerCase();\n if (!normalized.endsWith(expectedExtension.toLowerCase())) return -1;\n if (normalized.includes(\"blockmap\") || normalized.includes(\"shasum\")) return -1;\n\n let score = 1;\n if (normalized.includes(\"rudder\")) score += 2;\n if (normalized.includes(target.platform)) score += 4;\n if (normalized.includes(\"portable\")) score += 6;\n if (target.platform === \"macos\" && (normalized.includes(\"macos\") || normalized.includes(\"darwin\") || normalized.includes(\"mac-\"))) {\n score += 4;\n }\n if (target.platform === \"windows\" && (normalized.includes(\"windows\") || normalized.includes(\"win\"))) {\n score += 4;\n }\n if (target.arch === \"arm64\" && normalized.includes(\"arm64\")) score += 4;\n if (target.arch === \"x64\" && (normalized.includes(\"x64\") || normalized.includes(\"amd64\"))) score += 4;\n\n if (target.platform === \"macos\" && target.arch === \"x64\" && normalized.includes(\"arm64\")) score -= 10;\n if (target.arch === \"arm64\" && normalized.includes(\"x64\")) score -= 10;\n\n return score;\n}\n\nexport function selectDesktopAsset(\n assets: GithubReleaseAsset[],\n target: DesktopAssetTarget,\n): GithubReleaseAsset | null {\n const scored = assets\n .map((asset) => ({ asset, score: scoreDesktopAsset(asset, target) }))\n .filter((item) => item.score >= 0)\n .sort((a, b) => b.score - a.score || a.asset.name.localeCompare(b.asset.name));\n\n if (scored.length === 0) return null;\n\n const best = scored[0];\n if (!best) return null;\n\n const equallyGood = scored.filter((item) => item.score === best.score);\n if (equallyGood.length === 1) return best.asset;\n\n const exactArch = equallyGood.find((item) => normalizeAssetName(item.asset.name).includes(target.arch));\n return exactArch?.asset ?? best.asset;\n}\n\nexport function selectChecksumAsset(assets: GithubReleaseAsset[]): GithubReleaseAsset | null {\n return assets.find((asset) => asset.name.toLowerCase() === DESKTOP_CHECKSUM_ASSET_NAME.toLowerCase()) ?? null;\n}\n\nfunction githubApiHeaders(): HeadersInit {\n return {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"rudder-cli-installer\",\n };\n}\n\nasync function fetchGithubRelease(repo: string, tag: string): Promise<GithubRelease> {\n const endpoint =\n tag === \"latest\"\n ? `https://api.github.com/repos/${repo}/releases/latest`\n : `https://api.github.com/repos/${repo}/releases/tags/${encodeURIComponent(tag)}`;\n const response = await fetch(endpoint, { headers: githubApiHeaders() });\n if (!response.ok) {\n throw new Error(`GitHub Release ${tag} was not found in ${repo} (${response.status}).`);\n }\n return (await response.json()) as GithubRelease;\n}\n\nexport function resolveDesktopReleaseVersion(tag: string): string | null {\n if (!tag || tag === \"latest\") return null;\n\n const name = tag.split(\"/\").pop() ?? tag;\n if (!name.startsWith(\"v\")) return null;\n\n const version = name.slice(1);\n if (STABLE_SEMVER_RE.test(version) || CANARY_SEMVER_RE.test(version)) return version;\n\n return null;\n}\n\nexport function resolveDesktopAssetName(version: string, target: DesktopAssetTarget): string {\n if (target.platform === \"macos\") return `${DESKTOP_APP_NAME}-${version}-macos-${target.arch}-portable.zip`;\n if (target.platform === \"windows\") return `${DESKTOP_APP_NAME}-${version}-windows-x64-portable.zip`;\n return `${DESKTOP_APP_NAME}-${version}-linux-x64.AppImage`;\n}\n\nfunction encodeReleaseTagForDownloadUrl(tag: string): string {\n return tag.split(\"/\").map((segment) => encodeURIComponent(segment)).join(\"/\");\n}\n\nexport function buildGithubReleaseAssetDownloadUrl(repo: string, tag: string, assetName: string): string {\n const encodedTag = encodeReleaseTagForDownloadUrl(tag);\n return `https://github.com/${repo}/releases/download/${encodedTag}/${encodeURIComponent(assetName)}`;\n}\n\nfunction buildGithubReleaseAsset(repo: string, tag: string, assetName: string): GithubReleaseAsset {\n return {\n name: assetName,\n browser_download_url: buildGithubReleaseAssetDownloadUrl(repo, tag, assetName),\n };\n}\n\nfunction uniqueAssetDownloadUrls(asset: GithubReleaseAsset): string[] {\n const urls = [asset.url, asset.browser_download_url].filter((url): url is string => Boolean(url));\n return Array.from(new Set(urls));\n}\n\nfunction downloadHeadersForAssetUrl(asset: GithubReleaseAsset, url: string): HeadersInit {\n return {\n Accept: url === asset.url ? GITHUB_ASSET_DOWNLOAD_ACCEPT : \"*/*\",\n \"User-Agent\": \"rudder-cli-installer\",\n };\n}\n\nfunction formatFetchError(error: unknown): string {\n if (!(error instanceof Error)) return String(error);\n\n const cause = (error as { cause?: unknown }).cause;\n if (cause instanceof Error) {\n const code = (cause as { code?: unknown }).code;\n const suffix = typeof code === \"string\" ? ` [${code}]` : \"\";\n return `${error.message}: ${cause.message}${suffix}`;\n }\n\n return error.message;\n}\n\nfunction contentLengthFromHeaders(headers: Headers): number | null {\n const raw = headers.get(\"content-length\");\n if (!raw) return null;\n const value = Number(raw);\n return Number.isFinite(value) && value > 0 ? value : null;\n}\n\nexport async function downloadAsset(\n asset: GithubReleaseAsset,\n outputDir: string,\n progressFactory: ProgressReporterFactory = createByteProgress,\n): Promise<string> {\n mkdirSync(outputDir, { recursive: true });\n const outputPath = path.join(outputDir, path.basename(asset.name));\n\n let response: Response | null = null;\n const failures: string[] = [];\n for (const url of uniqueAssetDownloadUrls(asset)) {\n try {\n const candidate = await fetch(url, {\n headers: downloadHeadersForAssetUrl(asset, url),\n });\n if (candidate.ok && candidate.body) {\n response = candidate;\n break;\n }\n failures.push(`Failed to download ${asset.name} from ${url} (${candidate.status}).`);\n } catch (error) {\n failures.push(`Failed to download ${asset.name} from ${url}: ${formatFetchError(error)}.`);\n }\n }\n\n if (!response) {\n throw new Error(failures.join(\"\\n\"));\n }\n\n const totalBytes = contentLengthFromHeaders(response.headers);\n const progress = progressFactory(`Downloading ${asset.name}`);\n let receivedBytes = 0;\n const monitor = new Transform({\n transform(chunk: Buffer | string, _encoding, callback) {\n receivedBytes += typeof chunk === \"string\" ? Buffer.byteLength(chunk) : chunk.length;\n progress.update(receivedBytes, totalBytes);\n callback(null, chunk);\n },\n });\n\n progress.start(totalBytes);\n try {\n await pipeline(Readable.fromWeb(response.body as never), monitor, createWriteStream(outputPath));\n progress.finish(receivedBytes, totalBytes);\n } catch (error) {\n progress.fail();\n throw error;\n }\n return outputPath;\n}\n\nfunction checksumForFile(filePath: string): string {\n const hash = createHash(\"sha256\");\n hash.update(readFileSync(filePath));\n return hash.digest(\"hex\");\n}\n\nexport function parseChecksumFile(contents: string): Map<string, string> {\n const checksums = new Map<string, string>();\n for (const line of contents.split(/\\r?\\n/)) {\n const match = line.match(/^([a-fA-F0-9]{64})\\s+\\*?(.+)$/);\n if (!match) continue;\n checksums.set(match[2].trim(), match[1].toLowerCase());\n }\n return checksums;\n}\n\nexport function resolveAssetChecksum(checksums: Map<string, string>, assetName: string): string {\n const expected = checksums.get(path.basename(assetName));\n if (!expected) {\n throw new Error(`Desktop release checksums do not include ${path.basename(assetName)}.`);\n }\n return expected;\n}\n\nexport function assertChecksumMatch(filePath: string, expected: string): string {\n const actual = checksumForFile(filePath);\n if (actual !== expected.toLowerCase()) {\n throw new Error(`Checksum mismatch for ${path.basename(filePath)}.`);\n }\n return actual;\n}\n\nexport async function downloadChecksums(\n checksumAsset: GithubReleaseAsset | null,\n outputDir: string,\n progressFactory: ProgressReporterFactory = createByteProgress,\n): Promise<Map<string, string>> {\n if (!checksumAsset) {\n throw new Error(\"Desktop release is missing SHASUMS256.txt.\");\n }\n const checksumPath = await downloadAsset(checksumAsset, outputDir, progressFactory);\n return parseChecksumFile(readFileSync(checksumPath, \"utf8\"));\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await access(targetPath, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction runChecked(command: string, args: string[], options: { cwd?: string; shell?: boolean } = {}): void {\n const result = spawnSync(command, args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n ...options,\n });\n if (result.status === 0) return;\n\n const output = [result.stdout, result.stderr]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n throw new Error(`${command} ${args.join(\" \")} failed${output ? `: ${output}` : \"\"}`);\n}\n\nfunction formatCommandFailure(command: string, args: string[], stdout: unknown, stderr: unknown): string {\n const output = [stdout, stderr]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n return `${command} ${args.join(\" \")} failed${output ? `: ${output}` : \"\"}`;\n}\n\nfunction powershellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nexport function buildWindowsZipExtractCommand(zipPath: string, outputDir: string): { command: string; args: string[] } {\n return { command: \"tar.exe\", args: [\"-xf\", zipPath, \"-C\", outputDir] };\n}\n\nexport function buildWindowsRobocopyMirrorCommand(sourcePath: string, destinationPath: string): { command: string; args: string[] } {\n return {\n command: \"robocopy.exe\",\n args: [sourcePath, destinationPath, \"/MIR\", \"/R:2\", \"/W:1\", \"/NFL\", \"/NDL\", \"/NJH\", \"/NJS\", \"/NP\"],\n };\n}\n\nexport function isSuccessfulRobocopyExitCode(status: number | null): boolean {\n return typeof status === \"number\" && status >= 0 && status <= 7;\n}\n\nasync function extractZip(zipPath: string, outputDir: string, target: DesktopAssetTarget): Promise<void> {\n await rm(outputDir, { recursive: true, force: true });\n await mkdir(outputDir, { recursive: true });\n\n if (target.platform === \"macos\") {\n runChecked(\"ditto\", [\"-x\", \"-k\", zipPath, outputDir]);\n return;\n }\n\n if (target.platform === \"windows\") {\n const command = buildWindowsZipExtractCommand(zipPath, outputDir);\n runChecked(command.command, command.args);\n return;\n }\n\n throw new Error(`Zip assets are not supported for ${target.platform}.`);\n}\n\nasync function findPath(\n root: string,\n predicate: (filePath: string, isDirectory: boolean) => boolean,\n maxDepth = 5,\n): Promise<string | null> {\n async function visit(dir: string, depth: number): Promise<string | null> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (predicate(fullPath, entry.isDirectory())) return fullPath;\n if (entry.isDirectory() && depth < maxDepth) {\n const nested = await visit(fullPath, depth + 1);\n if (nested) return nested;\n }\n }\n return null;\n }\n\n return await visit(root, 0);\n}\n\nasync function findMacApp(extractDir: string): Promise<string> {\n const direct = path.join(extractDir, `${DESKTOP_APP_NAME}.app`);\n if (await pathExists(direct)) return direct;\n const found = await findPath(extractDir, (filePath, isDirectory) =>\n isDirectory && path.basename(filePath) === `${DESKTOP_APP_NAME}.app`);\n if (!found) throw new Error(`Portable macOS archive did not contain ${DESKTOP_APP_NAME}.app.`);\n return found;\n}\n\nasync function findWindowsAppDir(extractDir: string): Promise<string> {\n const direct = path.join(extractDir, `${DESKTOP_APP_NAME}.exe`);\n if (await pathExists(direct)) return extractDir;\n const executable = await findPath(extractDir, (filePath, isDirectory) =>\n !isDirectory && path.basename(filePath).toLowerCase() === `${DESKTOP_APP_NAME.toLowerCase()}.exe`);\n if (!executable) throw new Error(`Portable Windows archive did not contain ${DESKTOP_APP_NAME}.exe.`);\n return path.dirname(executable);\n}\n\nasync function readInstallMetadata(metadataPath: string): Promise<DesktopInstallMetadata | null> {\n try {\n const parsed = JSON.parse(await readFile(metadataPath, \"utf8\")) as DesktopInstallMetadata;\n if (parsed.version !== 1) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport function isInstalledDesktopCurrent(\n metadata: DesktopInstallMetadata | null,\n releaseTag: string,\n assetName: string,\n assetChecksum: string,\n): boolean {\n return Boolean(\n metadata &&\n metadata.releaseTag === releaseTag &&\n metadata.assetName === assetName &&\n metadata.assetChecksum === assetChecksum,\n );\n}\n\nexport function buildForceQuitCommand(target: DesktopAssetTarget): { command: string; args: string[] } {\n if (target.platform === \"windows\") return { command: \"taskkill.exe\", args: [\"/IM\", `${DESKTOP_APP_NAME}.exe`, \"/T\", \"/F\"] };\n return { command: \"pkill\", args: [\"-x\", DESKTOP_APP_NAME] };\n}\n\nfunction forceQuitDesktopProcesses(target: DesktopAssetTarget): void {\n const command = buildForceQuitCommand(target);\n spawnSync(command.command, command.args, { stdio: \"ignore\" });\n}\n\nfunction isRunningInsideDesktopExecutable(): boolean {\n return path.basename(process.execPath).toLowerCase().startsWith(DESKTOP_APP_NAME.toLowerCase());\n}\n\nasync function waitForUpdateQuitResponse(responsePath: string, timeoutMs = 8_000): Promise<UpdateQuitResponse | null> {\n const startedAt = Date.now();\n while (Date.now() - startedAt < timeoutMs) {\n if (await pathExists(responsePath)) {\n return JSON.parse(await readFile(responsePath, \"utf8\")) as UpdateQuitResponse;\n }\n await delay(200);\n }\n return null;\n}\n\nasync function requestDesktopQuit(executablePath: string, target: DesktopAssetTarget): Promise<UpdateQuitResponse | null> {\n if (!(await pathExists(executablePath))) return { ok: true, status: \"not_running\" };\n const responsePath = path.join(tmpdir(), `rudder-update-quit-${process.pid}-${Date.now()}.json`);\n const result = spawnSync(executablePath, [`${DESKTOP_UPDATE_QUIT_ARG}=${responsePath}`], {\n stdio: \"ignore\",\n timeout: 5_000,\n });\n if (result.error && target.platform === \"windows\") {\n return null;\n }\n\n try {\n return await waitForUpdateQuitResponse(responsePath);\n } finally {\n await rm(responsePath, { force: true });\n }\n}\n\nasync function removePathWithRetry(targetPath: string, attempts = 5): Promise<boolean> {\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n try {\n await rm(targetPath, { recursive: true, force: true });\n if (!(await pathExists(targetPath))) return true;\n } catch {\n // Retry below; Windows can keep files locked briefly after process exit.\n }\n await delay(500);\n }\n return false;\n}\n\nasync function prepareForDesktopReplace(\n paths: DesktopInstallPaths,\n target: DesktopAssetTarget,\n options: { waitForActiveRuns?: boolean; activeRunPollIntervalMs?: number } = {},\n): Promise<void> {\n const hasManagedExecutable = await pathExists(paths.executablePath);\n if (hasManagedExecutable) {\n let quitResponse = await requestDesktopQuit(paths.executablePath, target);\n while (quitResponse && !quitResponse.ok && quitResponse.status === \"active_runs\" && options.waitForActiveRuns) {\n p.log.warn(\n `Rudder Desktop has ${quitResponse.totalRuns} active run${quitResponse.totalRuns === 1 ? \"\" : \"s\"}; waiting before replacing Desktop.`,\n );\n await delay(options.activeRunPollIntervalMs ?? 15_000);\n quitResponse = await requestDesktopQuit(paths.executablePath, target);\n }\n if (quitResponse && !quitResponse.ok && quitResponse.status === \"active_runs\") {\n throw new Error(\n `Rudder Desktop has ${quitResponse.totalRuns} active run${quitResponse.totalRuns === 1 ? \"\" : \"s\"}. Stop active work, then rerun start.`,\n );\n }\n await delay(1_000);\n } else if (!isRunningInsideDesktopExecutable()) {\n forceQuitDesktopProcesses(target);\n }\n\n const replacePath = target.platform === \"windows\" ? paths.installRoot : paths.appPath;\n if (await removePathWithRetry(replacePath)) return;\n\n forceQuitDesktopProcesses(target);\n await delay(1_000);\n if (await removePathWithRetry(replacePath, 6)) return;\n\n throw new Error(`Failed to replace existing Rudder Desktop at ${replacePath}. Close Rudder and rerun start.`);\n}\n\nasync function installPortableDesktop(\n installerPath: string,\n paths: DesktopInstallPaths,\n target: DesktopAssetTarget,\n): Promise<void> {\n await mkdir(paths.installRoot, { recursive: true });\n\n if (target.platform === \"linux\") {\n await copyFile(installerPath, paths.appPath);\n await chmod(paths.appPath, 0o755);\n return;\n }\n\n const extractDir = await mkdtemp(path.join(tmpdir(), \"rudder-desktop-extract.\"));\n try {\n await extractZip(installerPath, extractDir, target);\n if (target.platform === \"macos\") {\n const appSource = await findMacApp(extractDir);\n await copyPortableAppBundle(appSource, paths.appPath);\n return;\n }\n\n const appSource = await findWindowsAppDir(extractDir);\n await mkdir(path.dirname(paths.installRoot), { recursive: true });\n await copyPortableAppBundle(appSource, paths.installRoot);\n } finally {\n await rm(extractDir, { recursive: true, force: true });\n }\n}\n\nexport async function copyPortableAppBundle(sourcePath: string, destinationPath: string): Promise<void> {\n if (process.platform === \"win32\") {\n await mkdir(destinationPath, { recursive: true });\n const command = buildWindowsRobocopyMirrorCommand(sourcePath, destinationPath);\n const result = spawnSync(command.command, command.args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n if (isSuccessfulRobocopyExitCode(result.status)) return;\n throw new Error(formatCommandFailure(command.command, command.args, result.stdout, result.stderr));\n }\n\n await cp(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });\n}\n\nasync function removeMacQuarantine(paths: DesktopInstallPaths, target: DesktopAssetTarget): Promise<void> {\n if (target.platform !== \"macos\") return;\n const result = spawnSync(\"xattr\", [\"-dr\", \"com.apple.quarantine\", paths.appPath], { stdio: \"ignore\" });\n if (result.status !== 0) {\n p.log.warn(`Could not remove macOS quarantine attributes from ${paths.appPath}.`);\n }\n}\n\nfunction quoteDesktopExec(value: string): string {\n return `\"${value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"\\\"\", \"\\\\\\\"\")}\"`;\n}\n\nexport function buildLinuxDesktopEntry(executablePath: string): string {\n return [\n \"[Desktop Entry]\",\n \"Type=Application\",\n \"Name=Rudder\",\n `Exec=${quoteDesktopExec(executablePath)}`,\n \"Terminal=false\",\n \"Categories=Development;\",\n \"\",\n ].join(\"\\n\");\n}\n\nasync function writeLinuxLaunchers(paths: DesktopInstallPaths): Promise<void> {\n const desktopDir = path.join(homedir(), \".local\", \"share\", \"applications\");\n await mkdir(desktopDir, { recursive: true });\n await writeFile(path.join(desktopDir, \"rudder.desktop\"), buildLinuxDesktopEntry(paths.executablePath), \"utf8\");\n\n const binDir = path.join(homedir(), \".local\", \"bin\");\n await mkdir(binDir, { recursive: true });\n const wrapperPath = path.join(binDir, \"rudder-desktop\");\n const escaped = paths.executablePath.replaceAll(\"'\", \"'\\\"'\\\"'\");\n await writeFile(wrapperPath, `#!/bin/sh\\nexec '${escaped}' \"$@\"\\n`, \"utf8\");\n await chmod(wrapperPath, 0o755);\n}\n\nfunction buildWindowsShortcutScript(executablePath: string): string {\n const appData = process.env.APPDATA?.trim() || path.join(homedir(), \"AppData\", \"Roaming\");\n const shortcutPath = path.join(appData, \"Microsoft\", \"Windows\", \"Start Menu\", \"Programs\", \"Rudder.lnk\");\n return [\n \"$shell = New-Object -ComObject WScript.Shell\",\n `$shortcut = $shell.CreateShortcut(${powershellQuote(shortcutPath)})`,\n `$shortcut.TargetPath = ${powershellQuote(executablePath)}`,\n `$shortcut.WorkingDirectory = ${powershellQuote(path.dirname(executablePath))}`,\n \"$shortcut.Save()\",\n ].join(\"; \");\n}\n\nasync function createPlatformLaunchers(paths: DesktopInstallPaths, target: DesktopAssetTarget): Promise<void> {\n if (target.platform === \"linux\") {\n await writeLinuxLaunchers(paths);\n return;\n }\n if (target.platform === \"windows\") {\n const result = spawnSync(\"powershell.exe\", [\n \"-NoProfile\",\n \"-ExecutionPolicy\",\n \"Bypass\",\n \"-Command\",\n buildWindowsShortcutScript(paths.executablePath),\n ], { stdio: \"ignore\" });\n if (result.status !== 0) p.log.warn(\"Could not create the Windows Start Menu shortcut.\");\n }\n}\n\nfunction launchDesktop(paths: DesktopInstallPaths, target: DesktopAssetTarget): void {\n if (target.platform === \"macos\") {\n spawn(\"open\", [paths.appPath], { detached: true, stdio: \"ignore\" }).unref();\n return;\n }\n if (target.platform === \"windows\") {\n spawn(\"cmd.exe\", [\"/c\", \"start\", \"\", paths.executablePath], { detached: true, stdio: \"ignore\" }).unref();\n return;\n }\n spawn(paths.executablePath, [], { detached: true, stdio: \"ignore\" }).unref();\n}\n\nasync function writeInstallMetadata(\n paths: DesktopInstallPaths,\n releaseTag: string,\n assetName: string,\n assetChecksum: string,\n): Promise<void> {\n mkdirSync(path.dirname(paths.metadataPath), { recursive: true });\n const metadata: DesktopInstallMetadata = {\n version: 1,\n releaseTag,\n assetName,\n assetChecksum,\n installedAt: new Date().toISOString(),\n };\n mkdirSync(paths.installRoot, { recursive: true });\n await writeFile(paths.metadataPath, `${JSON.stringify(metadata, null, 2)}\\n`, \"utf8\");\n}\n\nasync function runStartPhase<T>(\n message: string,\n successMessage: string,\n task: () => Promise<T> | T,\n progressPhase?: DesktopUpdateProgressPhase | null,\n): Promise<T> {\n if (progressPhase) {\n writeDesktopProgress({ phase: progressPhase, message });\n }\n const spinner = p.spinner();\n spinner.start(message);\n try {\n const result = await task();\n spinner.stop(successMessage);\n if (progressPhase) {\n writeDesktopProgress({ phase: progressPhase, message: successMessage });\n }\n return result;\n } catch (error) {\n spinner.stop(pc.red(`${message} failed.`));\n if (progressPhase) {\n writeDesktopProgress({\n phase: \"failed\",\n message: `${message} failed.`,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n throw error;\n }\n}\n\nexport async function startCommand(opts: StartCommandOptions): Promise<void> {\n const installCli = opts.cli !== false;\n const installDesktop = opts.desktop !== false;\n const installRuntime = opts.runtime !== false;\n const repo = opts.repo?.trim() || DEFAULT_DESKTOP_RELEASE_REPO;\n const version = opts.targetVersion?.trim() || opts.version?.trim() || resolveCurrentCliVersion();\n const dryRun = opts.dryRun === true;\n const desktopProgressJson = opts.desktopProgressJson === true;\n\n if (desktopProgressJson) {\n process.stdout.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code !== \"EPIPE\") throw error;\n });\n }\n\n if (!installCli && !installDesktop && !installRuntime) {\n throw new Error(\"Nothing to start. Remove --no-cli, --no-runtime, or --no-desktop.\");\n }\n\n p.intro(pc.bgCyan(pc.black(\" rudder start \")));\n\n if (opts.versionCheck !== false) {\n const updateNotice = await getCliUpdateNotice(version);\n if (updateNotice) p.log.warn(updateNotice);\n }\n\n if (installRuntime) {\n p.log.step(\"Preparing Rudder runtime\");\n if (dryRun) {\n p.log.message(`[dry-run] Would install or reuse ${pc.cyan(`@rudderhq/server@${version}`)} in the Rudder runtime cache.`);\n } else {\n const spinner = p.spinner();\n spinner.start(\"Installing or reusing Rudder runtime...\");\n try {\n const runtime = await ensureRuntimeInstalled({ version });\n spinner.stop(\n runtime.status === \"hit\"\n ? `Rudder runtime cache hit at ${pc.cyan(runtime.cacheDir)}.`\n : `Rudder runtime installed at ${pc.cyan(runtime.cacheDir)}.`,\n );\n } catch (error) {\n spinner.stop(pc.red(\"Rudder runtime installation failed.\"));\n if (error instanceof RuntimeInstallError && error.output) {\n p.log.message(pc.dim(error.output));\n }\n throw error;\n }\n }\n }\n\n if (installCli) {\n const installSpec = resolveCliInstallSpec(version);\n const command = `npm install --global ${installSpec}`;\n const installedVersion = getGlobalInstalledPackageVersion(CLI_NPM_PACKAGE_NAME);\n p.log.step(\"Preparing persistent CLI\");\n if (isPersistentCliVersionCurrent(version, installedVersion)) {\n p.log.success(`${pc.cyan(\"rudder\")} CLI ${version} is already installed.`);\n } else if (dryRun) {\n p.log.message(`[dry-run] ${command}`);\n } else {\n p.log.message(pc.dim(`Running: ${command}`));\n const spinner = p.spinner();\n spinner.start(\"Installing persistent CLI...\");\n let result: ReturnType<typeof installPersistentCli>;\n try {\n result = installPersistentCli({ installSpec });\n } catch (error) {\n spinner.stop(pc.red(\"Persistent CLI installation failed.\"));\n throw error;\n }\n if (!result.ok) {\n spinner.stop(pc.red(\"Persistent CLI installation failed.\"));\n if (result.output) p.log.message(pc.dim(result.output));\n throw new Error(`Persistent CLI installation failed. Re-run manually: ${result.command}`);\n }\n spinner.stop(`${pc.cyan(\"rudder\")} CLI installed.`);\n }\n }\n\n if (installDesktop) {\n const target = resolveDesktopAssetTarget();\n const tag = resolveDesktopReleaseTag(version);\n const installRoot = opts.desktopInstallDir\n ? path.resolve(opts.desktopInstallDir)\n : resolveDefaultDesktopInstallRoot(target);\n const installPaths = resolveDesktopInstallPaths(target, installRoot);\n const outputDir = opts.outputDir\n ? path.resolve(opts.outputDir)\n : await mkdtemp(path.join(tmpdir(), \"rudder-desktop-installer.\"));\n\n p.log.step(\"Installing desktop app\");\n p.log.message(`Release: ${pc.cyan(`${repo}@${tag}`)}`);\n p.log.message(`Target: ${pc.cyan(`${target.platform}/${target.arch}`)}`);\n p.log.message(`Install: ${pc.cyan(installPaths.appPath)}`);\n\n if (dryRun) {\n p.log.message(`[dry-run] Would resolve, download, verify, install, and ${opts.open === false ? \"not launch\" : \"launch\"} Rudder Desktop.`);\n p.outro(pc.green(\"Dry run complete.\"));\n return;\n }\n\n const directReleaseVersion = resolveDesktopReleaseVersion(tag);\n const progressFactory: ProgressReporterFactory = desktopProgressJson\n ? createDesktopProgressFactory()\n : createByteProgress;\n let release: GithubRelease | null = null;\n try {\n release = await runStartPhase(\n \"Resolving Desktop release...\",\n \"Desktop release resolved.\",\n () => fetchGithubRelease(repo, tag),\n desktopProgressJson ? \"resolving_release\" : null,\n );\n } catch (error) {\n if (!directReleaseVersion) throw error;\n p.log.warn(\n `Desktop release metadata could not be resolved; falling back to deterministic download URLs. ${formatFetchError(error)}`,\n );\n }\n\n const releaseTag = release?.tag_name ?? (directReleaseVersion ? tag : null);\n if (!releaseTag) {\n throw new Error(`Unable to resolve Rudder Desktop release tag for ${repo}@${tag}.`);\n }\n\n const asset = selectDesktopAsset(release?.assets ?? [], target)\n ?? (\n directReleaseVersion\n ? buildGithubReleaseAsset(repo, tag, resolveDesktopAssetName(directReleaseVersion, target))\n : null\n );\n if (!asset) {\n throw new Error(`No Rudder Desktop portable asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);\n }\n\n const checksumAsset = selectChecksumAsset(release?.assets ?? [])\n ?? (\n directReleaseVersion\n ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME)\n : null\n );\n const checksums = await downloadChecksums(checksumAsset, outputDir, progressFactory);\n const expectedChecksum = resolveAssetChecksum(checksums, asset.name);\n\n const metadata = await readInstallMetadata(installPaths.metadataPath);\n if (\n isInstalledDesktopCurrent(metadata, releaseTag, asset.name, expectedChecksum) &&\n await pathExists(installPaths.executablePath)\n ) {\n p.log.success(`Rudder Desktop is already installed at ${pc.cyan(installPaths.appPath)}.`);\n await runStartPhase(\n \"Refreshing Desktop launchers...\",\n \"Desktop launchers ready.\",\n async () => {\n await removeMacQuarantine(installPaths, target);\n await createPlatformLaunchers(installPaths, target);\n },\n desktopProgressJson ? \"preparing_restart\" : null,\n );\n } else {\n const installerPath = await downloadAsset(asset, outputDir, progressFactory);\n const checksum = await runStartPhase(\n \"Verifying Desktop checksum...\",\n `Verified ${pc.cyan(path.basename(installerPath))}.`,\n () => assertChecksumMatch(installerPath, expectedChecksum),\n desktopProgressJson ? \"verifying_checksum\" : null,\n );\n\n if (desktopProgressJson && opts.desktopWaitForApply === true) {\n writeDesktopProgress({\n phase: \"ready_to_install\",\n message: \"Desktop update is downloaded and verified.\",\n percent: 100,\n });\n await waitForDesktopApplySignal();\n writeDesktopProgress({\n phase: \"preparing_restart\",\n message: \"Applying Desktop update...\",\n });\n }\n\n await runStartPhase(\n \"Replacing existing Rudder Desktop if needed...\",\n \"Existing Desktop install is ready for replacement.\",\n () => prepareForDesktopReplace(installPaths, target, { waitForActiveRuns: opts.waitForActiveRuns === true }),\n desktopProgressJson ? (opts.waitForActiveRuns === true ? \"waiting_for_active_runs\" : \"preparing_restart\") : null,\n );\n await runStartPhase(\n \"Installing portable Desktop app...\",\n `Installed Rudder Desktop to ${pc.cyan(installPaths.appPath)}.`,\n () => installPortableDesktop(installerPath, installPaths, target),\n desktopProgressJson ? \"preparing_restart\" : null,\n );\n await runStartPhase(\n \"Preparing Desktop launchers...\",\n \"Desktop launchers ready.\",\n async () => {\n await removeMacQuarantine(installPaths, target);\n await createPlatformLaunchers(installPaths, target);\n },\n desktopProgressJson ? \"preparing_restart\" : null,\n );\n await writeInstallMetadata(installPaths, releaseTag, asset.name, checksum);\n }\n\n if (opts.open !== false) {\n await runStartPhase(\n \"Launching Rudder Desktop...\",\n \"Rudder Desktop launched.\",\n () => launchDesktop(installPaths, target),\n desktopProgressJson ? \"closing\" : null,\n );\n }\n }\n\n p.outro(pc.green(\"Rudder start complete.\"));\n}\n", "import type { Writable } from \"node:stream\";\n\nexport interface ByteProgressState {\n receivedBytes: number;\n totalBytes?: number | null;\n width?: number;\n}\n\nexport interface ByteProgressOptions {\n stream?: Writable;\n isTty?: boolean;\n width?: number;\n minIntervalMs?: number;\n now?: () => number;\n}\n\nexport interface ByteProgressReporter {\n start(totalBytes?: number | null): void;\n update(receivedBytes: number, totalBytes?: number | null): void;\n finish(receivedBytes?: number, totalBytes?: number | null): void;\n fail(): void;\n}\n\nconst BYTE_UNITS = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n\nexport function formatBytes(bytes: number): string {\n let value = Math.max(0, bytes);\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < BYTE_UNITS.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n if (unitIndex === 0) return `${Math.round(value)} ${BYTE_UNITS[unitIndex]}`;\n return `${value.toFixed(1)} ${BYTE_UNITS[unitIndex]}`;\n}\n\nfunction normalizeTotalBytes(totalBytes: number | null | undefined): number | null {\n if (typeof totalBytes !== \"number\" || !Number.isFinite(totalBytes) || totalBytes <= 0) {\n return null;\n }\n return totalBytes;\n}\n\nexport function formatByteProgress(state: ByteProgressState): string {\n const width = Math.max(4, state.width ?? 20);\n const receivedBytes = Math.max(0, state.receivedBytes);\n const totalBytes = normalizeTotalBytes(state.totalBytes);\n\n if (totalBytes === null) {\n return `[downloaded ${formatBytes(receivedBytes)}]`;\n }\n\n const ratio = Math.max(0, Math.min(1, receivedBytes / totalBytes));\n const filled = Math.round(ratio * width);\n const percent = Math.floor(ratio * 100);\n return `[${\"#\".repeat(filled)}${\"-\".repeat(width - filled)}] ${percent}% ${formatBytes(receivedBytes)}/${formatBytes(totalBytes)}`;\n}\n\nfunction progressSummary(receivedBytes: number, totalBytes: number | null | undefined): string {\n const total = normalizeTotalBytes(totalBytes);\n if (total === null) return formatBytes(receivedBytes);\n return `${formatBytes(receivedBytes)}/${formatBytes(total)}`;\n}\n\nexport function createByteProgress(label: string, options: ByteProgressOptions = {}): ByteProgressReporter {\n const stream = options.stream ?? process.stdout;\n const isTty = options.isTty ?? Boolean((stream as Writable & { isTTY?: boolean }).isTTY);\n const width = options.width ?? 20;\n const minIntervalMs = options.minIntervalMs ?? 80;\n const now = options.now ?? (() => Date.now());\n\n let started = false;\n let finished = false;\n let lastRenderAt = 0;\n let lastLineLength = 0;\n let latestReceivedBytes = 0;\n let latestTotalBytes: number | null | undefined = null;\n\n function render(receivedBytes: number, totalBytes: number | null | undefined, force = false): void {\n if (finished) return;\n latestReceivedBytes = receivedBytes;\n latestTotalBytes = totalBytes;\n\n if (!isTty) return;\n\n const currentTime = now();\n const total = normalizeTotalBytes(totalBytes);\n const complete = total !== null && receivedBytes >= total;\n if (!force && currentTime - lastRenderAt < minIntervalMs && !complete) return;\n\n const line = `${label} ${formatByteProgress({ receivedBytes, totalBytes, width })}`;\n const padding = lastLineLength > line.length ? \" \".repeat(lastLineLength - line.length) : \"\";\n stream.write(`\\r${line}${padding}`);\n lastLineLength = line.length;\n lastRenderAt = currentTime;\n }\n\n function start(totalBytes?: number | null): void {\n if (started || finished) return;\n started = true;\n latestTotalBytes = totalBytes;\n if (isTty) {\n render(0, totalBytes, true);\n } else {\n stream.write(`${label}...\\n`);\n }\n }\n\n function update(receivedBytes: number, totalBytes?: number | null): void {\n if (!started) start(totalBytes);\n render(receivedBytes, totalBytes, false);\n }\n\n function finish(receivedBytes = latestReceivedBytes, totalBytes = latestTotalBytes): void {\n if (finished) return;\n if (!started) start(totalBytes);\n if (isTty) {\n render(receivedBytes, totalBytes, true);\n stream.write(\"\\n\");\n } else {\n stream.write(`${label} complete (${progressSummary(receivedBytes, totalBytes)}).\\n`);\n }\n finished = true;\n }\n\n function fail(): void {\n if (finished) return;\n if (isTty && started) {\n stream.write(\"\\n\");\n } else if (!isTty && started) {\n stream.write(`${label} failed.\\n`);\n }\n finished = true;\n }\n\n return {\n start,\n update,\n finish,\n fail,\n };\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { normalizeHostnameInput } from \"../config/hostnames.js\";\nimport { readConfig, resolveConfigPath, writeConfig } from \"../config/store.js\";\n\nexport async function addAllowedHostname(host: string, opts: { config?: string }): Promise<void> {\n const configPath = resolveConfigPath(opts.config);\n const config = readConfig(opts.config);\n\n if (!config) {\n p.log.error(`No config found at ${configPath}. Run ${pc.cyan(\"rudder onboard\")} first.`);\n return;\n }\n\n const normalized = normalizeHostnameInput(host);\n const current = new Set((config.server.allowedHostnames ?? []).map((value) => value.trim().toLowerCase()).filter(Boolean));\n const existed = current.has(normalized);\n current.add(normalized);\n\n config.server.allowedHostnames = Array.from(current).sort();\n config.$meta.updatedAt = new Date().toISOString();\n config.$meta.source = \"configure\";\n writeConfig(config, opts.config);\n\n if (existed) {\n p.log.info(`Hostname ${pc.cyan(normalized)} is already allowed.`);\n } else {\n p.log.success(`Added allowed hostname: ${pc.cyan(normalized)}`);\n p.log.message(\n pc.dim(\"Restart the Rudder server for this change to take effect.\"),\n );\n }\n\n if (!(config.server.deploymentMode === \"authenticated\" && config.server.exposure === \"private\")) {\n p.log.message(\n pc.dim(\"Note: allowed hostnames are enforced only in authenticated/private mode.\"),\n );\n }\n}\n\n", "import { setTimeout as delay } from \"node:timers/promises\";\nimport pc from \"picocolors\";\nimport type { Agent, HeartbeatRun, HeartbeatRunEvent, HeartbeatRunStatus } from \"@rudderhq/shared\";\nimport { getCLIAdapter } from \"../agent-runtimes/index.js\";\nimport { resolveCommandContext } from \"./client/common.js\";\n\nconst HEARTBEAT_SOURCES = [\"timer\", \"assignment\", \"on_demand\", \"automation\"] as const;\nconst HEARTBEAT_TRIGGERS = [\"manual\", \"ping\", \"callback\", \"system\"] as const;\nconst TERMINAL_STATUSES = new Set<HeartbeatRunStatus>([\"succeeded\", \"failed\", \"cancelled\", \"timed_out\"]);\nconst POLL_INTERVAL_MS = 200;\n\ntype HeartbeatSource = (typeof HEARTBEAT_SOURCES)[number];\ntype HeartbeatTrigger = (typeof HEARTBEAT_TRIGGERS)[number];\ntype InvokedHeartbeat = HeartbeatRun | { status: \"skipped\" };\ninterface HeartbeatRunEventRecord extends HeartbeatRunEvent {\n type?: string | null;\n}\n\ninterface HeartbeatRunOptions {\n config?: string;\n context?: string;\n profile?: string;\n agentId: string;\n apiBase?: string;\n apiKey?: string;\n source: string;\n trigger: string;\n timeoutMs: string;\n debug?: boolean;\n json?: boolean;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asErrorText(value: unknown): string {\n if (typeof value === \"string\") return value;\n const obj = asRecord(value);\n if (!obj) return \"\";\n const message =\n (typeof obj.message === \"string\" && obj.message) ||\n (typeof obj.error === \"string\" && obj.error) ||\n (typeof obj.code === \"string\" && obj.code) ||\n \"\";\n if (message) return message;\n try {\n return JSON.stringify(obj);\n } catch {\n return \"\";\n }\n}\n\ntype AdapterType = string;\n\nexport async function heartbeatRun(opts: HeartbeatRunOptions): Promise<void> {\n const debug = Boolean(opts.debug);\n const parsedTimeout = Number.parseInt(opts.timeoutMs, 10);\n const timeoutMs = Number.isFinite(parsedTimeout) ? parsedTimeout : 0;\n const source = HEARTBEAT_SOURCES.includes(opts.source as HeartbeatSource)\n ? (opts.source as HeartbeatSource)\n : \"on_demand\";\n const triggerDetail = HEARTBEAT_TRIGGERS.includes(opts.trigger as HeartbeatTrigger)\n ? (opts.trigger as HeartbeatTrigger)\n : \"manual\";\n\n const ctx = resolveCommandContext({\n config: opts.config,\n context: opts.context,\n profile: opts.profile,\n apiBase: opts.apiBase,\n apiKey: opts.apiKey,\n json: opts.json,\n });\n const api = ctx.api;\n\n const agent = await api.get<Agent>(`/api/agents/${opts.agentId}`);\n if (!agent || typeof agent !== \"object\" || !agent.id) {\n console.error(pc.red(`Agent not found: ${opts.agentId}`));\n return;\n }\n\n const invokeRes = await api.post<InvokedHeartbeat>(\n `/api/agents/${opts.agentId}/wakeup`,\n {\n source: source,\n triggerDetail: triggerDetail,\n },\n );\n if (!invokeRes) {\n console.error(pc.red(\"Failed to invoke heartbeat\"));\n return;\n }\n if ((invokeRes as { status?: string }).status === \"skipped\") {\n console.log(pc.yellow(\"Heartbeat invocation was skipped\"));\n return;\n }\n\n const run = invokeRes as HeartbeatRun;\n console.log(pc.cyan(`Invoked heartbeat run ${run.id} for agent ${agent.name} (${agent.id})`));\n\n const runId = run.id;\n let activeRunId: string | null = null;\n let lastEventSeq = 0;\n let logOffset = 0;\n let stdoutJsonBuffer = \"\";\n\n const printRawChunk = (stream: \"stdout\" | \"stderr\" | \"system\", chunk: string) => {\n if (stream === \"stdout\") process.stdout.write(pc.green(\"[stdout] \") + chunk);\n else if (stream === \"stderr\") process.stdout.write(pc.red(\"[stderr] \") + chunk);\n else process.stdout.write(pc.yellow(\"[system] \") + chunk);\n };\n\n const printAdapterInvoke = (payload: Record<string, unknown>) => {\n const agentRuntimeType = typeof payload.agentRuntimeType === \"string\" ? payload.agentRuntimeType : \"unknown\";\n const command = typeof payload.command === \"string\" ? payload.command : \"\";\n const cwd = typeof payload.cwd === \"string\" ? payload.cwd : \"\";\n const args =\n Array.isArray(payload.commandArgs) &&\n (payload.commandArgs as unknown[]).every((v) => typeof v === \"string\")\n ? (payload.commandArgs as string[])\n : [];\n const env =\n typeof payload.env === \"object\" && payload.env !== null && !Array.isArray(payload.env)\n ? (payload.env as Record<string, unknown>)\n : null;\n const prompt = typeof payload.prompt === \"string\" ? payload.prompt : \"\";\n const context =\n typeof payload.context === \"object\" && payload.context !== null && !Array.isArray(payload.context)\n ? (payload.context as Record<string, unknown>)\n : null;\n\n console.log(pc.cyan(`Adapter: ${agentRuntimeType}`));\n if (cwd) console.log(pc.cyan(`Working dir: ${cwd}`));\n if (command) {\n const rendered = args.length > 0 ? `${command} ${args.join(\" \")}` : command;\n console.log(pc.cyan(`Command: ${rendered}`));\n }\n if (env) {\n console.log(pc.cyan(\"Env:\"));\n console.log(pc.gray(JSON.stringify(env, null, 2)));\n }\n if (context) {\n console.log(pc.cyan(\"Context:\"));\n console.log(pc.gray(JSON.stringify(context, null, 2)));\n }\n if (prompt) {\n console.log(pc.cyan(\"Prompt:\"));\n console.log(prompt);\n }\n };\n\n const agentRuntimeType: AdapterType = agent.agentRuntimeType ?? \"claude_local\";\n const cliAdapter = getCLIAdapter(agentRuntimeType);\n\n const handleStreamChunk = (stream: \"stdout\" | \"stderr\" | \"system\", chunk: string) => {\n if (debug) {\n printRawChunk(stream, chunk);\n return;\n }\n\n if (stream !== \"stdout\") {\n printRawChunk(stream, chunk);\n return;\n }\n\n const combined = stdoutJsonBuffer + chunk;\n const lines = combined.split(/\\r?\\n/);\n stdoutJsonBuffer = lines.pop() ?? \"\";\n for (const line of lines) {\n cliAdapter.formatStdoutEvent(line, debug);\n }\n };\n\n const handleEvent = (event: HeartbeatRunEventRecord) => {\n const payload = normalizePayload(event.payload);\n if (event.runId !== runId) return;\n const eventType = typeof event.eventType === \"string\"\n ? event.eventType\n : typeof event.type === \"string\"\n ? event.type\n : \"\";\n\n if (eventType === \"heartbeat.run.status\") {\n const status = typeof payload.status === \"string\" ? payload.status : null;\n if (status) {\n console.log(pc.blue(`[status] ${status}`));\n }\n } else if (eventType === \"adapter.invoke\") {\n printAdapterInvoke(payload);\n } else if (eventType === \"heartbeat.run.log\") {\n const stream = typeof payload.stream === \"string\" ? payload.stream : \"system\";\n const chunk = typeof payload.chunk === \"string\" ? payload.chunk : \"\";\n if (!chunk) return;\n if (stream === \"stdout\" || stream === \"stderr\" || stream === \"system\") {\n handleStreamChunk(stream, chunk);\n }\n } else if (typeof event.message === \"string\") {\n console.log(pc.gray(`[event] ${eventType || \"heartbeat.run.event\"}: ${event.message}`));\n }\n\n lastEventSeq = Math.max(lastEventSeq, event.seq ?? 0);\n };\n\n activeRunId = runId;\n let finalStatus: string | null = null;\n let finalError: string | null = null;\n let finalRun: HeartbeatRun | null = null;\n\n const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : null;\n if (!activeRunId) {\n console.error(pc.red(\"Failed to capture heartbeat run id\"));\n return;\n }\n\n while (true) {\n const events = await api.get<HeartbeatRunEvent[]>(\n `/api/heartbeat-runs/${activeRunId}/events?afterSeq=${lastEventSeq}&limit=100`,\n );\n for (const event of Array.isArray(events) ? (events as HeartbeatRunEventRecord[]) : []) {\n handleEvent(event);\n }\n\n const runList = (await api.get<(HeartbeatRun | null)[]>(\n `/api/orgs/${agent.orgId}/heartbeat-runs?agentId=${agent.id}`,\n )) || [];\n const currentRun = runList.find((r) => r && r.id === activeRunId) ?? null;\n\n if (!currentRun) {\n console.error(pc.red(\"Heartbeat run disappeared\"));\n break;\n }\n\n const currentStatus = currentRun.status as HeartbeatRunStatus | undefined;\n if (currentStatus !== finalStatus && currentStatus) {\n finalStatus = currentStatus;\n console.log(pc.blue(`Status: ${currentStatus}`));\n }\n\n if (currentStatus && TERMINAL_STATUSES.has(currentStatus)) {\n finalStatus = currentRun.status;\n finalError = currentRun.error;\n finalRun = currentRun;\n break;\n }\n\n if (deadline && Date.now() >= deadline) {\n finalError = `CLI timed out after ${timeoutMs}ms`;\n finalStatus = \"timed_out\";\n console.error(pc.yellow(finalError));\n break;\n }\n\n const logResult = await api.get<{ content: string; endOffset?: number; nextOffset?: number }>(\n `/api/heartbeat-runs/${activeRunId}/log?offset=${logOffset}&limitBytes=16384`,\n { ignoreNotFound: true },\n );\n if (logResult && logResult.content) {\n for (const chunk of logResult.content.split(/\\r?\\n/)) {\n if (!chunk) continue;\n const parsed = safeParseLogLine(chunk);\n if (!parsed) continue;\n handleStreamChunk(parsed.stream, parsed.chunk);\n }\n if (typeof logResult.nextOffset === \"number\") {\n logOffset = logResult.nextOffset;\n } else if (typeof logResult.endOffset === \"number\") {\n logOffset = logResult.endOffset;\n } else if (logResult.content) {\n logOffset += Buffer.byteLength(logResult.content, \"utf8\");\n }\n }\n\n await delay(POLL_INTERVAL_MS);\n }\n\n if (finalStatus) {\n if (!debug && stdoutJsonBuffer.trim()) {\n cliAdapter.formatStdoutEvent(stdoutJsonBuffer, debug);\n stdoutJsonBuffer = \"\";\n }\n const label = `Run ${activeRunId} completed with status ${finalStatus}`;\n if (finalStatus === \"succeeded\") {\n console.log(pc.green(label));\n return;\n }\n\n console.log(pc.red(label));\n if (finalError) {\n console.log(pc.red(`Error: ${finalError}`));\n }\n if (finalRun) {\n const resultObj = asRecord(finalRun.resultJson);\n if (resultObj) {\n const subtype = typeof resultObj.subtype === \"string\" ? resultObj.subtype : \"\";\n const isError = resultObj.is_error === true;\n const errors = Array.isArray(resultObj.errors) ? resultObj.errors.map(asErrorText).filter(Boolean) : [];\n const resultText = typeof resultObj.result === \"string\" ? resultObj.result.trim() : \"\";\n if (subtype || isError || errors.length > 0 || resultText) {\n console.log(pc.red(\"Claude result details:\"));\n if (subtype) console.log(pc.red(` subtype: ${subtype}`));\n if (isError) console.log(pc.red(\" is_error: true\"));\n if (errors.length > 0) console.log(pc.red(` errors: ${errors.join(\" | \")}`));\n if (resultText) console.log(pc.red(` result: ${resultText}`));\n }\n }\n\n const stderrExcerpt = typeof finalRun.stderrExcerpt === \"string\" ? finalRun.stderrExcerpt.trim() : \"\";\n const stdoutExcerpt = typeof finalRun.stdoutExcerpt === \"string\" ? finalRun.stdoutExcerpt.trim() : \"\";\n if (stderrExcerpt) {\n console.log(pc.red(\"stderr excerpt:\"));\n console.log(stderrExcerpt);\n }\n if (stdoutExcerpt && (debug || !stderrExcerpt)) {\n console.log(pc.gray(\"stdout excerpt:\"));\n console.log(stdoutExcerpt);\n }\n }\n process.exitCode = 1;\n } else {\n process.exitCode = 1;\n console.log(pc.gray(\"Heartbeat stream ended without terminal status\"));\n }\n}\n\nfunction normalizePayload(payload: unknown): Record<string, unknown> {\n return typeof payload === \"object\" && payload !== null ? (payload as Record<string, unknown>) : {};\n}\n\nfunction safeParseLogLine(line: string): { stream: \"stdout\" | \"stderr\" | \"system\"; chunk: string } | null {\n try {\n const parsed = JSON.parse(line) as { stream?: unknown; chunk?: unknown };\n const stream =\n parsed.stream === \"stdout\" || parsed.stream === \"stderr\" || parsed.stream === \"system\"\n ? parsed.stream\n : \"system\";\n const chunk = typeof parsed.chunk === \"string\" ? parsed.chunk : \"\";\n\n if (!chunk) return null;\n return { stream, chunk };\n } catch {\n return null;\n }\n}\n", "export function printProcessStdoutEvent(raw: string, _debug: boolean): void {\n const line = raw.trim();\n if (line) console.log(line);\n}\n", "import type { CLIAgentRuntimeModule } from \"@rudderhq/agent-runtime-utils\";\nimport { printProcessStdoutEvent } from \"./format-event.js\";\n\nexport const processCLIAdapter: CLIAgentRuntimeModule = {\n type: \"process\",\n formatStdoutEvent: printProcessStdoutEvent,\n};\n", "export function printHttpStdoutEvent(raw: string, _debug: boolean): void {\n const line = raw.trim();\n if (line) console.log(line);\n}\n", "import type { CLIAgentRuntimeModule } from \"@rudderhq/agent-runtime-utils\";\nimport { printHttpStdoutEvent } from \"./format-event.js\";\n\nexport const httpCLIAdapter: CLIAgentRuntimeModule = {\n type: \"http\",\n formatStdoutEvent: printHttpStdoutEvent,\n};\n", "import type { CLIAgentRuntimeModule } from \"@rudderhq/agent-runtime-utils\";\nimport { processCLIAdapter } from \"./process/index.js\";\nimport { httpCLIAdapter } from \"./http/index.js\";\n\nconst localRuntimeTypes = [\n \"claude_local\",\n \"codex_local\",\n \"opencode_local\",\n \"pi_local\",\n \"cursor\",\n \"gemini_local\",\n \"openclaw_gateway\",\n];\n\nconst adaptersByType = new Map<string, CLIAgentRuntimeModule>([\n [processCLIAdapter.type, processCLIAdapter],\n [httpCLIAdapter.type, httpCLIAdapter],\n ...localRuntimeTypes.map((type): [string, CLIAgentRuntimeModule] => [\n type,\n { ...processCLIAdapter, type },\n ]),\n]);\n\nexport function getCLIAdapter(type: string): CLIAgentRuntimeModule {\n return adaptersByType.get(type) ?? processCLIAdapter;\n}\n", "import pc from \"picocolors\";\nimport type { Command } from \"commander\";\nimport { getStoredBoardCredential, loginBoardCli } from \"../../client/board-auth.js\";\nimport { buildCliCommandLabel } from \"../../client/command-label.js\";\nimport { readConfig } from \"../../config/store.js\";\nimport { readContext, resolveProfile, type ClientContextProfile } from \"../../client/context.js\";\nimport { ApiRequestError, RudderApiClient } from \"../../client/http.js\";\n\nexport interface BaseClientOptions {\n config?: string;\n dataDir?: string;\n context?: string;\n profile?: string;\n apiBase?: string;\n apiKey?: string;\n orgId?: string;\n companyId?: string;\n runId?: string;\n json?: boolean;\n}\n\nexport interface ResolvedClientContext {\n api: RudderApiClient;\n orgId?: string;\n agentId?: string;\n runId?: string;\n profileName: string;\n profile: ClientContextProfile;\n json: boolean;\n}\n\nexport function addCommonClientOptions(command: Command, opts?: { includeCompany?: boolean }): Command {\n command\n .option(\"-c, --config <path>\", \"Path to Rudder config file\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"CLI context profile name\")\n .option(\"--api-base <url>\", \"Base URL for the Rudder API\")\n .option(\"--api-key <token>\", \"Bearer token for agent-authenticated calls\")\n .option(\"--run-id <id>\", \"Run ID to attach on mutating agent requests\")\n .option(\"--json\", \"Output raw JSON\");\n\n if (opts?.includeCompany) {\n command.option(\"-O, --org-id <id>\", \"Organization ID (overrides context default)\");\n }\n\n return command;\n}\n\nexport function resolveCommandContext(\n options: BaseClientOptions,\n opts?: { requireCompany?: boolean },\n): ResolvedClientContext {\n const context = readContext(options.context);\n const { name: profileName, profile } = resolveProfile(context, options.profile);\n\n const apiBase =\n options.apiBase?.trim() ||\n process.env.RUDDER_API_URL?.trim() ||\n profile.apiBase ||\n inferApiBaseFromConfig(options.config);\n\n const explicitApiKey =\n options.apiKey?.trim() ||\n process.env.RUDDER_API_KEY?.trim() ||\n readKeyFromProfileEnv(profile);\n const storedBoardCredential = explicitApiKey ? null : getStoredBoardCredential(apiBase);\n const apiKey = explicitApiKey || storedBoardCredential?.token;\n\n const orgId =\n options.orgId?.trim() ||\n options.companyId?.trim() ||\n process.env.RUDDER_ORG_ID?.trim() ||\n profile.orgId;\n const agentId = process.env.RUDDER_AGENT_ID?.trim() || undefined;\n const runId = options.runId?.trim() || process.env.RUDDER_RUN_ID?.trim() || undefined;\n\n if (opts?.requireCompany && !orgId) {\n throw new Error(\n \"Organization ID is required. Pass --org-id, set RUDDER_ORG_ID, or set context profile orgId via `rudder context set`.\",\n );\n }\n\n const api = new RudderApiClient({\n apiBase,\n apiKey,\n agentId,\n runId,\n recoverAuth: explicitApiKey || !canAttemptInteractiveBoardAuth()\n ? undefined\n : async ({ error }) => {\n const requestedAccess = error.message.includes(\"Instance admin required\")\n ? \"instance_admin_required\"\n : \"board\";\n if (!shouldRecoverBoardAuth(error)) {\n return null;\n }\n const login = await loginBoardCli({\n apiBase,\n requestedAccess,\n requestedCompanyId: orgId ?? null,\n command: buildCliCommandLabel(),\n });\n return login.token;\n },\n });\n return {\n api,\n orgId,\n agentId,\n runId,\n profileName,\n profile,\n json: Boolean(options.json),\n };\n}\n\nfunction shouldRecoverBoardAuth(error: ApiRequestError): boolean {\n if (error.status === 401) return true;\n if (error.status !== 403) return false;\n return error.message.includes(\"Board access required\") || error.message.includes(\"Instance admin required\");\n}\n\nfunction canAttemptInteractiveBoardAuth(): boolean {\n return Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}\n\nexport function printOutput(data: unknown, opts: { json?: boolean; label?: string } = {}): void {\n if (opts.json) {\n const output = JSON.stringify(data, null, 2);\n process.stdout.write(output + \"\\n\");\n return;\n }\n\n if (opts.label) {\n console.log(pc.bold(opts.label));\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log(pc.dim(\"(empty)\"));\n return;\n }\n for (const item of data) {\n if (typeof item === \"object\" && item !== null) {\n console.log(formatInlineRecord(item as Record<string, unknown>));\n } else {\n console.log(String(item));\n }\n }\n return;\n }\n\n if (typeof data === \"object\" && data !== null) {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n if (data === undefined || data === null) {\n console.log(pc.dim(\"(null)\"));\n return;\n }\n\n console.log(String(data));\n}\n\nexport function formatInlineRecord(record: Record<string, unknown>): string {\n const keyOrder = [\"identifier\", \"id\", \"name\", \"status\", \"priority\", \"title\", \"action\"];\n const seen = new Set<string>();\n const parts: string[] = [];\n\n for (const key of keyOrder) {\n if (!(key in record)) continue;\n parts.push(`${key}=${renderValue(record[key])}`);\n seen.add(key);\n }\n\n for (const [key, value] of Object.entries(record)) {\n if (seen.has(key)) continue;\n if (typeof value === \"object\") continue;\n parts.push(`${key}=${renderValue(value)}`);\n }\n\n return parts.join(\" \");\n}\n\nfunction renderValue(value: unknown): string {\n if (value === null || value === undefined) return \"-\";\n if (typeof value === \"string\") {\n const compact = value.replace(/\\s+/g, \" \").trim();\n return compact.length > 90 ? `${compact.slice(0, 87)}...` : compact;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return \"[object]\";\n}\n\nfunction inferApiBaseFromConfig(configPath?: string): string {\n const envHost = process.env.RUDDER_SERVER_HOST?.trim() || \"localhost\";\n let port = Number(process.env.RUDDER_SERVER_PORT || \"\");\n\n if (!Number.isFinite(port) || port <= 0) {\n try {\n const config = readConfig(configPath);\n port = Number(config?.server?.port ?? 3100);\n } catch {\n port = 3100;\n }\n }\n\n if (!Number.isFinite(port) || port <= 0) {\n port = 3100;\n }\n\n return `http://${envHost}:${port}`;\n}\n\nfunction readKeyFromProfileEnv(profile: ClientContextProfile): string | undefined {\n if (!profile.apiKeyEnvVarName) return undefined;\n return process.env[profile.apiKeyEnvVarName]?.trim() || undefined;\n}\n\nexport function handleCommandError(error: unknown): never {\n if (process.argv.includes(\"--json\")) {\n const payload = buildCommandErrorPayload(error);\n process.stderr.write(`${JSON.stringify(payload, null, 2)}\\n`);\n process.exit(1);\n }\n\n if (error instanceof ApiRequestError) {\n const detailSuffix = error.details !== undefined ? ` details=${JSON.stringify(error.details)}` : \"\";\n console.error(pc.red(`API error ${error.status}: ${error.message}${detailSuffix}`));\n process.exit(1);\n }\n\n const message = error instanceof Error ? error.message : String(error);\n console.error(pc.red(message));\n process.exit(1);\n}\n\nfunction buildCommandErrorPayload(error: unknown) {\n if (error instanceof ApiRequestError) {\n return {\n error: error.message,\n status: error.status,\n code: error.code ?? \"api_request_error\",\n details: error.details ?? null,\n };\n }\n\n return {\n error: error instanceof Error ? error.message : String(error),\n status: null,\n code: \"cli_error\",\n details: null,\n };\n}\n", "import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport pc from \"picocolors\";\nimport { buildCliCommandLabel } from \"./command-label.js\";\nimport { resolveDefaultCliAuthPath } from \"../config/home.js\";\n\ntype RequestedAccess = \"board\" | \"instance_admin_required\";\n\ninterface BoardAuthCredential {\n apiBase: string;\n token: string;\n createdAt: string;\n updatedAt: string;\n userId?: string | null;\n}\n\ninterface BoardAuthStore {\n version: 1;\n credentials: Record<string, BoardAuthCredential>;\n}\n\ninterface CreateChallengeResponse {\n id: string;\n token: string;\n boardApiToken: string;\n approvalPath: string;\n approvalUrl: string | null;\n pollPath: string;\n expiresAt: string;\n suggestedPollIntervalMs: number;\n}\n\ninterface ChallengeStatusResponse {\n id: string;\n status: \"pending\" | \"approved\" | \"cancelled\" | \"expired\";\n command: string;\n clientName: string | null;\n requestedAccess: RequestedAccess;\n requestedCompanyId: string | null;\n requestedCompanyName: string | null;\n approvedAt: string | null;\n cancelledAt: string | null;\n expiresAt: string;\n approvedByUser: { id: string; name: string; email: string } | null;\n}\n\nfunction defaultBoardAuthStore(): BoardAuthStore {\n return {\n version: 1,\n credentials: {},\n };\n}\n\nfunction toStringOrNull(value: unknown): string | null {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : null;\n}\n\nfunction normalizeApiBase(apiBase: string): string {\n return apiBase.trim().replace(/\\/+$/, \"\");\n}\n\nexport function resolveBoardAuthStorePath(overridePath?: string): string {\n if (overridePath?.trim()) return path.resolve(overridePath.trim());\n if (process.env.RUDDER_AUTH_STORE?.trim()) return path.resolve(process.env.RUDDER_AUTH_STORE.trim());\n return resolveDefaultCliAuthPath();\n}\n\nexport function readBoardAuthStore(storePath?: string): BoardAuthStore {\n const filePath = resolveBoardAuthStorePath(storePath);\n if (!fs.existsSync(filePath)) return defaultBoardAuthStore();\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf8\")) as Partial<BoardAuthStore> | null;\n const credentials = raw?.credentials && typeof raw.credentials === \"object\" ? raw.credentials : {};\n const normalized: Record<string, BoardAuthCredential> = {};\n\n for (const [key, value] of Object.entries(credentials)) {\n if (typeof value !== \"object\" || value === null) continue;\n const record = value as unknown as Record<string, unknown>;\n const apiBase = toStringOrNull(record.apiBase);\n const token = toStringOrNull(record.token);\n const createdAt = toStringOrNull(record.createdAt);\n const updatedAt = toStringOrNull(record.updatedAt);\n if (!apiBase || !token || !createdAt || !updatedAt) continue;\n normalized[normalizeApiBase(key)] = {\n apiBase,\n token,\n createdAt,\n updatedAt,\n userId: toStringOrNull(record.userId),\n };\n }\n\n return {\n version: 1,\n credentials: normalized,\n };\n}\n\nexport function writeBoardAuthStore(store: BoardAuthStore, storePath?: string): void {\n const filePath = resolveBoardAuthStorePath(storePath);\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, `${JSON.stringify(store, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function getStoredBoardCredential(apiBase: string, storePath?: string): BoardAuthCredential | null {\n const store = readBoardAuthStore(storePath);\n return store.credentials[normalizeApiBase(apiBase)] ?? null;\n}\n\nexport function setStoredBoardCredential(input: {\n apiBase: string;\n token: string;\n userId?: string | null;\n storePath?: string;\n}): BoardAuthCredential {\n const normalizedApiBase = normalizeApiBase(input.apiBase);\n const store = readBoardAuthStore(input.storePath);\n const now = new Date().toISOString();\n const existing = store.credentials[normalizedApiBase];\n const credential: BoardAuthCredential = {\n apiBase: normalizedApiBase,\n token: input.token.trim(),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n userId: input.userId ?? existing?.userId ?? null,\n };\n store.credentials[normalizedApiBase] = credential;\n writeBoardAuthStore(store, input.storePath);\n return credential;\n}\n\nexport function removeStoredBoardCredential(apiBase: string, storePath?: string): boolean {\n const normalizedApiBase = normalizeApiBase(apiBase);\n const store = readBoardAuthStore(storePath);\n if (!store.credentials[normalizedApiBase]) return false;\n delete store.credentials[normalizedApiBase];\n writeBoardAuthStore(store, storePath);\n return true;\n}\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function requestJson<T>(url: string, init?: RequestInit): Promise<T> {\n const headers = new Headers(init?.headers ?? undefined);\n if (init?.body !== undefined && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n if (!headers.has(\"accept\")) {\n headers.set(\"accept\", \"application/json\");\n }\n\n const response = await fetch(url, {\n ...init,\n headers,\n });\n\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n const message =\n body && typeof body === \"object\" && typeof (body as { error?: unknown }).error === \"string\"\n ? (body as { error: string }).error\n : `Request failed: ${response.status}`;\n throw new Error(message);\n }\n\n return response.json() as Promise<T>;\n}\n\nexport function openUrl(url: string): boolean {\n const platform = process.platform;\n try {\n if (platform === \"darwin\") {\n const child = spawn(\"open\", [url], { detached: true, stdio: \"ignore\" });\n child.unref();\n return true;\n }\n if (platform === \"win32\") {\n const child = spawn(\"cmd\", [\"/c\", \"start\", \"\", url], { detached: true, stdio: \"ignore\" });\n child.unref();\n return true;\n }\n const child = spawn(\"xdg-open\", [url], { detached: true, stdio: \"ignore\" });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function loginBoardCli(params: {\n apiBase: string;\n requestedAccess: RequestedAccess;\n requestedCompanyId?: string | null;\n clientName?: string | null;\n command?: string;\n storePath?: string;\n print?: boolean;\n}): Promise<{ token: string; approvalUrl: string; userId?: string | null }> {\n const apiBase = normalizeApiBase(params.apiBase);\n const createUrl = `${apiBase}/api/cli-auth/challenges`;\n const command = params.command?.trim() || buildCliCommandLabel();\n\n const challenge = await requestJson<CreateChallengeResponse>(createUrl, {\n method: \"POST\",\n body: JSON.stringify({\n command,\n clientName: params.clientName?.trim() || \"rudder cli\",\n requestedAccess: params.requestedAccess,\n requestedCompanyId: params.requestedCompanyId?.trim() || null,\n }),\n });\n\n const approvalUrl = challenge.approvalUrl ?? `${apiBase}${challenge.approvalPath}`;\n if (params.print !== false) {\n console.error(pc.bold(\"Board authentication required\"));\n console.error(`Open this URL in your browser to approve CLI access:\\n${approvalUrl}`);\n }\n\n const opened = openUrl(approvalUrl);\n if (params.print !== false && opened) {\n console.error(pc.dim(\"Opened the approval page in your browser.\"));\n }\n\n const expiresAtMs = Date.parse(challenge.expiresAt);\n const pollMs = Math.max(500, challenge.suggestedPollIntervalMs || 1000);\n\n while (Number.isFinite(expiresAtMs) ? Date.now() < expiresAtMs : true) {\n const status = await requestJson<ChallengeStatusResponse>(\n `${apiBase}/api${challenge.pollPath}?token=${encodeURIComponent(challenge.token)}`,\n );\n\n if (status.status === \"approved\") {\n const me = await requestJson<{ userId: string; user?: { id: string } | null }>(\n `${apiBase}/api/cli-auth/me`,\n {\n headers: {\n authorization: `Bearer ${challenge.boardApiToken}`,\n },\n },\n );\n setStoredBoardCredential({\n apiBase,\n token: challenge.boardApiToken,\n userId: me.userId ?? me.user?.id ?? null,\n storePath: params.storePath,\n });\n return {\n token: challenge.boardApiToken,\n approvalUrl,\n userId: me.userId ?? me.user?.id ?? null,\n };\n }\n\n if (status.status === \"cancelled\") {\n throw new Error(\"CLI auth challenge was cancelled.\");\n }\n if (status.status === \"expired\") {\n throw new Error(\"CLI auth challenge expired before approval.\");\n }\n\n await sleep(pollMs);\n }\n\n throw new Error(\"CLI auth challenge expired before approval.\");\n}\n\nexport async function revokeStoredBoardCredential(params: {\n apiBase: string;\n token: string;\n}): Promise<void> {\n const apiBase = normalizeApiBase(params.apiBase);\n await requestJson<{ revoked: boolean }>(`${apiBase}/api/cli-auth/revoke-current`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${params.token}`,\n },\n body: JSON.stringify({}),\n });\n}\n", "export function buildCliCommandLabel(): string {\n const args = process.argv.slice(2);\n return args.length > 0 ? `rudder ${args.join(\" \")}` : \"rudder\";\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { resolveDefaultContextPath } from \"../config/home.js\";\n\nconst DEFAULT_CONTEXT_BASENAME = \"context.json\";\nconst DEFAULT_PROFILE = \"default\";\n\nexport interface ClientContextProfile {\n apiBase?: string;\n orgId?: string;\n apiKeyEnvVarName?: string;\n}\n\nexport interface ClientContext {\n version: 1;\n currentProfile: string;\n profiles: Record<string, ClientContextProfile>;\n}\n\nfunction findContextFileFromAncestors(startDir: string): string | null {\n const absoluteStartDir = path.resolve(startDir);\n let currentDir = absoluteStartDir;\n\n while (true) {\n const candidate = path.resolve(currentDir, \".rudder\", DEFAULT_CONTEXT_BASENAME);\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n\n const nextDir = path.resolve(currentDir, \"..\");\n if (nextDir === currentDir) break;\n currentDir = nextDir;\n }\n\n return null;\n}\n\nexport function resolveContextPath(overridePath?: string): string {\n if (overridePath) return path.resolve(overridePath);\n if (process.env.RUDDER_CONTEXT) return path.resolve(process.env.RUDDER_CONTEXT);\n return findContextFileFromAncestors(process.cwd()) ?? resolveDefaultContextPath();\n}\n\nexport function defaultClientContext(): ClientContext {\n return {\n version: 1,\n currentProfile: DEFAULT_PROFILE,\n profiles: {\n [DEFAULT_PROFILE]: {},\n },\n };\n}\n\nfunction parseJson(filePath: string): unknown {\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n } catch (err) {\n throw new Error(`Failed to parse JSON at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction toStringOrUndefined(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction normalizeProfile(value: unknown): ClientContextProfile {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return {};\n const profile = value as Record<string, unknown>;\n\n return {\n apiBase: toStringOrUndefined(profile.apiBase),\n orgId: toStringOrUndefined(profile.orgId ?? profile.companyId),\n apiKeyEnvVarName: toStringOrUndefined(profile.apiKeyEnvVarName),\n };\n}\n\nfunction normalizeContext(raw: unknown): ClientContext {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n return defaultClientContext();\n }\n\n const record = raw as Record<string, unknown>;\n const version = record.version === 1 ? 1 : 1;\n const currentProfile = toStringOrUndefined(record.currentProfile) ?? DEFAULT_PROFILE;\n\n const rawProfiles = record.profiles;\n const profiles: Record<string, ClientContextProfile> = {};\n\n if (typeof rawProfiles === \"object\" && rawProfiles !== null && !Array.isArray(rawProfiles)) {\n for (const [name, profile] of Object.entries(rawProfiles as Record<string, unknown>)) {\n if (!name.trim()) continue;\n profiles[name] = normalizeProfile(profile);\n }\n }\n\n if (!profiles[currentProfile]) {\n profiles[currentProfile] = {};\n }\n\n if (Object.keys(profiles).length === 0) {\n profiles[DEFAULT_PROFILE] = {};\n }\n\n return {\n version,\n currentProfile,\n profiles,\n };\n}\n\nexport function readContext(contextPath?: string): ClientContext {\n const filePath = resolveContextPath(contextPath);\n if (!fs.existsSync(filePath)) {\n return defaultClientContext();\n }\n\n const raw = parseJson(filePath);\n return normalizeContext(raw);\n}\n\nexport function writeContext(context: ClientContext, contextPath?: string): void {\n const filePath = resolveContextPath(contextPath);\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n\n const normalized = normalizeContext(context);\n fs.writeFileSync(filePath, `${JSON.stringify(normalized, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function upsertProfile(\n profileName: string,\n patch: Partial<ClientContextProfile>,\n contextPath?: string,\n): ClientContext {\n const context = readContext(contextPath);\n const existing = context.profiles[profileName] ?? {};\n const merged: ClientContextProfile = {\n ...existing,\n ...patch,\n };\n\n if (patch.apiBase !== undefined && patch.apiBase.trim().length === 0) {\n delete merged.apiBase;\n }\n if (patch.orgId !== undefined && patch.orgId.trim().length === 0) {\n delete merged.orgId;\n }\n if (patch.apiKeyEnvVarName !== undefined && patch.apiKeyEnvVarName.trim().length === 0) {\n delete merged.apiKeyEnvVarName;\n }\n\n context.profiles[profileName] = merged;\n context.currentProfile = context.currentProfile || profileName;\n writeContext(context, contextPath);\n return context;\n}\n\nexport function setCurrentProfile(profileName: string, contextPath?: string): ClientContext {\n const context = readContext(contextPath);\n if (!context.profiles[profileName]) {\n context.profiles[profileName] = {};\n }\n context.currentProfile = profileName;\n writeContext(context, contextPath);\n return context;\n}\n\nexport function resolveProfile(\n context: ClientContext,\n profileName?: string,\n): { name: string; profile: ClientContextProfile } {\n const name = profileName?.trim() || context.currentProfile || DEFAULT_PROFILE;\n const profile = context.profiles[name] ?? {};\n return { name, profile };\n}\n", "import { URL } from \"node:url\";\n\nexport class ApiRequestError extends Error {\n status: number;\n code?: string | null;\n details?: unknown;\n body?: unknown;\n\n constructor(status: number, message: string, details?: unknown, body?: unknown, code?: string | null) {\n super(message);\n this.status = status;\n this.code = code ?? null;\n this.details = details;\n this.body = body;\n }\n}\n\ninterface RequestOptions {\n ignoreNotFound?: boolean;\n}\n\ninterface RecoverAuthInput {\n path: string;\n method: string;\n error: ApiRequestError;\n}\n\ninterface ApiClientOptions {\n apiBase: string;\n apiKey?: string;\n agentId?: string;\n runId?: string;\n recoverAuth?: (input: RecoverAuthInput) => Promise<string | null>;\n}\n\nexport class RudderApiClient {\n readonly apiBase: string;\n apiKey?: string;\n readonly agentId?: string;\n readonly runId?: string;\n readonly recoverAuth?: (input: RecoverAuthInput) => Promise<string | null>;\n\n constructor(opts: ApiClientOptions) {\n this.apiBase = opts.apiBase.replace(/\\/+$/, \"\");\n this.apiKey = opts.apiKey?.trim() || undefined;\n this.agentId = opts.agentId?.trim() || undefined;\n this.runId = opts.runId?.trim() || undefined;\n this.recoverAuth = opts.recoverAuth;\n }\n\n get<T>(path: string, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, { method: \"GET\" }, opts);\n }\n\n post<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"POST\",\n body: body === undefined ? undefined : JSON.stringify(body),\n }, opts);\n }\n\n postForm<T>(path: string, form: FormData, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"POST\",\n body: form,\n }, opts);\n }\n\n patch<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"PATCH\",\n body: body === undefined ? undefined : JSON.stringify(body),\n }, opts);\n }\n\n put<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"PUT\",\n body: body === undefined ? undefined : JSON.stringify(body),\n }, opts);\n }\n\n delete<T>(path: string, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, { method: \"DELETE\" }, opts);\n }\n\n setApiKey(apiKey: string | undefined) {\n this.apiKey = apiKey?.trim() || undefined;\n }\n\n private async request<T>(\n path: string,\n init: RequestInit,\n opts?: RequestOptions,\n hasRetriedAuth = false,\n ): Promise<T | null> {\n const url = buildUrl(this.apiBase, path);\n\n const headers: Record<string, string> = {\n accept: \"application/json\",\n ...toStringRecord(init.headers),\n };\n\n if (typeof init.body === \"string\") {\n headers[\"content-type\"] = headers[\"content-type\"] ?? \"application/json\";\n }\n\n if (this.apiKey) {\n headers.authorization = `Bearer ${this.apiKey}`;\n }\n\n if (shouldAttachAgentContext(init.method)) {\n if (this.agentId) {\n headers[\"x-rudder-agent-id\"] = this.agentId;\n }\n if (this.runId) {\n headers[\"x-rudder-run-id\"] = this.runId;\n }\n }\n\n const response = await fetch(url, {\n ...init,\n headers,\n });\n\n if (opts?.ignoreNotFound && response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n const apiError = await toApiError(response);\n if (!hasRetriedAuth && this.recoverAuth) {\n const recoveredToken = await this.recoverAuth({\n path,\n method: String(init.method ?? \"GET\").toUpperCase(),\n error: apiError,\n });\n if (recoveredToken) {\n this.setApiKey(recoveredToken);\n return this.request<T>(path, init, opts, true);\n }\n }\n throw apiError;\n }\n\n if (response.status === 204) {\n return null;\n }\n\n const text = await response.text();\n if (!text.trim()) {\n return null;\n }\n\n return safeParseJson(text) as T;\n }\n}\n\nfunction shouldAttachAgentContext(method: string | undefined): boolean {\n const normalized = String(method ?? \"GET\").toUpperCase();\n return normalized !== \"GET\" && normalized !== \"HEAD\";\n}\n\nfunction buildUrl(apiBase: string, path: string): string {\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n const [pathname, query] = normalizedPath.split(\"?\");\n const url = new URL(apiBase);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}${pathname}`;\n if (query) url.search = query;\n return url.toString();\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nasync function toApiError(response: Response): Promise<ApiRequestError> {\n const text = await response.text();\n const parsed = safeParseJson(text);\n\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n const body = parsed as Record<string, unknown>;\n const message =\n (typeof body.error === \"string\" && body.error.trim()) ||\n (typeof body.message === \"string\" && body.message.trim()) ||\n `Request failed with status ${response.status}`;\n const code = typeof body.code === \"string\" && body.code.trim().length > 0\n ? body.code.trim()\n : null;\n\n return new ApiRequestError(response.status, message, body.details, parsed, code);\n }\n\n return new ApiRequestError(\n response.status,\n `Request failed with status ${response.status}`,\n undefined,\n parsed,\n null,\n );\n}\n\nfunction toStringRecord(headers: HeadersInit | undefined): Record<string, string> {\n if (!headers) return {};\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers.map(([key, value]) => [key, String(value)]));\n }\n if (headers instanceof Headers) {\n return Object.fromEntries(headers.entries());\n }\n return Object.fromEntries(\n Object.entries(headers).map(([key, value]) => [key, String(value)]),\n );\n}\n", "import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n readContext,\n resolveContextPath,\n resolveProfile,\n setCurrentProfile,\n upsertProfile,\n} from \"../../client/context.js\";\nimport { printOutput } from \"./common.js\";\n\ninterface ContextOptions {\n dataDir?: string;\n context?: string;\n profile?: string;\n json?: boolean;\n}\n\ninterface ContextSetOptions extends ContextOptions {\n apiBase?: string;\n orgId?: string;\n apiKeyEnvVarName?: string;\n use?: boolean;\n}\n\nexport function registerContextCommands(program: Command): void {\n const context = program.command(\"context\").description(\"Manage CLI client context profiles\");\n\n context\n .command(\"show\")\n .description(\"Show current context and active profile\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"Profile to inspect\")\n .option(\"--json\", \"Output raw JSON\")\n .action((opts: ContextOptions) => {\n const contextPath = resolveContextPath(opts.context);\n const store = readContext(opts.context);\n const resolved = resolveProfile(store, opts.profile);\n const payload = {\n contextPath,\n currentProfile: store.currentProfile,\n profileName: resolved.name,\n profile: resolved.profile,\n profiles: store.profiles,\n };\n printOutput(payload, { json: opts.json });\n });\n\n context\n .command(\"list\")\n .description(\"List available context profiles\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--json\", \"Output raw JSON\")\n .action((opts: ContextOptions) => {\n const store = readContext(opts.context);\n const rows = Object.entries(store.profiles).map(([name, profile]) => ({\n name,\n current: name === store.currentProfile,\n apiBase: profile.apiBase ?? null,\n orgId: profile.orgId ?? null,\n apiKeyEnvVarName: profile.apiKeyEnvVarName ?? null,\n }));\n printOutput(rows, { json: opts.json });\n });\n\n context\n .command(\"use\")\n .description(\"Set active context profile\")\n .argument(\"<profile>\", \"Profile name\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .action((profile: string, opts: ContextOptions) => {\n setCurrentProfile(profile, opts.context);\n console.log(pc.green(`Active profile set to '${profile}'.`));\n });\n\n context\n .command(\"set\")\n .description(\"Set values on a profile\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"Profile name (default: current profile)\")\n .option(\"--api-base <url>\", \"Default API base URL\")\n .option(\"--org-id <id>\", \"Default organization ID\")\n .option(\"--api-key-env-var-name <name>\", \"Env var containing API key (recommended)\")\n .option(\"--use\", \"Set this profile as active\")\n .option(\"--json\", \"Output raw JSON\")\n .action((opts: ContextSetOptions) => {\n const existing = readContext(opts.context);\n const targetProfile = opts.profile?.trim() || existing.currentProfile || \"default\";\n\n upsertProfile(\n targetProfile,\n {\n apiBase: opts.apiBase,\n orgId: opts.orgId,\n apiKeyEnvVarName: opts.apiKeyEnvVarName,\n },\n opts.context,\n );\n\n if (opts.use) {\n setCurrentProfile(targetProfile, opts.context);\n }\n\n const updated = readContext(opts.context);\n const resolved = resolveProfile(updated, targetProfile);\n const payload = {\n contextPath: resolveContextPath(opts.context),\n currentProfile: updated.currentProfile,\n profileName: resolved.name,\n profile: resolved.profile,\n };\n\n if (!opts.json) {\n console.log(pc.green(`Updated profile '${targetProfile}'.`));\n if (opts.use) {\n console.log(pc.green(`Set '${targetProfile}' as active profile.`));\n }\n }\n printOutput(payload, { json: opts.json });\n });\n}\n", "import { Command } from \"commander\";\nimport { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type {\n Organization,\n OrganizationPortabilityFileEntry,\n OrganizationPortabilityExportResult,\n OrganizationPortabilityInclude,\n OrganizationPortabilityPreviewResult,\n OrganizationPortabilityImportResult,\n} from \"@rudderhq/shared\";\nimport { ApiRequestError } from \"../../client/http.js\";\nimport { openUrl } from \"../../client/board-auth.js\";\nimport { binaryContentTypeByExtension, readZipArchive } from \"./zip.js\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface CompanyCommandOptions extends BaseClientOptions {}\ntype CompanyDeleteSelectorMode = \"auto\" | \"id\" | \"prefix\";\ntype CompanyImportTargetMode = \"new\" | \"existing\";\ntype CompanyCollisionMode = \"rename\" | \"skip\" | \"replace\";\n\ninterface CompanyDeleteOptions extends BaseClientOptions {\n by?: CompanyDeleteSelectorMode;\n yes?: boolean;\n confirm?: string;\n}\n\ninterface CompanyExportOptions extends BaseClientOptions {\n out?: string;\n include?: string;\n skills?: string;\n projects?: string;\n issues?: string;\n projectIssues?: string;\n expandReferencedSkills?: boolean;\n}\n\ninterface CompanyImportOptions extends BaseClientOptions {\n include?: string;\n target?: CompanyImportTargetMode;\n orgId?: string;\n newOrganizationName?: string;\n agents?: string;\n collision?: CompanyCollisionMode;\n ref?: string;\n rudderUrl?: string;\n yes?: boolean;\n dryRun?: boolean;\n}\n\nconst DEFAULT_EXPORT_INCLUDE: OrganizationPortabilityInclude = {\n organization: true,\n agents: true,\n projects: false,\n issues: false,\n skills: false,\n};\n\nconst DEFAULT_IMPORT_INCLUDE: OrganizationPortabilityInclude = {\n organization: true,\n agents: true,\n projects: true,\n issues: true,\n skills: true,\n};\n\nconst IMPORT_INCLUDE_OPTIONS: Array<{\n value: keyof OrganizationPortabilityInclude;\n label: string;\n hint: string;\n}> = [\n { value: \"organization\", label: \"Organization\", hint: \"name, branding, and organization settings\" },\n { value: \"projects\", label: \"Projects\", hint: \"projects and workspace metadata\" },\n { value: \"issues\", label: \"Tasks\", hint: \"tasks and recurring automations\" },\n { value: \"agents\", label: \"Agents\", hint: \"agent records and organization structure\" },\n { value: \"skills\", label: \"Skills\", hint: \"organization skill packages and references\" },\n];\n\nconst IMPORT_PREVIEW_SAMPLE_LIMIT = 6;\n\ntype ImportSelectableGroup = \"projects\" | \"issues\" | \"agents\" | \"skills\";\n\ntype ImportSelectionCatalog = {\n organization: {\n includedByDefault: boolean;\n files: string[];\n };\n projects: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n issues: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n agents: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n skills: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n extensionPath: string | null;\n};\n\ntype ImportSelectionState = {\n organization: boolean;\n projects: Set<string>;\n issues: Set<string>;\n agents: Set<string>;\n skills: Set<string>;\n};\n\nfunction readPortableFileEntry(filePath: string, contents: Buffer): OrganizationPortabilityFileEntry {\n const contentType = binaryContentTypeByExtension[path.extname(filePath).toLowerCase()];\n if (!contentType) return contents.toString(\"utf8\");\n return {\n encoding: \"base64\",\n data: contents.toString(\"base64\"),\n contentType,\n };\n}\n\nfunction portableFileEntryToWriteValue(entry: OrganizationPortabilityFileEntry): string | Uint8Array {\n if (typeof entry === \"string\") return entry;\n return Buffer.from(entry.data, \"base64\");\n}\n\nfunction isUuidLike(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n\nfunction normalizeSelector(input: string): string {\n return input.trim();\n}\n\nfunction parseInclude(\n input: string | undefined,\n fallback: OrganizationPortabilityInclude = DEFAULT_EXPORT_INCLUDE,\n): OrganizationPortabilityInclude {\n if (!input || !input.trim()) return { ...fallback };\n const values = input.split(\",\").map((part) => part.trim().toLowerCase()).filter(Boolean);\n const include = {\n organization: values.includes(\"organization\") || values.includes(\"company\"),\n agents: values.includes(\"agents\"),\n projects: values.includes(\"projects\"),\n issues: values.includes(\"issues\") || values.includes(\"tasks\"),\n skills: values.includes(\"skills\"),\n };\n if (!include.organization && !include.agents && !include.projects && !include.issues && !include.skills) {\n throw new Error(\"Invalid --include value. Use one or more of: organization,agents,projects,issues,tasks,skills\");\n }\n return include;\n}\n\nfunction parseAgents(input: string | undefined): \"all\" | string[] {\n if (!input || !input.trim()) return \"all\";\n const normalized = input.trim().toLowerCase();\n if (normalized === \"all\") return \"all\";\n const values = input.split(\",\").map((part) => part.trim()).filter(Boolean);\n if (values.length === 0) return \"all\";\n return Array.from(new Set(values));\n}\n\nfunction parseCsvValues(input: string | undefined): string[] {\n if (!input || !input.trim()) return [];\n return Array.from(new Set(input.split(\",\").map((part) => part.trim()).filter(Boolean)));\n}\n\nfunction isInteractiveTerminal(): boolean {\n return Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}\n\nfunction resolveImportInclude(input: string | undefined): OrganizationPortabilityInclude {\n return parseInclude(input, DEFAULT_IMPORT_INCLUDE);\n}\n\nfunction normalizePortablePath(filePath: string): string {\n return filePath.replace(/\\\\/g, \"/\");\n}\n\nfunction shouldIncludePortableFile(filePath: string): boolean {\n const baseName = path.basename(filePath);\n const isMarkdown = baseName.endsWith(\".md\");\n const isPaperclipYaml = baseName === \".rudder.yaml\" || baseName === \".rudder.yml\";\n const contentType = binaryContentTypeByExtension[path.extname(baseName).toLowerCase()];\n return isMarkdown || isPaperclipYaml || Boolean(contentType);\n}\n\nfunction findPortableExtensionPath(files: Record<string, OrganizationPortabilityFileEntry>): string | null {\n if (files[\".rudder.yaml\"] !== undefined) return \".rudder.yaml\";\n if (files[\".rudder.yml\"] !== undefined) return \".rudder.yml\";\n return Object.keys(files).find((entry) => entry.endsWith(\"/.rudder.yaml\") || entry.endsWith(\"/.rudder.yml\")) ?? null;\n}\n\nfunction collectFilesUnderDirectory(\n files: Record<string, OrganizationPortabilityFileEntry>,\n directory: string,\n opts?: { excludePrefixes?: string[] },\n): string[] {\n const normalizedDirectory = normalizePortablePath(directory).replace(/\\/+$/, \"\");\n if (!normalizedDirectory) return [];\n const prefix = `${normalizedDirectory}/`;\n const excluded = (opts?.excludePrefixes ?? []).map((entry) => normalizePortablePath(entry).replace(/\\/+$/, \"\")).filter(Boolean);\n return Object.keys(files)\n .map(normalizePortablePath)\n .filter((filePath) => filePath.startsWith(prefix))\n .filter((filePath) => !excluded.some((excludePrefix) => filePath.startsWith(`${excludePrefix}/`)))\n .sort((left, right) => left.localeCompare(right));\n}\n\nfunction collectEntityFiles(\n files: Record<string, OrganizationPortabilityFileEntry>,\n entryPath: string,\n opts?: { excludePrefixes?: string[] },\n): string[] {\n const normalizedPath = normalizePortablePath(entryPath);\n const directory = normalizedPath.includes(\"/\") ? normalizedPath.slice(0, normalizedPath.lastIndexOf(\"/\")) : \"\";\n const selected = new Set<string>([normalizedPath]);\n if (directory) {\n for (const filePath of collectFilesUnderDirectory(files, directory, opts)) {\n selected.add(filePath);\n }\n }\n return Array.from(selected).sort((left, right) => left.localeCompare(right));\n}\n\nexport function buildImportSelectionCatalog(preview: OrganizationPortabilityPreviewResult): ImportSelectionCatalog {\n const selectedAgentSlugs = new Set(preview.selectedAgentSlugs);\n const organizationFiles = new Set<string>();\n const organizationPath = preview.manifest.organization?.path\n ? normalizePortablePath(preview.manifest.organization.path)\n : null;\n if (organizationPath) {\n organizationFiles.add(organizationPath);\n }\n const readmePath = Object.keys(preview.files).find((entry) => normalizePortablePath(entry) === \"README.md\");\n if (readmePath) {\n organizationFiles.add(normalizePortablePath(readmePath));\n }\n const logoPath = preview.manifest.organization?.logoPath\n ? normalizePortablePath(preview.manifest.organization.logoPath)\n : null;\n if (logoPath && preview.files[logoPath] !== undefined) {\n organizationFiles.add(logoPath);\n }\n\n return {\n organization: {\n includedByDefault: preview.include.organization && preview.manifest.organization !== null,\n files: Array.from(organizationFiles).sort((left, right) => left.localeCompare(right)),\n },\n projects: preview.manifest.projects.map((project) => {\n const projectPath = normalizePortablePath(project.path);\n const projectDir = projectPath.includes(\"/\") ? projectPath.slice(0, projectPath.lastIndexOf(\"/\")) : \"\";\n return {\n key: project.slug,\n label: project.name,\n hint: project.slug,\n files: collectEntityFiles(preview.files, projectPath, {\n excludePrefixes: projectDir ? [`${projectDir}/issues`] : [],\n }),\n };\n }),\n issues: preview.manifest.issues.map((issue) => ({\n key: issue.slug,\n label: issue.title,\n hint: issue.identifier ?? issue.slug,\n files: collectEntityFiles(preview.files, normalizePortablePath(issue.path)),\n })),\n agents: preview.manifest.agents\n .filter((agent) => selectedAgentSlugs.size === 0 || selectedAgentSlugs.has(agent.slug))\n .map((agent) => ({\n key: agent.slug,\n label: agent.name,\n hint: agent.slug,\n files: collectEntityFiles(preview.files, normalizePortablePath(agent.path)),\n })),\n skills: preview.manifest.skills.map((skill) => ({\n key: skill.slug,\n label: skill.name,\n hint: skill.slug,\n files: collectEntityFiles(preview.files, normalizePortablePath(skill.path)),\n })),\n extensionPath: findPortableExtensionPath(preview.files),\n };\n}\n\nfunction toKeySet(items: Array<{ key: string }>): Set<string> {\n return new Set(items.map((item) => item.key));\n}\n\nexport function buildDefaultImportSelectionState(catalog: ImportSelectionCatalog): ImportSelectionState {\n return {\n organization: catalog.organization.includedByDefault,\n projects: toKeySet(catalog.projects),\n issues: toKeySet(catalog.issues),\n agents: toKeySet(catalog.agents),\n skills: toKeySet(catalog.skills),\n };\n}\n\nfunction countSelected(state: ImportSelectionState, group: ImportSelectableGroup): number {\n return state[group].size;\n}\n\nfunction countTotal(catalog: ImportSelectionCatalog, group: ImportSelectableGroup): number {\n return catalog[group].length;\n}\n\nfunction summarizeGroupSelection(catalog: ImportSelectionCatalog, state: ImportSelectionState, group: ImportSelectableGroup): string {\n return `${countSelected(state, group)}/${countTotal(catalog, group)} selected`;\n}\n\nfunction getGroupLabel(group: ImportSelectableGroup): string {\n switch (group) {\n case \"projects\":\n return \"Projects\";\n case \"issues\":\n return \"Tasks\";\n case \"agents\":\n return \"Agents\";\n case \"skills\":\n return \"Skills\";\n }\n}\n\nexport function buildSelectedFilesFromImportSelection(\n catalog: ImportSelectionCatalog,\n state: ImportSelectionState,\n): string[] {\n const selected = new Set<string>();\n\n if (state.organization) {\n for (const filePath of catalog.organization.files) {\n selected.add(normalizePortablePath(filePath));\n }\n }\n\n for (const group of [\"projects\", \"issues\", \"agents\", \"skills\"] as const) {\n const selectedKeys = state[group];\n for (const item of catalog[group]) {\n if (!selectedKeys.has(item.key)) continue;\n for (const filePath of item.files) {\n selected.add(normalizePortablePath(filePath));\n }\n }\n }\n\n if (selected.size > 0 && catalog.extensionPath) {\n selected.add(normalizePortablePath(catalog.extensionPath));\n }\n\n return Array.from(selected).sort((left, right) => left.localeCompare(right));\n}\n\nexport function buildDefaultImportAdapterOverrides(\n preview: Pick<OrganizationPortabilityPreviewResult, \"manifest\" | \"selectedAgentSlugs\">,\n): Record<string, { agentRuntimeType: string }> | undefined {\n const selectedAgentSlugs = new Set(preview.selectedAgentSlugs);\n const overrides = Object.fromEntries(\n preview.manifest.agents\n .filter((agent) => selectedAgentSlugs.size === 0 || selectedAgentSlugs.has(agent.slug))\n .filter((agent) => agent.agentRuntimeType === \"process\")\n .map((agent) => [\n agent.slug,\n {\n // TODO: replace this temporary claude_local fallback with adapter selection in the import TUI.\n agentRuntimeType: \"claude_local\",\n },\n ]),\n );\n return Object.keys(overrides).length > 0 ? overrides : undefined;\n}\n\nfunction buildDefaultImportAdapterMessages(\n overrides: Record<string, { agentRuntimeType: string }> | undefined,\n): string[] {\n if (!overrides) return [];\n const agentRuntimeTypes = Array.from(new Set(Object.values(overrides).map((override) => override.agentRuntimeType)))\n .map((agentRuntimeType) => agentRuntimeType.replace(/_/g, \"-\"));\n const agentCount = Object.keys(overrides).length;\n return [\n `Using ${agentRuntimeTypes.join(\", \")} adapter${agentRuntimeTypes.length === 1 ? \"\" : \"s\"} for ${agentCount} imported ${pluralize(agentCount, \"agent\")} without an explicit adapter.`,\n ];\n}\n\nasync function promptForImportSelection(preview: OrganizationPortabilityPreviewResult): Promise<string[]> {\n const catalog = buildImportSelectionCatalog(preview);\n const state = buildDefaultImportSelectionState(catalog);\n\n while (true) {\n const choice = await p.select<ImportSelectableGroup | \"organization\" | \"confirm\">({\n message: \"Select what Rudder should import\",\n options: [\n {\n value: \"organization\",\n label: state.organization ? \"Organization: included\" : \"Organization: skipped\",\n hint: catalog.organization.files.length > 0\n ? \"toggle organization metadata\"\n : \"no organization metadata in package\",\n },\n {\n value: \"projects\",\n label: \"Select Projects\",\n hint: summarizeGroupSelection(catalog, state, \"projects\"),\n },\n {\n value: \"issues\",\n label: \"Select Tasks\",\n hint: summarizeGroupSelection(catalog, state, \"issues\"),\n },\n {\n value: \"agents\",\n label: \"Select Agents\",\n hint: summarizeGroupSelection(catalog, state, \"agents\"),\n },\n {\n value: \"skills\",\n label: \"Select Skills\",\n hint: summarizeGroupSelection(catalog, state, \"skills\"),\n },\n {\n value: \"confirm\",\n label: \"Confirm\",\n hint: `${buildSelectedFilesFromImportSelection(catalog, state).length} files selected`,\n },\n ],\n initialValue: \"confirm\",\n });\n\n if (p.isCancel(choice)) {\n p.cancel(\"Import cancelled.\");\n process.exit(0);\n }\n\n if (choice === \"confirm\") {\n const selectedFiles = buildSelectedFilesFromImportSelection(catalog, state);\n if (selectedFiles.length === 0) {\n p.note(\"Select at least one import target before confirming.\", \"Nothing selected\");\n continue;\n }\n return selectedFiles;\n }\n\n if (choice === \"organization\") {\n if (catalog.organization.files.length === 0) {\n p.note(\"This package does not include organization metadata to toggle.\", \"No organization metadata\");\n continue;\n }\n state.organization = !state.organization;\n continue;\n }\n\n const group = choice;\n const groupItems = catalog[group];\n if (groupItems.length === 0) {\n p.note(`This package does not include any ${getGroupLabel(group).toLowerCase()}.`, `No ${getGroupLabel(group)}`);\n continue;\n }\n\n const selection = await p.multiselect<string>({\n message: `${getGroupLabel(group)} to import. Space toggles, enter returns to the main menu.`,\n options: groupItems.map((item) => ({\n value: item.key,\n label: item.label,\n hint: item.hint,\n })),\n initialValues: Array.from(state[group]),\n });\n\n if (p.isCancel(selection)) {\n p.cancel(\"Import cancelled.\");\n process.exit(0);\n }\n\n state[group] = new Set(selection);\n }\n}\n\nfunction summarizeInclude(include: OrganizationPortabilityInclude): string {\n const labels = IMPORT_INCLUDE_OPTIONS\n .filter((option) => include[option.value])\n .map((option) => option.label.toLowerCase());\n return labels.length > 0 ? labels.join(\", \") : \"nothing selected\";\n}\n\nfunction formatSourceLabel(source: { type: \"inline\"; rootPath?: string | null } | { type: \"github\"; url: string }): string {\n if (source.type === \"github\") {\n return `GitHub: ${source.url}`;\n }\n return `Local package: ${source.rootPath?.trim() || \"(current folder)\"}`;\n}\n\nfunction formatTargetLabel(\n target: { mode: \"existing_organization\"; orgId?: string | null } | { mode: \"new_organization\"; newOrganizationName?: string | null },\n preview?: OrganizationPortabilityPreviewResult,\n): string {\n if (target.mode === \"existing_organization\") {\n const targetName = preview?.targetOrganizationName?.trim();\n const targetId = preview?.targetOrganizationId?.trim() || target.orgId?.trim() || \"unknown-organization\";\n return targetName ? `${targetName} (${targetId})` : targetId;\n }\n return target.newOrganizationName?.trim() || preview?.manifest.organization?.name || \"new organization\";\n}\n\nfunction pluralize(count: number, singular: string, plural = `${singular}s`): string {\n return count === 1 ? singular : plural;\n}\n\nfunction summarizePlanCounts(\n plans: Array<{ action: \"create\" | \"update\" | \"skip\" }>,\n noun: string,\n): string {\n if (plans.length === 0) return `0 ${pluralize(0, noun)} selected`;\n const createCount = plans.filter((plan) => plan.action === \"create\").length;\n const updateCount = plans.filter((plan) => plan.action === \"update\").length;\n const skipCount = plans.filter((plan) => plan.action === \"skip\").length;\n const parts: string[] = [];\n if (createCount > 0) parts.push(`${createCount} create`);\n if (updateCount > 0) parts.push(`${updateCount} update`);\n if (skipCount > 0) parts.push(`${skipCount} skip`);\n return `${plans.length} ${pluralize(plans.length, noun)} total (${parts.join(\", \")})`;\n}\n\nfunction summarizeImportAgentResults(agents: OrganizationPortabilityImportResult[\"agents\"]): string {\n if (agents.length === 0) return \"0 agents changed\";\n const created = agents.filter((agent) => agent.action === \"created\").length;\n const updated = agents.filter((agent) => agent.action === \"updated\").length;\n const skipped = agents.filter((agent) => agent.action === \"skipped\").length;\n const parts: string[] = [];\n if (created > 0) parts.push(`${created} created`);\n if (updated > 0) parts.push(`${updated} updated`);\n if (skipped > 0) parts.push(`${skipped} skipped`);\n return `${agents.length} ${pluralize(agents.length, \"agent\")} total (${parts.join(\", \")})`;\n}\n\nfunction summarizeImportProjectResults(projects: OrganizationPortabilityImportResult[\"projects\"]): string {\n if (projects.length === 0) return \"0 projects changed\";\n const created = projects.filter((project) => project.action === \"created\").length;\n const updated = projects.filter((project) => project.action === \"updated\").length;\n const skipped = projects.filter((project) => project.action === \"skipped\").length;\n const parts: string[] = [];\n if (created > 0) parts.push(`${created} created`);\n if (updated > 0) parts.push(`${updated} updated`);\n if (skipped > 0) parts.push(`${skipped} skipped`);\n return `${projects.length} ${pluralize(projects.length, \"project\")} total (${parts.join(\", \")})`;\n}\n\nfunction actionChip(action: string): string {\n switch (action) {\n case \"create\":\n case \"created\":\n return pc.green(action);\n case \"update\":\n case \"updated\":\n return pc.yellow(action);\n case \"skip\":\n case \"skipped\":\n case \"none\":\n case \"unchanged\":\n return pc.dim(action);\n default:\n return action;\n }\n}\n\nfunction appendPreviewExamples(\n lines: string[],\n title: string,\n entries: Array<{ action: string; label: string; reason?: string | null }>,\n): void {\n if (entries.length === 0) return;\n lines.push(\"\");\n lines.push(pc.bold(title));\n const shown = entries.slice(0, IMPORT_PREVIEW_SAMPLE_LIMIT);\n for (const entry of shown) {\n const reason = entry.reason?.trim() ? pc.dim(` (${entry.reason.trim()})`) : \"\";\n lines.push(`- ${actionChip(entry.action)} ${entry.label}${reason}`);\n }\n if (entries.length > shown.length) {\n lines.push(pc.dim(`- +${entries.length - shown.length} more`));\n }\n}\n\nfunction appendMessageBlock(lines: string[], title: string, messages: string[]): void {\n if (messages.length === 0) return;\n lines.push(\"\");\n lines.push(pc.bold(title));\n for (const message of messages) {\n lines.push(`- ${message}`);\n }\n}\n\nexport function renderCompanyImportPreview(\n preview: OrganizationPortabilityPreviewResult,\n meta: {\n sourceLabel: string;\n targetLabel: string;\n infoMessages?: string[];\n },\n): string {\n const lines: string[] = [\n `${pc.bold(\"Source\")} ${meta.sourceLabel}`,\n `${pc.bold(\"Target\")} ${meta.targetLabel}`,\n `${pc.bold(\"Include\")} ${summarizeInclude(preview.include)}`,\n `${pc.bold(\"Mode\")} ${preview.collisionStrategy} collisions`,\n \"\",\n pc.bold(\"Package\"),\n `- organization: ${preview.manifest.organization?.name ?? preview.manifest.source?.organizationName ?? \"not included\"}`,\n `- agents: ${preview.manifest.agents.length}`,\n `- projects: ${preview.manifest.projects.length}`,\n `- tasks: ${preview.manifest.issues.length}`,\n `- skills: ${preview.manifest.skills.length}`,\n ];\n\n if (preview.envInputs.length > 0) {\n const requiredCount = preview.envInputs.filter((item) => item.requirement === \"required\").length;\n lines.push(`- env inputs: ${preview.envInputs.length} (${requiredCount} required)`);\n }\n\n lines.push(\"\");\n lines.push(pc.bold(\"Plan\"));\n lines.push(\n `- organization: ${actionChip(\n preview.plan.organizationAction === \"none\" ? \"unchanged\" : preview.plan.organizationAction,\n )}`,\n );\n lines.push(`- agents: ${summarizePlanCounts(preview.plan.agentPlans, \"agent\")}`);\n lines.push(`- projects: ${summarizePlanCounts(preview.plan.projectPlans, \"project\")}`);\n lines.push(`- tasks: ${summarizePlanCounts(preview.plan.issuePlans, \"task\")}`);\n if (preview.include.skills) {\n lines.push(`- skills: ${preview.manifest.skills.length} ${pluralize(preview.manifest.skills.length, \"skill\")} packaged`);\n }\n\n appendPreviewExamples(\n lines,\n \"Agent examples\",\n preview.plan.agentPlans.map((plan) => ({\n action: plan.action,\n label: `${plan.slug} -> ${plan.plannedName}`,\n reason: plan.reason,\n })),\n );\n appendPreviewExamples(\n lines,\n \"Project examples\",\n preview.plan.projectPlans.map((plan) => ({\n action: plan.action,\n label: `${plan.slug} -> ${plan.plannedName}`,\n reason: plan.reason,\n })),\n );\n appendPreviewExamples(\n lines,\n \"Task examples\",\n preview.plan.issuePlans.map((plan) => ({\n action: plan.action,\n label: `${plan.slug} -> ${plan.plannedTitle}`,\n reason: plan.reason,\n })),\n );\n\n appendMessageBlock(lines, pc.cyan(\"Info\"), meta.infoMessages ?? []);\n appendMessageBlock(lines, pc.yellow(\"Warnings\"), preview.warnings);\n appendMessageBlock(lines, pc.red(\"Errors\"), preview.errors);\n\n return lines.join(\"\\n\");\n}\n\nexport function renderCompanyImportResult(\n result: OrganizationPortabilityImportResult,\n meta: { targetLabel: string; organizationUrl?: string; infoMessages?: string[] },\n): string {\n const lines: string[] = [\n `${pc.bold(\"Target\")} ${meta.targetLabel}`,\n `${pc.bold(\"Organization\")} ${result.organization.name} (${actionChip(result.organization.action)})`,\n `${pc.bold(\"Agents\")} ${summarizeImportAgentResults(result.agents)}`,\n `${pc.bold(\"Projects\")} ${summarizeImportProjectResults(result.projects)}`,\n ];\n\n if (meta.organizationUrl) {\n lines.splice(1, 0, `${pc.bold(\"URL\")} ${meta.organizationUrl}`);\n }\n\n appendPreviewExamples(\n lines,\n \"Agent results\",\n result.agents.map((agent) => ({\n action: agent.action,\n label: `${agent.slug} -> ${agent.name}`,\n reason: agent.reason,\n })),\n );\n appendPreviewExamples(\n lines,\n \"Project results\",\n result.projects.map((project) => ({\n action: project.action,\n label: `${project.slug} -> ${project.name}`,\n reason: project.reason,\n })),\n );\n\n if (result.envInputs.length > 0) {\n lines.push(\"\");\n lines.push(pc.bold(\"Env inputs\"));\n lines.push(\n `- ${result.envInputs.length} ${pluralize(result.envInputs.length, \"input\")} may need values after import`,\n );\n }\n\n appendMessageBlock(lines, pc.cyan(\"Info\"), meta.infoMessages ?? []);\n appendMessageBlock(lines, pc.yellow(\"Warnings\"), result.warnings);\n\n return lines.join(\"\\n\");\n}\n\nfunction printCompanyImportView(title: string, body: string, opts?: { interactive?: boolean }): void {\n if (opts?.interactive) {\n p.note(body, title);\n return;\n }\n console.log(pc.bold(title));\n console.log(body);\n}\n\nexport function resolveCompanyImportApiPath(input: {\n dryRun: boolean;\n targetMode: \"new_organization\" | \"existing_organization\";\n orgId?: string | null;\n}): string {\n if (input.targetMode === \"existing_organization\") {\n const orgId = input.orgId?.trim();\n if (!orgId) {\n throw new Error(\"Existing-organization imports require an orgId to resolve the API route.\");\n }\n return input.dryRun\n ? `/api/orgs/${orgId}/imports/preview`\n : `/api/orgs/${orgId}/imports/apply`;\n }\n\n return input.dryRun ? \"/api/orgs/import/preview\" : \"/api/orgs/import\";\n}\n\nexport function buildCompanyDashboardUrl(apiBase: string, issuePrefix: string): string {\n const url = new URL(apiBase);\n const normalizedPrefix = issuePrefix.trim().replace(/^\\/+|\\/+$/g, \"\");\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/${normalizedPrefix}/dashboard`;\n url.search = \"\";\n url.hash = \"\";\n return url.toString();\n}\n\nexport function resolveCompanyImportApplyConfirmationMode(input: {\n yes?: boolean;\n interactive: boolean;\n json: boolean;\n}): \"skip\" | \"prompt\" {\n if (input.yes) {\n return \"skip\";\n }\n if (input.json) {\n throw new Error(\n \"Applying an organization import with --json requires --yes. Use --dry-run first to inspect the preview.\",\n );\n }\n if (!input.interactive) {\n throw new Error(\n \"Applying an organization import from a non-interactive terminal requires --yes. Use --dry-run first to inspect the preview.\",\n );\n }\n return \"prompt\";\n}\n\nexport function isHttpUrl(input: string): boolean {\n return /^https?:\\/\\//i.test(input.trim());\n}\n\nexport function isGithubUrl(input: string): boolean {\n return /^https?:\\/\\/github\\.com\\//i.test(input.trim());\n}\n\nfunction isGithubSegment(input: string): boolean {\n return /^[A-Za-z0-9._-]+$/.test(input);\n}\n\nexport function isGithubShorthand(input: string): boolean {\n const trimmed = input.trim();\n if (!trimmed || isHttpUrl(trimmed)) return false;\n if (\n trimmed.startsWith(\".\") ||\n trimmed.startsWith(\"/\") ||\n trimmed.startsWith(\"~\") ||\n trimmed.includes(\"\\\\\") ||\n /^[A-Za-z]:/.test(trimmed)\n ) {\n return false;\n }\n\n const segments = trimmed.split(\"/\").filter(Boolean);\n return segments.length >= 2 && segments.every(isGithubSegment);\n}\n\nfunction normalizeGithubImportPath(input: string | null | undefined): string | null {\n if (!input) return null;\n const trimmed = input.trim().replace(/^\\/+|\\/+$/g, \"\");\n return trimmed || null;\n}\n\nfunction buildGithubImportUrl(input: {\n owner: string;\n repo: string;\n ref?: string | null;\n path?: string | null;\n companyPath?: string | null;\n}): string {\n const url = new URL(`https://github.com/${input.owner}/${input.repo.replace(/\\.git$/i, \"\")}`);\n const ref = input.ref?.trim();\n if (ref) {\n url.searchParams.set(\"ref\", ref);\n }\n const companyPath = normalizeGithubImportPath(input.companyPath);\n if (companyPath) {\n url.searchParams.set(\"companyPath\", companyPath);\n return url.toString();\n }\n const sourcePath = normalizeGithubImportPath(input.path);\n if (sourcePath) {\n url.searchParams.set(\"path\", sourcePath);\n }\n return url.toString();\n}\n\nexport function normalizeGithubImportSource(input: string, refOverride?: string): string {\n const trimmed = input.trim();\n const ref = refOverride?.trim();\n\n if (isGithubShorthand(trimmed)) {\n const [owner, repo, ...repoPath] = trimmed.split(\"/\").filter(Boolean);\n return buildGithubImportUrl({\n owner: owner!,\n repo: repo!,\n ref: ref || \"main\",\n path: repoPath.join(\"/\"),\n });\n }\n\n if (!isGithubUrl(trimmed)) {\n throw new Error(\"GitHub source must be a github.com URL or owner/repo[/path] shorthand.\");\n }\n if (!ref) {\n return trimmed;\n }\n\n const url = new URL(trimmed);\n const parts = url.pathname.split(\"/\").filter(Boolean);\n if (parts.length < 2) {\n throw new Error(\"Invalid GitHub URL.\");\n }\n\n const owner = parts[0]!;\n const repo = parts[1]!;\n const existingPath = normalizeGithubImportPath(url.searchParams.get(\"path\"));\n const existingCompanyPath = normalizeGithubImportPath(url.searchParams.get(\"companyPath\"));\n if (existingCompanyPath) {\n return buildGithubImportUrl({ owner, repo, ref, companyPath: existingCompanyPath });\n }\n if (existingPath) {\n return buildGithubImportUrl({ owner, repo, ref, path: existingPath });\n }\n if (parts[2] === \"tree\") {\n return buildGithubImportUrl({ owner, repo, ref, path: parts.slice(4).join(\"/\") });\n }\n if (parts[2] === \"blob\") {\n return buildGithubImportUrl({ owner, repo, ref, companyPath: parts.slice(4).join(\"/\") });\n }\n return buildGithubImportUrl({ owner, repo, ref });\n}\n\nasync function pathExists(inputPath: string): Promise<boolean> {\n try {\n await stat(path.resolve(inputPath));\n return true;\n } catch {\n return false;\n }\n}\n\nasync function collectPackageFiles(\n root: string,\n current: string,\n files: Record<string, OrganizationPortabilityFileEntry>,\n): Promise<void> {\n const entries = await readdir(current, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name.startsWith(\".git\")) continue;\n const absolutePath = path.join(current, entry.name);\n if (entry.isDirectory()) {\n await collectPackageFiles(root, absolutePath, files);\n continue;\n }\n if (!entry.isFile()) continue;\n const relativePath = path.relative(root, absolutePath).replace(/\\\\/g, \"/\");\n if (!shouldIncludePortableFile(relativePath)) continue;\n files[relativePath] = readPortableFileEntry(relativePath, await readFile(absolutePath));\n }\n}\n\nexport async function resolveInlineSourceFromPath(inputPath: string): Promise<{\n rootPath: string;\n files: Record<string, OrganizationPortabilityFileEntry>;\n}> {\n const resolved = path.resolve(inputPath);\n const resolvedStat = await stat(resolved);\n if (resolvedStat.isFile() && path.extname(resolved).toLowerCase() === \".zip\") {\n const archive = await readZipArchive(await readFile(resolved));\n const filteredFiles = Object.fromEntries(\n Object.entries(archive.files).filter(([relativePath]) => shouldIncludePortableFile(relativePath)),\n );\n return {\n rootPath: archive.rootPath ?? path.basename(resolved, \".zip\"),\n files: filteredFiles,\n };\n }\n\n const rootDir = resolvedStat.isDirectory() ? resolved : path.dirname(resolved);\n const files: Record<string, OrganizationPortabilityFileEntry> = {};\n await collectPackageFiles(rootDir, rootDir, files);\n return {\n rootPath: path.basename(rootDir),\n files,\n };\n}\n\nasync function writeExportToFolder(outDir: string, exported: OrganizationPortabilityExportResult): Promise<void> {\n const root = path.resolve(outDir);\n await mkdir(root, { recursive: true });\n for (const [relativePath, content] of Object.entries(exported.files)) {\n const normalized = relativePath.replace(/\\\\/g, \"/\");\n const filePath = path.join(root, normalized);\n await mkdir(path.dirname(filePath), { recursive: true });\n const writeValue = portableFileEntryToWriteValue(content);\n if (typeof writeValue === \"string\") {\n await writeFile(filePath, writeValue, \"utf8\");\n } else {\n await writeFile(filePath, writeValue);\n }\n }\n}\n\nasync function confirmOverwriteExportDirectory(outDir: string): Promise<void> {\n const root = path.resolve(outDir);\n const stats = await stat(root).catch(() => null);\n if (!stats) return;\n if (!stats.isDirectory()) {\n throw new Error(`Export output path ${root} exists and is not a directory.`);\n }\n\n const entries = await readdir(root);\n if (entries.length === 0) return;\n\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n throw new Error(`Export output directory ${root} already contains files. Re-run interactively or choose an empty directory.`);\n }\n\n const confirmed = await p.confirm({\n message: `Overwrite existing files in ${root}?`,\n initialValue: false,\n });\n\n if (p.isCancel(confirmed) || !confirmed) {\n throw new Error(\"Export cancelled.\");\n }\n}\n\nfunction matchesPrefix(company: Organization, selector: string): boolean {\n return company.issuePrefix.toUpperCase() === selector.toUpperCase();\n}\n\nexport function resolveCompanyForDeletion(\n organizations: Organization[],\n selectorRaw: string,\n by: CompanyDeleteSelectorMode = \"auto\",\n): Organization {\n const selector = normalizeSelector(selectorRaw);\n if (!selector) {\n throw new Error(\"Organization selector is required.\");\n }\n\n const idMatch = organizations.find((company) => company.id === selector);\n const prefixMatch = organizations.find((company) => matchesPrefix(company, selector));\n\n if (by === \"id\") {\n if (!idMatch) {\n throw new Error(`No organization found by ID '${selector}'.`);\n }\n return idMatch;\n }\n\n if (by === \"prefix\") {\n if (!prefixMatch) {\n throw new Error(`No organization found by shortname/prefix '${selector}'.`);\n }\n return prefixMatch;\n }\n\n if (idMatch && prefixMatch && idMatch.id !== prefixMatch.id) {\n throw new Error(\n `Selector '${selector}' is ambiguous (matches both an ID and a shortname). Re-run with --by id or --by prefix.`,\n );\n }\n\n if (idMatch) return idMatch;\n if (prefixMatch) return prefixMatch;\n\n throw new Error(\n `No organization found for selector '${selector}'. Use organization ID or issue prefix (for example PAP).`,\n );\n}\n\nexport function assertDeleteConfirmation(company: Organization, opts: CompanyDeleteOptions): void {\n if (!opts.yes) {\n throw new Error(\"Deletion requires --yes.\");\n }\n\n const confirm = opts.confirm?.trim();\n if (!confirm) {\n throw new Error(\n \"Deletion requires --confirm <value> where value matches the company ID or issue prefix.\",\n );\n }\n\n const confirmsById = confirm === company.id;\n const confirmsByPrefix = confirm.toUpperCase() === company.issuePrefix.toUpperCase();\n if (!confirmsById && !confirmsByPrefix) {\n throw new Error(\n `Confirmation '${confirm}' does not match target organization. Expected ID '${company.id}' or prefix '${company.issuePrefix}'.`,\n );\n }\n}\n\nfunction assertDeleteFlags(opts: CompanyDeleteOptions): void {\n if (!opts.yes) {\n throw new Error(\"Deletion requires --yes.\");\n }\n if (!opts.confirm?.trim()) {\n throw new Error(\n \"Deletion requires --confirm <value> where value matches the company ID or issue prefix.\",\n );\n }\n}\n\nexport function registerCompanyCommands(program: Command): void {\n const company = program.command(\"org\").description(\"Organization operations\");\n\n addCommonClientOptions(\n company\n .command(\"list\")\n .description(\"List organizations\")\n .action(async (opts: CompanyCommandOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<Organization[]>(\"/api/orgs\")) ?? [];\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n const formatted = rows.map((row) => ({\n id: row.id,\n name: row.name,\n status: row.status,\n budgetMonthlyCents: row.budgetMonthlyCents,\n spentMonthlyCents: row.spentMonthlyCents,\n requireBoardApprovalForNewAgents: row.requireBoardApprovalForNewAgents,\n }));\n for (const row of formatted) {\n console.log(formatInlineRecord(row));\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"get\")\n .description(\"Get one organization\")\n .argument(\"<orgId>\", \"Organization ID\")\n .action(async (orgId: string, opts: CompanyCommandOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<Organization>(`/api/orgs/${orgId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"export\")\n .description(\"Export an organization into a portable markdown package\")\n .argument(\"<orgId>\", \"Organization ID\")\n .requiredOption(\"--out <path>\", \"Output directory\")\n .option(\n \"--include <values>\",\n \"Comma-separated include set: organization,agents,projects,issues,tasks,skills\",\n \"organization,agents\",\n )\n .option(\"--skills <values>\", \"Comma-separated skill slugs/keys to export\")\n .option(\"--projects <values>\", \"Comma-separated project shortnames/ids to export\")\n .option(\"--issues <values>\", \"Comma-separated issue identifiers/ids to export\")\n .option(\"--project-issues <values>\", \"Comma-separated project shortnames/ids whose issues should be exported\")\n .option(\"--expand-referenced-skills\", \"Vendor skill contents instead of exporting upstream references\", false)\n .action(async (orgId: string, opts: CompanyExportOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const include = parseInclude(opts.include);\n const exported = await ctx.api.post<OrganizationPortabilityExportResult>(\n `/api/orgs/${orgId}/export`,\n {\n include,\n skills: parseCsvValues(opts.skills),\n projects: parseCsvValues(opts.projects),\n issues: parseCsvValues(opts.issues),\n projectIssues: parseCsvValues(opts.projectIssues),\n expandReferencedSkills: Boolean(opts.expandReferencedSkills),\n },\n );\n if (!exported) {\n throw new Error(\"Export request returned no data\");\n }\n await confirmOverwriteExportDirectory(opts.out!);\n await writeExportToFolder(opts.out!, exported);\n printOutput(\n {\n ok: true,\n out: path.resolve(opts.out!),\n rootPath: exported.rootPath,\n filesWritten: Object.keys(exported.files).length,\n rudderExtensionPath: exported.rudderExtensionPath,\n warningCount: exported.warnings.length,\n },\n { json: ctx.json },\n );\n if (!ctx.json && exported.warnings.length > 0) {\n for (const warning of exported.warnings) {\n console.log(`warning=${warning}`);\n }\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"import\")\n .description(\"Import a portable markdown organization package from local path, URL, or GitHub\")\n .argument(\"<fromPathOrUrl>\", \"Source path or URL\")\n .option(\"--include <values>\", \"Comma-separated include set: organization,agents,projects,issues,tasks,skills\")\n .option(\"--target <mode>\", \"Target mode: new | existing\")\n .option(\"-O, --org-id <id>\", \"Existing target organization ID\")\n .option(\"--new-organization-name <name>\", \"Name override for --target new\")\n .option(\"--agents <list>\", \"Comma-separated agent slugs to import, or all\", \"all\")\n .option(\"--collision <mode>\", \"Collision strategy: rename | skip | replace\", \"rename\")\n .option(\"--ref <value>\", \"Git ref to use for GitHub imports (branch, tag, or commit)\")\n .option(\"--rudder-url <url>\", \"Alias for --api-base on this command\")\n .option(\"--yes\", \"Accept default selection and skip the pre-import confirmation prompt\", false)\n .option(\"--dry-run\", \"Run preview only without applying\", false)\n .action(async (fromPathOrUrl: string, opts: CompanyImportOptions) => {\n try {\n if (!opts.apiBase?.trim() && opts.rudderUrl?.trim()) {\n opts.apiBase = opts.rudderUrl.trim();\n }\n const ctx = resolveCommandContext(opts);\n const interactiveView = isInteractiveTerminal() && !ctx.json;\n const from = fromPathOrUrl.trim();\n if (!from) {\n throw new Error(\"Source path or URL is required.\");\n }\n\n const include = resolveImportInclude(opts.include);\n const agents = parseAgents(opts.agents);\n const collision = (opts.collision ?? \"rename\").toLowerCase() as CompanyCollisionMode;\n if (![\"rename\", \"skip\", \"replace\"].includes(collision)) {\n throw new Error(\"Invalid --collision value. Use: rename, skip, replace\");\n }\n\n const inferredTarget = opts.target ?? (opts.orgId || ctx.orgId ? \"existing\" : \"new\");\n const target = inferredTarget.toLowerCase() as CompanyImportTargetMode;\n if (![\"new\", \"existing\"].includes(target)) {\n throw new Error(\"Invalid --target value. Use: new | existing\");\n }\n\n const existingTargetOrganizationId = opts.orgId?.trim() || ctx.orgId;\n const targetPayload =\n target === \"existing\"\n ? {\n mode: \"existing_organization\" as const,\n orgId: existingTargetOrganizationId,\n }\n : {\n mode: \"new_organization\" as const,\n newOrganizationName: opts.newOrganizationName?.trim() || null,\n };\n\n if (targetPayload.mode === \"existing_organization\" && !targetPayload.orgId) {\n throw new Error(\"Target existing organization requires --org-id (or context default orgId).\");\n }\n\n let sourcePayload:\n | { type: \"inline\"; rootPath?: string | null; files: Record<string, OrganizationPortabilityFileEntry> }\n | { type: \"github\"; url: string };\n\n const treatAsLocalPath = !isHttpUrl(from) && await pathExists(from);\n const isGithubSource = isGithubUrl(from) || (isGithubShorthand(from) && !treatAsLocalPath);\n\n if (isHttpUrl(from) || isGithubSource) {\n if (!isGithubUrl(from) && !isGithubShorthand(from)) {\n throw new Error(\n \"Only GitHub URLs and local paths are supported for import. \" +\n \"Generic HTTP URLs are not supported. Use a GitHub URL (https://github.com/...) or a local directory path.\",\n );\n }\n sourcePayload = { type: \"github\", url: normalizeGithubImportSource(from, opts.ref) };\n } else {\n if (opts.ref?.trim()) {\n throw new Error(\"--ref is only supported for GitHub import sources.\");\n }\n const inline = await resolveInlineSourceFromPath(from);\n sourcePayload = {\n type: \"inline\",\n rootPath: inline.rootPath,\n files: inline.files,\n };\n }\n\n const sourceLabel = formatSourceLabel(sourcePayload);\n const targetLabel = formatTargetLabel(targetPayload);\n const previewApiPath = resolveCompanyImportApiPath({\n dryRun: true,\n targetMode: targetPayload.mode,\n orgId: targetPayload.mode === \"existing_organization\" ? targetPayload.orgId : null,\n });\n\n let selectedFiles: string[] | undefined;\n if (interactiveView && !opts.yes && !opts.include?.trim()) {\n const initialPreview = await ctx.api.post<OrganizationPortabilityPreviewResult>(previewApiPath, {\n source: sourcePayload,\n include,\n target: targetPayload,\n agents,\n collisionStrategy: collision,\n });\n if (!initialPreview) {\n throw new Error(\"Import preview returned no data.\");\n }\n selectedFiles = await promptForImportSelection(initialPreview);\n }\n\n const previewPayload = {\n source: sourcePayload,\n include,\n target: targetPayload,\n agents,\n collisionStrategy: collision,\n selectedFiles,\n };\n const preview = await ctx.api.post<OrganizationPortabilityPreviewResult>(previewApiPath, previewPayload);\n if (!preview) {\n throw new Error(\"Import preview returned no data.\");\n }\n const agentRuntimeOverrides = buildDefaultImportAdapterOverrides(preview);\n const adapterMessages = buildDefaultImportAdapterMessages(agentRuntimeOverrides);\n\n if (opts.dryRun) {\n if (ctx.json) {\n printOutput(preview, { json: true });\n } else {\n printCompanyImportView(\n \"Import Preview\",\n renderCompanyImportPreview(preview, {\n sourceLabel,\n targetLabel: formatTargetLabel(targetPayload, preview),\n infoMessages: adapterMessages,\n }),\n { interactive: interactiveView },\n );\n }\n return;\n }\n\n if (!ctx.json) {\n printCompanyImportView(\n \"Import Preview\",\n renderCompanyImportPreview(preview, {\n sourceLabel,\n targetLabel: formatTargetLabel(targetPayload, preview),\n infoMessages: adapterMessages,\n }),\n { interactive: interactiveView },\n );\n }\n\n const confirmationMode = resolveCompanyImportApplyConfirmationMode({\n yes: opts.yes,\n interactive: interactiveView,\n json: ctx.json,\n });\n if (confirmationMode === \"prompt\") {\n const confirmed = await p.confirm({\n message: \"Apply this import? (y/N)\",\n initialValue: false,\n });\n if (p.isCancel(confirmed) || !confirmed) {\n p.log.warn(\"Import cancelled.\");\n return;\n }\n }\n\n const importApiPath = resolveCompanyImportApiPath({\n dryRun: false,\n targetMode: targetPayload.mode,\n orgId: targetPayload.mode === \"existing_organization\" ? targetPayload.orgId : null,\n });\n const imported = await ctx.api.post<OrganizationPortabilityImportResult>(importApiPath, {\n ...previewPayload,\n agentRuntimeOverrides,\n });\n if (!imported) {\n throw new Error(\"Import request returned no data.\");\n }\n let organizationUrl: string | undefined;\n if (!ctx.json) {\n try {\n const importedOrganization = await ctx.api.get<Organization>(`/api/orgs/${imported.organization.id}`);\n const issuePrefix = importedOrganization?.issuePrefix?.trim();\n if (issuePrefix) {\n organizationUrl = buildCompanyDashboardUrl(ctx.api.apiBase, issuePrefix);\n }\n } catch {\n organizationUrl = undefined;\n }\n }\n if (ctx.json) {\n printOutput(imported, { json: true });\n } else {\n printCompanyImportView(\n \"Import Result\",\n renderCompanyImportResult(imported, {\n targetLabel,\n organizationUrl,\n infoMessages: adapterMessages,\n }),\n { interactive: interactiveView },\n );\n if (interactiveView && organizationUrl) {\n const openImportedOrganization = await p.confirm({\n message: \"Open the imported organization in your browser?\",\n initialValue: true,\n });\n if (!p.isCancel(openImportedOrganization) && openImportedOrganization) {\n if (openUrl(organizationUrl)) {\n p.log.info(`Opened ${organizationUrl}`);\n } else {\n p.log.warn(`Could not open your browser automatically. Open this URL manually:\\n${organizationUrl}`);\n }\n }\n }\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"delete\")\n .description(\"Delete an organization by ID or shortname/prefix (destructive)\")\n .argument(\"<selector>\", \"Organization ID or issue prefix (for example PAP)\")\n .option(\n \"--by <mode>\",\n \"Selector mode: auto | id | prefix\",\n \"auto\",\n )\n .option(\"--yes\", \"Required safety flag to confirm destructive action\", false)\n .option(\n \"--confirm <value>\",\n \"Required safety value: target organization ID or shortname/prefix\",\n )\n .action(async (selector: string, opts: CompanyDeleteOptions) => {\n try {\n const by = (opts.by ?? \"auto\").trim().toLowerCase() as CompanyDeleteSelectorMode;\n if (![\"auto\", \"id\", \"prefix\"].includes(by)) {\n throw new Error(`Invalid --by mode '${opts.by}'. Expected one of: auto, id, prefix.`);\n }\n\n const ctx = resolveCommandContext(opts);\n const normalizedSelector = normalizeSelector(selector);\n assertDeleteFlags(opts);\n\n let target: Organization | null = null;\n const shouldTryIdLookup = by === \"id\" || (by === \"auto\" && isUuidLike(normalizedSelector));\n if (shouldTryIdLookup) {\n const byId = await ctx.api.get<Organization>(`/api/orgs/${normalizedSelector}`, { ignoreNotFound: true });\n if (byId) {\n target = byId;\n } else if (by === \"id\") {\n throw new Error(`No organization found by ID '${normalizedSelector}'.`);\n }\n }\n\n if (!target && ctx.orgId) {\n const scoped = await ctx.api.get<Organization>(`/api/orgs/${ctx.orgId}`, { ignoreNotFound: true });\n if (scoped) {\n try {\n target = resolveCompanyForDeletion([scoped], normalizedSelector, by);\n } catch {\n // Fallback to board-wide lookup below.\n }\n }\n }\n\n if (!target) {\n try {\n const organizations = (await ctx.api.get<Organization[]>(\"/api/orgs\")) ?? [];\n target = resolveCompanyForDeletion(organizations, normalizedSelector, by);\n } catch (error) {\n if (error instanceof ApiRequestError && error.status === 403 && error.message.includes(\"Board access required\")) {\n throw new Error(\n \"Board access is required to resolve organizations across the instance. Use an organization ID/prefix for your current organization, or run with board authentication.\",\n );\n }\n throw error;\n }\n }\n\n if (!target) {\n throw new Error(`No organization found for selector '${normalizedSelector}'.`);\n }\n\n assertDeleteConfirmation(target, opts);\n\n await ctx.api.delete<{ ok: true }>(`/api/orgs/${target.id}`);\n\n printOutput(\n {\n ok: true,\n deletedOrganizationId: target.id,\n deletedOrganizationName: target.name,\n deletedOrganizationPrefix: target.issuePrefix,\n },\n { json: ctx.json },\n );\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n", "import { inflateRawSync } from \"node:zlib\";\nimport path from \"node:path\";\nimport type { OrganizationPortabilityFileEntry } from \"@rudderhq/shared\";\n\nconst textDecoder = new TextDecoder();\n\nexport const binaryContentTypeByExtension: Record<string, string> = {\n \".gif\": \"image/gif\",\n \".jpeg\": \"image/jpeg\",\n \".jpg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".svg\": \"image/svg+xml\",\n \".webp\": \"image/webp\",\n};\n\nfunction normalizeArchivePath(pathValue: string) {\n return pathValue\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .filter(Boolean)\n .join(\"/\");\n}\n\nfunction readUint16(source: Uint8Array, offset: number) {\n return source[offset]! | (source[offset + 1]! << 8);\n}\n\nfunction readUint32(source: Uint8Array, offset: number) {\n return (\n source[offset]! |\n (source[offset + 1]! << 8) |\n (source[offset + 2]! << 16) |\n (source[offset + 3]! << 24)\n ) >>> 0;\n}\n\nfunction sharedArchiveRoot(paths: string[]) {\n if (paths.length === 0) return null;\n const firstSegments = paths\n .map((entry) => normalizeArchivePath(entry).split(\"/\").filter(Boolean))\n .filter((parts) => parts.length > 0);\n if (firstSegments.length === 0) return null;\n const candidate = firstSegments[0]![0]!;\n return firstSegments.every((parts) => parts.length > 1 && parts[0] === candidate)\n ? candidate\n : null;\n}\n\nfunction bytesToPortableFileEntry(pathValue: string, bytes: Uint8Array): OrganizationPortabilityFileEntry {\n const contentType = binaryContentTypeByExtension[path.extname(pathValue).toLowerCase()];\n if (!contentType) return textDecoder.decode(bytes);\n return {\n encoding: \"base64\",\n data: Buffer.from(bytes).toString(\"base64\"),\n contentType,\n };\n}\n\nasync function inflateZipEntry(compressionMethod: number, bytes: Uint8Array) {\n if (compressionMethod === 0) return bytes;\n if (compressionMethod !== 8) {\n throw new Error(\"Unsupported zip archive: only STORE and DEFLATE entries are supported.\");\n }\n return new Uint8Array(inflateRawSync(bytes));\n}\n\nexport async function readZipArchive(source: ArrayBuffer | Uint8Array): Promise<{\n rootPath: string | null;\n files: Record<string, OrganizationPortabilityFileEntry>;\n}> {\n const bytes = source instanceof Uint8Array ? source : new Uint8Array(source);\n const entries: Array<{ path: string; body: OrganizationPortabilityFileEntry }> = [];\n let offset = 0;\n\n while (offset + 4 <= bytes.length) {\n const signature = readUint32(bytes, offset);\n if (signature === 0x02014b50 || signature === 0x06054b50) break;\n if (signature !== 0x04034b50) {\n throw new Error(\"Invalid zip archive: unsupported local file header.\");\n }\n\n if (offset + 30 > bytes.length) {\n throw new Error(\"Invalid zip archive: truncated local file header.\");\n }\n\n const generalPurposeFlag = readUint16(bytes, offset + 6);\n const compressionMethod = readUint16(bytes, offset + 8);\n const compressedSize = readUint32(bytes, offset + 18);\n const fileNameLength = readUint16(bytes, offset + 26);\n const extraFieldLength = readUint16(bytes, offset + 28);\n\n if ((generalPurposeFlag & 0x0008) !== 0) {\n throw new Error(\"Unsupported zip archive: data descriptors are not supported.\");\n }\n\n const nameOffset = offset + 30;\n const bodyOffset = nameOffset + fileNameLength + extraFieldLength;\n const bodyEnd = bodyOffset + compressedSize;\n if (bodyEnd > bytes.length) {\n throw new Error(\"Invalid zip archive: truncated file contents.\");\n }\n\n const rawArchivePath = textDecoder.decode(bytes.slice(nameOffset, nameOffset + fileNameLength));\n const archivePath = normalizeArchivePath(rawArchivePath);\n const isDirectoryEntry = /\\/$/.test(rawArchivePath.replace(/\\\\/g, \"/\"));\n if (archivePath && !isDirectoryEntry) {\n const entryBytes = await inflateZipEntry(compressionMethod, bytes.slice(bodyOffset, bodyEnd));\n entries.push({\n path: archivePath,\n body: bytesToPortableFileEntry(archivePath, entryBytes),\n });\n }\n\n offset = bodyEnd;\n }\n\n const rootPath = sharedArchiveRoot(entries.map((entry) => entry.path));\n const files: Record<string, OrganizationPortabilityFileEntry> = {};\n for (const entry of entries) {\n const normalizedPath =\n rootPath && entry.path.startsWith(`${rootPath}/`)\n ? entry.path.slice(rootPath.length + 1)\n : entry.path;\n if (!normalizedPath) continue;\n files[normalizedPath] = entry.body;\n }\n\n return { rootPath, files };\n}\n", "import { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport {\n addIssueCommentSchema,\n checkoutIssueSchema,\n createIssueSchema,\n reportIssueCommitSchema,\n updateIssueSchema,\n upsertIssueDocumentSchema,\n type DocumentRevision,\n type IssueDocument,\n type IssueDocumentSummary,\n type LegacyPlanDocument,\n type Issue,\n type IssueAttachment,\n type IssueComment,\n type IssueCommitReport,\n} from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport { getAgentCliCapabilityById } from \"../../agent-v1-registry.js\";\n\ninterface IssueBaseOptions extends BaseClientOptions {\n status?: string;\n assigneeAgentId?: string;\n projectId?: string;\n query?: string;\n match?: string;\n}\n\ninterface IssueSearchOptions extends BaseClientOptions {\n status?: string;\n assigneeAgentId?: string;\n projectId?: string;\n}\n\ninterface IssueCreateOptions extends BaseClientOptions {\n title: string;\n description?: string;\n status?: string;\n priority?: string;\n assigneeAgentId?: string;\n projectId?: string;\n goalId?: string;\n parentId?: string;\n requestDepth?: string;\n billingCode?: string;\n}\n\ninterface IssueUpdateOptions extends BaseClientOptions {\n title?: string;\n description?: string;\n status?: string;\n priority?: string;\n assigneeAgentId?: string;\n projectId?: string;\n goalId?: string;\n parentId?: string;\n requestDepth?: string;\n billingCode?: string;\n comment?: string;\n image?: string[];\n hiddenAt?: string;\n}\n\ninterface IssueCommentOptions extends BaseClientOptions {\n body: string;\n image?: string[];\n reopen?: boolean;\n}\n\ninterface IssueCommitOptions extends BaseClientOptions {\n sha: string;\n message: string;\n branch?: string;\n repoPath?: string;\n workspacePath?: string;\n count?: string;\n}\n\ninterface IssueCheckoutOptions extends BaseClientOptions {\n agentId?: string;\n expectedStatuses?: string;\n}\n\ninterface IssueStatusCommentOptions extends BaseClientOptions {\n comment: string;\n image?: string[];\n}\n\ninterface IssueReviewOptions extends BaseClientOptions {\n decision: \"approve\" | \"request_changes\" | \"needs_followup\" | \"blocked\";\n comment: string;\n}\n\ntype CommandContext = ReturnType<typeof resolveCommandContext>;\n\ninterface IssueContextOptions extends BaseClientOptions {\n wakeCommentId?: string;\n}\n\ninterface IssueCommentsListOptions extends BaseClientOptions {\n after?: string;\n order?: string;\n}\n\ninterface IssueDocumentPutOptions extends BaseClientOptions {\n body: string;\n title?: string;\n format?: string;\n changeSummary?: string;\n baseRevisionId?: string;\n}\n\ninterface IssueHeartbeatContext {\n issue: {\n id: string;\n identifier: string | null;\n title: string;\n description: string | null;\n status: string;\n priority: string;\n projectId: string | null;\n goalId: string | null;\n parentId: string | null;\n assigneeAgentId: string | null;\n assigneeUserId: string | null;\n updatedAt: string;\n };\n ancestors: Array<{\n id: string;\n identifier: string | null;\n title: string;\n status: string;\n priority: string;\n }>;\n project: {\n id: string;\n name: string;\n status: string;\n targetDate: string | null;\n } | null;\n goal: {\n id: string;\n title: string;\n status: string;\n level: string;\n parentId: string | null;\n } | null;\n commentCursor: {\n latestCommentId: string | null;\n latestCommentCreatedAt: string | null;\n commentCount: number;\n };\n planDocument: IssueDocument | null;\n documentSummaries: IssueDocumentSummary[];\n legacyPlanDocument: LegacyPlanDocument | null;\n issueDocumentsPrompt: string;\n wakeComment: IssueComment | null;\n}\n\nexport function registerIssueCommands(program: Command): void {\n const issue = program.command(\"issue\").description(\"Issue operations\");\n\n addCommonClientOptions(\n issue\n .command(\"list\")\n .description(\"List issues for an organization\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--status <csv>\", \"Comma-separated statuses\")\n .option(\"--assignee-agent-id <id>\", \"Filter by assignee agent ID\")\n .option(\"--project-id <id>\", \"Filter by project ID\")\n .option(\"--query <text>\", \"Server-side search on identifier/title/description/comments\")\n .option(\"--match <text>\", \"Local text match on identifier/title/description\")\n .action(async (opts: IssueBaseOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<Issue[]>(buildIssueListPath(ctx.orgId!, opts, opts.query))) ?? [];\n const filtered = filterIssueRows(rows, opts.match);\n printIssueRows(filtered, ctx.json);\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n issue\n .command(\"search\")\n .description(getAgentCliCapabilityById(\"issue.search\").description)\n .argument(\"<query>\", \"Server-side issue search query\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--status <csv>\", \"Comma-separated statuses\")\n .option(\"--assignee-agent-id <id>\", \"Filter by assignee agent ID\")\n .option(\"--project-id <id>\", \"Filter by project ID\")\n .action(async (query: string, opts: IssueSearchOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<Issue[]>(buildIssueListPath(ctx.orgId!, opts, query))) ?? [];\n printIssueRows(rows, ctx.json);\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n issue\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"issue.get\").description)\n .argument(\"<idOrIdentifier>\", \"Issue ID or identifier\")\n .action(async (idOrIdentifier: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<Issue>(`/api/issues/${idOrIdentifier}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"context\")\n .description(getAgentCliCapabilityById(\"issue.context\").description)\n .argument(\"<issueId>\", \"Issue ID or identifier\")\n .option(\"--wake-comment-id <id>\", \"Fetch one wake comment in the heartbeat context response\")\n .action(async (issueId: string, opts: IssueContextOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const params = new URLSearchParams();\n if (opts.wakeCommentId) params.set(\"wakeCommentId\", opts.wakeCommentId);\n const query = params.toString();\n const row = await ctx.api.get<IssueHeartbeatContext>(\n `/api/issues/${issueId}/heartbeat-context${query ? `?${query}` : \"\"}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"create\")\n .description(getAgentCliCapabilityById(\"issue.create\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--title <title>\", \"Issue title\")\n .option(\"--description <text>\", \"Issue description\")\n .option(\"--status <status>\", \"Issue status\")\n .option(\"--priority <priority>\", \"Issue priority\")\n .option(\"--assignee-agent-id <id>\", \"Assignee agent ID\")\n .option(\"--project-id <id>\", \"Project ID\")\n .option(\"--goal-id <id>\", \"Goal ID\")\n .option(\"--parent-id <id>\", \"Parent issue ID\")\n .option(\"--request-depth <n>\", \"Request depth integer\")\n .option(\"--billing-code <code>\", \"Billing code\")\n .action(async (opts: IssueCreateOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = createIssueSchema.parse({\n title: opts.title,\n description: opts.description,\n status: opts.status,\n priority: opts.priority,\n assigneeAgentId: opts.assigneeAgentId,\n projectId: opts.projectId,\n goalId: opts.goalId,\n parentId: opts.parentId,\n requestDepth: parseOptionalInt(opts.requestDepth),\n billingCode: opts.billingCode,\n });\n\n const created = await ctx.api.post<Issue>(`/api/orgs/${ctx.orgId}/issues`, payload);\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n issue\n .command(\"update\")\n .description(getAgentCliCapabilityById(\"issue.update\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .option(\"--title <title>\", \"Issue title\")\n .option(\"--description <text>\", \"Issue description\")\n .option(\"--status <status>\", \"Issue status\")\n .option(\"--priority <priority>\", \"Issue priority\")\n .option(\"--assignee-agent-id <id>\", \"Assignee agent ID\")\n .option(\"--project-id <id>\", \"Project ID\")\n .option(\"--goal-id <id>\", \"Goal ID\")\n .option(\"--parent-id <id>\", \"Parent issue ID\")\n .option(\"--request-depth <n>\", \"Request depth integer\")\n .option(\"--billing-code <code>\", \"Billing code\")\n .option(\"--comment <text>\", \"Optional comment to add with update\")\n .option(\"--image <path>\", \"Image file to upload and append to the update comment; may be repeated\", collectImagePath, [] as string[])\n .option(\"--hidden-at <iso8601|null>\", \"Set hiddenAt timestamp or literal 'null'\")\n .action(async (issueId: string, opts: IssueUpdateOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const comment = await appendUploadedIssueImages(ctx, issueId, opts.comment, opts.image);\n const payload = updateIssueSchema.parse({\n title: opts.title,\n description: opts.description,\n status: opts.status,\n priority: opts.priority,\n assigneeAgentId: opts.assigneeAgentId,\n projectId: opts.projectId,\n goalId: opts.goalId,\n parentId: opts.parentId,\n requestDepth: parseOptionalInt(opts.requestDepth),\n billingCode: opts.billingCode,\n comment,\n hiddenAt: parseHiddenAt(opts.hiddenAt),\n });\n\n const updated = await ctx.api.patch<Issue & { comment?: IssueComment | null }>(`/api/issues/${issueId}`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"comment\")\n .description(getAgentCliCapabilityById(\"issue.comment\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--body <text>\", \"Comment body\")\n .option(\"--image <path>\", \"Image file to upload and append to the comment; may be repeated\", collectImagePath, [] as string[])\n .option(\"--reopen\", \"Reopen if issue is done/cancelled\")\n .action(async (issueId: string, opts: IssueCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const body = await appendUploadedIssueImages(ctx, issueId, opts.body, opts.image);\n const payload = addIssueCommentSchema.parse({\n body,\n reopen: opts.reopen,\n });\n const comment = await ctx.api.post<IssueComment>(`/api/issues/${issueId}/comments`, payload);\n printOutput(comment, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"review\")\n .description(getAgentCliCapabilityById(\"issue.review\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\n \"--decision <decision>\",\n \"Review decision: approve, request_changes, needs_followup, or blocked\",\n )\n .requiredOption(\"--comment <text>\", \"Required review comment\")\n .action(async (issueId: string, opts: IssueReviewOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const decision = parseReviewDecision(opts.decision);\n const updated = await ctx.api.patch<Issue & { comment?: IssueComment | null }>(`/api/issues/${issueId}`, {\n reviewDecision: decision,\n comment: opts.comment,\n });\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"commit\")\n .description(getAgentCliCapabilityById(\"issue.commit\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--sha <sha>\", \"Commit SHA\")\n .requiredOption(\"--message <subject>\", \"Commit subject or message\")\n .option(\"--branch <name>\", \"Branch name\")\n .option(\"--repo-path <path>\", \"Repository path\")\n .option(\"--workspace-path <path>\", \"Workspace path\")\n .option(\"--count <n>\", \"Number of commits represented by this report\")\n .action(async (issueId: string, opts: IssueCommitOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = reportIssueCommitSchema.parse({\n sha: opts.sha,\n message: opts.message,\n branch: opts.branch,\n repoPath: opts.repoPath,\n workspacePath: opts.workspacePath,\n commitCount: parseOptionalInt(opts.count),\n });\n const reported = await ctx.api.post<IssueCommitReport>(`/api/issues/${issueId}/commit`, payload);\n printOutput(reported, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"done\")\n .description(getAgentCliCapabilityById(\"issue.done\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--comment <text>\", \"Required completion comment\")\n .option(\"--image <path>\", \"Image file to upload and append to the completion comment; may be repeated\", collectImagePath, [] as string[])\n .action(async (issueId: string, opts: IssueStatusCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const comment = await appendUploadedIssueImages(ctx, issueId, opts.comment, opts.image);\n const updated = await ctx.api.patch<Issue>(`/api/issues/${issueId}`, {\n status: \"done\",\n comment,\n });\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"block\")\n .description(getAgentCliCapabilityById(\"issue.block\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--comment <text>\", \"Required blocker comment\")\n .option(\"--image <path>\", \"Image file to upload and append to the blocker comment; may be repeated\", collectImagePath, [] as string[])\n .action(async (issueId: string, opts: IssueStatusCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const comment = await appendUploadedIssueImages(ctx, issueId, opts.comment, opts.image);\n const updated = await ctx.api.patch<Issue>(`/api/issues/${issueId}`, {\n status: \"blocked\",\n comment,\n });\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n const comments = issue.command(\"comments\").description(\"Issue comment operations\");\n\n addCommonClientOptions(\n comments\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"issue.comments.list\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .option(\"--after <commentId>\", \"Only return comments after this comment ID\")\n .option(\"--order <order>\", \"Comment ordering (asc or desc)\", \"desc\")\n .action(async (issueId: string, opts: IssueCommentsListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const params = new URLSearchParams();\n if (opts.after) params.set(\"after\", opts.after);\n if (opts.order) params.set(\"order\", opts.order);\n const query = params.toString();\n const rows = (await ctx.api.get<IssueComment[]>(\n `/api/issues/${issueId}/comments${query ? `?${query}` : \"\"}`,\n )) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n comments\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"issue.comments.get\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<commentId>\", \"Comment ID\")\n .action(async (issueId: string, commentId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<IssueComment>(`/api/issues/${issueId}/comments/${commentId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n const documents = issue.command(\"documents\").description(\"Issue document operations\");\n\n addCommonClientOptions(\n documents\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"issue.documents.list\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .action(async (issueId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<IssueDocumentSummary[]>(`/api/issues/${issueId}/documents`)) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n documents\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"issue.documents.get\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<key>\", \"Document key\")\n .action(async (issueId: string, key: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<IssueDocument>(`/api/issues/${issueId}/documents/${key}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n documents\n .command(\"put\")\n .description(getAgentCliCapabilityById(\"issue.documents.put\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<key>\", \"Document key\")\n .requiredOption(\"--body <text>\", \"Document body\")\n .option(\"--title <text>\", \"Document title\")\n .option(\"--format <format>\", \"Document format\", \"markdown\")\n .option(\"--change-summary <text>\", \"Optional change summary\")\n .option(\"--base-revision-id <id>\", \"Latest revision id for optimistic concurrency\")\n .action(async (issueId: string, key: string, opts: IssueDocumentPutOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = upsertIssueDocumentSchema.parse({\n title: opts.title,\n format: opts.format,\n body: opts.body,\n changeSummary: opts.changeSummary,\n baseRevisionId: opts.baseRevisionId,\n });\n const row = await ctx.api.put<IssueDocument>(`/api/issues/${issueId}/documents/${key}`, payload);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n documents\n .command(\"revisions\")\n .description(getAgentCliCapabilityById(\"issue.documents.revisions\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<key>\", \"Document key\")\n .action(async (issueId: string, key: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<DocumentRevision[]>(`/api/issues/${issueId}/documents/${key}/revisions`)) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"checkout\")\n .description(getAgentCliCapabilityById(\"issue.checkout\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .option(\"--agent-id <id>\", \"Agent ID (defaults to RUDDER_AGENT_ID)\")\n .option(\n \"--expected-statuses <csv>\",\n \"Expected current statuses\",\n \"todo,backlog,blocked\",\n )\n .action(async (issueId: string, opts: IssueCheckoutOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const agentId = opts.agentId?.trim() || ctx.agentId;\n if (!agentId) {\n throw new Error(\"Agent ID is required. Pass --agent-id or set RUDDER_AGENT_ID.\");\n }\n const payload = checkoutIssueSchema.parse({\n agentId,\n expectedStatuses: parseCsv(opts.expectedStatuses),\n });\n const updated = await ctx.api.post<Issue>(`/api/issues/${issueId}/checkout`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"release\")\n .description(getAgentCliCapabilityById(\"issue.release\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .action(async (issueId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const updated = await ctx.api.post<Issue>(`/api/issues/${issueId}/release`, {});\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n\nfunction collectImagePath(value: string, previous: string[]): string[] {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(\"--image path cannot be empty\");\n }\n return [...previous, trimmed];\n}\n\nasync function appendUploadedIssueImages(\n ctx: CommandContext,\n issueId: string,\n body: string | undefined,\n imagePaths: string[] | undefined,\n): Promise<string | undefined> {\n const paths = imagePaths ?? [];\n if (paths.length === 0) return body;\n\n const issue = await ctx.api.get<Issue>(`/api/issues/${issueId}`);\n if (!issue) {\n throw new Error(\"Issue not found\");\n }\n\n const links: string[] = [];\n for (const imagePath of paths) {\n const attachment = await uploadIssueCommentImage(ctx, issue, imagePath);\n links.push(formatAttachmentMarkdown(attachment));\n }\n\n const base = body?.trimEnd() ?? \"\";\n const imageBlock = links.join(\"\\n\");\n return base ? `${base}\\n\\n${imageBlock}` : imageBlock;\n}\n\nasync function uploadIssueCommentImage(\n ctx: CommandContext,\n issue: Issue,\n imagePath: string,\n): Promise<IssueAttachment> {\n const resolvedPath = path.resolve(process.cwd(), imagePath);\n const stats = await stat(resolvedPath).catch((err: unknown) => {\n throw new Error(`Unable to read image ${imagePath}: ${err instanceof Error ? err.message : String(err)}`);\n });\n if (!stats.isFile()) {\n throw new Error(`Image path must be a file: ${imagePath}`);\n }\n\n const filename = path.basename(resolvedPath);\n const contentType = inferCommentImageContentType(filename);\n const buffer = await readFile(resolvedPath);\n if (buffer.length <= 0) {\n throw new Error(`Image is empty: ${imagePath}`);\n }\n\n const form = new FormData();\n form.set(\"usage\", \"comment_inline\");\n form.set(\"file\", new Blob([buffer], { type: contentType }), filename);\n\n const attachment = await ctx.api.postForm<IssueAttachment>(\n `/api/orgs/${issue.orgId}/issues/${issue.id}/attachments`,\n form,\n );\n if (!attachment) {\n throw new Error(`Image upload returned no attachment: ${imagePath}`);\n }\n return attachment;\n}\n\nfunction inferCommentImageContentType(filename: string): string {\n const ext = path.extname(filename).toLowerCase();\n switch (ext) {\n case \".png\":\n return \"image/png\";\n case \".jpg\":\n case \".jpeg\":\n return \"image/jpeg\";\n case \".webp\":\n return \"image/webp\";\n case \".gif\":\n return \"image/gif\";\n default:\n throw new Error(`Unsupported comment image type: ${filename}. Use PNG, JPEG, WebP, or GIF.`);\n }\n}\n\nfunction formatAttachmentMarkdown(attachment: IssueAttachment): string {\n const alt = escapeMarkdownAltText(attachment.originalFilename ?? \"image\");\n return `![${alt}](${attachment.contentPath})`;\n}\n\nfunction escapeMarkdownAltText(value: string): string {\n return value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"]\", \"\\\\]\");\n}\n\nfunction parseCsv(value: string | undefined): string[] {\n if (!value) return [];\n return value.split(\",\").map((v) => v.trim()).filter(Boolean);\n}\n\nfunction parseOptionalInt(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number.parseInt(value, 10);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid integer value: ${value}`);\n }\n return parsed;\n}\n\nfunction parseHiddenAt(value: string | undefined): string | null | undefined {\n if (value === undefined) return undefined;\n if (value.trim().toLowerCase() === \"null\") return null;\n return value;\n}\n\nfunction parseReviewDecision(value: string): IssueReviewOptions[\"decision\"] {\n const normalized = value.trim();\n if (\n normalized === \"approve\" ||\n normalized === \"request_changes\" ||\n normalized === \"needs_followup\" ||\n normalized === \"blocked\"\n ) {\n return normalized;\n }\n throw new Error(\"Invalid review decision. Use approve, request_changes, needs_followup, or blocked.\");\n}\n\nfunction filterIssueRows(rows: Issue[], match: string | undefined): Issue[] {\n if (!match?.trim()) return rows;\n const needle = match.trim().toLowerCase();\n return rows.filter((row) => {\n const text = [row.identifier, row.title, row.description]\n .filter((part): part is string => Boolean(part))\n .join(\"\\n\")\n .toLowerCase();\n return text.includes(needle);\n });\n}\n\nfunction buildIssueListPath(orgId: string, opts: IssueSearchOptions, searchQuery?: string): string {\n const params = new URLSearchParams();\n if (opts.status) params.set(\"status\", opts.status);\n if (opts.assigneeAgentId) params.set(\"assigneeAgentId\", opts.assigneeAgentId);\n if (opts.projectId) params.set(\"projectId\", opts.projectId);\n if (searchQuery?.trim()) params.set(\"q\", searchQuery.trim());\n\n const query = params.toString();\n return `/api/orgs/${orgId}/issues${query ? `?${query}` : \"\"}`;\n}\n\nfunction printIssueRows(rows: Issue[], json: boolean): void {\n if (json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const item of rows) {\n console.log(\n formatInlineRecord({\n identifier: item.identifier,\n id: item.id,\n status: item.status,\n priority: item.priority,\n assigneeAgentId: item.assigneeAgentId,\n assigneeUserId: item.assigneeUserId,\n title: item.title,\n projectId: item.projectId,\n updatedAt: item.updatedAt,\n ...(item.searchMatch ? { match: formatIssueSearchMatch(item.searchMatch) } : {}),\n }),\n );\n }\n}\n\nfunction formatIssueSearchMatch(match: NonNullable<Issue[\"searchMatch\"]>): string {\n const commentSuffix = match.commentId ? `#${match.commentId}` : \"\";\n return `${match.field}${commentSuffix}: ${match.snippet}`;\n}\n", "export type AgentCliCapabilityCategory = \"agent\" | \"issue\" | \"approval\" | \"skill\";\nexport type AgentCliCapabilityContract = \"agent-v1\" | \"compat\";\n\nexport interface AgentCliCapability {\n id: string;\n command: string;\n category: AgentCliCapabilityCategory;\n description: string;\n mutating: boolean;\n contract: AgentCliCapabilityContract;\n requiresOrgId: boolean;\n requiresAgentId: boolean;\n requiresRunId: boolean;\n attachesRunIdWhenAvailable: boolean;\n}\n\nexport interface AgentCliCapabilitiesManifestEntry extends AgentCliCapability {\n agentV1: boolean;\n}\n\nexport interface AgentCliCapabilitiesManifest {\n schema: \"rudder.agent-capabilities/v1\";\n contract: AgentCliCapabilityContract | \"all\";\n defaults: {\n orgIdEnvVar: \"RUDDER_ORG_ID\";\n agentIdEnvVar: \"RUDDER_AGENT_ID\";\n runIdEnvVar: \"RUDDER_RUN_ID\";\n jsonErrors: \"stderr-error-envelope\";\n };\n capabilities: AgentCliCapabilitiesManifestEntry[];\n}\n\nconst AGENT_CLI_CAPABILITIES: AgentCliCapability[] = [\n {\n id: \"agent.me\",\n command: \"rudder agent me\",\n category: \"agent\",\n description: \"Show the authenticated agent identity, budget, and chain of command.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.inbox\",\n command: \"rudder agent inbox\",\n category: \"agent\",\n description: \"List the compact assignee and reviewer work inbox for the authenticated agent.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.capabilities\",\n command: \"rudder agent capabilities\",\n category: \"agent\",\n description: \"List the stable Rudder agent command contract.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.list\",\n command: \"rudder agent list --org-id <id>\",\n category: \"agent\",\n description: \"List agents for an organization.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.get\",\n command: \"rudder agent get <agent-id-or-shortname>\",\n category: \"agent\",\n description: \"Read one agent by id or shortname.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.skills.enable\",\n command: \"rudder agent skills enable <agent-id> <selection-ref...>\",\n category: \"agent\",\n description: \"Add skill selections to an agent without replacing existing enabled skills.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"agent.skills.sync\",\n command: \"rudder agent skills sync <agent-id>\",\n category: \"agent\",\n description: \"Sync the desired enabled skill set for an agent.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"agent.hire\",\n command: \"rudder agent hire --org-id <id> --payload <json>\",\n category: \"agent\",\n description: \"Create a new hire using the canonical hire workflow.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"agent.config.index\",\n command: \"rudder agent config index\",\n category: \"agent\",\n description: \"Read the installed agent runtime configuration index.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.config.doc\",\n command: \"rudder agent config doc <agent-runtime-type>\",\n category: \"agent\",\n description: \"Read adapter-specific configuration guidance for one runtime.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.config.list\",\n command: \"rudder agent config list --org-id <id>\",\n category: \"agent\",\n description: \"List redacted agent configuration snapshots for an organization.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.config.get\",\n command: \"rudder agent config get <agent-id-or-shortname>\",\n category: \"agent\",\n description: \"Read one redacted agent configuration snapshot by id or shortname.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.icons\",\n command: \"rudder agent icons\",\n category: \"agent\",\n description: \"List allowed agent icon names for create and hire payloads.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.get\",\n command: \"rudder issue get <issue>\",\n category: \"issue\",\n description: \"Read a full issue by UUID or identifier.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.search\",\n command: \"rudder issue search <query> [--org-id <id>]\",\n category: \"issue\",\n description: \"Search issues with the server-side issue index across title, identifier, description, and comments.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.context\",\n command: \"rudder issue context <issue>\",\n category: \"issue\",\n description: \"Read the compact heartbeat context for an issue.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.checkout\",\n command: \"rudder issue checkout <issue>\",\n category: \"issue\",\n description: \"Atomically checkout an issue for the current or specified agent.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: true,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.comment\",\n command: \"rudder issue comment <issue> --body <text> [--image <path>]\",\n category: \"issue\",\n description: \"Add a comment to an issue, optionally uploading images and appending Markdown image links.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.comments.list\",\n command: \"rudder issue comments list <issue>\",\n category: \"issue\",\n description: \"List issue comments, optionally only newer comments after a cursor.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.comments.get\",\n command: \"rudder issue comments get <issue> <comment-id>\",\n category: \"issue\",\n description: \"Read one issue comment by id.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.update\",\n command: \"rudder issue update <issue> ... [--image <path>]\",\n category: \"issue\",\n description: \"Apply generic issue updates when workflow commands are not enough, optionally uploading images for the update comment.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.review\",\n command: \"rudder issue review <issue> --decision <decision> --comment <text>\",\n category: \"issue\",\n description: \"Record a structured reviewer decision with a required comment.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.commit\",\n command: \"rudder issue commit <issue> --sha <sha> --message <subject>\",\n category: \"issue\",\n description: \"Report a code commit created during issue work as structured issue activity.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.done\",\n command: \"rudder issue done <issue> --comment <text> [--image <path>]\",\n category: \"issue\",\n description: \"Mark an issue done with a required completion comment, optionally uploading images.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.block\",\n command: \"rudder issue block <issue> --comment <text> [--image <path>]\",\n category: \"issue\",\n description: \"Mark an issue blocked with a required blocker comment, optionally uploading images.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.release\",\n command: \"rudder issue release <issue>\",\n category: \"issue\",\n description: \"Release an issue back to todo and clear ownership.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.documents.list\",\n command: \"rudder issue documents list <issue>\",\n category: \"issue\",\n description: \"List issue documents.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.documents.get\",\n command: \"rudder issue documents get <issue> <key>\",\n category: \"issue\",\n description: \"Read one issue document by key.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.documents.put\",\n command: \"rudder issue documents put <issue> <key> --body <text>\",\n category: \"issue\",\n description: \"Create or update an issue document.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.documents.revisions\",\n command: \"rudder issue documents revisions <issue> <key>\",\n category: \"issue\",\n description: \"List revisions for an issue document.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.create\",\n command: \"rudder issue create --org-id <id> ...\",\n category: \"issue\",\n description: \"Create a new issue or subtask with the generic issue surface; agent-created issues default to the creating agent when no assignee is supplied.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"approval.get\",\n command: \"rudder approval get <approval-id>\",\n category: \"approval\",\n description: \"Read one approval request.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"approval.create\",\n command: \"rudder approval create --org-id <id> --type <type> --payload <json>\",\n category: \"approval\",\n description: \"Create a new approval request.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"approval.issues\",\n command: \"rudder approval issues <approval-id>\",\n category: \"approval\",\n description: \"List the issues linked to an approval.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"approval.comment\",\n command: \"rudder approval comment <approval-id> --body <text>\",\n category: \"approval\",\n description: \"Add a comment to an approval.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"approval.resubmit\",\n command: \"rudder approval resubmit <approval-id> [--payload <json>]\",\n category: \"approval\",\n description: \"Resubmit a revision-requested approval, optionally with updated payload.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"skill.list\",\n command: \"rudder skill list --org-id <id>\",\n category: \"skill\",\n description: \"List organization-visible skills.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"skill.get\",\n command: \"rudder skill get <skill-id> --org-id <id>\",\n category: \"skill\",\n description: \"Read one organization skill detail.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"skill.file\",\n command: \"rudder skill file <skill-id> --org-id <id> [--path SKILL.md]\",\n category: \"skill\",\n description: \"Read one file from an organization skill package.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"skill.import\",\n command: \"rudder skill import --org-id <id> --source <source>\",\n category: \"skill\",\n description: \"Import a skill package into the organization skill library.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"skill.scan-local\",\n command: \"rudder skill scan-local --org-id <id> [--roots <csv>]\",\n category: \"skill\",\n description: \"Scan local roots for skill packages and import new ones.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"skill.scan-projects\",\n command: \"rudder skill scan-projects --org-id <id> [--project-ids <csv>] [--workspace-ids <csv>]\",\n category: \"skill\",\n description:\n \"Scan the org workspace and any legacy project workspace records for skill packages and import new ones.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n];\n\nconst CATEGORY_TITLES: Record<AgentCliCapabilityCategory, string> = {\n agent: \"Agent\",\n issue: \"Issue\",\n approval: \"Approval\",\n skill: \"Skill\",\n};\n\nexport function getAgentCliCapabilities(): AgentCliCapability[] {\n return AGENT_CLI_CAPABILITIES.map((entry) => ({ ...entry }));\n}\n\nexport function getAgentCliCapabilityById(id: string): AgentCliCapability {\n const entry = AGENT_CLI_CAPABILITIES.find((capability) => capability.id === id);\n if (!entry) {\n throw new Error(`Unknown agent CLI capability: ${id}`);\n }\n return entry;\n}\n\nexport function buildAgentCliCapabilitiesManifest(\n contract: AgentCliCapabilityContract | \"all\" = \"agent-v1\",\n): AgentCliCapabilitiesManifest {\n const capabilities = AGENT_CLI_CAPABILITIES\n .filter((entry) => contract === \"all\" || entry.contract === contract)\n .map((entry) => ({\n ...entry,\n agentV1: entry.contract === \"agent-v1\",\n }));\n\n return {\n schema: \"rudder.agent-capabilities/v1\",\n contract,\n defaults: {\n orgIdEnvVar: \"RUDDER_ORG_ID\",\n agentIdEnvVar: \"RUDDER_AGENT_ID\",\n runIdEnvVar: \"RUDDER_RUN_ID\",\n jsonErrors: \"stderr-error-envelope\",\n },\n capabilities,\n };\n}\n\nexport function renderAgentCliReferenceMarkdown(): string {\n const manifest = buildAgentCliCapabilitiesManifest(\"agent-v1\");\n const lines: string[] = [\n \"# Rudder Agent CLI Reference\",\n \"\",\n \"Stable CLI contract for agents using the bundled `rudder` skill. Prefer these commands over direct `/api` calls.\",\n \"\",\n \"## Defaults\",\n \"\",\n \"- All commands support `--json`.\",\n \"- `--org-id` defaults to `RUDDER_ORG_ID` when relevant.\",\n \"- `--run-id` defaults to `RUDDER_RUN_ID` and is attached to mutating requests when available.\",\n \"- `issue checkout` defaults `--agent-id` from `RUDDER_AGENT_ID`.\",\n \"\",\n \"## Agent V1 Commands\",\n \"\",\n \"| Command | Description | Mutating | Org | Agent | Run ID |\",\n \"| --- | --- | --- | --- | --- | --- |\",\n ];\n\n for (const capability of manifest.capabilities) {\n lines.push(\n `| \\`${capability.command}\\` | ${capability.description} | ${capability.mutating ? \"yes\" : \"no\"} | ${\n capability.requiresOrgId ? \"required\" : \"no\"\n } | ${capability.requiresAgentId ? \"required\" : \"no\"} | ${\n capability.requiresRunId ? \"required\" : capability.attachesRunIdWhenAvailable ? \"attached when available\" : \"no\"\n } |`,\n );\n }\n\n lines.push(\n \"\",\n \"## Issue Close-Out Signals\",\n \"\",\n \"Before a successful `todo` or `in_progress` issue run exits, leave one close-out signal with the command that matches the outcome:\",\n \"\",\n \"- progress remains: `rudder issue comment <issue> --body <text> [--image <path>]`\",\n \"- work is complete: `rudder issue done <issue> --comment <text> [--image <path>]`\",\n \"- work is blocked: `rudder issue block <issue> --comment <text> [--image <path>]`\",\n \"- ownership changes: add an explicit handoff comment before or with the assignee update\",\n \"\",\n \"If an issue has a reviewer, moving it to `blocked` is also a reviewer handoff: the reviewer should confirm the blocker, request changes, approve, or keep explicit follow-up open with `rudder issue review`.\",\n \"\",\n \"`--image` may be repeated. The CLI uploads each local PNG/JPEG/WebP/GIF as an issue attachment and appends Markdown image links to the comment text before sending it.\",\n \"\",\n \"If your issue comment cites a screenshot path or visual validation artifact, attach that file with `--image <path>` instead of leaving only the local path in the text.\",\n \"\",\n \"If `RUDDER_WAKE_REASON=issue_passive_followup`, the run is close-out governance for the same issue. Inspect current issue state first, then leave a progress comment, completion, blocker, or explicit handoff.\",\n \"\",\n \"## Git Identity Policy\",\n \"\",\n \"Local runtime `HOME` is isolated from the operator home. Codex local runs and runtime-created git worktrees are prepared with `user.useConfigOnly=true` so missing identity fails fast instead of producing `*@*.local` commits. If Git reports missing author or committer identity, configure the repository explicitly with `git config user.name <name>` and `git config user.email <safe-email>`; do not unset the guard or accept auto-detected local-host metadata.\",\n \"\",\n \"## Reviewer Close-Out Signals\",\n \"\",\n \"When the inbox row or wake context says `relationship: \\\"reviewer\\\"`, `role: \\\"reviewer\\\"`, or `wakeSource: \\\"review\\\"`, finish the review with one structured reviewer decision. Reviewer work can be either `in_review` or `blocked`; blocked reviewer work means blocker triage, not implementation takeover.\",\n \"\",\n \"- approve: `rudder issue review <issue> --decision approve --comment <text>`\",\n \"- request changes: `rudder issue review <issue> --decision request_changes --comment <text>`\",\n \"- needs follow-up: `rudder issue review <issue> --decision needs_followup --comment <text>`\",\n \"- blocked or blocker confirmed: `rudder issue review <issue> --decision blocked --comment <text>`; use this only for a confirmed human/external blocker and name the next human action.\",\n \"\",\n \"Do not rely on a free-form reject or accept comment as the review outcome. The structured decision is the durable close-out signal. A blocked reviewer decision records a human handoff and removes the issue from repeated reviewer pickup until the board changes the issue.\",\n );\n\n lines.push(\"\", \"## Compatibility Commands\", \"\");\n for (const capability of AGENT_CLI_CAPABILITIES.filter((entry) => entry.contract === \"compat\")) {\n lines.push(`- \\`${capability.command}\\` \u2014 ${capability.description}`);\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nexport function formatAgentCliCapabilitiesHumanReadable(\n capabilities: AgentCliCapability[] = getAgentCliCapabilities(),\n): string {\n const lines: string[] = [];\n\n for (const category of Object.keys(CATEGORY_TITLES) as AgentCliCapabilityCategory[]) {\n const entries = capabilities.filter((capability) => capability.category === category);\n if (entries.length === 0) continue;\n lines.push(`${CATEGORY_TITLES[category]} commands:`);\n for (const entry of entries) {\n const tags = [\n entry.contract,\n entry.mutating ? \"mutating\" : \"read-only\",\n entry.requiresOrgId ? \"org\" : null,\n entry.requiresAgentId ? \"agent\" : null,\n entry.attachesRunIdWhenAvailable ? \"run-id\" : null,\n ].filter(Boolean);\n lines.push(`- ${entry.command} \u2014 ${entry.description} [${tags.join(\", \")}]`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd();\n}\n", "import { Command } from \"commander\";\nimport {\n createAgentHireSchema,\n type Agent,\n type AgentDetail,\n type AgentSkillSnapshot,\n type Approval,\n} from \"@rudderhq/shared\";\nimport {\n removeMaintainerOnlySkillSymlinks,\n resolveRudderSkillsDir,\n} from \"@rudderhq/agent-runtime-utils/server-utils\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport {\n buildAgentCliCapabilitiesManifest,\n formatAgentCliCapabilitiesHumanReadable,\n getAgentCliCapabilityById,\n getAgentCliCapabilities,\n} from \"../../agent-v1-registry.js\";\n\ninterface AgentListOptions extends BaseClientOptions {\n orgId?: string;\n}\n\ninterface AgentInboxItem {\n id: string;\n identifier: string | null;\n title: string;\n relationship?: \"assignee\" | \"reviewer\";\n status: string;\n priority: string;\n projectId: string | null;\n goalId: string | null;\n parentId: string | null;\n updatedAt: string;\n activeRun: unknown;\n}\n\ninterface AgentLocalCliOptions extends BaseClientOptions {\n orgId?: string;\n keyName?: string;\n installSkills?: boolean;\n}\n\ninterface AgentCapabilitiesOptions extends BaseClientOptions {\n contract?: string;\n}\n\ninterface AgentHireOptions extends BaseClientOptions {\n orgId?: string;\n payload: string;\n}\n\ninterface AgentSkillSyncOptions extends BaseClientOptions {\n desiredSkills: string;\n}\n\ninterface AgentSkillEnableOptions extends BaseClientOptions {}\n\ninterface AgentConfigurationRow {\n id: string;\n orgId: string;\n name: string;\n role: string;\n title: string | null;\n status: string;\n reportsTo: string | null;\n agentRuntimeType: string;\n agentRuntimeConfig: Record<string, unknown>;\n runtimeConfig: Record<string, unknown>;\n permissions: Record<string, unknown> | null;\n updatedAt: string;\n}\n\ninterface AgentHireResult {\n agent: Agent;\n approval: Approval | null;\n}\n\ninterface CreatedAgentKey {\n id: string;\n name: string;\n token: string;\n createdAt: string;\n}\n\ninterface SkillsInstallSummary {\n tool: \"codex\" | \"claude\";\n target: string;\n linked: string[];\n removed: string[];\n skipped: string[];\n failed: Array<{ name: string; error: string }>;\n}\n\nconst __moduleDir = path.dirname(fileURLToPath(import.meta.url));\n\nfunction codexSkillsHome(): string {\n const fromEnv = process.env.CODEX_HOME?.trim();\n const base = fromEnv && fromEnv.length > 0 ? fromEnv : path.join(os.homedir(), \".codex\");\n return path.join(base, \"skills\");\n}\n\nfunction claudeSkillsHome(): string {\n const fromEnv = process.env.CLAUDE_HOME?.trim();\n const base = fromEnv && fromEnv.length > 0 ? fromEnv : path.join(os.homedir(), \".claude\");\n return path.join(base, \"skills\");\n}\n\nasync function installSkillsForTarget(\n sourceSkillsDir: string,\n targetSkillsDir: string,\n tool: \"codex\" | \"claude\",\n): Promise<SkillsInstallSummary> {\n const summary: SkillsInstallSummary = {\n tool,\n target: targetSkillsDir,\n linked: [],\n removed: [],\n skipped: [],\n failed: [],\n };\n\n await fs.mkdir(targetSkillsDir, { recursive: true });\n const entries = await fs.readdir(sourceSkillsDir, { withFileTypes: true });\n summary.removed = await removeMaintainerOnlySkillSymlinks(\n targetSkillsDir,\n entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name),\n );\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const source = path.join(sourceSkillsDir, entry.name);\n const target = path.join(targetSkillsDir, entry.name);\n const existing = await fs.lstat(target).catch(() => null);\n if (existing) {\n if (existing.isSymbolicLink()) {\n let linkedPath: string | null = null;\n try {\n linkedPath = await fs.readlink(target);\n } catch (err) {\n await fs.unlink(target);\n try {\n await fs.symlink(source, target);\n summary.linked.push(entry.name);\n continue;\n } catch (linkErr) {\n summary.failed.push({\n name: entry.name,\n error:\n err instanceof Error && linkErr instanceof Error\n ? `${err.message}; then ${linkErr.message}`\n : err instanceof Error\n ? err.message\n : `Failed to recover broken symlink: ${String(err)}`,\n });\n continue;\n }\n }\n\n const resolvedLinkedPath = path.isAbsolute(linkedPath)\n ? linkedPath\n : path.resolve(path.dirname(target), linkedPath);\n const linkedTargetExists = await fs\n .stat(resolvedLinkedPath)\n .then(() => true)\n .catch(() => false);\n\n if (!linkedTargetExists) {\n await fs.unlink(target);\n } else {\n summary.skipped.push(entry.name);\n continue;\n }\n } else {\n summary.skipped.push(entry.name);\n continue;\n }\n }\n\n try {\n await fs.symlink(source, target);\n summary.linked.push(entry.name);\n } catch (err) {\n summary.failed.push({\n name: entry.name,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return summary;\n}\n\nfunction buildAgentEnvExports(input: {\n apiBase: string;\n orgId: string;\n agentId: string;\n apiKey: string;\n}): string {\n const escaped = (value: string) => value.replace(/'/g, \"'\\\"'\\\"'\");\n return [\n `export RUDDER_API_URL='${escaped(input.apiBase)}'`,\n `export RUDDER_ORG_ID='${escaped(input.orgId)}'`,\n `export RUDDER_AGENT_ID='${escaped(input.agentId)}'`,\n `export RUDDER_API_KEY='${escaped(input.apiKey)}'`,\n ].join(\"\\n\");\n}\n\nexport function registerAgentCommands(program: Command): void {\n const agent = program.command(\"agent\").description(\"Agent operations\");\n const config = agent.command(\"config\").description(\"Agent configuration discovery and redacted snapshots\");\n\n addCommonClientOptions(\n agent\n .command(\"me\")\n .description(getAgentCliCapabilityById(\"agent.me\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<AgentDetail>(\"/api/agents/me\");\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"inbox\")\n .description(getAgentCliCapabilityById(\"agent.inbox\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<AgentInboxItem[]>(\"/api/agents/me/inbox-lite\")) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n identifier: row.identifier,\n id: row.id,\n relationship: row.relationship ?? \"assignee\",\n status: row.status,\n priority: row.priority,\n title: row.title,\n projectId: row.projectId,\n goalId: row.goalId,\n parentId: row.parentId,\n updatedAt: row.updatedAt,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"capabilities\")\n .description(getAgentCliCapabilityById(\"agent.capabilities\").description)\n .option(\"--contract <name>\", \"Capability subset to show (agent-v1 or all)\", \"agent-v1\")\n .action(async (opts: AgentCapabilitiesOptions) => {\n try {\n const contract = opts.contract === \"all\" ? \"all\" : \"agent-v1\";\n const capabilities = getAgentCliCapabilities().filter((entry) =>\n contract === \"all\" ? true : entry.contract === contract);\n\n if (opts.json) {\n printOutput(buildAgentCliCapabilitiesManifest(contract), { json: true });\n return;\n }\n\n console.log(formatAgentCliCapabilitiesHumanReadable(capabilities));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"agent.list\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<Agent[]>(`/api/orgs/${ctx.orgId}/agents`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n name: row.name,\n role: row.role,\n status: row.status,\n reportsTo: row.reportsTo,\n budgetMonthlyCents: row.budgetMonthlyCents,\n spentMonthlyCents: row.spentMonthlyCents,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n config\n .command(\"index\")\n .description(getAgentCliCapabilityById(\"agent.config.index\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const doc = await ctx.api.get<string>(\"/llms/agent-configuration.txt\");\n printOutput(doc ?? \"\", { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n config\n .command(\"doc\")\n .description(getAgentCliCapabilityById(\"agent.config.doc\").description)\n .argument(\"<agentRuntimeType>\", \"Agent runtime type\")\n .action(async (agentRuntimeType: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const doc = await ctx.api.get<string>(\n `/llms/agent-configuration/${encodeURIComponent(agentRuntimeType)}.txt`,\n );\n printOutput(doc ?? \"\", { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n config\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"agent.config.list\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows =\n (await ctx.api.get<AgentConfigurationRow[]>(`/api/orgs/${ctx.orgId}/agent-configurations`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n name: row.name,\n role: row.role,\n status: row.status,\n agentRuntimeType: row.agentRuntimeType,\n reportsTo: row.reportsTo,\n updatedAt: row.updatedAt,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n config\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"agent.config.get\").description)\n .argument(\"<agentId>\", \"Agent ID or shortname/url-key\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (agentId: string, opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const query = new URLSearchParams();\n if (ctx.orgId) query.set(\"orgId\", ctx.orgId);\n const row = await ctx.api.get<AgentConfigurationRow>(\n `/api/agents/${encodeURIComponent(agentId)}/configuration${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"icons\")\n .description(getAgentCliCapabilityById(\"agent.icons\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const doc = await ctx.api.get<string>(\"/llms/agent-icons.txt\");\n printOutput(doc ?? \"\", { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n const skills = agent.command(\"skills\").description(\"Agent skill selection operations\");\n\n addCommonClientOptions(\n skills\n .command(\"enable\")\n .description(getAgentCliCapabilityById(\"agent.skills.enable\").description)\n .argument(\"<agentId>\", \"Agent ID\")\n .argument(\"<selectionRefs...>\", \"Skill selection refs to enable\")\n .action(async (agentId: string, selectionRefs: string[], opts: AgentSkillEnableOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const snapshot = await ctx.api.post<AgentSkillSnapshot>(`/api/agents/${agentId}/skills/enable`, {\n skills: selectionRefs,\n });\n printOutput(snapshot, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n skills\n .command(\"sync\")\n .description(getAgentCliCapabilityById(\"agent.skills.sync\").description)\n .argument(\"<agentId>\", \"Agent ID\")\n .requiredOption(\n \"--desired-skills <csv>\",\n \"Comma-separated desired skill refs (for example rudder/rudder)\",\n )\n .action(async (agentId: string, opts: AgentSkillSyncOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const snapshot = await ctx.api.post<AgentSkillSnapshot>(`/api/agents/${agentId}/skills/sync`, {\n desiredSkills: parseCsv(opts.desiredSkills),\n });\n printOutput(snapshot, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"agent.get\").description)\n .argument(\"<agentId>\", \"Agent ID or shortname/url-key\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (agentId: string, opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const query = new URLSearchParams();\n if (ctx.orgId) query.set(\"orgId\", ctx.orgId);\n const row = await ctx.api.get<Agent>(\n `/api/agents/${encodeURIComponent(agentId)}${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"hire\")\n .description(getAgentCliCapabilityById(\"agent.hire\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--payload <json>\", \"Hire payload as JSON object\")\n .action(async (opts: AgentHireOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payloadJson = parseJsonObject(opts.payload, \"payload\");\n const payload = createAgentHireSchema.parse(payloadJson);\n const created = await ctx.api.post<AgentHireResult>(`/api/orgs/${ctx.orgId}/agent-hires`, payload);\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n agent\n .command(\"local-cli\")\n .description(\n \"Create an agent API key, optionally install local Rudder skills for direct Codex/Claude CLI use, and print shell exports\",\n )\n .argument(\"<agentRef>\", \"Agent ID or shortname/url-key\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--key-name <name>\", \"API key label\", \"local-cli\")\n .option(\n \"--no-install-skills\",\n \"Skip the optional local Codex/Claude skill installation step\",\n )\n .action(async (agentRef: string, opts: AgentLocalCliOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const query = new URLSearchParams({ orgId: ctx.orgId ?? \"\" });\n const agentRow = await ctx.api.get<Agent>(\n `/api/agents/${encodeURIComponent(agentRef)}?${query.toString()}`,\n );\n if (!agentRow) {\n throw new Error(`Agent not found: ${agentRef}`);\n }\n\n const now = new Date().toISOString().replaceAll(\":\", \"-\");\n const keyName = opts.keyName?.trim() ? opts.keyName.trim() : `local-cli-${now}`;\n const key = await ctx.api.post<CreatedAgentKey>(`/api/agents/${agentRow.id}/keys`, { name: keyName });\n if (!key) {\n throw new Error(\"Failed to create API key\");\n }\n\n const installSummaries: SkillsInstallSummary[] = [];\n if (opts.installSkills !== false) {\n const skillsDir = await resolveRudderSkillsDir(__moduleDir, [path.resolve(process.cwd(), \"skills\")]);\n if (!skillsDir) {\n throw new Error(\n \"Could not locate local Rudder skills directory. Expected ./skills in the repo checkout.\",\n );\n }\n\n installSummaries.push(\n await installSkillsForTarget(skillsDir, codexSkillsHome(), \"codex\"),\n await installSkillsForTarget(skillsDir, claudeSkillsHome(), \"claude\"),\n );\n }\n\n const exportsText = buildAgentEnvExports({\n apiBase: ctx.api.apiBase,\n orgId: agentRow.orgId,\n agentId: agentRow.id,\n apiKey: key.token,\n });\n\n if (ctx.json) {\n printOutput(\n {\n agent: {\n id: agentRow.id,\n name: agentRow.name,\n urlKey: agentRow.urlKey,\n orgId: agentRow.orgId,\n },\n key: {\n id: key.id,\n name: key.name,\n createdAt: key.createdAt,\n token: key.token,\n },\n skills: installSummaries,\n exports: exportsText,\n },\n { json: true },\n );\n return;\n }\n\n console.log(`Agent: ${agentRow.name} (${agentRow.id})`);\n console.log(`API key created: ${key.name} (${key.id})`);\n if (installSummaries.length > 0) {\n for (const summary of installSummaries) {\n console.log(\n `${summary.tool}: linked=${summary.linked.length} removed=${summary.removed.length} skipped=${summary.skipped.length} failed=${summary.failed.length} target=${summary.target}`,\n );\n for (const failed of summary.failed) {\n console.log(` failed ${failed.name}: ${failed.error}`);\n }\n }\n }\n console.log(\"\");\n console.log(\"# Run this in your shell before launching codex/claude:\");\n console.log(exportsText);\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n\nfunction parseCsv(value: string | undefined): string[] {\n if (!value) return [];\n return value.split(\",\").map((entry) => entry.trim()).filter(Boolean);\n}\n\nfunction parseJsonObject(value: string, name: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(value) as unknown;\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${name} must be a JSON object`);\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n throw new Error(`Invalid ${name} JSON: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n", "import { createHash } from \"node:crypto\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { constants as fsConstants, promises as fs, type Dirent } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type {\n AgentRuntimeSkillEntry,\n AgentRuntimeSkillSnapshot,\n} from \"./types.js\";\n\nexport interface RunProcessResult {\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n stdout: string;\n stderr: string;\n pid: number | null;\n startedAt: string | null;\n}\n\ninterface RunningProcess {\n child: ChildProcess;\n graceSec: number;\n}\n\ninterface SpawnTarget {\n command: string;\n args: string[];\n}\n\ntype ChildProcessWithEvents = ChildProcess & {\n on(event: \"error\", listener: (err: Error) => void): ChildProcess;\n on(\n event: \"close\",\n listener: (code: number | null, signal: NodeJS.Signals | null) => void,\n ): ChildProcess;\n};\n\nexport const runningProcesses = new Map<string, RunningProcess>();\n\nfunction isChildProcessAlive(child: ChildProcessWithEvents): boolean {\n const pid = child.pid;\n if (typeof pid !== \"number\" || pid <= 0) return false;\n if (child.exitCode !== null || child.signalCode !== null) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n const code = error instanceof Error && \"code\" in error ? (error as NodeJS.ErrnoException).code : null;\n return code === \"EPERM\";\n }\n}\nexport const MAX_CAPTURE_BYTES = 4 * 1024 * 1024;\nexport const MAX_EXCERPT_BYTES = 32 * 1024;\nconst SENSITIVE_ENV_KEY = /(key|token|secret|password|passwd|authorization|cookie)/i;\nconst RUDDER_SKILL_ROOT_RELATIVE_CANDIDATES = [\n \"../../server/resources/bundled-skills\",\n \"../../skills\",\n \"../../../../../server/resources/bundled-skills\",\n];\nconst DEFAULT_LOCAL_CLI_CREDENTIAL_HOME_ENTRIES = [\n \".aws\",\n \".azure\",\n \".config/gh\",\n \".config/gcloud\",\n \".config/op\",\n \".config/vercel\",\n \".config/configstore\",\n \".docker\",\n \".fly\",\n \".git-credentials\",\n \".gnupg\",\n \".kube\",\n \".netrc\",\n \".npmrc\",\n \".ssh\",\n \".vercel\",\n \"Library/Application Support/gh\",\n \"Library/Application Support/com.heroku.cli\",\n] as const;\ntype LocalCliCredentialShimCommand = {\n command: string;\n authCheckArgs?: readonly string[];\n credentialEntries?: readonly string[];\n};\n\nconst DEFAULT_LOCAL_CLI_OPERATOR_HOME_SHIM_COMMANDS = [\n {\n command: \"gh\",\n authCheckArgs: [\"auth\", \"status\"],\n credentialEntries: [\".config/gh\", \"Library/Application Support/gh\"],\n },\n {\n command: \"vercel\",\n authCheckArgs: [\"whoami\"],\n credentialEntries: [\".config/vercel\", \".vercel\", \".config/configstore\"],\n },\n] as const satisfies readonly LocalCliCredentialShimCommand[];\n\nexport interface RudderSkillEntry {\n key: string;\n runtimeName: string;\n source: string;\n name: string | null;\n description: string | null;\n}\n\nexport interface InstalledSkillTarget {\n targetPath: string | null;\n kind: \"symlink\" | \"directory\" | \"file\";\n}\n\ninterface PersistentSkillSnapshotOptions {\n agentRuntimeType: string;\n availableEntries: RudderSkillEntry[];\n desiredSkills: string[];\n installed: Map<string, InstalledSkillTarget>;\n skillsHome: string;\n locationLabel?: string | null;\n installedDetail?: string | null;\n missingDetail: string;\n externalConflictDetail: string;\n externalDetail: string;\n warnings?: string[];\n}\n\nfunction normalizePathSlashes(value: string): string {\n return value.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction isMaintainerOnlySkillTarget(candidate: string): boolean {\n const normalized = normalizePathSlashes(candidate);\n return (\n normalized.includes(\"/server/resources/bundled-skills/\")\n || normalized.includes(\"/.agents/skills/\")\n );\n}\n\nfunction skillLocationLabel(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction buildManagedSkillOrigin(): Pick<\n AgentRuntimeSkillEntry,\n \"origin\" | \"originLabel\" | \"readOnly\"\n> {\n return {\n origin: \"organization_managed\",\n readOnly: false,\n };\n}\n\nfunction compactSkillText(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const compacted = value\n .replace(/\\r\\n/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return compacted.length > 0 ? compacted : null;\n}\n\nfunction parseSkillFrontmatterMetadata(markdown: string): {\n name: string | null;\n description: string | null;\n} {\n const match = markdown.match(/^---\\n([\\s\\S]*?)\\n---(?:\\n|$)/);\n if (!match) {\n return { name: null, description: null };\n }\n\n const yaml = match[1];\n const nameMatch = yaml.match(/^name:\\s*[\"']?(.*?)[\"']?\\s*$/m);\n const descriptionMatch = yaml.match(\n /^description:\\s*(?:>\\s*\\n((?:\\s{2,}[^\\n]*\\n?)+)|[|]\\s*\\n((?:\\s{2,}[^\\n]*\\n?)+)|[\"']?(.*?)[\"']?\\s*$)/m,\n );\n\n return {\n name: compactSkillText(nameMatch?.[1] ?? null),\n description: compactSkillText(descriptionMatch?.[1] ?? descriptionMatch?.[2] ?? descriptionMatch?.[3] ?? null),\n };\n}\n\nasync function readSkillMetadataFromDirectory(skillDir: string): Promise<{\n name: string | null;\n description: string | null;\n}> {\n const skillFile = path.join(skillDir, \"SKILL.md\");\n try {\n const markdown = await fs.readFile(skillFile, \"utf8\");\n return parseSkillFrontmatterMetadata(markdown);\n } catch {\n return { name: null, description: null };\n }\n}\n\nexport async function readSkillMetadataFromPath(candidatePath: string | null | undefined): Promise<{\n name: string | null;\n description: string | null;\n}> {\n if (typeof candidatePath !== \"string\" || candidatePath.trim().length === 0) {\n return { name: null, description: null };\n }\n const resolvedPath = path.resolve(candidatePath);\n const skillDir = path.basename(resolvedPath).toLowerCase() === \"skill.md\"\n ? path.dirname(resolvedPath)\n : resolvedPath;\n return readSkillMetadataFromDirectory(skillDir);\n}\n\nfunction resolveInstalledEntryTarget(\n skillsHome: string,\n entryName: string,\n dirent: Dirent,\n linkedPath: string | null,\n): InstalledSkillTarget {\n const fullPath = path.join(skillsHome, entryName);\n if (dirent.isSymbolicLink()) {\n return {\n targetPath: linkedPath ? path.resolve(path.dirname(fullPath), linkedPath) : null,\n kind: \"symlink\",\n };\n }\n if (dirent.isDirectory()) {\n return { targetPath: fullPath, kind: \"directory\" };\n }\n return { targetPath: fullPath, kind: \"file\" };\n}\n\nexport function parseObject(value: unknown): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nexport function asString(value: unknown, fallback: string): string {\n return typeof value === \"string\" && value.length > 0 ? value : fallback;\n}\n\nexport function asNumber(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nexport function asBoolean(value: unknown, fallback: boolean): boolean {\n return typeof value === \"boolean\" ? value : fallback;\n}\n\nexport function asStringArray(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nexport function parseJson(value: string): Record<string, unknown> | null {\n try {\n return JSON.parse(value) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport function appendWithCap(prev: string, chunk: string, cap = MAX_CAPTURE_BYTES) {\n const combined = prev + chunk;\n return combined.length > cap ? combined.slice(combined.length - cap) : combined;\n}\n\nexport function resolvePathValue(obj: Record<string, unknown>, dottedPath: string) {\n const parts = dottedPath.split(\".\");\n let cursor: unknown = obj;\n\n for (const part of parts) {\n if (typeof cursor !== \"object\" || cursor === null || Array.isArray(cursor)) {\n return \"\";\n }\n cursor = (cursor as Record<string, unknown>)[part];\n }\n\n if (cursor === null || cursor === undefined) return \"\";\n if (typeof cursor === \"string\") return cursor;\n if (typeof cursor === \"number\" || typeof cursor === \"boolean\") return String(cursor);\n\n try {\n return JSON.stringify(cursor);\n } catch {\n return \"\";\n }\n}\n\nexport function renderTemplate(template: string, data: Record<string, unknown>) {\n return template.replace(/{{\\s*([a-zA-Z0-9_.-]+)\\s*}}/g, (_, path) => resolvePathValue(data, path));\n}\n\nconst ISSUE_DOCUMENT_PROMPT_BODY_CHAR_LIMIT = 16_000;\n\ntype IssueDocumentPromptInput = {\n planDocument?: {\n key?: string | null;\n title?: string | null;\n body?: string | null;\n issueId?: string | null;\n } | null;\n documentSummaries?: Array<{\n key?: string | null;\n title?: string | null;\n latestRevisionNumber?: number | null;\n updatedAt?: string | Date | null;\n issueId?: string | null;\n }> | null;\n legacyPlanDocument?: {\n key?: string | null;\n body?: string | null;\n source?: string | null;\n } | null;\n};\n\nfunction truncateIssueDocumentBody(body: string) {\n if (body.length <= ISSUE_DOCUMENT_PROMPT_BODY_CHAR_LIMIT) return body;\n return `${body.slice(0, ISSUE_DOCUMENT_PROMPT_BODY_CHAR_LIMIT).trimEnd()}\\n\\n[Document truncated in prompt. Fetch the full document with the Rudder CLI.]`;\n}\n\nfunction formatDocumentHeading(key: string, title?: string | null) {\n const cleanTitle = typeof title === \"string\" ? title.trim() : \"\";\n return cleanTitle ? `### ${key} \u2014 ${cleanTitle}` : `### ${key}`;\n}\n\nfunction readIssueDocumentPromptIssueId(input: IssueDocumentPromptInput) {\n const planIssueId = typeof input.planDocument?.issueId === \"string\" ? input.planDocument.issueId.trim() : \"\";\n if (planIssueId) return planIssueId;\n for (const summary of input.documentSummaries ?? []) {\n const issueId = typeof summary.issueId === \"string\" ? summary.issueId.trim() : \"\";\n if (issueId) return issueId;\n }\n return \"<issue-id>\";\n}\n\nexport function buildIssueDocumentsPrompt(input: IssueDocumentPromptInput | null | undefined) {\n if (!input) return \"\";\n\n const sections: string[] = [];\n const planKey = input.planDocument?.key?.trim() || input.legacyPlanDocument?.key?.trim() || \"plan\";\n const planBody = input.planDocument?.body?.trim() || input.legacyPlanDocument?.body?.trim() || \"\";\n if (planBody) {\n sections.push([\n formatDocumentHeading(planKey, input.planDocument?.title),\n input.legacyPlanDocument ? \"Source: legacy `<plan>` block in the issue description.\" : `Source: issue document \\`${planKey}\\`.`,\n \"\",\n truncateIssueDocumentBody(planBody),\n ].join(\"\\n\"));\n }\n\n const otherDocuments = (input.documentSummaries ?? []).filter((doc) => {\n const key = typeof doc.key === \"string\" ? doc.key.trim() : \"\";\n return key && key !== planKey;\n });\n if (otherDocuments.length > 0) {\n const issueId = readIssueDocumentPromptIssueId(input);\n sections.push([\n \"### Additional Issue Documents\",\n ...otherDocuments.map((doc) => {\n const key = doc.key?.trim() || \"document\";\n const title = doc.title?.trim();\n const revision = typeof doc.latestRevisionNumber === \"number\" ? `, revision ${doc.latestRevisionNumber}` : \"\";\n const titlePart = title ? ` \u2014 ${title}` : \"\";\n return `- \\`${key}\\`${titlePart}${revision}. Fetch with \\`rudder issue documents get ${issueId} ${key} --json\\`.`;\n }),\n ].join(\"\\n\"));\n }\n\n if (sections.length === 0) return \"\";\n return [\"## Issue Documents\", ...sections].join(\"\\n\\n\");\n}\n\n// Default prompt templates for different wake sources\nexport const DEFAULT_AGENT_PROMPT_TEMPLATE =\n `You are agent {{agent.id}} ({{agent.name}}). Continue your Rudder work.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n{{context.issueDocumentsPrompt}}`;\n\nexport const ISSUE_ASSIGN_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). You have been assigned to work on an issue.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Task Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n**Status:** {{issue.status}}\n**Priority:** {{issue.priority}}\n\n**Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\nYour task is to review this issue and begin working on it. Use the available tools to explore the codebase, understand the requirements, and implement a solution.`;\n\nexport const COMMENT_MENTION_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). You were mentioned in a comment and your attention is needed.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n\n**Issue Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\n**Comment:**\n{{comment.body}}\n\nPlease review the comment above and respond or take action as appropriate.`;\n\nexport const ISSUE_COMMENTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). There is a new comment on an issue you own.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n**Status:** {{issue.status}}\n\n**Issue Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\n**Latest Comment:**\n{{comment.body}}\n\nReview the new comment and continue the issue from the current state. Respond or take action as needed.`;\n\nexport const ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). A reviewer requested changes on an issue you own.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n**Status:** {{issue.status}}\n\n**Issue Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\n**Reviewer Comment:**\n{{comment.body}}\n\nReview the requested changes and continue the issue from the current state. Address the reviewer feedback before handing it back for review.`;\n\nexport const ISSUE_RECOVERY_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a recovery run, not a fresh task.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Recovery Context\n\n- Original Run ID: {{context.recovery.originalRunId}}\n- Failure Kind: {{context.recovery.failureKind}}\n- Failure Summary: {{context.recovery.failureSummary}}\n- Recovery Trigger: {{context.recovery.recoveryTrigger}}\n- Recovery Mode: {{context.recovery.recoveryMode}}\n\n## Current Issue Context\n\n- Issue: {{issue.title}}\n- ID: {{issue.id}}\n- Status: {{issue.status}}\n- Priority: {{issue.priority}}\n\n- Description:\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\nBefore doing anything else, inspect what the previous run already completed and any side effects it may have caused. Continue the remaining work from the current state. Avoid blindly re-running the whole task.`;\n\nexport const RECOVERY_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a recovery run, not a fresh task.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Recovery Context\n\n- Original Run ID: {{context.recovery.originalRunId}}\n- Failure Kind: {{context.recovery.failureKind}}\n- Failure Summary: {{context.recovery.failureSummary}}\n- Recovery Trigger: {{context.recovery.recoveryTrigger}}\n- Recovery Mode: {{context.recovery.recoveryMode}}\n\nBefore doing anything else, inspect what the previous run already completed and any side effects it may have caused. Continue the remaining work from the current state. Avoid blindly re-running the whole task.`;\n\nexport const ISSUE_PASSIVE_FOLLOWUP_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a passive issue follow-up, not a fresh assignment and not a failure recovery.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Why You Were Woken\n\nThe previous run ended without sufficient issue close-out.\n\n- Origin Run ID: {{context.passiveFollowup.originRunId}}\n- Previous Run ID: {{context.passiveFollowup.previousRunId}}\n- Attempt: {{context.passiveFollowup.attempt}} / {{context.passiveFollowup.maxAttempts}}\nReason: {{context.passiveFollowup.reason}}\n\n## Current Issue Context\n\n- Issue: {{issue.title}}\n- ID: {{issue.id}}\n- Status: {{issue.status}}\n- Priority: {{issue.priority}}\n\n- Description:\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\nBefore changing the issue, inspect the current issue state and any side effects from the previous run. Then do exactly one close-out action: add a progress comment, mark the issue done, block it with a reason, or hand it off explicitly with explanation.`;\n\n/**\n * Selects the base heartbeat prompt template used by runtimes before final prompt assembly.\n *\n * Prompt shape by wake trigger:\n * - assignment:\n * \"You are agent ... You have been assigned ...\"\n * Includes issue title/id/status/priority/description so the agent can start immediately.\n * - comment.mention:\n * \"You were mentioned in a comment ...\"\n * Includes issue summary plus mention comment body so the agent can respond without extra fetches.\n * - issue_changes_requested:\n * \"A reviewer requested changes on an issue you own ...\"\n * Includes issue summary plus reviewer comment body so the assignee can act on feedback immediately.\n * - issue_commented:\n * \"There is a new comment on an issue you own ...\"\n * Includes issue summary plus the newest comment body so the assignee can continue immediately.\n * - recovery:\n * \"This is a recovery run, not a fresh task ...\"\n * Includes original run id, failure metadata, and a continue-preferred instruction to\n * inspect prior progress/side effects before resuming.\n * - passive issue follow-up:\n * \"This is a passive issue follow-up, not a fresh assignment ...\"\n * Includes close-out lineage and tells the agent to comment, finish, block, or hand off.\n * - fallback:\n * Generic \"Continue your Rudder work.\"\n *\n * Concrete rendered example (comment mention):\n * \"You are agent agent-456 (Backend Worker). You were mentioned in a comment and your attention is needed.\n * Issue: Stabilize queue worker\n * Comment: @agent please check timeout handling in retry path.\"\n *\n * Reasoning:\n * - Keep backward compatibility: custom configured templates always win.\n * - Keep first-turn latency low: include the minimum task context directly in prompt text.\n * - Keep behavior deterministic across runtimes: template selection is centralized here.\n *\n * See also:\n * - doc/plans/2026-04-07-agent-prompt-context-injection.md\n * - doc/DEVELOPING.md\n */\nexport function selectPromptTemplate(\n configuredTemplate: string | undefined,\n context: Record<string, unknown>,\n): string {\n // If user configured a custom template, use it\n if (configuredTemplate?.trim()) {\n return configuredTemplate;\n }\n\n // Select based on wake source/reason\n const wakeSource = String(context.wakeSource ?? \"\");\n const wakeReason = String(context.wakeReason ?? \"\");\n const recovery = context.recovery;\n const hasRecoveryContext =\n typeof recovery === \"object\" &&\n recovery !== null &&\n !Array.isArray(recovery) &&\n typeof (recovery as Record<string, unknown>).originalRunId === \"string\";\n\n if (hasRecoveryContext || wakeReason === \"process_lost_retry\" || wakeReason === \"retry_failed_run\") {\n return typeof context.issue === \"object\" && context.issue !== null && !Array.isArray(context.issue)\n ? ISSUE_RECOVERY_PROMPT_TEMPLATE\n : RECOVERY_PROMPT_TEMPLATE;\n }\n if (wakeReason === \"issue_passive_followup\") {\n return ISSUE_PASSIVE_FOLLOWUP_PROMPT_TEMPLATE;\n }\n if (wakeReason === \"issue_changes_requested\") {\n return ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE;\n }\n if (wakeSource === \"assignment\" || wakeReason === \"issue_assigned\") {\n return ISSUE_ASSIGN_PROMPT_TEMPLATE;\n }\n if (wakeSource === \"comment.mention\" || wakeReason === \"issue_comment_mentioned\") {\n return COMMENT_MENTION_PROMPT_TEMPLATE;\n }\n if (wakeReason === \"issue_commented\") {\n return ISSUE_COMMENTED_PROMPT_TEMPLATE;\n }\n\n return DEFAULT_AGENT_PROMPT_TEMPLATE;\n}\n\nexport function joinPromptSections(\n sections: Array<string | null | undefined>,\n separator = \"\\n\\n\",\n) {\n return sections\n .map((value) => (typeof value === \"string\" ? value.trim() : \"\"))\n .filter(Boolean)\n .join(separator);\n}\n\nexport const RUDDER_AGENT_OPERATING_CONTRACT = [\n \"# Rudder Agent Operating Contract\",\n \"\",\n \"Your home directory is `$AGENT_HOME`. Everything personal to you -- life, memory, knowledge -- lives there. Other agents may have their own folders and you may update them when necessary.\",\n \"\",\n \"Use these paths consistently:\",\n \"\",\n \"- Personal instructions live under `$AGENT_HOME/instructions`.\",\n \"- Personal memory lives under `$AGENT_HOME/memory`.\",\n \"- Tacit memory instruction lives at `$AGENT_HOME/instructions/MEMORY.md` and is automatically loaded when present.\",\n \"- Personal skills live under `$AGENT_HOME/skills`.\",\n \"- Shared organization workspace root lives under `$RUDDER_ORG_WORKSPACE_ROOT`.\",\n \"- Shared organization skills live under `$RUDDER_ORG_SKILLS_DIR`.\",\n \"- Shared organization plans live under `$RUDDER_ORG_PLANS_DIR`.\",\n \"- Shared organization artifacts live under `$RUDDER_ORG_ARTIFACTS_DIR`.\",\n \"- Durable generated outputs such as screenshots, images, mockups, reports, CSVs, handoff logs, and other user-visible files should be written under `$RUDDER_ORG_ARTIFACTS_DIR` when available.\",\n \"- Use `/tmp` only for transient scratch files and temporary verification artifacts; do not put durable work product there.\",\n \"- Local trusted runtimes may expose the host operator home as `$RUDDER_OPERATOR_HOME`; use it only when a local skill or script intentionally needs operator-owned desktop app or CLI state. Do not replace `$HOME` with it.\",\n \"- Durable shared work output should prefer these managed workspace paths instead of ad-hoc top-level `projects/` folders.\",\n \"\",\n \"When you create or copy a skill under `$AGENT_HOME/skills/<slug>/`, check the agent's Skills snapshot before claiming it will load in future runs. If it is installed but not enabled, say exactly that future runs will not load it until enabled, and offer to enable it with `rudder agent skills enable <agent-id> <selection-ref>` when you have permission.\",\n \"\",\n \"When you write issue comments or chat replies, match the language of the user's or board's most recent substantive message unless they explicitly ask for a different language.\",\n \"\",\n \"When an issue comment, done comment, or blocker comment cites visual evidence from a local screenshot/image path, attach the image with the Rudder CLI `--image <path>` option instead of leaving only the filesystem path in the text.\",\n \"\",\n \"## Memory and Planning\",\n \"\",\n \"You MUST use the `para-memory-files` skill for all memory operations: storing facts, writing daily notes, creating entities, running weekly synthesis, recalling past context, and managing plans. The skill defines your three-layer memory system (knowledge graph, daily notes, tacit knowledge), the PARA folder structure, atomic fact schemas, memory decay rules, and recall/planning conventions.\",\n \"\",\n \"Keep stable preferences and operating lessons in `$AGENT_HOME/instructions/MEMORY.md`. Use `$AGENT_HOME/memory/YYYY-MM-DD.md` for daily notes and `$AGENT_HOME/life/` for structured long-term memory; those files are not auto-loaded.\",\n \"\",\n \"Invoke it whenever you need to remember, retrieve, or organize anything.\",\n \"\",\n \"## Safety Considerations\",\n \"\",\n \"- Never exfiltrate secrets or private data.\",\n \"- Do not perform any destructive commands unless explicitly requested by the board.\",\n].join(\"\\n\");\n\nexport interface LoadedAgentInstructionsPrefix {\n prefix: string;\n commandNotes: string[];\n instructionsFilePath: string;\n instructionsDir: string;\n soulFilePath: string | null;\n toolsFilePath: string | null;\n memoryFilePath: string | null;\n readFailed: boolean;\n metrics: {\n instructionsChars: number;\n operatingContractChars: number;\n instructionEntryChars: number;\n soulChars: number;\n toolsChars: number;\n memoryChars: number;\n };\n}\n\nfunction toPromptPath(pathValue: string): string {\n return pathValue.split(path.sep).join(\"/\");\n}\n\nfunction isInsidePath(parentPath: string, childPath: string): boolean {\n const relativePath = path.relative(parentPath, childPath);\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !path.isAbsolute(relativePath));\n}\n\nfunction displayInstructionPath(filePath: string, instructionsFilePath: string): string {\n const resolvedFilePath = path.resolve(filePath);\n const resolvedInstructionsPath = path.resolve(instructionsFilePath);\n const instructionsDir = path.dirname(resolvedInstructionsPath);\n if (path.basename(instructionsDir) === \"instructions\") {\n const agentHome = path.dirname(instructionsDir);\n if (isInsidePath(agentHome, resolvedFilePath)) {\n const relativePath = path.relative(agentHome, resolvedFilePath);\n return relativePath ? `$AGENT_HOME/${toPromptPath(relativePath)}` : \"$AGENT_HOME\";\n }\n }\n return filePath;\n}\n\nfunction displayInstructionDir(filePath: string, instructionsFilePath: string): string {\n const displayPath = displayInstructionPath(filePath, instructionsFilePath);\n const lastSlash = displayPath.lastIndexOf(\"/\");\n return lastSlash >= 0 ? `${displayPath.slice(0, lastSlash)}/` : \"\";\n}\n\nexport async function loadAgentInstructionsPrefix(input: {\n instructionsFilePath: string;\n onLog: (stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>;\n warningStream?: \"stdout\" | \"stderr\";\n}): Promise<LoadedAgentInstructionsPrefix> {\n const instructionsFilePath = input.instructionsFilePath.trim();\n const instructionsDir = instructionsFilePath ? `${path.dirname(instructionsFilePath)}/` : \"\";\n const displayInstructionsFilePath = instructionsFilePath\n ? displayInstructionPath(instructionsFilePath, instructionsFilePath)\n : \"\";\n const displayInstructionsDir = instructionsFilePath\n ? displayInstructionDir(instructionsFilePath, instructionsFilePath)\n : \"\";\n const warningStream = input.warningStream ?? \"stdout\";\n const operatingContractSection =\n `${RUDDER_AGENT_OPERATING_CONTRACT}\\n\\n` +\n \"The above Rudder agent operating contract was injected by Rudder at runtime.\";\n const empty = {\n prefix: operatingContractSection,\n commandNotes: [\"Loaded Rudder agent operating contract from runtime code\"],\n instructionsFilePath,\n instructionsDir,\n soulFilePath: null,\n toolsFilePath: null,\n memoryFilePath: null,\n readFailed: false,\n metrics: {\n instructionsChars: operatingContractSection.length,\n operatingContractChars: operatingContractSection.length,\n instructionEntryChars: 0,\n soulChars: 0,\n toolsChars: 0,\n memoryChars: 0,\n },\n } satisfies LoadedAgentInstructionsPrefix;\n\n if (!instructionsFilePath) return empty;\n\n const loadedPaths = new Set<string>();\n const commandNotes = [...empty.commandNotes];\n let entrySection = \"\";\n try {\n const instructionsContents = await fs.readFile(instructionsFilePath, \"utf8\");\n loadedPaths.add(path.resolve(instructionsFilePath));\n entrySection =\n `${instructionsContents}\\n\\n` +\n `The above agent instructions were loaded from ${displayInstructionsFilePath}. ` +\n `Resolve any relative file references from ${displayInstructionsDir}.`;\n await input.onLog(\n \"stdout\",\n `[rudder] Loaded agent instructions file: ${displayInstructionsFilePath}\\n`,\n );\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n await input.onLog(\n warningStream,\n `[rudder] Warning: could not read agent instructions file \"${instructionsFilePath}\": ${reason}\\n`,\n );\n commandNotes.push(\n `Configured instructionsFilePath ${displayInstructionsFilePath}, but file could not be read; continuing without injected instructions.`,\n );\n }\n\n async function loadSiblingInstructionFile(siblingInput: {\n fileName: string;\n label: string;\n logLabel: string;\n }): Promise<{ path: string | null; section: string }> {\n const filePath = path.join(path.dirname(instructionsFilePath), siblingInput.fileName);\n const resolvedPath = path.resolve(filePath);\n const displayFilePath = displayInstructionPath(filePath, instructionsFilePath);\n const displayFileDir = displayInstructionDir(filePath, instructionsFilePath);\n if (loadedPaths.has(resolvedPath)) return { path: filePath, section: \"\" };\n try {\n const contents = await fs.readFile(filePath, \"utf8\");\n loadedPaths.add(resolvedPath);\n await input.onLog(\n \"stdout\",\n `[rudder] Loaded ${siblingInput.logLabel}: ${displayFilePath}\\n`,\n );\n return {\n path: filePath,\n section:\n `${contents}\\n\\n` +\n `The above ${siblingInput.label} were loaded from ${displayFilePath}. ` +\n `Resolve any relative file references from ${displayFileDir}.`,\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n const reason = err instanceof Error ? err.message : String(err);\n await input.onLog(\n warningStream,\n `[rudder] Warning: could not read ${siblingInput.logLabel} \"${filePath}\": ${reason}\\n`,\n );\n }\n return { path: null, section: \"\" };\n }\n }\n\n const soul = await loadSiblingInstructionFile({\n fileName: \"SOUL.md\",\n label: \"agent role and persona instructions\",\n logLabel: \"agent soul instructions file\",\n });\n if (soul.section && soul.path) {\n commandNotes.push(`Loaded agent soul instructions from ${displayInstructionPath(soul.path, instructionsFilePath)}`);\n }\n\n const tools = await loadSiblingInstructionFile({\n fileName: \"TOOLS.md\",\n label: \"agent tool notes\",\n logLabel: \"agent tool notes file\",\n });\n if (tools.section && tools.path) {\n commandNotes.push(`Loaded agent tool notes from ${displayInstructionPath(tools.path, instructionsFilePath)}`);\n }\n\n const memory = await loadSiblingInstructionFile({\n fileName: \"MEMORY.md\",\n label: \"agent memory instructions\",\n logLabel: \"agent memory instructions file\",\n });\n if (memory.section && memory.path) {\n commandNotes.push(`Loaded agent memory instructions from ${displayInstructionPath(memory.path, instructionsFilePath)}`);\n }\n\n const memoryFilePath = memory.section ? memory.path : null;\n const memorySection = memory.section;\n if (entrySection) commandNotes.splice(1, 0, `Loaded agent instructions from ${displayInstructionsFilePath}`);\n\n const prefix = joinPromptSections([operatingContractSection, entrySection, soul.section, tools.section, memorySection]);\n return {\n prefix,\n commandNotes,\n instructionsFilePath,\n instructionsDir,\n soulFilePath: soul.section ? soul.path : null,\n toolsFilePath: tools.section ? tools.path : null,\n memoryFilePath,\n readFailed: !entrySection,\n metrics: {\n instructionsChars: prefix.length,\n operatingContractChars: operatingContractSection.length,\n instructionEntryChars: entrySection.length,\n soulChars: soul.section.length,\n toolsChars: tools.section.length,\n memoryChars: memorySection.length,\n },\n };\n}\n\nexport function redactEnvForLogs(env: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n redacted[key] = SENSITIVE_ENV_KEY.test(key) ? \"***REDACTED***\" : value;\n }\n return redacted;\n}\n\nexport function buildRudderEnv(agent: { id: string; orgId: string }): Record<string, string> {\n const resolveHostForUrl = (rawHost: string): string => {\n const host = rawHost.trim();\n if (!host || host === \"0.0.0.0\" || host === \"::\") return \"localhost\";\n if (host.includes(\":\") && !host.startsWith(\"[\") && !host.endsWith(\"]\")) return `[${host}]`;\n return host;\n };\n const vars: Record<string, string> = {\n RUDDER_AGENT_ID: agent.id,\n RUDDER_ORG_ID: agent.orgId,\n };\n const runtimeHost = resolveHostForUrl(\n process.env.RUDDER_LISTEN_HOST ?? process.env.HOST ?? \"localhost\",\n );\n const runtimePort = process.env.RUDDER_LISTEN_PORT ?? process.env.PORT ?? \"3100\";\n const apiUrl = process.env.RUDDER_API_URL ?? `http://${runtimeHost}:${runtimePort}`;\n vars.RUDDER_API_URL = apiUrl;\n return vars;\n}\n\nexport function defaultPathForPlatform() {\n if (process.platform === \"win32\") {\n return \"C:\\\\Windows\\\\System32;C:\\\\Windows;C:\\\\Windows\\\\System32\\\\Wbem\";\n }\n return \"/usr/local/bin:/opt/homebrew/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin\";\n}\n\nfunction windowsPathExts(env: NodeJS.ProcessEnv): string[] {\n return (env.PATHEXT ?? \".EXE;.CMD;.BAT;.COM\").split(\";\").filter(Boolean);\n}\n\nasync function pathExists(candidate: string) {\n try {\n await fs.access(candidate, process.platform === \"win32\" ? fsConstants.F_OK : fsConstants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function fileExists(candidate: string) {\n try {\n await fs.access(candidate, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function resolveCommandPath(command: string, cwd: string, env: NodeJS.ProcessEnv): Promise<string | null> {\n const hasPathSeparator = command.includes(\"/\") || command.includes(\"\\\\\");\n if (hasPathSeparator) {\n const absolute = path.isAbsolute(command) ? command : path.resolve(cwd, command);\n return (await pathExists(absolute)) ? absolute : null;\n }\n\n const pathValue = env.PATH ?? env.Path ?? \"\";\n const delimiter = process.platform === \"win32\" ? \";\" : \":\";\n const dirs = pathValue.split(delimiter).filter(Boolean);\n const exts = process.platform === \"win32\" ? windowsPathExts(env) : [\"\"];\n const hasExtension = process.platform === \"win32\" && path.extname(command).length > 0;\n\n for (const dir of dirs) {\n const candidates =\n process.platform === \"win32\"\n ? hasExtension\n ? [path.join(dir, command)]\n : exts.map((ext) => path.join(dir, `${command}${ext}`))\n : [path.join(dir, command)];\n for (const candidate of candidates) {\n if (await pathExists(candidate)) return candidate;\n }\n }\n\n return null;\n}\n\nfunction quoteForCmd(arg: string) {\n if (!arg.length) return '\"\"';\n const escaped = arg.replace(/\"/g, '\"\"');\n return /[\\s\"&<>|^()]/.test(escaped) ? `\"${escaped}\"` : escaped;\n}\n\nasync function resolveSpawnTarget(\n command: string,\n args: string[],\n cwd: string,\n env: NodeJS.ProcessEnv,\n): Promise<SpawnTarget> {\n const resolved = await resolveCommandPath(command, cwd, env);\n const executable = resolved ?? command;\n\n if (process.platform !== \"win32\") {\n return { command: executable, args };\n }\n\n if (/\\.(cmd|bat)$/i.test(executable)) {\n const shell = env.ComSpec || process.env.ComSpec || \"cmd.exe\";\n const commandLine = [quoteForCmd(executable), ...args.map(quoteForCmd)].join(\" \");\n return {\n command: shell,\n args: [\"/d\", \"/s\", \"/c\", commandLine],\n };\n }\n\n return { command: executable, args };\n}\n\nexport function ensurePathInEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n if (typeof env.PATH === \"string\" && env.PATH.length > 0) return env;\n if (typeof env.Path === \"string\" && env.Path.length > 0) return env;\n return { ...env, PATH: defaultPathForPlatform() };\n}\n\nfunction prependPathEntry(env: NodeJS.ProcessEnv, entry: string): NodeJS.ProcessEnv {\n const normalized = ensurePathInEnv(env);\n const pathKey = typeof normalized.PATH === \"string\" ? \"PATH\" : \"Path\";\n const current = normalized[pathKey] ?? \"\";\n const delimiter = process.platform === \"win32\" ? \";\" : \":\";\n const segments = current.split(delimiter).filter(Boolean);\n if (segments.includes(entry)) return normalized;\n return {\n ...normalized,\n [pathKey]: current.length > 0 ? `${entry}${delimiter}${current}` : entry,\n };\n}\n\nasync function findAncestorWithFile(\n startDir: string,\n relativePath: string,\n maxDepth = 12,\n): Promise<string | null> {\n let current = path.resolve(startDir);\n for (let depth = 0; depth <= maxDepth; depth += 1) {\n const candidate = path.join(current, relativePath);\n if (await fileExists(candidate)) return candidate;\n const parent = path.dirname(current);\n if (parent === current) break;\n current = parent;\n }\n return null;\n}\n\nfunction shellQuote(arg: string): string {\n return `'${arg.replace(/'/g, `'\\\\''`)}'`;\n}\n\nasync function resolveRudderCliShimTarget(moduleDir: string): Promise<SpawnTarget | null> {\n const packagedCli = await findAncestorWithFile(moduleDir, \"desktop-cli.js\");\n if (packagedCli) {\n return {\n command: process.execPath,\n args: [packagedCli],\n };\n }\n\n const repoRoot = await findAncestorWithFile(moduleDir, path.join(\"cli\", \"src\", \"index.ts\"));\n if (!repoRoot) return null;\n const rootDir = path.dirname(path.dirname(path.dirname(repoRoot)));\n const tsxEntry = path.join(rootDir, \"cli\", \"node_modules\", \"tsx\", \"dist\", \"cli.mjs\");\n const cliSource = path.join(rootDir, \"cli\", \"src\", \"index.ts\");\n if (await fileExists(tsxEntry)) {\n return {\n command: process.execPath,\n args: [tsxEntry, cliSource],\n };\n }\n\n const builtCliEntry = path.join(rootDir, \"cli\", \"dist\", \"index.js\");\n if (await fileExists(builtCliEntry)) {\n return {\n command: process.execPath,\n args: [builtCliEntry],\n };\n }\n\n return null;\n}\n\nasync function materializeRudderCliShim(target: SpawnTarget): Promise<string> {\n const hash = createHash(\"sha1\")\n .update(JSON.stringify({ command: target.command, args: target.args, platform: process.platform }))\n .digest(\"hex\")\n .slice(0, 12);\n const shimDir = path.join(os.tmpdir(), \"rudder-cli-shims\", hash);\n await fs.mkdir(shimDir, { recursive: true });\n\n if (process.platform === \"win32\") {\n const shimPath = path.join(shimDir, \"rudder.cmd\");\n const commandLine = [quoteForCmd(target.command), ...target.args.map(quoteForCmd), \"%*\"].join(\" \");\n await fs.writeFile(shimPath, `@echo off\\r\\n${commandLine}\\r\\n`, \"utf8\");\n return shimPath;\n }\n\n const shimPath = path.join(shimDir, \"rudder\");\n const commandLine = [target.command, ...target.args].map(shellQuote).join(\" \");\n await fs.writeFile(shimPath, `#!/bin/sh\\nexec ${commandLine} \"$@\"\\n`, \"utf8\");\n await fs.chmod(shimPath, 0o755);\n return shimPath;\n}\n\nexport async function ensureRudderCliInPath(\n moduleDir: string,\n env: NodeJS.ProcessEnv,\n): Promise<NodeJS.ProcessEnv> {\n const normalized = ensurePathInEnv(env);\n const target = await resolveRudderCliShimTarget(moduleDir);\n if (!target) {\n return normalized;\n }\n\n const shimPath = await materializeRudderCliShim(target);\n return prependPathEntry(normalized, path.dirname(shimPath));\n}\n\nexport async function ensureAbsoluteDirectory(\n cwd: string,\n opts: { createIfMissing?: boolean } = {},\n) {\n if (!path.isAbsolute(cwd)) {\n throw new Error(`Working directory must be an absolute path: \"${cwd}\"`);\n }\n\n const assertDirectory = async () => {\n const stats = await fs.stat(cwd);\n if (!stats.isDirectory()) {\n throw new Error(`Working directory is not a directory: \"${cwd}\"`);\n }\n };\n\n try {\n await assertDirectory();\n return;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (!opts.createIfMissing || code !== \"ENOENT\") {\n if (code === \"ENOENT\") {\n throw new Error(`Working directory does not exist: \"${cwd}\"`);\n }\n throw err instanceof Error ? err : new Error(String(err));\n }\n }\n\n try {\n await fs.mkdir(cwd, { recursive: true });\n await assertDirectory();\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n throw new Error(`Could not create working directory \"${cwd}\": ${reason}`);\n }\n}\n\nexport async function resolveRudderSkillsDir(\n moduleDir: string,\n additionalCandidates: string[] = [],\n): Promise<string | null> {\n const candidates = [\n ...RUDDER_SKILL_ROOT_RELATIVE_CANDIDATES.map((relativePath) => path.resolve(moduleDir, relativePath)),\n ...additionalCandidates.map((candidate) => path.resolve(candidate)),\n ];\n const seenRoots = new Set<string>();\n\n for (const root of candidates) {\n if (seenRoots.has(root)) continue;\n seenRoots.add(root);\n const isDirectory = await fs.stat(root).then((stats) => stats.isDirectory()).catch(() => false);\n if (isDirectory) return root;\n }\n\n return null;\n}\n\nexport async function listRudderSkillEntries(\n moduleDir: string,\n additionalCandidates: string[] = [],\n): Promise<RudderSkillEntry[]> {\n const root = await resolveRudderSkillsDir(moduleDir, additionalCandidates);\n if (!root) return [];\n\n try {\n const entries = await fs.readdir(root, { withFileTypes: true });\n const skillDirectories = entries\n .filter((entry) => entry.isDirectory())\n .sort((left, right) => left.name.localeCompare(right.name));\n const skillEntries = await Promise.all(\n skillDirectories.map(async (entry) => {\n const source = path.join(root, entry.name);\n const metadata = await readSkillMetadataFromDirectory(source);\n return {\n key: `rudder/${entry.name}`,\n runtimeName: entry.name,\n source,\n name: metadata.name ?? entry.name,\n description: metadata.description,\n };\n }),\n );\n return skillEntries;\n } catch {\n return [];\n }\n}\n\nexport async function readInstalledSkillTargets(skillsHome: string): Promise<Map<string, InstalledSkillTarget>> {\n const entries = await fs.readdir(skillsHome, { withFileTypes: true }).catch(() => []);\n const out = new Map<string, InstalledSkillTarget>();\n for (const entry of entries) {\n const fullPath = path.join(skillsHome, entry.name);\n const linkedPath = entry.isSymbolicLink() ? await fs.readlink(fullPath).catch(() => null) : null;\n out.set(entry.name, resolveInstalledEntryTarget(skillsHome, entry.name, entry, linkedPath));\n }\n return out;\n}\n\nexport function buildPersistentSkillSnapshot(\n options: PersistentSkillSnapshotOptions,\n): AgentRuntimeSkillSnapshot {\n const {\n agentRuntimeType,\n availableEntries,\n desiredSkills,\n installed,\n skillsHome,\n locationLabel,\n installedDetail,\n missingDetail,\n externalConflictDetail,\n externalDetail,\n } = options;\n const availableByKey = new Map(availableEntries.map((entry) => [entry.key, entry]));\n const desiredSet = new Set(desiredSkills);\n const entries: AgentRuntimeSkillEntry[] = [];\n const warnings = [...(options.warnings ?? [])];\n\n for (const available of availableEntries) {\n const installedEntry = installed.get(available.runtimeName) ?? null;\n const desired = desiredSet.has(available.key);\n let state: AgentRuntimeSkillEntry[\"state\"] = \"available\";\n let managed = false;\n let detail: string | null = null;\n\n if (installedEntry?.targetPath === available.source) {\n managed = true;\n state = desired ? \"installed\" : \"stale\";\n detail = installedDetail ?? null;\n } else if (installedEntry) {\n state = \"external\";\n detail = desired ? externalConflictDetail : externalDetail;\n } else if (desired) {\n state = \"missing\";\n detail = missingDetail;\n }\n\n entries.push({\n key: available.key,\n runtimeName: available.runtimeName,\n description: available.description ?? null,\n desired,\n managed,\n state,\n sourcePath: available.source,\n targetPath: path.join(skillsHome, available.runtimeName),\n detail,\n ...buildManagedSkillOrigin(),\n });\n }\n\n for (const desiredSkill of desiredSkills) {\n if (availableByKey.has(desiredSkill)) continue;\n warnings.push(`Desired skill \"${desiredSkill}\" is not available from the Rudder skills directory.`);\n entries.push({\n key: desiredSkill,\n runtimeName: null,\n desired: true,\n managed: true,\n state: \"missing\",\n sourcePath: null,\n targetPath: null,\n detail: \"Rudder cannot find this skill in the local runtime skills directory.\",\n origin: \"external_unknown\",\n originLabel: \"External or unavailable\",\n readOnly: false,\n });\n }\n\n for (const [name, installedEntry] of installed.entries()) {\n if (availableEntries.some((entry) => entry.runtimeName === name)) continue;\n entries.push({\n key: name,\n runtimeName: name,\n description: null,\n desired: false,\n managed: false,\n state: \"external\",\n origin: \"user_installed\",\n originLabel: \"User-installed\",\n locationLabel: skillLocationLabel(locationLabel),\n readOnly: true,\n sourcePath: null,\n targetPath: installedEntry.targetPath ?? path.join(skillsHome, name),\n detail: externalDetail,\n });\n }\n\n entries.sort((left, right) => left.key.localeCompare(right.key));\n\n return {\n agentRuntimeType,\n supported: true,\n mode: \"persistent\",\n desiredSkills,\n entries,\n warnings,\n };\n}\n\nfunction normalizeConfiguredPaperclipRuntimeSkills(value: unknown): RudderSkillEntry[] {\n if (!Array.isArray(value)) return [];\n const out: RudderSkillEntry[] = [];\n for (const rawEntry of value) {\n const entry = parseObject(rawEntry);\n const key = asString(entry.key, asString(entry.name, \"\")).trim();\n const runtimeName = asString(entry.runtimeName, asString(entry.name, \"\")).trim();\n const source = asString(entry.source, \"\").trim();\n if (!key || !runtimeName || !source) continue;\n out.push({\n key,\n runtimeName,\n source,\n name: compactSkillText(asString(entry.displayName, asString(entry.name, \"\"))) ?? runtimeName,\n description: compactSkillText(\n typeof entry.description === \"string\"\n ? entry.description\n : typeof entry.summary === \"string\"\n ? entry.summary\n : null,\n ),\n });\n }\n return out;\n}\n\nexport async function readRudderRuntimeSkillEntries(\n config: Record<string, unknown>,\n moduleDir: string,\n additionalCandidates: string[] = [],\n): Promise<RudderSkillEntry[]> {\n const configuredEntries = normalizeConfiguredPaperclipRuntimeSkills(\n config.rudderRuntimeSkills ?? config.paperclipRuntimeSkills,\n );\n if (configuredEntries.length > 0) return configuredEntries;\n return listRudderSkillEntries(moduleDir, additionalCandidates);\n}\n\nexport async function readRudderSkillMarkdown(\n moduleDir: string,\n skillKey: string,\n): Promise<string | null> {\n const normalized = skillKey.trim().toLowerCase().replace(/^rudder\\/rudder\\//, \"rudder/\");\n if (!normalized) return null;\n\n const entries = await listRudderSkillEntries(moduleDir);\n const match = entries.find((entry) => entry.key === normalized);\n if (!match) return null;\n\n try {\n return await fs.readFile(path.join(match.source, \"SKILL.md\"), \"utf8\");\n } catch {\n return null;\n }\n}\n\nexport function readRudderSkillSyncPreference(config: Record<string, unknown>): {\n explicit: boolean;\n desiredSkills: string[];\n} {\n const raw = config.rudderSkillSync ?? config.paperclipSkillSync;\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n return { explicit: false, desiredSkills: [] };\n }\n const syncConfig = raw as Record<string, unknown>;\n const desiredValues = syncConfig.desiredSkills;\n const desired = Array.isArray(desiredValues)\n ? desiredValues\n .filter((value): value is string => typeof value === \"string\")\n .map((value) => value.trim())\n .filter(Boolean)\n : [];\n return {\n explicit: Object.prototype.hasOwnProperty.call(raw, \"desiredSkills\"),\n desiredSkills: Array.from(new Set(desired)),\n };\n}\n\nfunction canonicalizeDesiredRudderSkillReference(\n reference: string,\n availableEntries: Array<{ key: string; runtimeName?: string | null }>,\n): string {\n const normalizedReference = reference.trim().toLowerCase().replace(/^rudder\\/rudder\\//, \"rudder/\");\n if (!normalizedReference) return \"\";\n\n const exactKey = availableEntries.find((entry) => entry.key.trim().toLowerCase() === normalizedReference);\n if (exactKey) return exactKey.key;\n\n const byRuntimeName = availableEntries.filter((entry) =>\n typeof entry.runtimeName === \"string\" && entry.runtimeName.trim().toLowerCase() === normalizedReference,\n );\n if (byRuntimeName.length === 1) return byRuntimeName[0]!.key;\n\n const slugMatches = availableEntries.filter((entry) =>\n entry.key.trim().toLowerCase().split(\"/\").pop() === normalizedReference,\n );\n if (slugMatches.length === 1) return slugMatches[0]!.key;\n\n return normalizedReference;\n}\n\nexport function resolveRudderDesiredSkillNames(\n config: Record<string, unknown>,\n availableEntries: Array<{ key: string; runtimeName?: string | null }>,\n): string[] {\n const preference = readRudderSkillSyncPreference(config);\n const desiredSkills = preference.desiredSkills\n .map((reference) => canonicalizeDesiredRudderSkillReference(reference, availableEntries))\n .filter(Boolean);\n return Array.from(new Set(desiredSkills));\n}\n\nexport function writeRudderSkillSyncPreference(\n config: Record<string, unknown>,\n desiredSkills: string[],\n): Record<string, unknown> {\n const next = { ...config };\n const raw = next.rudderSkillSync;\n const current =\n typeof raw === \"object\" && raw !== null && !Array.isArray(raw)\n ? { ...(raw as Record<string, unknown>) }\n : {};\n current.desiredSkills = Array.from(\n new Set(\n desiredSkills\n .map((value) => value.trim())\n .filter(Boolean),\n ),\n );\n next.rudderSkillSync = current;\n return next;\n}\n\nfunction nonEmptyEnvPath(value: string | undefined): string | null {\n return typeof value === \"string\" && value.trim().length > 0 ? path.resolve(value.trim()) : null;\n}\n\nexport function resolveLocalOperatorHome(sourceEnv: NodeJS.ProcessEnv = process.env): string {\n return (\n nonEmptyEnvPath(sourceEnv.RUDDER_OPERATOR_HOME)\n ?? nonEmptyEnvPath(process.env.RUDDER_OPERATOR_HOME)\n ?? nonEmptyEnvPath(process.env.HOME)\n ?? nonEmptyEnvPath(sourceEnv.HOME)\n ?? path.resolve(os.homedir())\n );\n}\n\nexport function applyLocalCliHomeEnv(\n targetEnv: Record<string, string>,\n sourceEnv: NodeJS.ProcessEnv = process.env,\n): void {\n const home = nonEmptyEnvPath(sourceEnv.HOME) ?? path.resolve(os.homedir());\n targetEnv.HOME = home;\n\n const userProfile = nonEmptyEnvPath(sourceEnv.USERPROFILE);\n if (userProfile) {\n targetEnv.USERPROFILE = userProfile;\n } else if (process.platform === \"win32\") {\n targetEnv.USERPROFILE = home;\n }\n}\n\nasync function localCliPathExists(candidate: string): Promise<boolean> {\n return fs.access(candidate).then(() => true).catch(() => false);\n}\n\nasync function directoryIsEmpty(target: string): Promise<boolean> {\n const entries = await fs.readdir(target).catch(() => null);\n return Array.isArray(entries) && entries.length === 0;\n}\n\nasync function ensureSymlinkToSource(target: string, source: string): Promise<\"created\" | \"repaired\" | \"skipped\"> {\n const existing = await fs.lstat(target).catch(() => null);\n if (!existing) {\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.symlink(source, target);\n return \"created\";\n }\n\n if (!existing.isSymbolicLink()) {\n if (existing.isDirectory() && await directoryIsEmpty(target)) {\n await fs.rmdir(target);\n await fs.symlink(source, target);\n return \"repaired\";\n }\n return \"skipped\";\n }\n\n const linkedPath = await fs.readlink(target).catch(() => null);\n if (!linkedPath) return \"skipped\";\n\n const resolvedLinkedPath = path.isAbsolute(linkedPath)\n ? linkedPath\n : path.resolve(path.dirname(target), linkedPath);\n if (resolvedLinkedPath === source) return \"skipped\";\n\n await fs.unlink(target);\n await fs.symlink(source, target);\n return \"repaired\";\n}\n\nexport async function syncLocalCliCredentialHomeEntries(input: {\n sourceHome?: string | null;\n targetHome: string;\n entries?: readonly string[];\n onLog?: ((stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>) | null;\n}): Promise<{ linked: string[]; skipped: string[] }> {\n const sourceHome = nonEmptyEnvPath(input.sourceHome ?? undefined) ?? path.resolve(os.homedir());\n const targetHome = path.resolve(input.targetHome);\n const linked: string[] = [];\n const skipped: string[] = [];\n if (sourceHome === targetHome) return { linked, skipped };\n\n const entries = input.entries ?? DEFAULT_LOCAL_CLI_CREDENTIAL_HOME_ENTRIES;\n for (const relativeEntry of entries) {\n const source = path.join(sourceHome, relativeEntry);\n if (!(await localCliPathExists(source))) continue;\n\n const target = path.join(targetHome, relativeEntry);\n try {\n const result = await ensureSymlinkToSource(target, source);\n if (result === \"skipped\") skipped.push(relativeEntry);\n else linked.push(relativeEntry);\n } catch {\n skipped.push(relativeEntry);\n }\n }\n\n if (input.onLog && linked.length > 0) {\n await input.onLog(\n \"stdout\",\n `[rudder] Shared ${linked.length} local CLI credential entr${linked.length === 1 ? \"y\" : \"ies\"} into managed HOME ${targetHome}: ${linked.join(\", \")}\\n`,\n );\n }\n\n return { linked, skipped };\n}\n\nasync function writeOperatorHomeShim(input: {\n shimDir: string;\n command: string;\n targetCommand: string;\n operatorHome: string;\n}): Promise<string> {\n await fs.mkdir(input.shimDir, { recursive: true });\n\n if (process.platform === \"win32\") {\n const shimPath = path.join(input.shimDir, `${input.command}.cmd`);\n const lines = [\n \"@echo off\",\n `set \"HOME=${input.operatorHome}\"`,\n `set \"USERPROFILE=${input.operatorHome}\"`,\n `${quoteForCmd(input.targetCommand)} %*`,\n \"\",\n ];\n await fs.writeFile(shimPath, lines.join(\"\\r\\n\"), \"utf8\");\n return shimPath;\n }\n\n const shimPath = path.join(input.shimDir, input.command);\n await fs.writeFile(\n shimPath,\n [\n \"#!/bin/sh\",\n `export HOME=${shellQuote(input.operatorHome)}`,\n `export USERPROFILE=${shellQuote(input.operatorHome)}`,\n `exec ${shellQuote(input.targetCommand)} \"$@\"`,\n \"\",\n ].join(\"\\n\"),\n \"utf8\",\n );\n await fs.chmod(shimPath, 0o755);\n return shimPath;\n}\n\nfunction normalizeShimCommand(input: string | LocalCliCredentialShimCommand): LocalCliCredentialShimCommand {\n return typeof input === \"string\" ? { command: input } : input;\n}\n\nasync function runCredentialShimAuthCheck(input: {\n targetCommand: string;\n args: readonly string[];\n cwd: string;\n env: NodeJS.ProcessEnv;\n home: string;\n}): Promise<boolean> {\n const env = {\n ...input.env,\n HOME: input.home,\n USERPROFILE: input.home,\n };\n return await new Promise<boolean>((resolve) => {\n const child = spawn(input.targetCommand, [...input.args], {\n cwd: input.cwd,\n env,\n stdio: [\"ignore\", \"ignore\", \"ignore\"],\n });\n const timeout = setTimeout(() => {\n child.kill(\"SIGTERM\");\n resolve(false);\n }, 1000);\n child.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(false);\n });\n child.on(\"close\", (code) => {\n clearTimeout(timeout);\n resolve(code === 0);\n });\n });\n}\n\nasync function credentialBridgeSatisfied(input: {\n operatorHome: string;\n targetHome: string;\n entries: readonly string[];\n}): Promise<boolean> {\n for (const entry of input.entries) {\n const source = path.join(input.operatorHome, entry);\n const target = path.join(input.targetHome, entry);\n if (!(await localCliPathExists(source)) || !(await localCliPathExists(target))) continue;\n const [sourceRealpath, targetRealpath] = await Promise.all([\n fs.realpath(source).catch(() => null),\n fs.realpath(target).catch(() => null),\n ]);\n if (sourceRealpath && targetRealpath && sourceRealpath === targetRealpath) return true;\n }\n return false;\n}\n\nasync function shouldPrepareOperatorHomeShim(input: {\n command: LocalCliCredentialShimCommand;\n targetCommand: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n targetHome: string;\n operatorHome: string;\n}): Promise<boolean> {\n const authCheckArgs = input.command.authCheckArgs;\n if (!authCheckArgs || authCheckArgs.length === 0) return true;\n\n if (input.command.credentialEntries && input.command.credentialEntries.length > 0) {\n const hasOperatorCredentialEntry = await Promise.all(\n input.command.credentialEntries.map((entry) => localCliPathExists(path.join(input.operatorHome, entry))),\n );\n if (!hasOperatorCredentialEntry.some(Boolean)) return false;\n if (await credentialBridgeSatisfied({\n operatorHome: input.operatorHome,\n targetHome: input.targetHome,\n entries: input.command.credentialEntries,\n })) {\n return false;\n }\n }\n\n const managedHomeWorks = await runCredentialShimAuthCheck({\n targetCommand: input.targetCommand,\n args: authCheckArgs,\n cwd: input.cwd,\n env: input.env,\n home: input.targetHome,\n });\n if (managedHomeWorks) return false;\n\n return await runCredentialShimAuthCheck({\n targetCommand: input.targetCommand,\n args: authCheckArgs,\n cwd: input.cwd,\n env: input.env,\n home: input.operatorHome,\n });\n}\n\nexport async function ensureLocalCliCredentialShimsInPath(input: {\n operatorHome?: string | null;\n targetHome: string;\n env: NodeJS.ProcessEnv;\n cwd?: string;\n commands?: readonly (string | LocalCliCredentialShimCommand)[];\n onLog?: ((stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>) | null;\n}): Promise<NodeJS.ProcessEnv> {\n const operatorHome = nonEmptyEnvPath(input.operatorHome ?? undefined);\n const targetHome = nonEmptyEnvPath(input.targetHome);\n if (!operatorHome || !targetHome || operatorHome === targetHome) {\n return ensurePathInEnv(input.env);\n }\n\n const normalized = ensurePathInEnv(input.env);\n const cwd = input.cwd ?? process.cwd();\n const commands = input.commands ?? DEFAULT_LOCAL_CLI_OPERATOR_HOME_SHIM_COMMANDS;\n const shimDir = path.join(targetHome, \".rudder\", \"local-cli-shims\");\n const prepared: string[] = [];\n\n for (const rawCommand of commands) {\n const command = normalizeShimCommand(rawCommand);\n const targetCommand = await resolveCommandPath(command.command, cwd, normalized);\n if (!targetCommand) continue;\n if (path.dirname(targetCommand) === shimDir) continue;\n if (!(await shouldPrepareOperatorHomeShim({\n command,\n targetCommand,\n cwd,\n env: normalized,\n targetHome,\n operatorHome,\n }))) {\n continue;\n }\n await writeOperatorHomeShim({ shimDir, command: command.command, targetCommand, operatorHome });\n prepared.push(command.command);\n }\n\n if (prepared.length === 0) return normalized;\n if (input.onLog) {\n await input.onLog(\n \"stdout\",\n `[rudder] Prepared local CLI credential shim${prepared.length === 1 ? \"\" : \"s\"} for: ${prepared.join(\", \")}\\n`,\n );\n }\n return prependPathEntry(normalized, shimDir);\n}\n\nexport async function ensureRudderSkillSymlink(\n source: string,\n target: string,\n linkSkill: (source: string, target: string) => Promise<void> = (linkSource, linkTarget) =>\n fs.symlink(linkSource, linkTarget),\n): Promise<\"created\" | \"repaired\" | \"skipped\"> {\n const existing = await fs.lstat(target).catch(() => null);\n if (!existing) {\n await linkSkill(source, target);\n return \"created\";\n }\n\n if (!existing.isSymbolicLink()) {\n return \"skipped\";\n }\n\n const linkedPath = await fs.readlink(target).catch(() => null);\n if (!linkedPath) return \"skipped\";\n\n const resolvedLinkedPath = path.resolve(path.dirname(target), linkedPath);\n if (resolvedLinkedPath === source) {\n return \"skipped\";\n }\n\n const linkedPathExists = await fs.stat(resolvedLinkedPath).then(() => true).catch(() => false);\n if (linkedPathExists) {\n return \"skipped\";\n }\n\n await fs.unlink(target);\n await linkSkill(source, target);\n return \"repaired\";\n}\n\nexport async function removeMaintainerOnlySkillSymlinks(\n skillsHome: string,\n allowedSkillNames: Iterable<string>,\n): Promise<string[]> {\n const allowed = new Set(Array.from(allowedSkillNames));\n try {\n const entries = await fs.readdir(skillsHome, { withFileTypes: true });\n const removed: string[] = [];\n for (const entry of entries) {\n if (allowed.has(entry.name)) continue;\n\n const target = path.join(skillsHome, entry.name);\n const existing = await fs.lstat(target).catch(() => null);\n if (!existing?.isSymbolicLink()) continue;\n\n const linkedPath = await fs.readlink(target).catch(() => null);\n if (!linkedPath) continue;\n\n const resolvedLinkedPath = path.isAbsolute(linkedPath)\n ? linkedPath\n : path.resolve(path.dirname(target), linkedPath);\n if (\n !isMaintainerOnlySkillTarget(linkedPath) &&\n !isMaintainerOnlySkillTarget(resolvedLinkedPath)\n ) {\n continue;\n }\n\n await fs.unlink(target);\n removed.push(entry.name);\n }\n\n return removed;\n } catch {\n return [];\n }\n}\n\nexport async function ensureCommandResolvable(command: string, cwd: string, env: NodeJS.ProcessEnv) {\n const resolved = await resolveCommandPath(command, cwd, env);\n if (resolved) return;\n if (command.includes(\"/\") || command.includes(\"\\\\\")) {\n const absolute = path.isAbsolute(command) ? command : path.resolve(cwd, command);\n throw new Error(`Command is not executable: \"${command}\" (resolved: \"${absolute}\")`);\n }\n throw new Error(`Command not found in PATH: \"${command}\"`);\n}\n\nexport async function runChildProcess(\n runId: string,\n command: string,\n args: string[],\n opts: {\n cwd: string;\n env: Record<string, string>;\n timeoutSec: number;\n graceSec: number;\n onLog: (stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>;\n onLogError?: (err: unknown, runId: string, message: string) => void;\n onSpawn?: (meta: { pid: number; startedAt: string }) => Promise<void>;\n stdin?: string;\n abortSignal?: AbortSignal;\n },\n): Promise<RunProcessResult> {\n const onLogError = opts.onLogError ?? ((err, id, msg) => console.warn({ err, runId: id }, msg));\n\n return new Promise<RunProcessResult>((resolve, reject) => {\n const rawMerged: NodeJS.ProcessEnv = { ...process.env, ...opts.env };\n const requestedHome =\n typeof opts.env.HOME === \"string\" && opts.env.HOME.trim().length > 0\n ? path.resolve(opts.env.HOME)\n : null;\n const inheritedHome =\n typeof process.env.HOME === \"string\" && process.env.HOME.trim().length > 0\n ? path.resolve(process.env.HOME)\n : null;\n const hasExplicitZdotdir =\n typeof opts.env.ZDOTDIR === \"string\" && opts.env.ZDOTDIR.trim().length > 0;\n\n // Strip Claude Code nesting-guard env vars so spawned `claude` processes\n // don't refuse to start with \"cannot be launched inside another session\".\n // These vars leak in when the Rudder server itself is started from\n // within a Claude Code session (e.g. `npx rudder run` in a terminal\n // owned by Claude Code) or when cron inherits a contaminated shell env.\n const CLAUDE_CODE_NESTING_VARS = [\n \"CLAUDECODE\",\n \"CLAUDE_CODE_ENTRYPOINT\",\n \"CLAUDE_CODE_SESSION\",\n \"CLAUDE_CODE_PARENT_SESSION\",\n ] as const;\n for (const key of CLAUDE_CODE_NESTING_VARS) {\n delete rawMerged[key];\n }\n\n const GIT_IDENTITY_ENV_VARS = [\n \"GIT_AUTHOR_NAME\",\n \"GIT_AUTHOR_EMAIL\",\n \"GIT_COMMITTER_NAME\",\n \"GIT_COMMITTER_EMAIL\",\n ] as const;\n for (const key of GIT_IDENTITY_ENV_VARS) {\n if (rawMerged[key] === \"\" && !Object.prototype.hasOwnProperty.call(opts.env, key)) {\n delete rawMerged[key];\n }\n }\n\n // When Rudder isolates HOME for child agents, don't let zsh keep using the\n // host user's startup dir via an inherited ZDOTDIR. That mismatch makes\n // child `zsh -lc` invocations source the host `.zshenv` with the agent HOME.\n if (requestedHome && requestedHome !== inheritedHome && !hasExplicitZdotdir) {\n delete rawMerged.ZDOTDIR;\n }\n\n const mergedEnv = ensurePathInEnv(rawMerged);\n void resolveSpawnTarget(command, args, opts.cwd, mergedEnv)\n .then((target) => {\n if (opts.abortSignal?.aborted) {\n resolve({\n exitCode: null,\n signal: \"SIGTERM\",\n timedOut: false,\n stdout: \"\",\n stderr: \"\",\n pid: null,\n startedAt: null,\n });\n return;\n }\n\n const child = spawn(target.command, target.args, {\n cwd: opts.cwd,\n env: mergedEnv,\n shell: false,\n stdio: [opts.stdin != null ? \"pipe\" : \"ignore\", \"pipe\", \"pipe\"],\n }) as ChildProcessWithEvents;\n const startedAt = new Date().toISOString();\n\n if (opts.stdin != null && child.stdin) {\n child.stdin.write(opts.stdin);\n child.stdin.end();\n }\n\n if (typeof child.pid === \"number\" && child.pid > 0 && opts.onSpawn) {\n void opts.onSpawn({ pid: child.pid, startedAt }).catch((err) => {\n onLogError(err, runId, \"failed to record child process metadata\");\n });\n }\n\n runningProcesses.set(runId, { child, graceSec: opts.graceSec });\n\n let timedOut = false;\n let aborted = false;\n let stdout = \"\";\n let stderr = \"\";\n let logChain: Promise<void> = Promise.resolve();\n\n const timeout =\n opts.timeoutSec > 0\n ? setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n if (isChildProcessAlive(child)) {\n child.kill(\"SIGKILL\");\n }\n }, Math.max(1, opts.graceSec) * 1000);\n }, opts.timeoutSec * 1000)\n : null;\n\n let abortCleanup: (() => void) | null = null;\n if (opts.abortSignal) {\n const onAbort = () => {\n aborted = true;\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n if (isChildProcessAlive(child)) {\n child.kill(\"SIGKILL\");\n }\n }, Math.max(1, opts.graceSec) * 1000);\n };\n\n opts.abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n abortCleanup = () => opts.abortSignal?.removeEventListener(\"abort\", onAbort);\n }\n\n child.stdout?.on(\"data\", (chunk: unknown) => {\n const text = String(chunk);\n stdout = appendWithCap(stdout, text);\n logChain = logChain\n .then(() => opts.onLog(\"stdout\", text))\n .catch((err) => onLogError(err, runId, \"failed to append stdout log chunk\"));\n });\n\n child.stderr?.on(\"data\", (chunk: unknown) => {\n const text = String(chunk);\n stderr = appendWithCap(stderr, text);\n logChain = logChain\n .then(() => opts.onLog(\"stderr\", text))\n .catch((err) => onLogError(err, runId, \"failed to append stderr log chunk\"));\n });\n\n child.on(\"error\", (err: Error) => {\n if (timeout) clearTimeout(timeout);\n if (abortCleanup) abortCleanup();\n runningProcesses.delete(runId);\n const errno = (err as NodeJS.ErrnoException).code;\n const pathValue = mergedEnv.PATH ?? mergedEnv.Path ?? \"\";\n const msg =\n errno === \"ENOENT\"\n ? `Failed to start command \"${command}\" in \"${opts.cwd}\". Verify adapter command, working directory, and PATH (${pathValue}).`\n : `Failed to start command \"${command}\" in \"${opts.cwd}\": ${err.message}`;\n reject(new Error(msg));\n });\n\n child.on(\"close\", (code: number | null, signal: NodeJS.Signals | null) => {\n if (timeout) clearTimeout(timeout);\n if (abortCleanup) abortCleanup();\n runningProcesses.delete(runId);\n void logChain.finally(() => {\n resolve({\n exitCode: code,\n signal: aborted ? \"SIGTERM\" : signal,\n timedOut,\n stdout,\n stderr,\n pid: child.pid ?? null,\n startedAt,\n });\n });\n });\n })\n .catch(reject);\n });\n}\n", "import { Command } from \"commander\";\nimport {\n createApprovalSchema,\n requestApprovalRevisionSchema,\n resolveApprovalSchema,\n resubmitApprovalSchema,\n type Issue,\n type Approval,\n type ApprovalComment,\n} from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport { getAgentCliCapabilityById } from \"../../agent-v1-registry.js\";\n\ninterface ApprovalListOptions extends BaseClientOptions {\n orgId?: string;\n status?: string;\n}\n\ninterface ApprovalDecisionOptions extends BaseClientOptions {\n decisionNote?: string;\n decidedByUserId?: string;\n}\n\ninterface ApprovalCreateOptions extends BaseClientOptions {\n orgId?: string;\n type: string;\n requestedByAgentId?: string;\n payload: string;\n issueIds?: string;\n}\n\ninterface ApprovalResubmitOptions extends BaseClientOptions {\n payload?: string;\n}\n\ninterface ApprovalCommentOptions extends BaseClientOptions {\n body: string;\n}\n\nexport function registerApprovalCommands(program: Command): void {\n const approval = program.command(\"approval\").description(\"Approval operations\");\n\n addCommonClientOptions(\n approval\n .command(\"list\")\n .description(\"List approvals for an organization\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--status <status>\", \"Status filter\")\n .action(async (opts: ApprovalListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const params = new URLSearchParams();\n if (opts.status) params.set(\"status\", opts.status);\n const query = params.toString();\n const rows =\n (await ctx.api.get<Approval[]>(`/api/orgs/${ctx.orgId}/approvals${query ? `?${query}` : \"\"}`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n type: row.type,\n status: row.status,\n requestedByAgentId: row.requestedByAgentId,\n requestedByUserId: row.requestedByUserId,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n approval\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"approval.get\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .action(async (approvalId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<Approval>(`/api/approvals/${approvalId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"issues\")\n .description(getAgentCliCapabilityById(\"approval.issues\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .action(async (approvalId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<Issue[]>(`/api/approvals/${approvalId}/issues`)) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"create\")\n .description(getAgentCliCapabilityById(\"approval.create\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--type <type>\", \"Approval type (hire_agent|approve_ceo_strategy)\")\n .requiredOption(\"--payload <json>\", \"Approval payload as JSON object\")\n .option(\"--requested-by-agent-id <id>\", \"Requesting agent ID\")\n .option(\"--issue-ids <csv>\", \"Comma-separated linked issue IDs\")\n .action(async (opts: ApprovalCreateOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payloadJson = parseJsonObject(opts.payload, \"payload\");\n const payload = createApprovalSchema.parse({\n type: opts.type,\n payload: payloadJson,\n requestedByAgentId: opts.requestedByAgentId,\n issueIds: parseCsv(opts.issueIds),\n });\n const created = await ctx.api.post<Approval>(`/api/orgs/${ctx.orgId}/approvals`, payload);\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n approval\n .command(\"approve\")\n .description(\"Approve an approval request\")\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--decision-note <text>\", \"Decision note\")\n .option(\"--decided-by-user-id <id>\", \"Decision actor user ID\")\n .action(async (approvalId: string, opts: ApprovalDecisionOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = resolveApprovalSchema.parse({\n decisionNote: opts.decisionNote,\n decidedByUserId: opts.decidedByUserId,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/approve`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"reject\")\n .description(\"Reject an approval request\")\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--decision-note <text>\", \"Decision note\")\n .option(\"--decided-by-user-id <id>\", \"Decision actor user ID\")\n .action(async (approvalId: string, opts: ApprovalDecisionOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = resolveApprovalSchema.parse({\n decisionNote: opts.decisionNote,\n decidedByUserId: opts.decidedByUserId,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/reject`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"request-revision\")\n .description(\"Request revision for an approval\")\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--decision-note <text>\", \"Decision note\")\n .option(\"--decided-by-user-id <id>\", \"Decision actor user ID\")\n .action(async (approvalId: string, opts: ApprovalDecisionOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = requestApprovalRevisionSchema.parse({\n decisionNote: opts.decisionNote,\n decidedByUserId: opts.decidedByUserId,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/request-revision`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"resubmit\")\n .description(getAgentCliCapabilityById(\"approval.resubmit\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--payload <json>\", \"Payload JSON object\")\n .action(async (approvalId: string, opts: ApprovalResubmitOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = resubmitApprovalSchema.parse({\n payload: opts.payload ? parseJsonObject(opts.payload, \"payload\") : undefined,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/resubmit`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"comment\")\n .description(getAgentCliCapabilityById(\"approval.comment\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .requiredOption(\"--body <text>\", \"Comment body\")\n .action(async (approvalId: string, opts: ApprovalCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const created = await ctx.api.post<ApprovalComment>(`/api/approvals/${approvalId}/comments`, {\n body: opts.body,\n });\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n\nfunction parseCsv(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const rows = value.split(\",\").map((v) => v.trim()).filter(Boolean);\n return rows.length > 0 ? rows : undefined;\n}\n\nfunction parseJsonObject(value: string, name: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(value) as unknown;\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${name} must be a JSON object`);\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n throw new Error(`Invalid ${name} JSON: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n", "import { Command } from \"commander\";\nimport type { ActivityEvent } from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface ActivityListOptions extends BaseClientOptions {\n orgId?: string;\n agentId?: string;\n entityType?: string;\n entityId?: string;\n}\n\nexport function registerActivityCommands(program: Command): void {\n const activity = program.command(\"activity\").description(\"Activity log operations\");\n\n addCommonClientOptions(\n activity\n .command(\"list\")\n .description(\"List organization activity log entries\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--agent-id <id>\", \"Filter by agent ID\")\n .option(\"--entity-type <type>\", \"Filter by entity type\")\n .option(\"--entity-id <id>\", \"Filter by entity ID\")\n .action(async (opts: ActivityListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const params = new URLSearchParams();\n if (opts.agentId) params.set(\"agentId\", opts.agentId);\n if (opts.entityType) params.set(\"entityType\", opts.entityType);\n if (opts.entityId) params.set(\"entityId\", opts.entityId);\n\n const query = params.toString();\n const path = `/api/orgs/${ctx.orgId}/activity${query ? `?${query}` : \"\"}`;\n const rows = (await ctx.api.get<ActivityEvent[]>(path)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n action: row.action,\n actorType: row.actorType,\n actorId: row.actorId,\n entityType: row.entityType,\n entityId: row.entityId,\n createdAt: String(row.createdAt),\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n", "import { Command } from \"commander\";\nimport type { DashboardSummary } from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface DashboardGetOptions extends BaseClientOptions {\n orgId?: string;\n}\n\nexport function registerDashboardCommands(program: Command): void {\n const dashboard = program.command(\"dashboard\").description(\"Dashboard summary operations\");\n\n addCommonClientOptions(\n dashboard\n .command(\"get\")\n .description(\"Get dashboard summary for an organization\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: DashboardGetOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const row = await ctx.api.get<DashboardSummary>(`/api/orgs/${ctx.orgId}/dashboard`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n", "import { Command } from \"commander\";\nimport {\n organizationSkillImportSchema,\n organizationSkillLocalScanRequestSchema,\n organizationSkillProjectScanRequestSchema,\n type OrganizationSkillDetail,\n type OrganizationSkillFileDetail,\n type OrganizationSkillImportResult,\n type OrganizationSkillListItem,\n type OrganizationSkillLocalScanResult,\n type OrganizationSkillProjectScanResult,\n} from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport { getAgentCliCapabilityById } from \"../../agent-v1-registry.js\";\n\ninterface SkillListOptions extends BaseClientOptions {\n orgId?: string;\n}\n\ninterface SkillImportOptions extends BaseClientOptions {\n orgId?: string;\n source: string;\n}\n\ninterface SkillFileOptions extends BaseClientOptions {\n orgId?: string;\n path?: string;\n}\n\ninterface SkillScanLocalOptions extends BaseClientOptions {\n orgId?: string;\n roots?: string;\n}\n\ninterface SkillScanProjectsOptions extends BaseClientOptions {\n orgId?: string;\n projectIds?: string;\n workspaceIds?: string;\n}\n\nexport function registerSkillCommands(program: Command): void {\n const skill = program.command(\"skill\").description(\"Organization skill library operations\");\n\n addCommonClientOptions(\n skill\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"skill.list\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: SkillListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<OrganizationSkillListItem[]>(`/api/orgs/${ctx.orgId}/skills`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n key: row.key,\n slug: row.slug,\n name: row.name,\n sourceBadge: row.sourceBadge,\n compatibility: row.compatibility,\n attachedAgentCount: row.attachedAgentCount,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"skill.get\").description)\n .argument(\"<skillId>\", \"Skill ID\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (skillId: string, opts: SkillListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const row = await ctx.api.get<OrganizationSkillDetail>(`/api/orgs/${ctx.orgId}/skills/${skillId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"file\")\n .description(getAgentCliCapabilityById(\"skill.file\").description)\n .argument(\"<skillId>\", \"Skill ID\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--path <path>\", \"Skill package file path\", \"SKILL.md\")\n .action(async (skillId: string, opts: SkillFileOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const query = new URLSearchParams({ path: opts.path ?? \"SKILL.md\" });\n const row = await ctx.api.get<OrganizationSkillFileDetail>(\n `/api/orgs/${ctx.orgId}/skills/${skillId}/files?${query.toString()}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"import\")\n .description(getAgentCliCapabilityById(\"skill.import\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--source <source>\", \"Skill source (local path, URL, or repo ref)\")\n .action(async (opts: SkillImportOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = organizationSkillImportSchema.parse({ source: opts.source });\n const result = await ctx.api.post<OrganizationSkillImportResult>(`/api/orgs/${ctx.orgId}/skills/import`, payload);\n printOutput(result, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"scan-local\")\n .description(getAgentCliCapabilityById(\"skill.scan-local\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--roots <csv>\", \"Comma-separated local roots to scan\")\n .action(async (opts: SkillScanLocalOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = organizationSkillLocalScanRequestSchema.parse({\n roots: parseCsv(opts.roots),\n });\n const result = await ctx.api.post<OrganizationSkillLocalScanResult>(\n `/api/orgs/${ctx.orgId}/skills/scan-local`,\n payload,\n );\n printOutput(result, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"scan-projects\")\n .description(getAgentCliCapabilityById(\"skill.scan-projects\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--project-ids <csv>\", \"Comma-separated project IDs\")\n .option(\"--workspace-ids <csv>\", \"Comma-separated workspace IDs\")\n .action(async (opts: SkillScanProjectsOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = organizationSkillProjectScanRequestSchema.parse({\n projectIds: parseCsv(opts.projectIds),\n workspaceIds: parseCsv(opts.workspaceIds),\n });\n const result = await ctx.api.post<OrganizationSkillProjectScanResult>(\n `/api/orgs/${ctx.orgId}/skills/scan-projects`,\n payload,\n );\n printOutput(result, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n\nfunction parseCsv(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const rows = value.split(\",\").map((entry) => entry.trim()).filter(Boolean);\n return rows.length > 0 ? rows : undefined;\n}\n", "import path from \"node:path\";\nimport {\n expandHomePrefix,\n resolveDefaultConfigPath,\n resolveDefaultContextPath,\n resolveRudderInstanceId,\n} from \"./home.js\";\n\nexport interface DataDirOptionLike {\n dataDir?: string;\n config?: string;\n context?: string;\n instance?: string;\n localEnv?: string;\n}\n\nexport interface DataDirCommandSupport {\n hasConfigOption?: boolean;\n hasContextOption?: boolean;\n}\n\nexport function applyDataDirOverride(\n options: DataDirOptionLike,\n support: DataDirCommandSupport = {},\n): string | null {\n const rawDataDir = options.dataDir?.trim();\n if (!rawDataDir) return null;\n\n const resolvedDataDir = path.resolve(expandHomePrefix(rawDataDir));\n process.env.RUDDER_HOME = resolvedDataDir;\n\n if (support.hasConfigOption) {\n const hasConfigOverride = Boolean(options.config?.trim()) || Boolean(process.env.RUDDER_CONFIG?.trim());\n if (!hasConfigOverride) {\n const instanceId = resolveRudderInstanceId(options.instance);\n process.env.RUDDER_INSTANCE_ID = instanceId;\n process.env.RUDDER_CONFIG = resolveDefaultConfigPath(instanceId);\n }\n }\n\n if (support.hasContextOption) {\n const hasContextOverride = Boolean(options.context?.trim()) || Boolean(process.env.RUDDER_CONTEXT?.trim());\n if (!hasContextOverride) {\n process.env.RUDDER_CONTEXT = resolveDefaultContextPath();\n }\n }\n\n return resolvedDataDir;\n}\n", "import path from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n addCommonClientOptions,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\n// ---------------------------------------------------------------------------\n// Types mirroring server-side shapes\n// ---------------------------------------------------------------------------\n\ninterface PluginRecord {\n id: string;\n pluginKey: string;\n packageName: string;\n version: string;\n status: string;\n displayName?: string;\n lastError?: string | null;\n installedAt: string;\n updatedAt: string;\n}\n\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\ninterface PluginListOptions extends BaseClientOptions {\n status?: string;\n}\n\ninterface PluginInstallOptions extends BaseClientOptions {\n local?: boolean;\n version?: string;\n}\n\ninterface PluginUninstallOptions extends BaseClientOptions {\n force?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a local path argument to an absolute path so the server can find the\n * plugin on disk regardless of where the user ran the CLI.\n */\nfunction resolvePackageArg(packageArg: string, isLocal: boolean): string {\n if (!isLocal) return packageArg;\n // Already absolute\n if (path.isAbsolute(packageArg)) return packageArg;\n // Expand leading ~ to home directory\n if (packageArg.startsWith(\"~\")) {\n const home = process.env.HOME ?? process.env.USERPROFILE ?? \"\";\n return path.resolve(home, packageArg.slice(1).replace(/^[\\\\/]/, \"\"));\n }\n return path.resolve(process.cwd(), packageArg);\n}\n\nfunction formatPlugin(p: PluginRecord): string {\n const statusColor =\n p.status === \"ready\"\n ? pc.green(p.status)\n : p.status === \"error\"\n ? pc.red(p.status)\n : p.status === \"disabled\"\n ? pc.dim(p.status)\n : pc.yellow(p.status);\n\n const parts = [\n `key=${pc.bold(p.pluginKey)}`,\n `status=${statusColor}`,\n `version=${p.version}`,\n `id=${pc.dim(p.id)}`,\n ];\n\n if (p.lastError) {\n parts.push(`error=${pc.red(p.lastError.slice(0, 80))}`);\n }\n\n return parts.join(\" \");\n}\n\n// ---------------------------------------------------------------------------\n// Command registration\n// ---------------------------------------------------------------------------\n\nexport function registerPluginCommands(program: Command): void {\n const plugin = program.command(\"plugin\").description(\"Plugin lifecycle management\");\n\n // -------------------------------------------------------------------------\n // plugin list\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"list\")\n .description(\"List installed plugins\")\n .option(\"--status <status>\", \"Filter by status (ready, error, disabled, installed, upgrade_pending)\")\n .action(async (opts: PluginListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const qs = opts.status ? `?status=${encodeURIComponent(opts.status)}` : \"\";\n const plugins = await ctx.api.get<PluginRecord[]>(`/api/plugins${qs}`);\n\n if (ctx.json) {\n printOutput(plugins, { json: true });\n return;\n }\n\n const rows = plugins ?? [];\n if (rows.length === 0) {\n console.log(pc.dim(\"No plugins installed.\"));\n return;\n }\n\n for (const p of rows) {\n console.log(formatPlugin(p));\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin install <package-or-path>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"install <package>\")\n .description(\n \"Install a plugin from a local path or npm package.\\n\" +\n \" Examples:\\n\" +\n \" rudder plugin install ./my-plugin # local path\\n\" +\n \" rudder plugin install @acme/plugin-linear # npm package\\n\" +\n \" rudder plugin install @acme/plugin-linear@1.2 # pinned version\",\n )\n .option(\"-l, --local\", \"Treat <package> as a local filesystem path\", false)\n .option(\"--version <version>\", \"Specific npm version to install (npm packages only)\")\n .action(async (packageArg: string, opts: PluginInstallOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n\n // Auto-detect local paths: starts with . or / or ~ or is an absolute path\n const isLocal =\n opts.local ||\n packageArg.startsWith(\"./\") ||\n packageArg.startsWith(\"../\") ||\n packageArg.startsWith(\"/\") ||\n packageArg.startsWith(\"~\");\n\n const resolvedPackage = resolvePackageArg(packageArg, isLocal);\n\n if (!ctx.json) {\n console.log(\n pc.dim(\n isLocal\n ? `Installing plugin from local path: ${resolvedPackage}`\n : `Installing plugin: ${resolvedPackage}${opts.version ? `@${opts.version}` : \"\"}`,\n ),\n );\n }\n\n const installedPlugin = await ctx.api.post<PluginRecord>(\"/api/plugins/install\", {\n packageName: resolvedPackage,\n version: opts.version,\n isLocalPath: isLocal,\n });\n\n if (ctx.json) {\n printOutput(installedPlugin, { json: true });\n return;\n }\n\n if (!installedPlugin) {\n console.log(pc.dim(\"Install returned no plugin record.\"));\n return;\n }\n\n console.log(\n pc.green(\n `\u2713 Installed ${pc.bold(installedPlugin.pluginKey)} v${installedPlugin.version} (${installedPlugin.status})`,\n ),\n );\n\n if (installedPlugin.lastError) {\n console.log(pc.red(` Warning: ${installedPlugin.lastError}`));\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin uninstall <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"uninstall <pluginKey>\")\n .description(\n \"Uninstall a plugin by its plugin key or database ID.\\n\" +\n \" Use --force to hard-purge all state and config.\",\n )\n .option(\"--force\", \"Purge all plugin state and config (hard delete)\", false)\n .action(async (pluginKey: string, opts: PluginUninstallOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const purge = opts.force === true;\n const qs = purge ? \"?purge=true\" : \"\";\n\n if (!ctx.json) {\n console.log(\n pc.dim(\n purge\n ? `Uninstalling and purging plugin: ${pluginKey}`\n : `Uninstalling plugin: ${pluginKey}`,\n ),\n );\n }\n\n const result = await ctx.api.delete<PluginRecord | null>(\n `/api/plugins/${encodeURIComponent(pluginKey)}${qs}`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n console.log(pc.green(`\u2713 Uninstalled ${pc.bold(pluginKey)}${purge ? \" (purged)\" : \"\"}`));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin enable <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"enable <pluginKey>\")\n .description(\"Enable a disabled or errored plugin\")\n .action(async (pluginKey: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const result = await ctx.api.post<PluginRecord>(\n `/api/plugins/${encodeURIComponent(pluginKey)}/enable`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n console.log(pc.green(`\u2713 Enabled ${pc.bold(pluginKey)} \u2014 status: ${result?.status ?? \"unknown\"}`));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin disable <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"disable <pluginKey>\")\n .description(\"Disable a running plugin without uninstalling it\")\n .action(async (pluginKey: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const result = await ctx.api.post<PluginRecord>(\n `/api/plugins/${encodeURIComponent(pluginKey)}/disable`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n console.log(pc.dim(`Disabled ${pc.bold(pluginKey)} \u2014 status: ${result?.status ?? \"unknown\"}`));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin inspect <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"inspect <pluginKey>\")\n .description(\"Show full details for an installed plugin\")\n .action(async (pluginKey: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const result = await ctx.api.get<PluginRecord>(\n `/api/plugins/${encodeURIComponent(pluginKey)}`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n if (!result) {\n console.log(pc.red(`Plugin not found: ${pluginKey}`));\n process.exit(1);\n }\n\n console.log(formatPlugin(result));\n if (result.lastError) {\n console.log(`\\n${pc.red(\"Last error:\")}\\n${result.lastError}`);\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin examples\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"examples\")\n .description(\"List bundled example plugins available for local install\")\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const examples = await ctx.api.get<\n Array<{\n packageName: string;\n pluginKey: string;\n displayName: string;\n description: string;\n localPath: string;\n tag: string;\n }>\n >(\"/api/plugins/examples\");\n\n if (ctx.json) {\n printOutput(examples, { json: true });\n return;\n }\n\n const rows = examples ?? [];\n if (rows.length === 0) {\n console.log(pc.dim(\"No bundled examples available.\"));\n return;\n }\n\n for (const ex of rows) {\n console.log(\n `${pc.bold(ex.displayName)} ${pc.dim(ex.pluginKey)}\\n` +\n ` ${ex.description}\\n` +\n ` ${pc.cyan(`rudder plugin install ${ex.localPath}`)}`,\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n", "import type { Command } from \"commander\";\nimport {\n getStoredBoardCredential,\n loginBoardCli,\n removeStoredBoardCredential,\n revokeStoredBoardCredential,\n} from \"../../client/board-auth.js\";\nimport {\n addCommonClientOptions,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface AuthLoginOptions extends BaseClientOptions {\n instanceAdmin?: boolean;\n}\n\ninterface AuthLogoutOptions extends BaseClientOptions {}\ninterface AuthWhoamiOptions extends BaseClientOptions {}\n\nexport function registerClientAuthCommands(auth: Command): void {\n addCommonClientOptions(\n auth\n .command(\"login\")\n .description(\"Authenticate the CLI for board-user access\")\n .option(\"--instance-admin\", \"Request instance-admin approval instead of plain board access\", false)\n .action(async (opts: AuthLoginOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const login = await loginBoardCli({\n apiBase: ctx.api.apiBase,\n requestedAccess: opts.instanceAdmin ? \"instance_admin_required\" : \"board\",\n requestedCompanyId: ctx.orgId ?? null,\n command: \"rudder auth login\",\n });\n printOutput(\n {\n ok: true,\n apiBase: ctx.api.apiBase,\n userId: login.userId ?? null,\n approvalUrl: login.approvalUrl,\n },\n { json: ctx.json },\n );\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: true },\n );\n\n addCommonClientOptions(\n auth\n .command(\"logout\")\n .description(\"Remove the stored board-user credential for this API base\")\n .action(async (opts: AuthLogoutOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const credential = getStoredBoardCredential(ctx.api.apiBase);\n if (!credential) {\n printOutput({ ok: true, apiBase: ctx.api.apiBase, revoked: false, removedLocalCredential: false }, { json: ctx.json });\n return;\n }\n let revoked = false;\n try {\n await revokeStoredBoardCredential({\n apiBase: ctx.api.apiBase,\n token: credential.token,\n });\n revoked = true;\n } catch {\n // Remove the local credential even if the server-side revoke fails.\n }\n const removedLocalCredential = removeStoredBoardCredential(ctx.api.apiBase);\n printOutput(\n {\n ok: true,\n apiBase: ctx.api.apiBase,\n revoked,\n removedLocalCredential,\n },\n { json: ctx.json },\n );\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n auth\n .command(\"whoami\")\n .description(\"Show the current board-user identity for this API base\")\n .action(async (opts: AuthWhoamiOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const me = await ctx.api.get<{\n user: { id: string; name: string; email: string } | null;\n userId: string;\n isInstanceAdmin: boolean;\n companyIds: string[];\n source: string;\n keyId: string | null;\n }>(\"/api/cli-auth/me\");\n printOutput(me, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n", "import { runCli } from \"./program.js\";\n\nexport { runCli } from \"./program.js\";\n\nvoid runCli(process.argv).then(async (exitCode) => {\n // Ensure stdout is fully flushed before exiting to prevent truncated output\n // when the CLI is invoked via spawn/exec with large JSON payloads\n if (process.stdout.writableNeedDrain) {\n await new Promise<void>((resolve) => process.stdout.once('drain', resolve));\n }\n process.exit(exitCode);\n});\n"],
4
+ "sourcesContent": ["export const ORGANIZATION_STATUSES = [\"active\", \"paused\", \"archived\"] as const;\nexport type OrganizationStatus = (typeof ORGANIZATION_STATUSES)[number];\n\nexport const DEPLOYMENT_MODES = [\"local_trusted\", \"authenticated\"] as const;\nexport type DeploymentMode = (typeof DEPLOYMENT_MODES)[number];\n\nexport const DEPLOYMENT_EXPOSURES = [\"private\", \"public\"] as const;\nexport type DeploymentExposure = (typeof DEPLOYMENT_EXPOSURES)[number];\n\nexport const AUTH_BASE_URL_MODES = [\"auto\", \"explicit\"] as const;\nexport type AuthBaseUrlMode = (typeof AUTH_BASE_URL_MODES)[number];\n\nexport const AGENT_STATUSES = [\n \"active\",\n \"paused\",\n \"idle\",\n \"running\",\n \"error\",\n \"pending_approval\",\n \"terminated\",\n] as const;\nexport type AgentStatus = (typeof AGENT_STATUSES)[number];\n\nexport const AGENT_RUN_CONCURRENCY_DEFAULT = 3;\nexport const AGENT_RUN_CONCURRENCY_MIN = 1;\nexport const AGENT_RUN_CONCURRENCY_MAX = 10;\n\nexport const AGENT_RUNTIME_TYPES = [\n \"process\",\n \"http\",\n \"claude_local\",\n \"codex_local\",\n \"gemini_local\",\n \"opencode_local\",\n \"pi_local\",\n \"cursor\",\n \"openclaw_gateway\",\n \"hermes_local\",\n] as const;\nexport type AgentRuntimeType = (typeof AGENT_RUNTIME_TYPES)[number];\n\nexport const AGENT_ROLES = [\n \"ceo\",\n \"cto\",\n \"cmo\",\n \"cfo\",\n \"engineer\",\n \"designer\",\n \"pm\",\n \"qa\",\n \"devops\",\n \"researcher\",\n \"general\",\n] as const;\nexport type AgentRole = (typeof AGENT_ROLES)[number];\n\nexport const AGENT_ROLE_LABELS: Record<AgentRole, string> = {\n ceo: \"CEO\",\n cto: \"CTO\",\n cmo: \"CMO\",\n cfo: \"CFO\",\n engineer: \"Engineer\",\n designer: \"Designer\",\n pm: \"PM\",\n qa: \"QA\",\n devops: \"DevOps\",\n researcher: \"Researcher\",\n general: \"General\",\n};\n\nexport const AGENT_ICON_NAMES = [\n \"bot\",\n \"cpu\",\n \"brain\",\n \"zap\",\n \"rocket\",\n \"code\",\n \"terminal\",\n \"shield\",\n \"eye\",\n \"search\",\n \"wrench\",\n \"hammer\",\n \"lightbulb\",\n \"sparkles\",\n \"star\",\n \"heart\",\n \"flame\",\n \"bug\",\n \"cog\",\n \"database\",\n \"globe\",\n \"lock\",\n \"mail\",\n \"message-square\",\n \"file-code\",\n \"git-branch\",\n \"package\",\n \"puzzle\",\n \"target\",\n \"wand\",\n \"atom\",\n \"circuit-board\",\n \"radar\",\n \"swords\",\n \"telescope\",\n \"microscope\",\n \"crown\",\n \"gem\",\n \"hexagon\",\n \"pentagon\",\n \"fingerprint\",\n] as const;\nexport type AgentIconName = (typeof AGENT_ICON_NAMES)[number];\n\nexport const ISSUE_STATUSES = [\n \"backlog\",\n \"todo\",\n \"in_progress\",\n \"in_review\",\n \"done\",\n \"blocked\",\n \"cancelled\",\n] as const;\nexport type IssueStatus = (typeof ISSUE_STATUSES)[number];\n\nexport const ISSUE_PRIORITIES = [\"critical\", \"high\", \"medium\", \"low\"] as const;\nexport type IssuePriority = (typeof ISSUE_PRIORITIES)[number];\n\nexport const ISSUE_ORIGIN_KINDS = [\"manual\", \"automation_execution\"] as const;\nexport type IssueOriginKind = (typeof ISSUE_ORIGIN_KINDS)[number];\n\nexport const CALENDAR_SOURCE_TYPES = [\"rudder_local\", \"google_calendar\", \"agent_work\", \"system\"] as const;\nexport type CalendarSourceType = (typeof CALENDAR_SOURCE_TYPES)[number];\n\nexport const CALENDAR_OWNER_TYPES = [\"user\", \"agent\", \"system\"] as const;\nexport type CalendarOwnerType = (typeof CALENDAR_OWNER_TYPES)[number];\n\nexport const CALENDAR_VISIBILITIES = [\"full\", \"busy_only\", \"private\"] as const;\nexport type CalendarVisibility = (typeof CALENDAR_VISIBILITIES)[number];\n\nexport const CALENDAR_SOURCE_STATUSES = [\"active\", \"paused\", \"disconnected\", \"error\"] as const;\nexport type CalendarSourceStatus = (typeof CALENDAR_SOURCE_STATUSES)[number];\n\nexport const CALENDAR_EVENT_KINDS = [\"human_event\", \"agent_work_block\", \"external_event\", \"system_event\"] as const;\nexport type CalendarEventKind = (typeof CALENDAR_EVENT_KINDS)[number];\n\nexport const CALENDAR_EVENT_STATUSES = [\"planned\", \"in_progress\", \"actual\", \"cancelled\", \"external\", \"projected\"] as const;\nexport type CalendarEventStatus = (typeof CALENDAR_EVENT_STATUSES)[number];\n\nexport const CALENDAR_SOURCE_MODES = [\"manual\", \"derived\", \"imported\"] as const;\nexport type CalendarSourceMode = (typeof CALENDAR_SOURCE_MODES)[number];\n\nexport const CHAT_CONVERSATION_STATUSES = [\"active\", \"resolved\", \"archived\"] as const;\nexport type ChatConversationStatus = (typeof CHAT_CONVERSATION_STATUSES)[number];\n\nexport const CHAT_ISSUE_CREATION_MODES = [\"manual_approval\", \"auto_create\"] as const;\nexport type ChatIssueCreationMode = (typeof CHAT_ISSUE_CREATION_MODES)[number];\n\nexport const CHAT_MESSAGE_ROLES = [\"user\", \"assistant\", \"system\"] as const;\nexport type ChatMessageRole = (typeof CHAT_MESSAGE_ROLES)[number];\n\nexport const CHAT_MESSAGE_KINDS = [\n \"message\",\n \"ask_user\",\n \"issue_proposal\",\n \"operation_proposal\",\n \"system_event\",\n] as const;\nexport type ChatMessageKind = (typeof CHAT_MESSAGE_KINDS)[number];\n\nexport const CHAT_MESSAGE_STATUSES = [\"streaming\", \"completed\", \"stopped\", \"failed\", \"interrupted\"] as const;\nexport type ChatMessageStatus = (typeof CHAT_MESSAGE_STATUSES)[number];\n\nexport const CHAT_CONTEXT_ENTITY_TYPES = [\"issue\", \"project\", \"agent\"] as const;\nexport type ChatContextEntityType = (typeof CHAT_CONTEXT_ENTITY_TYPES)[number];\n\nexport const MESSENGER_THREAD_KINDS = [\n \"chat\",\n \"issues\",\n \"approvals\",\n \"failed-runs\",\n \"budget-alerts\",\n \"join-requests\",\n] as const;\nexport type MessengerThreadKind = (typeof MESSENGER_THREAD_KINDS)[number];\n\nexport const MESSENGER_SYSTEM_THREAD_KINDS = [\n \"failed-runs\",\n \"budget-alerts\",\n \"join-requests\",\n] as const;\nexport type MessengerSystemThreadKind = (typeof MESSENGER_SYSTEM_THREAD_KINDS)[number];\n\nexport const GOAL_LEVELS = [\"organization\", \"team\", \"agent\", \"task\"] as const;\nexport type GoalLevel = (typeof GOAL_LEVELS)[number];\n\nexport const GOAL_STATUSES = [\"planned\", \"active\", \"achieved\", \"cancelled\"] as const;\nexport type GoalStatus = (typeof GOAL_STATUSES)[number];\n\nexport const PROJECT_STATUSES = [\n \"backlog\",\n \"planned\",\n \"in_progress\",\n \"completed\",\n \"cancelled\",\n] as const;\nexport type ProjectStatus = (typeof PROJECT_STATUSES)[number];\n\nexport const ORGANIZATION_RESOURCE_KINDS = [\n \"file\",\n \"directory\",\n \"url\",\n \"connector_object\",\n] as const;\nexport type OrganizationResourceKind = (typeof ORGANIZATION_RESOURCE_KINDS)[number];\n\nexport const PROJECT_RESOURCE_ATTACHMENT_ROLES = [\n \"working_set\",\n \"reference\",\n \"tracking\",\n \"deliverable\",\n \"background\",\n] as const;\nexport type ProjectResourceAttachmentRole = (typeof PROJECT_RESOURCE_ATTACHMENT_ROLES)[number];\n\nexport const AUTOMATION_STATUSES = [\"active\", \"paused\", \"archived\"] as const;\nexport type AutomationStatus = (typeof AUTOMATION_STATUSES)[number];\n\nexport const AUTOMATION_CONCURRENCY_POLICIES = [\"coalesce_if_active\", \"always_enqueue\", \"skip_if_active\"] as const;\nexport type AutomationConcurrencyPolicy = (typeof AUTOMATION_CONCURRENCY_POLICIES)[number];\n\nexport const AUTOMATION_CATCH_UP_POLICIES = [\"skip_missed\", \"enqueue_missed_with_cap\"] as const;\nexport type AutomationCatchUpPolicy = (typeof AUTOMATION_CATCH_UP_POLICIES)[number];\n\nexport const AUTOMATION_TRIGGER_KINDS = [\"schedule\", \"webhook\", \"api\"] as const;\nexport type AutomationTriggerKind = (typeof AUTOMATION_TRIGGER_KINDS)[number];\n\nexport const AUTOMATION_TRIGGER_SIGNING_MODES = [\"bearer\", \"hmac_sha256\"] as const;\nexport type AutomationTriggerSigningMode = (typeof AUTOMATION_TRIGGER_SIGNING_MODES)[number];\n\nexport const AUTOMATION_RUN_STATUSES = [\n \"received\",\n \"coalesced\",\n \"skipped\",\n \"issue_created\",\n \"completed\",\n \"failed\",\n ] as const;\nexport type AutomationRunStatus = (typeof AUTOMATION_RUN_STATUSES)[number];\n\nexport const AUTOMATION_RUN_SOURCES = [\"schedule\", \"manual\", \"api\", \"webhook\"] as const;\nexport type AutomationRunSource = (typeof AUTOMATION_RUN_SOURCES)[number];\n\nexport const PAUSE_REASONS = [\"manual\", \"budget\", \"system\"] as const;\nexport type PauseReason = (typeof PAUSE_REASONS)[number];\n\nexport const PROJECT_COLORS = [\n \"linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)\",\n \"linear-gradient(135deg, #7c3aed 0%, #d946ef 100%)\",\n \"linear-gradient(135deg, #db2777 0%, #f97316 100%)\",\n \"linear-gradient(135deg, #ef4444 0%, #f59e0b 100%)\",\n \"linear-gradient(135deg, #f97316 0%, #facc15 100%)\",\n \"linear-gradient(135deg, #10b981 0%, #84cc16 100%)\",\n \"linear-gradient(135deg, #059669 0%, #14b8a6 100%)\",\n \"linear-gradient(135deg, #0d9488 0%, #06b6d4 100%)\",\n \"linear-gradient(135deg, #0284c7 0%, #2563eb 100%)\",\n \"linear-gradient(135deg, #2563eb 0%, #4f46e5 100%)\",\n \"linear-gradient(135deg, #f43f5e 0%, #ec4899 100%)\",\n \"linear-gradient(135deg, #be123c 0%, #7c2d12 100%)\",\n \"linear-gradient(135deg, #a16207 0%, #ca8a04 100%)\",\n \"linear-gradient(135deg, #16a34a 0%, #0f766e 100%)\",\n \"linear-gradient(135deg, #0891b2 0%, #4338ca 100%)\",\n \"linear-gradient(135deg, #6d28d9 0%, #be185d 100%)\",\n \"linear-gradient(135deg, #475569 0%, #0f766e 100%)\",\n \"linear-gradient(135deg, #334155 0%, #7c3aed 100%)\",\n] as const;\n\nexport const APPROVAL_TYPES = [\n \"hire_agent\",\n \"approve_ceo_strategy\",\n \"budget_override_required\",\n \"chat_issue_creation\",\n \"chat_operation\",\n] as const;\nexport type ApprovalType = (typeof APPROVAL_TYPES)[number];\n\nexport const APPROVAL_STATUSES = [\n \"pending\",\n \"revision_requested\",\n \"approved\",\n \"rejected\",\n \"cancelled\",\n] as const;\nexport type ApprovalStatus = (typeof APPROVAL_STATUSES)[number];\n\nexport const SECRET_PROVIDERS = [\n \"local_encrypted\",\n \"aws_secrets_manager\",\n \"gcp_secret_manager\",\n \"vault\",\n] as const;\nexport type SecretProvider = (typeof SECRET_PROVIDERS)[number];\n\nexport const STORAGE_PROVIDERS = [\"local_disk\", \"s3\"] as const;\nexport type StorageProvider = (typeof STORAGE_PROVIDERS)[number];\n\nexport const BILLING_TYPES = [\n \"metered_api\",\n \"subscription_included\",\n \"subscription_overage\",\n \"credits\",\n \"fixed\",\n \"unknown\",\n] as const;\nexport type BillingType = (typeof BILLING_TYPES)[number];\n\nexport const FINANCE_EVENT_KINDS = [\n \"inference_charge\",\n \"platform_fee\",\n \"credit_purchase\",\n \"credit_refund\",\n \"credit_expiry\",\n \"byok_fee\",\n \"gateway_overhead\",\n \"log_storage_charge\",\n \"logpush_charge\",\n \"provisioned_capacity_charge\",\n \"training_charge\",\n \"custom_model_import_charge\",\n \"custom_model_storage_charge\",\n \"manual_adjustment\",\n] as const;\nexport type FinanceEventKind = (typeof FINANCE_EVENT_KINDS)[number];\n\nexport const FINANCE_DIRECTIONS = [\"debit\", \"credit\"] as const;\nexport type FinanceDirection = (typeof FINANCE_DIRECTIONS)[number];\n\nexport const FINANCE_UNITS = [\n \"input_token\",\n \"output_token\",\n \"cached_input_token\",\n \"request\",\n \"credit_usd\",\n \"credit_unit\",\n \"model_unit_minute\",\n \"model_unit_hour\",\n \"gb_month\",\n \"train_token\",\n \"unknown\",\n] as const;\nexport type FinanceUnit = (typeof FINANCE_UNITS)[number];\n\nexport const BUDGET_SCOPE_TYPES = [\"organization\", \"agent\", \"project\"] as const;\nexport type BudgetScopeType = (typeof BUDGET_SCOPE_TYPES)[number];\n\nexport const BUDGET_METRICS = [\"billed_cents\"] as const;\nexport type BudgetMetric = (typeof BUDGET_METRICS)[number];\n\nexport const BUDGET_WINDOW_KINDS = [\"calendar_month_utc\", \"lifetime\"] as const;\nexport type BudgetWindowKind = (typeof BUDGET_WINDOW_KINDS)[number];\n\nexport const BUDGET_THRESHOLD_TYPES = [\"soft\", \"hard\"] as const;\nexport type BudgetThresholdType = (typeof BUDGET_THRESHOLD_TYPES)[number];\n\nexport const BUDGET_INCIDENT_STATUSES = [\"open\", \"resolved\", \"dismissed\"] as const;\nexport type BudgetIncidentStatus = (typeof BUDGET_INCIDENT_STATUSES)[number];\n\nexport const BUDGET_INCIDENT_RESOLUTION_ACTIONS = [\n \"keep_paused\",\n \"raise_budget_and_resume\",\n] as const;\nexport type BudgetIncidentResolutionAction = (typeof BUDGET_INCIDENT_RESOLUTION_ACTIONS)[number];\n\nexport const HEARTBEAT_INVOCATION_SOURCES = [\n \"timer\",\n \"assignment\",\n \"review\",\n \"on_demand\",\n \"automation\",\n] as const;\nexport type HeartbeatInvocationSource = (typeof HEARTBEAT_INVOCATION_SOURCES)[number];\n\nexport const WAKEUP_TRIGGER_DETAILS = [\"manual\", \"ping\", \"callback\", \"system\"] as const;\nexport type WakeupTriggerDetail = (typeof WAKEUP_TRIGGER_DETAILS)[number];\n\nexport const WAKEUP_REQUEST_STATUSES = [\n \"queued\",\n \"deferred_issue_execution\",\n \"deferred_agent_paused\",\n \"claimed\",\n \"coalesced\",\n \"skipped\",\n \"completed\",\n \"failed\",\n \"cancelled\",\n] as const;\nexport type WakeupRequestStatus = (typeof WAKEUP_REQUEST_STATUSES)[number];\n\nexport const HEARTBEAT_RUN_STATUSES = [\n \"queued\",\n \"running\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n \"timed_out\",\n] as const;\nexport type HeartbeatRunStatus = (typeof HEARTBEAT_RUN_STATUSES)[number];\n\nexport const LIVE_EVENT_TYPES = [\n \"heartbeat.run.queued\",\n \"heartbeat.run.status\",\n \"heartbeat.run.event\",\n \"heartbeat.run.log\",\n \"agent.status\",\n \"activity.logged\",\n \"plugin.ui.updated\",\n \"plugin.worker.crashed\",\n \"plugin.worker.restarted\",\n] as const;\nexport type LiveEventType = (typeof LIVE_EVENT_TYPES)[number];\n\nexport const PRINCIPAL_TYPES = [\"user\", \"agent\"] as const;\nexport type PrincipalType = (typeof PRINCIPAL_TYPES)[number];\n\nexport const MEMBERSHIP_STATUSES = [\"pending\", \"active\", \"suspended\"] as const;\nexport type MembershipStatus = (typeof MEMBERSHIP_STATUSES)[number];\n\nexport const INSTANCE_USER_ROLES = [\"instance_admin\"] as const;\nexport type InstanceUserRole = (typeof INSTANCE_USER_ROLES)[number];\n\nexport const INVITE_TYPES = [\"company_join\", \"bootstrap_ceo\"] as const;\nexport type InviteType = (typeof INVITE_TYPES)[number];\n\nexport const INVITE_JOIN_TYPES = [\"human\", \"agent\", \"both\"] as const;\nexport type InviteJoinType = (typeof INVITE_JOIN_TYPES)[number];\n\nexport const JOIN_REQUEST_TYPES = [\"human\", \"agent\"] as const;\nexport type JoinRequestType = (typeof JOIN_REQUEST_TYPES)[number];\n\nexport const JOIN_REQUEST_STATUSES = [\"pending_approval\", \"approved\", \"rejected\"] as const;\nexport type JoinRequestStatus = (typeof JOIN_REQUEST_STATUSES)[number];\n\nexport const PERMISSION_KEYS = [\n \"agents:create\",\n \"users:invite\",\n \"users:manage_permissions\",\n \"tasks:assign\",\n \"tasks:assign_scope\",\n \"joins:approve\",\n] as const;\nexport type PermissionKey = (typeof PERMISSION_KEYS)[number];\n\n// ---------------------------------------------------------------------------\n// Plugin System \u2014 see doc/plugins/PLUGIN_SPEC.md for the full specification\n// ---------------------------------------------------------------------------\n\n/**\n * The current version of the Plugin API contract.\n *\n * Increment this value whenever a breaking change is made to the plugin API\n * so that the host can reject incompatible plugin manifests.\n *\n * @see PLUGIN_SPEC.md \u00A74 \u2014 Versioning\n */\nexport const PLUGIN_API_VERSION = 1 as const;\n\n/**\n * Lifecycle statuses for an installed plugin.\n *\n * State machine: installed \u2192 ready | error, ready \u2192 disabled | error | upgrade_pending | uninstalled,\n * disabled \u2192 ready | uninstalled, error \u2192 ready | uninstalled,\n * upgrade_pending \u2192 ready | error | uninstalled, uninstalled \u2192 installed (reinstall).\n *\n * @see {@link PluginStatus} \u2014 inferred union type\n * @see PLUGIN_SPEC.md \u00A721.3 `plugins.status`\n */\nexport const PLUGIN_STATUSES = [\n \"installed\",\n \"ready\",\n \"disabled\",\n \"error\",\n \"upgrade_pending\",\n \"uninstalled\",\n] as const;\nexport type PluginStatus = (typeof PLUGIN_STATUSES)[number];\n\n/**\n * Plugin classification categories. A plugin declares one or more categories\n * in its manifest to describe its primary purpose.\n *\n * @see PLUGIN_SPEC.md \u00A76.2\n */\nexport const PLUGIN_CATEGORIES = [\n \"connector\",\n \"workspace\",\n \"automation\",\n \"ui\",\n] as const;\nexport type PluginCategory = (typeof PLUGIN_CATEGORIES)[number];\n\n/**\n * Named permissions the host grants to a plugin. Plugins declare required\n * capabilities in their manifest; the host enforces them at runtime via the\n * plugin capability validator.\n *\n * Grouped into: Data Read, Data Write, Plugin State, Runtime/Integration,\n * Agent Tools, and UI.\n *\n * @see PLUGIN_SPEC.md \u00A715 \u2014 Capability Model\n */\nexport const PLUGIN_CAPABILITIES = [\n // Data Read\n \"organizations.read\",\n \"projects.read\",\n \"project.workspaces.read\",\n \"issues.read\",\n \"issue.comments.read\",\n \"issue.documents.read\",\n \"agents.read\",\n \"goals.read\",\n \"goals.create\",\n \"goals.update\",\n \"activity.read\",\n \"costs.read\",\n // Data Write\n \"issues.create\",\n \"issues.update\",\n \"issue.comments.create\",\n \"issue.documents.write\",\n \"agents.pause\",\n \"agents.resume\",\n \"agents.invoke\",\n \"agent.sessions.create\",\n \"agent.sessions.list\",\n \"agent.sessions.send\",\n \"agent.sessions.close\",\n \"activity.log.write\",\n \"metrics.write\",\n // Plugin State\n \"plugin.state.read\",\n \"plugin.state.write\",\n // Runtime / Integration\n \"events.subscribe\",\n \"events.emit\",\n \"jobs.schedule\",\n \"webhooks.receive\",\n \"http.outbound\",\n \"secrets.read-ref\",\n // Agent Tools\n \"agent.tools.register\",\n // UI\n \"instance.settings.register\",\n \"ui.sidebar.register\",\n \"ui.page.register\",\n \"ui.detailTab.register\",\n \"ui.dashboardWidget.register\",\n \"ui.commentAnnotation.register\",\n \"ui.action.register\",\n] as const;\nexport type PluginCapability = (typeof PLUGIN_CAPABILITIES)[number];\n\n/**\n * UI extension slot types. Each slot type corresponds to a mount point in the\n * Rudder UI where plugin components can be rendered.\n *\n * @see PLUGIN_SPEC.md \u00A719 \u2014 UI Extension Model\n */\nexport const PLUGIN_UI_SLOT_TYPES = [\n \"page\",\n \"detailTab\",\n \"taskDetailView\",\n \"dashboardWidget\",\n \"sidebar\",\n \"sidebarPanel\",\n \"projectSidebarItem\",\n \"globalToolbarButton\",\n \"toolbarButton\",\n \"contextMenuItem\",\n \"commentAnnotation\",\n \"commentContextMenuItem\",\n \"settingsPage\",\n] as const;\nexport type PluginUiSlotType = (typeof PLUGIN_UI_SLOT_TYPES)[number];\n\n/**\n * Reserved organization-scoped route segments that plugin page routes may not claim.\n *\n * These map to first-class host pages under `/:organizationPrefix/...`.\n */\nexport const PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS = [\n \"dashboard\",\n \"onboarding\",\n \"organizations\",\n \"organization\",\n \"settings\",\n \"plugins\",\n \"org\",\n \"agents\",\n \"projects\",\n \"issues\",\n \"goals\",\n \"approvals\",\n \"costs\",\n \"activity\",\n \"inbox\",\n \"design-guide\",\n \"tests\",\n] as const;\nexport type PluginReservedCompanyRouteSegment =\n (typeof PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS)[number];\n\n/**\n * Launcher placement zones describe where a plugin-owned launcher can appear\n * in the host UI. These are intentionally aligned with current slot surfaces\n * so manifest authors can describe launch intent without coupling to a single\n * component implementation detail.\n */\nexport const PLUGIN_LAUNCHER_PLACEMENT_ZONES = [\n \"page\",\n \"detailTab\",\n \"taskDetailView\",\n \"dashboardWidget\",\n \"sidebar\",\n \"sidebarPanel\",\n \"projectSidebarItem\",\n \"globalToolbarButton\",\n \"toolbarButton\",\n \"contextMenuItem\",\n \"commentAnnotation\",\n \"commentContextMenuItem\",\n \"settingsPage\",\n] as const;\nexport type PluginLauncherPlacementZone = (typeof PLUGIN_LAUNCHER_PLACEMENT_ZONES)[number];\n\n/**\n * Launcher action kinds describe what the launcher does when activated.\n */\nexport const PLUGIN_LAUNCHER_ACTIONS = [\n \"navigate\",\n \"openModal\",\n \"openDrawer\",\n \"openPopover\",\n \"performAction\",\n \"deepLink\",\n] as const;\nexport type PluginLauncherAction = (typeof PLUGIN_LAUNCHER_ACTIONS)[number];\n\n/**\n * Optional size hints the host can use when rendering plugin-owned launcher\n * destinations such as overlays, drawers, or full page handoffs.\n */\nexport const PLUGIN_LAUNCHER_BOUNDS = [\n \"inline\",\n \"compact\",\n \"default\",\n \"wide\",\n \"full\",\n] as const;\nexport type PluginLauncherBounds = (typeof PLUGIN_LAUNCHER_BOUNDS)[number];\n\n/**\n * Render environments describe the container a launcher expects after it is\n * activated. The current host may map these to concrete UI primitives.\n */\nexport const PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS = [\n \"hostInline\",\n \"hostOverlay\",\n \"hostRoute\",\n \"external\",\n \"iframe\",\n] as const;\nexport type PluginLauncherRenderEnvironment =\n (typeof PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS)[number];\n\n/**\n * Entity types that a `detailTab` UI slot can attach to.\n *\n * @see PLUGIN_SPEC.md \u00A719.3 \u2014 Detail Tabs\n */\nexport const PLUGIN_UI_SLOT_ENTITY_TYPES = [\n \"project\",\n \"issue\",\n \"agent\",\n \"goal\",\n \"run\",\n \"comment\",\n] as const;\nexport type PluginUiSlotEntityType = (typeof PLUGIN_UI_SLOT_ENTITY_TYPES)[number];\n\n/**\n * Scope kinds for plugin state storage. Determines the granularity at which\n * a plugin stores key-value state data.\n *\n * @see PLUGIN_SPEC.md \u00A721.3 `plugin_state.scope_kind`\n */\nexport const PLUGIN_STATE_SCOPE_KINDS = [\n \"instance\",\n \"organization\",\n \"project\",\n \"project_workspace\",\n \"agent\",\n \"issue\",\n \"goal\",\n \"run\",\n] as const;\nexport type PluginStateScopeKind = (typeof PLUGIN_STATE_SCOPE_KINDS)[number];\n\n/** Statuses for a plugin's scheduled job definition. */\nexport const PLUGIN_JOB_STATUSES = [\n \"active\",\n \"paused\",\n \"failed\",\n] as const;\nexport type PluginJobStatus = (typeof PLUGIN_JOB_STATUSES)[number];\n\n/** Statuses for individual job run executions. */\nexport const PLUGIN_JOB_RUN_STATUSES = [\n \"pending\",\n \"queued\",\n \"running\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n] as const;\nexport type PluginJobRunStatus = (typeof PLUGIN_JOB_RUN_STATUSES)[number];\n\n/** What triggered a particular job run. */\nexport const PLUGIN_JOB_RUN_TRIGGERS = [\n \"schedule\",\n \"manual\",\n \"retry\",\n] as const;\nexport type PluginJobRunTrigger = (typeof PLUGIN_JOB_RUN_TRIGGERS)[number];\n\n/** Statuses for inbound webhook deliveries. */\nexport const PLUGIN_WEBHOOK_DELIVERY_STATUSES = [\n \"pending\",\n \"success\",\n \"failed\",\n] as const;\nexport type PluginWebhookDeliveryStatus = (typeof PLUGIN_WEBHOOK_DELIVERY_STATUSES)[number];\n\n/**\n * Core domain event types that plugins can subscribe to via the\n * `events.subscribe` capability.\n *\n * @see PLUGIN_SPEC.md \u00A716 \u2014 Event System\n */\nexport const PLUGIN_EVENT_TYPES = [\n \"organization.created\",\n \"organization.updated\",\n \"project.created\",\n \"project.updated\",\n \"project.workspace_created\",\n \"project.workspace_updated\",\n \"project.workspace_deleted\",\n \"issue.created\",\n \"issue.updated\",\n \"issue.comment.created\",\n \"agent.created\",\n \"agent.updated\",\n \"agent.status_changed\",\n \"agent.run.started\",\n \"agent.run.finished\",\n \"agent.run.failed\",\n \"agent.run.cancelled\",\n \"goal.created\",\n \"goal.updated\",\n \"approval.created\",\n \"approval.decided\",\n \"cost_event.created\",\n \"activity.logged\",\n] as const;\nexport type PluginEventType = (typeof PLUGIN_EVENT_TYPES)[number];\n\n/**\n * Error codes returned by the plugin bridge when a UI \u2192 worker call fails.\n *\n * @see PLUGIN_SPEC.md \u00A719.7 \u2014 Error Propagation Through The Bridge\n */\nexport const PLUGIN_BRIDGE_ERROR_CODES = [\n \"WORKER_UNAVAILABLE\",\n \"CAPABILITY_DENIED\",\n \"WORKER_ERROR\",\n \"TIMEOUT\",\n \"UNKNOWN\",\n] as const;\nexport type PluginBridgeErrorCode = (typeof PLUGIN_BRIDGE_ERROR_CODES)[number];\n", "export const EXECUTION_OBSERVABILITY_SURFACES = [\n \"heartbeat_run\",\n \"issue_run\",\n \"plugin_job_run\",\n \"workspace_operation\",\n \"chat_turn\",\n \"chat_action\",\n \"messenger_action\",\n \"activity_mutation\",\n \"cost_event\",\n] as const;\n\nexport type ExecutionObservabilitySurface = (typeof EXECUTION_OBSERVABILITY_SURFACES)[number];\n\nexport interface ExecutionObservabilityContext {\n surface: ExecutionObservabilitySurface;\n rootExecutionId: string;\n orgId?: string | null;\n agentId?: string | null;\n issueId?: string | null;\n pluginId?: string | null;\n sessionKey?: string | null;\n runtime?: string | null;\n trigger?: string | null;\n status?: string | null;\n environment?: string | null;\n release?: string | null;\n instanceId?: string | null;\n deploymentMode?: string | null;\n localEnv?: string | null;\n metadata?: Record<string, unknown> | null;\n tags?: string[] | null;\n}\n\nexport interface ExecutionLangfuseLink {\n traceId: string | null;\n traceUrl: string | null;\n}\n", "import type {\n OrganizationWorkspaceFileDetail,\n OrganizationWorkspaceFileList,\n} from \"./organization.js\";\n\nexport const WORKSPACE_BACKUP_DEFAULT_INTERVAL_HOURS = 24;\nexport const WORKSPACE_BACKUP_DEFAULT_RETENTION_DAYS = 30;\n\nexport type WorkspaceBackupStatus = \"running\" | \"succeeded\" | \"failed\" | \"restored\" | \"deleted\";\nexport type WorkspaceBackupTriggerSource = \"manual\" | \"scheduled\" | \"pre_restore\";\n\nexport interface WorkspaceBackupSummary {\n id: string;\n orgId: string;\n status: WorkspaceBackupStatus;\n triggerSource: WorkspaceBackupTriggerSource;\n artifactProvider: \"local_file\";\n artifactRef: string;\n archiveSha256: string | null;\n treeSha256: string | null;\n fileCount: number;\n byteSize: number;\n compressedSize: number;\n manifest: Record<string, unknown> | null;\n warnings: string[];\n error: string | null;\n startedAt: string | null;\n finishedAt: string | null;\n expiresAt: string | null;\n restoredFromBackupId: string | null;\n createdByUserId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface WorkspaceBackupList {\n backups: WorkspaceBackupSummary[];\n}\n\nexport interface WorkspaceBackupCreateRequest {\n triggerSource?: WorkspaceBackupTriggerSource;\n}\n\nexport interface WorkspaceBackupRestoreRequest {\n confirm: boolean;\n}\n\nexport interface WorkspaceBackupRestoreResult {\n restoredBackup: WorkspaceBackupSummary;\n preRestoreBackup: WorkspaceBackupSummary;\n}\n\nexport type WorkspaceBackupFileList = OrganizationWorkspaceFileList;\nexport type WorkspaceBackupFileDetail = OrganizationWorkspaceFileDetail;\n", "import { z } from \"zod\";\n\nexport const instanceLocaleSchema = z.enum([\"en\", \"zh-CN\"]);\n\nexport const instanceGeneralSettingsSchema = z.object({\n censorUsernameInLogs: z.boolean().default(false),\n showDeveloperDiagnostics: z.boolean().default(false),\n locale: instanceLocaleSchema.default(\"en\"),\n}).strict();\n\nexport const patchInstanceGeneralSettingsSchema = instanceGeneralSettingsSchema.partial();\n\nexport const instanceNotificationSettingsSchema = z.object({\n desktopInboxNotifications: z.boolean().default(true),\n desktopDockBadge: z.boolean().default(true),\n desktopIssueNotifications: z.boolean().default(true),\n desktopChatNotifications: z.boolean().default(true),\n}).strict();\n\nexport const patchInstanceNotificationSettingsSchema = instanceNotificationSettingsSchema.partial();\n\nexport const instanceLangfuseSettingsSchema = z.object({\n enabled: z.boolean().default(false),\n baseUrl: z.string().url().default(\"http://localhost:3000\"),\n publicKey: z.string().default(\"\"),\n environment: z.string().default(\"\"),\n secretKeyConfigured: z.boolean().default(false),\n managedByEnv: z.boolean().default(false),\n}).strict();\n\nexport const patchInstanceLangfuseSettingsSchema = z.object({\n enabled: z.boolean().optional(),\n baseUrl: z.string().url().optional(),\n publicKey: z.string().optional(),\n secretKey: z.string().optional(),\n environment: z.string().optional(),\n clearSecretKey: z.boolean().optional(),\n}).strict();\n\nexport const OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH = 8000;\n\nexport const operatorProfileSettingsSchema = z.object({\n nickname: z.string().max(80).default(\"\"),\n moreAboutYou: z.string().max(OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH).default(\"\"),\n}).strict();\n\nexport const patchOperatorProfileSettingsSchema = operatorProfileSettingsSchema.partial();\n\nexport const instancePathPickerSelectionTypeSchema = z.enum([\"file\", \"directory\"]);\n\nexport const instancePathPickerRequestSchema = z.object({\n selectionType: instancePathPickerSelectionTypeSchema,\n}).strict();\n\nexport const instancePathPickerResultSchema = z.object({\n path: z.string().nullable(),\n cancelled: z.boolean(),\n}).strict();\n\nexport type InstanceGeneralSettings = z.infer<typeof instanceGeneralSettingsSchema>;\nexport type PatchInstanceGeneralSettings = z.infer<typeof patchInstanceGeneralSettingsSchema>;\nexport type InstanceLangfuseSettings = z.infer<typeof instanceLangfuseSettingsSchema>;\nexport type PatchInstanceLangfuseSettings = z.infer<typeof patchInstanceLangfuseSettingsSchema>;\nexport type InstanceLocale = z.infer<typeof instanceLocaleSchema>;\nexport type OperatorProfileSettings = z.infer<typeof operatorProfileSettingsSchema>;\nexport type PatchOperatorProfileSettings = z.infer<typeof patchOperatorProfileSettingsSchema>;\nexport type InstanceNotificationSettings = z.infer<typeof instanceNotificationSettingsSchema>;\nexport type PatchInstanceNotificationSettings = z.infer<typeof patchInstanceNotificationSettingsSchema>;\nexport type InstancePathPickerSelectionType = z.infer<typeof instancePathPickerSelectionTypeSchema>;\nexport type InstancePathPickerRequest = z.infer<typeof instancePathPickerRequestSchema>;\nexport type InstancePathPickerResult = z.infer<typeof instancePathPickerResultSchema>;\n", "import { z } from \"zod\";\nimport {\n BUDGET_INCIDENT_RESOLUTION_ACTIONS,\n BUDGET_METRICS,\n BUDGET_SCOPE_TYPES,\n BUDGET_WINDOW_KINDS,\n} from \"../constants.js\";\n\nexport const upsertBudgetPolicySchema = z.object({\n scopeType: z.enum(BUDGET_SCOPE_TYPES),\n scopeId: z.string().uuid(),\n metric: z.enum(BUDGET_METRICS).optional().default(\"billed_cents\"),\n windowKind: z.enum(BUDGET_WINDOW_KINDS).optional().default(\"calendar_month_utc\"),\n amount: z.number().int().nonnegative(),\n warnPercent: z.number().int().min(1).max(99).optional().default(80),\n hardStopEnabled: z.boolean().optional().default(true),\n notifyEnabled: z.boolean().optional().default(true),\n isActive: z.boolean().optional().default(true),\n});\n\nexport type UpsertBudgetPolicy = z.infer<typeof upsertBudgetPolicySchema>;\n\nexport const resolveBudgetIncidentSchema = z.object({\n action: z.enum(BUDGET_INCIDENT_RESOLUTION_ACTIONS),\n amount: z.number().int().nonnegative().optional(),\n decisionNote: z.string().optional().nullable(),\n}).superRefine((value, ctx) => {\n if (value.action === \"raise_budget_and_resume\" && typeof value.amount !== \"number\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"amount is required when raising a budget\",\n path: [\"amount\"],\n });\n }\n});\n\nexport type ResolveBudgetIncident = z.infer<typeof resolveBudgetIncidentSchema>;\n", "import { z } from \"zod\";\nimport { CHAT_ISSUE_CREATION_MODES, ORGANIZATION_STATUSES } from \"../constants.js\";\n\nconst logoAssetIdSchema = z.string().uuid().nullable().optional();\nconst brandColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/).nullable().optional();\nexport const createOrganizationSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n budgetMonthlyCents: z.number().int().nonnegative().optional().default(0),\n defaultChatIssueCreationMode: z.enum(CHAT_ISSUE_CREATION_MODES).optional().default(\"manual_approval\"),\n brandColor: brandColorSchema,\n requireBoardApprovalForNewAgents: z.boolean().optional(),\n});\n\nexport type CreateOrganization = z.infer<typeof createOrganizationSchema>;\n\nexport const updateOrganizationSchema = createOrganizationSchema\n .partial()\n .extend({\n status: z.enum(ORGANIZATION_STATUSES).optional(),\n spentMonthlyCents: z.number().int().nonnegative().optional(),\n requireBoardApprovalForNewAgents: z.boolean().optional(),\n defaultChatIssueCreationMode: z.enum(CHAT_ISSUE_CREATION_MODES).optional(),\n brandColor: brandColorSchema,\n logoAssetId: logoAssetIdSchema,\n });\n\nexport type UpdateOrganization = z.infer<typeof updateOrganizationSchema>;\n\nexport const updateOrganizationBrandingSchema = z\n .object({\n name: z.string().min(1).optional(),\n description: z.string().nullable().optional(),\n brandColor: brandColorSchema,\n logoAssetId: logoAssetIdSchema,\n })\n .strict()\n .refine(\n (value) =>\n value.name !== undefined\n || value.description !== undefined\n || value.brandColor !== undefined\n || value.logoAssetId !== undefined,\n \"At least one branding field must be provided\",\n );\n\nexport type UpdateOrganizationBranding = z.infer<typeof updateOrganizationBrandingSchema>;\n\nexport const updateOrganizationWorkspaceFileSchema = z.object({\n content: z.string(),\n});\n\nexport type UpdateOrganizationWorkspaceFile = z.infer<typeof updateOrganizationWorkspaceFileSchema>;\n", "import { z } from \"zod\";\nimport { ORGANIZATION_RESOURCE_KINDS, PROJECT_RESOURCE_ATTACHMENT_ROLES } from \"../constants.js\";\n\nexport const organizationResourceKindSchema = z.enum(ORGANIZATION_RESOURCE_KINDS);\nexport const projectResourceAttachmentRoleSchema = z.enum(PROJECT_RESOURCE_ATTACHMENT_ROLES);\n\nexport const createOrganizationResourceSchema = z.object({\n name: z.string().min(1),\n kind: organizationResourceKindSchema,\n locator: z.string().min(1),\n description: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n});\n\nexport type CreateOrganizationResource = z.infer<typeof createOrganizationResourceSchema>;\n\nexport const updateOrganizationResourceSchema = z.object({\n name: z.string().min(1).optional(),\n kind: organizationResourceKindSchema.optional(),\n locator: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n}).strict();\n\nexport type UpdateOrganizationResource = z.infer<typeof updateOrganizationResourceSchema>;\n\nexport const projectResourceAttachmentInputSchema = z.object({\n resourceId: z.string().uuid(),\n role: projectResourceAttachmentRoleSchema.optional(),\n note: z.string().optional().nullable(),\n sortOrder: z.number().int().nonnegative().optional(),\n}).strict();\n\nexport type ProjectResourceAttachmentInputPayload = z.infer<typeof projectResourceAttachmentInputSchema>;\n\nexport const updateProjectResourceAttachmentSchema = z.object({\n role: projectResourceAttachmentRoleSchema.optional(),\n note: z.string().optional().nullable(),\n sortOrder: z.number().int().nonnegative().optional(),\n}).strict();\n\nexport type UpdateProjectResourceAttachment = z.infer<typeof updateProjectResourceAttachmentSchema>;\n\nexport const createProjectInlineResourceSchema = createOrganizationResourceSchema.extend({\n role: projectResourceAttachmentRoleSchema.optional(),\n note: z.string().optional().nullable(),\n sortOrder: z.number().int().nonnegative().optional(),\n}).strict();\n\nexport type CreateProjectInlineResource = z.infer<typeof createProjectInlineResourceSchema>;\n", "import { z } from \"zod\";\nimport {\n CHAT_CONTEXT_ENTITY_TYPES,\n CHAT_CONVERSATION_STATUSES,\n CHAT_ISSUE_CREATION_MODES,\n CHAT_MESSAGE_KINDS,\n CHAT_MESSAGE_ROLES,\n CHAT_MESSAGE_STATUSES,\n} from \"../constants.js\";\n\nexport const chatConversationStatusSchema = z.enum(CHAT_CONVERSATION_STATUSES);\nexport const chatIssueCreationModeSchema = z.enum(CHAT_ISSUE_CREATION_MODES);\nexport const chatMessageRoleSchema = z.enum(CHAT_MESSAGE_ROLES);\nexport const chatMessageKindSchema = z.enum(CHAT_MESSAGE_KINDS);\nexport const chatMessageStatusSchema = z.enum(CHAT_MESSAGE_STATUSES);\nexport const chatContextEntityTypeSchema = z.enum(CHAT_CONTEXT_ENTITY_TYPES);\n\nexport const createChatContextLinkSchema = z.object({\n entityType: chatContextEntityTypeSchema,\n entityId: z.string().min(1),\n metadata: z.record(z.unknown()).optional().nullable(),\n});\n\nexport const createChatConversationSchema = z.object({\n title: z.string().trim().min(1).max(200).optional(),\n summary: z.string().trim().max(5000).optional().nullable(),\n preferredAgentId: z.string().uuid().optional().nullable(),\n issueCreationMode: chatIssueCreationModeSchema.optional(),\n planMode: z.boolean().optional(),\n contextLinks: z.array(createChatContextLinkSchema).optional().default([]),\n});\n\nexport const setChatProjectContextSchema = z.object({\n projectId: z.string().uuid().optional().nullable(),\n});\n\nexport const updateChatConversationSchema = createChatConversationSchema\n .partial()\n .extend({\n status: chatConversationStatusSchema.optional(),\n routedAgentId: z.string().uuid().optional().nullable(),\n primaryIssueId: z.string().uuid().optional().nullable(),\n resolvedAt: z.string().datetime().optional().nullable(),\n });\n\nexport const addChatMessageSchema = z.object({\n body: z.string().trim().min(1).max(20000),\n editUserMessageId: z.string().uuid().optional().nullable(),\n});\n\nconst chatRichReferenceDisplaySchema = z.enum([\"card\", \"inline\"]);\nconst chatIssueIdentifierSchema = z.string().trim().min(1).max(64).regex(/^[A-Z0-9][A-Z0-9-]*$/i);\nconst chatAskUserIdentifierSchema = z.string().trim().min(1).max(64).regex(/^[a-zA-Z0-9_-]+$/);\n\nexport const chatAskUserOptionSchema = z.object({\n id: chatAskUserIdentifierSchema,\n label: z.string().trim().min(1).max(80),\n description: z.string().trim().min(1).max(220).optional(),\n recommended: z.boolean().optional(),\n});\n\nexport const chatAskUserQuestionSchema = z.object({\n id: chatAskUserIdentifierSchema,\n header: z.string().trim().min(1).max(32).optional(),\n question: z.string().trim().min(1).max(240),\n options: z.array(chatAskUserOptionSchema).min(2).max(3),\n allowFreeform: z.boolean().optional(),\n});\n\nexport const chatAskUserRequestSchema = z.object({\n questions: z.array(chatAskUserQuestionSchema).min(1).max(3),\n});\n\nconst chatIssueRichReferenceSchema = z.object({\n type: z.literal(\"issue\"),\n issueId: z.string().uuid().optional(),\n identifier: chatIssueIdentifierSchema.optional(),\n display: chatRichReferenceDisplaySchema.optional(),\n}).refine((value) => Boolean(value.issueId || value.identifier), {\n message: \"issueId or identifier is required\",\n});\n\nconst chatIssueCommentRichReferenceSchema = z.object({\n type: z.literal(\"issue_comment\"),\n issueId: z.string().uuid().optional(),\n identifier: chatIssueIdentifierSchema.optional(),\n commentId: z.string().uuid(),\n display: chatRichReferenceDisplaySchema.optional(),\n}).refine((value) => Boolean(value.issueId || value.identifier), {\n message: \"issueId or identifier is required\",\n});\n\nexport const chatRichReferenceSchema = z.union([\n chatIssueRichReferenceSchema,\n chatIssueCommentRichReferenceSchema,\n]);\n\nexport const chatRichReferencesSchema = z.array(chatRichReferenceSchema).max(5);\n\nexport function chatRichReferencesFromStructuredPayload(payload: unknown) {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return [];\n const rawReferences = (payload as Record<string, unknown>).richReferences;\n if (!Array.isArray(rawReferences)) return [];\n\n return rawReferences\n .map((reference) => chatRichReferenceSchema.safeParse(reference))\n .filter((result): result is z.SafeParseSuccess<z.infer<typeof chatRichReferenceSchema>> => result.success)\n .map((result) => result.data)\n .slice(0, 5);\n}\n\nexport function chatAskUserRequestFromStructuredPayload(payload: unknown) {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return null;\n const rawRequest = (payload as Record<string, unknown>).requestUserInput;\n const parsed = chatAskUserRequestSchema.safeParse(rawRequest);\n return parsed.success ? parsed.data : null;\n}\n\nexport function sanitizeChatStructuredPayload(payload: Record<string, unknown> | null | undefined) {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return null;\n const next = { ...payload };\n const requestUserInput = chatAskUserRequestFromStructuredPayload(payload);\n if (requestUserInput) {\n next.requestUserInput = requestUserInput;\n } else {\n delete next.requestUserInput;\n }\n const richReferences = chatRichReferencesFromStructuredPayload(payload);\n if (richReferences.length > 0) {\n next.richReferences = richReferences;\n } else {\n delete next.richReferences;\n }\n return Object.keys(next).length > 0 ? next : null;\n}\n\nexport const createChatAttachmentMetadataSchema = z.object({\n messageId: z.string().uuid(),\n});\n\nconst chatIssueProposalSchema = z.object({\n title: z.string().trim().min(1).max(200),\n description: z.string().trim().min(1).max(20000),\n priority: z.enum([\"critical\", \"high\", \"medium\", \"low\"]).optional().default(\"medium\"),\n projectId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n parentId: z.string().uuid().optional().nullable(),\n assigneeAgentId: z.string().uuid().optional().nullable(),\n assigneeUserId: z.string().trim().optional().nullable(),\n reviewerAgentId: z.string().uuid().optional().nullable(),\n reviewerUserId: z.string().trim().optional().nullable(),\n});\n\nexport const convertChatToIssueSchema = z.object({\n messageId: z.string().uuid().optional().nullable(),\n proposal: chatIssueProposalSchema.optional(),\n});\n\nexport const chatOperationProposalSchema = z.object({\n targetType: z.enum([\"organization\", \"agent\"]),\n targetId: z.string().min(1),\n summary: z.string().trim().min(1).max(500),\n patch: z.record(z.unknown()),\n});\n\nexport const resolveChatOperationProposalSchema = z.object({\n action: z.enum([\"approve\", \"reject\", \"requestRevision\"]),\n decisionNote: z.string().trim().max(5000).optional().nullable(),\n});\n\nexport const updateChatConversationUserStateSchema = z.object({\n pinned: z.boolean().optional(),\n unread: z.boolean().optional(),\n});\n\nexport type ChatConversationStatus = z.infer<typeof chatConversationStatusSchema>;\nexport type ChatIssueCreationMode = z.infer<typeof chatIssueCreationModeSchema>;\nexport type ChatMessageRole = z.infer<typeof chatMessageRoleSchema>;\nexport type ChatMessageKind = z.infer<typeof chatMessageKindSchema>;\nexport type ChatMessageStatus = z.infer<typeof chatMessageStatusSchema>;\nexport type ChatContextEntityType = z.infer<typeof chatContextEntityTypeSchema>;\nexport type CreateChatContextLink = z.infer<typeof createChatContextLinkSchema>;\nexport type CreateChatConversation = z.infer<typeof createChatConversationSchema>;\nexport type SetChatProjectContext = z.infer<typeof setChatProjectContextSchema>;\nexport type UpdateChatConversation = z.infer<typeof updateChatConversationSchema>;\nexport type AddChatMessage = z.infer<typeof addChatMessageSchema>;\nexport type ChatAskUserOption = z.infer<typeof chatAskUserOptionSchema>;\nexport type ChatAskUserQuestion = z.infer<typeof chatAskUserQuestionSchema>;\nexport type ChatAskUserRequest = z.infer<typeof chatAskUserRequestSchema>;\nexport type ChatRichReference = z.infer<typeof chatRichReferenceSchema>;\nexport type CreateChatAttachmentMetadata = z.infer<typeof createChatAttachmentMetadataSchema>;\nexport type ConvertChatToIssue = z.infer<typeof convertChatToIssueSchema>;\nexport type ChatOperationProposal = z.infer<typeof chatOperationProposalSchema>;\nexport type ResolveChatOperationProposal = z.infer<typeof resolveChatOperationProposalSchema>;\nexport type UpdateChatConversationUserState = z.infer<typeof updateChatConversationUserStateSchema>;\n", "import { z } from \"zod\";\n\nexport const organizationSkillSourceTypeSchema = z.enum([\"local_path\", \"github\", \"url\", \"catalog\", \"skills_sh\"]);\nexport const organizationSkillTrustLevelSchema = z.enum([\"markdown_only\", \"assets\", \"scripts_executables\"]);\nexport const organizationSkillCompatibilitySchema = z.enum([\"compatible\", \"unknown\", \"invalid\"]);\nexport const organizationSkillSourceBadgeSchema = z.enum([\n \"rudder\",\n \"community\",\n \"github\",\n \"local\",\n \"url\",\n \"catalog\",\n \"skills_sh\",\n]);\n\nexport const organizationSkillFileInventoryEntrySchema = z.object({\n path: z.string().min(1),\n kind: z.enum([\"skill\", \"markdown\", \"reference\", \"script\", \"asset\", \"other\"]),\n});\n\nexport const organizationSkillSchema = z.object({\n id: z.string().uuid(),\n orgId: z.string().uuid(),\n key: z.string().min(1),\n slug: z.string().min(1),\n name: z.string().min(1),\n description: z.string().nullable(),\n markdown: z.string(),\n sourceType: organizationSkillSourceTypeSchema,\n sourceLocator: z.string().nullable(),\n sourceRef: z.string().nullable(),\n trustLevel: organizationSkillTrustLevelSchema,\n compatibility: organizationSkillCompatibilitySchema,\n fileInventory: z.array(organizationSkillFileInventoryEntrySchema).default([]),\n metadata: z.record(z.unknown()).nullable(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n});\n\nexport const organizationSkillListItemSchema = organizationSkillSchema.extend({\n attachedAgentCount: z.number().int().nonnegative(),\n editable: z.boolean(),\n editableReason: z.string().nullable(),\n sourceLabel: z.string().nullable(),\n sourceBadge: organizationSkillSourceBadgeSchema,\n sourcePath: z.string().nullable(),\n workspaceEditPath: z.string().nullable(),\n});\n\nexport const organizationSkillUsageAgentSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(1),\n urlKey: z.string().min(1),\n agentRuntimeType: z.string().min(1),\n desired: z.boolean(),\n actualState: z.string().nullable(),\n});\n\nexport const organizationSkillDetailSchema = organizationSkillSchema.extend({\n attachedAgentCount: z.number().int().nonnegative(),\n usedByAgents: z.array(organizationSkillUsageAgentSchema).default([]),\n editable: z.boolean(),\n editableReason: z.string().nullable(),\n sourceLabel: z.string().nullable(),\n sourceBadge: organizationSkillSourceBadgeSchema,\n sourcePath: z.string().nullable(),\n workspaceEditPath: z.string().nullable(),\n});\n\nexport const organizationSkillUpdateStatusSchema = z.object({\n supported: z.boolean(),\n reason: z.string().nullable(),\n trackingRef: z.string().nullable(),\n currentRef: z.string().nullable(),\n latestRef: z.string().nullable(),\n hasUpdate: z.boolean(),\n});\n\nexport const organizationSkillImportSchema = z.object({\n source: z.string().min(1),\n});\n\nexport const organizationSkillProjectScanRequestSchema = z.object({\n projectIds: z.array(z.string().uuid()).optional(),\n workspaceIds: z.array(z.string().uuid()).optional(),\n});\n\nexport const organizationSkillProjectScanSkippedSchema = z.object({\n projectId: z.string().uuid(),\n projectName: z.string().min(1),\n workspaceId: z.string().uuid().nullable(),\n workspaceName: z.string().nullable(),\n path: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillProjectScanConflictSchema = z.object({\n slug: z.string().min(1),\n key: z.string().min(1),\n projectId: z.string().uuid(),\n projectName: z.string().min(1),\n workspaceId: z.string().uuid(),\n workspaceName: z.string().min(1),\n path: z.string().min(1),\n existingSkillId: z.string().uuid(),\n existingSkillKey: z.string().min(1),\n existingSourceLocator: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillProjectScanResultSchema = z.object({\n scannedProjects: z.number().int().nonnegative(),\n scannedWorkspaces: z.number().int().nonnegative(),\n discovered: z.number().int().nonnegative(),\n imported: z.array(organizationSkillSchema),\n updated: z.array(organizationSkillSchema),\n skipped: z.array(organizationSkillProjectScanSkippedSchema),\n conflicts: z.array(organizationSkillProjectScanConflictSchema),\n warnings: z.array(z.string()),\n});\n\nexport const organizationSkillLocalScanRequestSchema = z.object({\n roots: z.array(z.string().min(1)).optional(),\n});\n\nexport const organizationSkillLocalScanSkippedSchema = z.object({\n root: z.string().min(1),\n path: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillLocalScanConflictSchema = z.object({\n root: z.string().min(1),\n path: z.string().min(1),\n slug: z.string().min(1),\n key: z.string().min(1),\n existingSkillId: z.string().uuid(),\n existingSkillKey: z.string().min(1),\n existingSourceLocator: z.string().nullable(),\n reason: z.string().min(1),\n});\n\nexport const organizationSkillLocalScanResultSchema = z.object({\n scannedRoots: z.number().int().nonnegative(),\n discovered: z.number().int().nonnegative(),\n imported: z.array(organizationSkillSchema),\n updated: z.array(organizationSkillSchema),\n skipped: z.array(organizationSkillLocalScanSkippedSchema),\n conflicts: z.array(organizationSkillLocalScanConflictSchema),\n warnings: z.array(z.string()),\n});\n\nexport const organizationSkillCreateSchema = z.object({\n name: z.string().min(1),\n slug: z.string().min(1).nullable().optional(),\n description: z.string().nullable().optional(),\n markdown: z.string().nullable().optional(),\n});\n\nexport const organizationSkillFileDetailSchema = z.object({\n skillId: z.string().uuid(),\n path: z.string().min(1),\n kind: z.enum([\"skill\", \"markdown\", \"reference\", \"script\", \"asset\", \"other\"]),\n content: z.string(),\n language: z.string().nullable(),\n markdown: z.boolean(),\n editable: z.boolean(),\n});\n\nexport const organizationSkillFileUpdateSchema = z.object({\n path: z.string().min(1),\n content: z.string(),\n});\n\nexport type OrganizationSkillImport = z.infer<typeof organizationSkillImportSchema>;\nexport type OrganizationSkillProjectScan = z.infer<typeof organizationSkillProjectScanRequestSchema>;\nexport type OrganizationSkillLocalScan = z.infer<typeof organizationSkillLocalScanRequestSchema>;\nexport type OrganizationSkillCreate = z.infer<typeof organizationSkillCreateSchema>;\nexport type OrganizationSkillFileUpdate = z.infer<typeof organizationSkillFileUpdateSchema>;\n", "import { z } from \"zod\";\n\nexport const agentSkillStateSchema = z.enum([\n \"available\",\n \"configured\",\n \"installed\",\n \"missing\",\n \"stale\",\n \"external\",\n]);\n\nexport const agentSkillOriginSchema = z.preprocess((value) => {\n if (value === \"company_managed\") return \"organization_managed\";\n return value;\n}, z.enum([\n \"organization_managed\",\n \"user_installed\",\n \"external_unknown\",\n]));\n\nexport const agentSkillSourceClassSchema = z.enum([\n \"bundled\",\n \"organization\",\n \"agent_home\",\n \"global\",\n \"adapter_home\",\n]);\n\nexport const agentSkillSyncModeSchema = z.enum([\n \"unsupported\",\n \"persistent\",\n \"ephemeral\",\n]);\n\nexport const agentSkillEntrySchema = z.object({\n key: z.string().min(1),\n selectionKey: z.string().min(1),\n runtimeName: z.string().min(1).nullable(),\n description: z.string().nullable().optional(),\n desired: z.boolean(),\n configurable: z.boolean(),\n alwaysEnabled: z.boolean(),\n managed: z.boolean(),\n state: agentSkillStateSchema,\n sourceClass: agentSkillSourceClassSchema,\n origin: agentSkillOriginSchema.optional(),\n originLabel: z.string().nullable().optional(),\n locationLabel: z.string().nullable().optional(),\n readOnly: z.boolean().optional(),\n sourcePath: z.string().nullable().optional(),\n targetPath: z.string().nullable().optional(),\n workspaceEditPath: z.string().nullable().optional(),\n detail: z.string().nullable().optional(),\n});\n\nexport const agentSkillSnapshotSchema = z.object({\n agentRuntimeType: z.string().min(1),\n supported: z.boolean(),\n mode: agentSkillSyncModeSchema,\n desiredSkills: z.array(z.string().min(1)),\n entries: z.array(agentSkillEntrySchema),\n warnings: z.array(z.string()),\n});\n\nexport const agentSkillSyncSchema = z.object({\n desiredSkills: z.array(z.string().min(1)),\n});\n\nexport const agentSkillEnableSchema = z.object({\n skills: z.array(z.string().min(1)).min(1),\n});\n\nexport type AgentSkillSync = z.infer<typeof agentSkillSyncSchema>;\nexport type AgentSkillEnable = z.infer<typeof agentSkillEnableSchema>;\n", "import { z } from \"zod\";\n\nexport const portabilityIncludeSchema = z\n .object({\n organization: z.boolean().optional(),\n agents: z.boolean().optional(),\n projects: z.boolean().optional(),\n issues: z.boolean().optional(),\n skills: z.boolean().optional(),\n })\n .partial();\n\nexport const portabilityEnvInputSchema = z.object({\n key: z.string().min(1),\n description: z.string().nullable(),\n agentSlug: z.string().min(1).nullable(),\n kind: z.enum([\"secret\", \"plain\"]),\n requirement: z.enum([\"required\", \"optional\"]),\n defaultValue: z.string().nullable(),\n portability: z.enum([\"portable\", \"system_dependent\"]),\n});\n\nexport const portabilityFileEntrySchema = z.union([\n z.string(),\n z.object({\n encoding: z.literal(\"base64\"),\n data: z.string(),\n contentType: z.string().min(1).optional().nullable(),\n }),\n]);\n\nexport const portabilityOrganizationManifestEntrySchema = z.object({\n path: z.string().min(1),\n name: z.string().min(1),\n description: z.string().nullable(),\n brandColor: z.string().nullable(),\n logoPath: z.string().nullable(),\n requireBoardApprovalForNewAgents: z.boolean(),\n});\n\nexport const portabilitySidebarOrderSchema = z.object({\n agents: z.array(z.string().min(1)).default([]),\n projects: z.array(z.string().min(1)).default([]),\n});\n\nexport const portabilityAgentManifestEntrySchema = z.object({\n slug: z.string().min(1),\n name: z.string().min(1),\n path: z.string().min(1),\n skills: z.array(z.string().min(1)).default([]),\n role: z.string().min(1),\n title: z.string().nullable(),\n icon: z.string().nullable(),\n capabilities: z.string().nullable(),\n reportsToSlug: z.string().min(1).nullable(),\n agentRuntimeType: z.string().min(1),\n agentRuntimeConfig: z.record(z.unknown()),\n runtimeConfig: z.record(z.unknown()),\n permissions: z.record(z.unknown()),\n budgetMonthlyCents: z.number().int().nonnegative(),\n metadata: z.record(z.unknown()).nullable(),\n});\n\nexport const portabilitySkillManifestEntrySchema = z.object({\n key: z.string().min(1),\n slug: z.string().min(1),\n name: z.string().min(1),\n path: z.string().min(1),\n description: z.string().nullable(),\n sourceType: z.string().min(1),\n sourceLocator: z.string().nullable(),\n sourceRef: z.string().nullable(),\n trustLevel: z.string().nullable(),\n compatibility: z.string().nullable(),\n metadata: z.record(z.unknown()).nullable(),\n fileInventory: z.array(z.object({\n path: z.string().min(1),\n kind: z.string().min(1),\n })).default([]),\n});\n\nexport const portabilityProjectManifestEntrySchema = z.object({\n slug: z.string().min(1),\n name: z.string().min(1),\n path: z.string().min(1),\n description: z.string().nullable(),\n ownerAgentSlug: z.string().min(1).nullable(),\n leadAgentSlug: z.string().min(1).nullable(),\n targetDate: z.string().nullable(),\n color: z.string().nullable(),\n status: z.string().nullable(),\n executionWorkspacePolicy: z.record(z.unknown()).nullable(),\n workspaces: z.array(z.object({\n key: z.string().min(1),\n name: z.string().min(1),\n sourceType: z.string().nullable(),\n repoUrl: z.string().nullable(),\n repoRef: z.string().nullable(),\n defaultRef: z.string().nullable(),\n visibility: z.string().nullable(),\n setupCommand: z.string().nullable(),\n cleanupCommand: z.string().nullable(),\n metadata: z.record(z.unknown()).nullable(),\n isPrimary: z.boolean(),\n })).default([]),\n metadata: z.record(z.unknown()).nullable(),\n});\n\nexport const portabilityIssueAutomationTriggerManifestEntrySchema = z.object({\n kind: z.string().min(1),\n label: z.string().nullable(),\n enabled: z.boolean(),\n cronExpression: z.string().nullable(),\n timezone: z.string().nullable(),\n signingMode: z.string().nullable(),\n replayWindowSec: z.number().int().nullable(),\n});\n\nexport const portabilityIssueAutomationManifestEntrySchema = z.object({\n concurrencyPolicy: z.string().nullable(),\n catchUpPolicy: z.string().nullable(),\n triggers: z.array(portabilityIssueAutomationTriggerManifestEntrySchema).default([]),\n});\n\nexport const portabilityIssueManifestEntrySchema = z.object({\n slug: z.string().min(1),\n identifier: z.string().min(1).nullable(),\n title: z.string().min(1),\n path: z.string().min(1),\n projectSlug: z.string().min(1).nullable(),\n projectWorkspaceKey: z.string().min(1).nullable(),\n assigneeAgentSlug: z.string().min(1).nullable(),\n description: z.string().nullable(),\n recurring: z.boolean().default(false),\n automation: portabilityIssueAutomationManifestEntrySchema.nullable(),\n legacyRecurrence: z.record(z.unknown()).nullable(),\n status: z.string().nullable(),\n priority: z.string().nullable(),\n labelIds: z.array(z.string().min(1)).default([]),\n billingCode: z.string().nullable(),\n executionWorkspaceSettings: z.record(z.unknown()).nullable(),\n assigneeAgentRuntimeOverrides: z.record(z.unknown()).nullable(),\n metadata: z.record(z.unknown()).nullable(),\n});\n\nexport const portabilityManifestSchema = z.object({\n schemaVersion: z.number().int().positive(),\n generatedAt: z.string().datetime(),\n source: z\n .object({\n orgId: z.string().uuid(),\n organizationName: z.string().min(1),\n })\n .nullable(),\n includes: z.object({\n organization: z.boolean(),\n agents: z.boolean(),\n projects: z.boolean(),\n issues: z.boolean(),\n skills: z.boolean(),\n }),\n organization: portabilityOrganizationManifestEntrySchema.nullable(),\n sidebar: portabilitySidebarOrderSchema.nullable(),\n agents: z.array(portabilityAgentManifestEntrySchema),\n skills: z.array(portabilitySkillManifestEntrySchema).default([]),\n projects: z.array(portabilityProjectManifestEntrySchema).default([]),\n issues: z.array(portabilityIssueManifestEntrySchema).default([]),\n envInputs: z.array(portabilityEnvInputSchema).default([]),\n});\n\nexport const portabilitySourceSchema = z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"inline\"),\n rootPath: z.string().min(1).optional().nullable(),\n files: z.record(portabilityFileEntrySchema),\n }),\n z.object({\n type: z.literal(\"github\"),\n url: z.string().url(),\n }),\n]);\n\nexport const portabilityTargetSchema = z.discriminatedUnion(\"mode\", [\n z.object({\n mode: z.literal(\"new_organization\"),\n newOrganizationName: z.string().min(1).optional().nullable(),\n }),\n z.object({\n mode: z.literal(\"existing_organization\"),\n orgId: z.string().uuid(),\n }),\n]);\n\nexport const portabilityAgentSelectionSchema = z.union([\n z.literal(\"all\"),\n z.array(z.string().min(1)),\n]);\n\nexport const portabilityCollisionStrategySchema = z.enum([\"rename\", \"skip\", \"replace\"]);\n\nexport const organizationPortabilityExportSchema = z.object({\n include: portabilityIncludeSchema.optional(),\n agents: z.array(z.string().min(1)).optional(),\n skills: z.array(z.string().min(1)).optional(),\n projects: z.array(z.string().min(1)).optional(),\n issues: z.array(z.string().min(1)).optional(),\n projectIssues: z.array(z.string().min(1)).optional(),\n selectedFiles: z.array(z.string().min(1)).optional(),\n expandReferencedSkills: z.boolean().optional(),\n sidebarOrder: portabilitySidebarOrderSchema.partial().optional(),\n});\n\nexport type OrganizationPortabilityExport = z.infer<typeof organizationPortabilityExportSchema>;\n\nexport const organizationPortabilityPreviewSchema = z.object({\n source: portabilitySourceSchema,\n include: portabilityIncludeSchema.optional(),\n target: portabilityTargetSchema,\n agents: portabilityAgentSelectionSchema.optional(),\n collisionStrategy: portabilityCollisionStrategySchema.optional(),\n nameOverrides: z.record(z.string().min(1), z.string().min(1)).optional(),\n selectedFiles: z.array(z.string().min(1)).optional(),\n});\n\nexport type OrganizationPortabilityPreview = z.infer<typeof organizationPortabilityPreviewSchema>;\n\nexport const portabilityAdapterOverrideSchema = z.object({\n agentRuntimeType: z.string().min(1),\n agentRuntimeConfig: z.record(z.unknown()).optional(),\n});\n\nexport const organizationPortabilityImportSchema = organizationPortabilityPreviewSchema.extend({\n agentRuntimeOverrides: z.record(z.string().min(1), portabilityAdapterOverrideSchema).optional(),\n});\n\nexport type OrganizationPortabilityImport = z.infer<typeof organizationPortabilityImportSchema>;\n", "import { z } from \"zod\";\nimport { SECRET_PROVIDERS } from \"../constants.js\";\n\nexport const envBindingPlainSchema = z.object({\n type: z.literal(\"plain\"),\n value: z.string(),\n});\n\nexport const envBindingSecretRefSchema = z.object({\n type: z.literal(\"secret_ref\"),\n secretId: z.string().uuid(),\n version: z.union([z.literal(\"latest\"), z.number().int().positive()]).optional(),\n});\n\n// Backward-compatible union that accepts legacy inline values.\nexport const envBindingSchema = z.union([\n z.string(),\n envBindingPlainSchema,\n envBindingSecretRefSchema,\n]);\n\nexport const envConfigSchema = z.record(envBindingSchema);\n\nexport const createSecretSchema = z.object({\n name: z.string().min(1),\n provider: z.enum(SECRET_PROVIDERS).optional(),\n value: z.string().min(1),\n description: z.string().optional().nullable(),\n externalRef: z.string().optional().nullable(),\n});\n\nexport type CreateSecret = z.infer<typeof createSecretSchema>;\n\nexport const rotateSecretSchema = z.object({\n value: z.string().min(1),\n externalRef: z.string().optional().nullable(),\n});\n\nexport type RotateSecret = z.infer<typeof rotateSecretSchema>;\n\nexport const updateSecretSchema = z.object({\n name: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n externalRef: z.string().optional().nullable(),\n});\n\nexport type UpdateSecret = z.infer<typeof updateSecretSchema>;\n", "import { z } from \"zod\";\nimport { AGENT_RUNTIME_TYPES } from \"../constants.js\";\nimport { envConfigSchema } from \"./secret.js\";\n\nconst agentRuntimeTypes = new Set<string>(AGENT_RUNTIME_TYPES);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function validateModelFallbacksConfig(\n value: Record<string, unknown>,\n ctx: z.RefinementCtx,\n pathPrefix: Array<string | number>,\n) {\n const fallbackModels = value.modelFallbacks;\n if (fallbackModels === undefined) return;\n\n if (!Array.isArray(fallbackModels)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks must be an array\",\n path: [...pathPrefix, \"modelFallbacks\"],\n });\n return;\n }\n\n fallbackModels.forEach((fallback, index) => {\n if (typeof fallback === \"string\") {\n if (fallback.trim().length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks string entries must be non-empty\",\n path: [...pathPrefix, \"modelFallbacks\", index],\n });\n }\n return;\n }\n\n if (!isRecord(fallback)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must be strings or runtime/model objects\",\n path: [...pathPrefix, \"modelFallbacks\", index],\n });\n return;\n }\n\n if (typeof fallback.agentRuntimeType !== \"string\" || fallback.agentRuntimeType.trim().length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must include agentRuntimeType\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"agentRuntimeType\"],\n });\n } else if (!agentRuntimeTypes.has(fallback.agentRuntimeType)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must include a valid agentRuntimeType\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"agentRuntimeType\"],\n });\n }\n if (typeof fallback.model !== \"string\" || fallback.model.trim().length === 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entries must include model\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"model\"],\n });\n }\n if (fallback.config !== undefined && !isRecord(fallback.config)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entry config must be an object\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"config\"],\n });\n } else if (isRecord(fallback.config) && fallback.config.env !== undefined) {\n const parsed = envConfigSchema.safeParse(fallback.config.env);\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"modelFallbacks entry config.env must be a map of valid env bindings\",\n path: [...pathPrefix, \"modelFallbacks\", index, \"config\", \"env\"],\n });\n }\n }\n });\n}\n", "import { z } from \"zod\";\nimport {\n AGENT_RUNTIME_TYPES,\n AGENT_ICON_NAMES,\n AGENT_ROLES,\n AGENT_STATUSES,\n} from \"../constants.js\";\nimport { envConfigSchema } from \"./secret.js\";\nimport { validateModelFallbacksConfig } from \"./model-fallbacks.js\";\n\nexport const agentPermissionsSchema = z.object({\n canCreateAgents: z.boolean().optional().default(false),\n});\n\nexport const agentInstructionsBundleModeSchema = z.enum([\"managed\", \"external\"]);\n\nexport const updateAgentInstructionsBundleSchema = z.object({\n mode: agentInstructionsBundleModeSchema.optional(),\n rootPath: z.string().trim().min(1).nullable().optional(),\n entryFile: z.string().trim().min(1).optional(),\n clearLegacyPromptTemplate: z.boolean().optional().default(false),\n});\n\nexport type UpdateAgentInstructionsBundle = z.infer<typeof updateAgentInstructionsBundleSchema>;\n\nexport const upsertAgentInstructionsFileSchema = z.object({\n path: z.string().trim().min(1),\n content: z.string(),\n clearLegacyPromptTemplate: z.boolean().optional().default(false),\n});\n\nexport type UpsertAgentInstructionsFile = z.infer<typeof upsertAgentInstructionsFileSchema>;\n\nconst agentRuntimeConfigSchema = z.record(z.unknown()).superRefine((value, ctx) => {\n const envValue = value.env;\n if (envValue !== undefined) {\n const parsed = envConfigSchema.safeParse(envValue);\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"agentRuntimeConfig.env must be a map of valid env bindings\",\n path: [\"env\"],\n });\n }\n }\n\n validateModelFallbacksConfig(value, ctx, []);\n});\n\nconst optionalAgentNameSchema = z.preprocess(\n (value) => {\n if (typeof value !== \"string\") return value;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n },\n z.string().trim().min(1).optional(),\n);\n\nexport const uploadedAgentIconSchema = z.string().regex(\n /^asset:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n \"Invalid uploaded avatar reference\",\n);\n\nexport const customAgentIconSchema = z.string()\n .trim()\n .min(1)\n .max(24)\n .refine((value) => !value.toLowerCase().startsWith(\"asset:\"), \"Invalid uploaded avatar reference\")\n .refine((value) => !/[<>\\u0000-\\u001f\\u007f]/u.test(value), \"Icon cannot contain markup or control characters\");\n\nexport const agentIconSchema = z.preprocess(\n (value) => {\n if (typeof value !== \"string\") return value;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n },\n z.union([\n z.enum(AGENT_ICON_NAMES),\n uploadedAgentIconSchema,\n customAgentIconSchema,\n ]).nullable(),\n);\n\nexport const createAgentSchema = z.object({\n name: optionalAgentNameSchema,\n role: z.enum(AGENT_ROLES).optional().default(\"general\"),\n title: z.string().optional().nullable(),\n icon: agentIconSchema.optional(),\n reportsTo: z.string().uuid().optional().nullable(),\n capabilities: z.string().optional().nullable(),\n desiredSkills: z.array(z.string().min(1)).optional(),\n agentRuntimeType: z.enum(AGENT_RUNTIME_TYPES).optional().default(\"process\"),\n agentRuntimeConfig: agentRuntimeConfigSchema.optional().default({}),\n runtimeConfig: z.record(z.unknown()).optional().default({}),\n budgetMonthlyCents: z.number().int().nonnegative().optional().default(0),\n permissions: agentPermissionsSchema.optional(),\n metadata: z.record(z.unknown()).optional().nullable(),\n});\n\nexport type CreateAgent = z.infer<typeof createAgentSchema>;\n\nexport const createAgentHireSchema = createAgentSchema.extend({\n sourceIssueId: z.string().uuid().optional().nullable(),\n sourceIssueIds: z.array(z.string().uuid()).optional(),\n});\n\nexport type CreateAgentHire = z.infer<typeof createAgentHireSchema>;\n\nexport const updateAgentSchema = createAgentSchema\n .omit({ permissions: true })\n .partial()\n .extend({\n permissions: z.never().optional(),\n replaceAgentRuntimeConfig: z.boolean().optional(),\n status: z.enum(AGENT_STATUSES).optional(),\n spentMonthlyCents: z.number().int().nonnegative().optional(),\n });\n\nexport type UpdateAgent = z.infer<typeof updateAgentSchema>;\n\nexport const updateAgentInstructionsPathSchema = z.object({\n path: z.string().trim().min(1).nullable(),\n agentRuntimeConfigKey: z.string().trim().min(1).optional(),\n});\n\nexport type UpdateAgentInstructionsPath = z.infer<typeof updateAgentInstructionsPathSchema>;\n\nexport const createAgentKeySchema = z.object({\n name: z.string().min(1).default(\"default\"),\n});\n\nexport type CreateAgentKey = z.infer<typeof createAgentKeySchema>;\n\nexport const wakeAgentSchema = z.object({\n source: z.enum([\"timer\", \"assignment\", \"review\", \"on_demand\", \"automation\"]).optional().default(\"on_demand\"),\n triggerDetail: z.enum([\"manual\", \"ping\", \"callback\", \"system\"]).optional(),\n reason: z.string().optional().nullable(),\n payload: z.record(z.unknown()).optional().nullable(),\n idempotencyKey: z.string().optional().nullable(),\n forceFreshSession: z.preprocess(\n (value) => (value === null ? undefined : value),\n z.boolean().optional().default(false),\n ),\n});\n\nexport type WakeAgent = z.infer<typeof wakeAgentSchema>;\n\nexport const resetAgentSessionSchema = z.object({\n taskKey: z.string().min(1).optional().nullable(),\n});\n\nexport type ResetAgentSession = z.infer<typeof resetAgentSessionSchema>;\n\nexport const testAgentRuntimeEnvironmentSchema = z.object({\n agentRuntimeConfig: agentRuntimeConfigSchema.optional().default({}),\n});\n\nexport type TestAgentRuntimeEnvironment = z.infer<typeof testAgentRuntimeEnvironmentSchema>;\n\nexport const updateAgentPermissionsSchema = z.object({\n canCreateAgents: z.boolean(),\n canAssignTasks: z.boolean(),\n});\n\nexport type UpdateAgentPermissions = z.infer<typeof updateAgentPermissionsSchema>;\n", "import { z } from \"zod\";\nimport { PROJECT_COLORS, PROJECT_STATUSES } from \"../constants.js\";\nimport {\n createProjectInlineResourceSchema,\n projectResourceAttachmentInputSchema,\n} from \"./resource.js\";\n\nconst executionWorkspaceStrategySchema = z\n .object({\n type: z.enum([\"project_primary\", \"git_worktree\", \"adapter_managed\", \"cloud_sandbox\"]).optional(),\n baseRef: z.string().optional().nullable(),\n branchTemplate: z.string().optional().nullable(),\n worktreeParentDir: z.string().optional().nullable(),\n provisionCommand: z.string().optional().nullable(),\n teardownCommand: z.string().optional().nullable(),\n })\n .strict();\n\nexport const projectExecutionWorkspacePolicySchema = z\n .object({\n enabled: z.boolean(),\n defaultMode: z.enum([\"shared_workspace\", \"isolated_workspace\", \"operator_branch\", \"adapter_default\"]).optional(),\n allowIssueOverride: z.boolean().optional(),\n defaultProjectWorkspaceId: z.string().uuid().optional().nullable(),\n workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),\n workspaceRuntime: z.record(z.unknown()).optional().nullable(),\n branchPolicy: z.record(z.unknown()).optional().nullable(),\n pullRequestPolicy: z.record(z.unknown()).optional().nullable(),\n runtimePolicy: z.record(z.unknown()).optional().nullable(),\n cleanupPolicy: z.record(z.unknown()).optional().nullable(),\n })\n .strict();\n\nconst projectWorkspaceSourceTypeSchema = z.enum([\"local_path\", \"git_repo\", \"remote_managed\", \"non_git_path\"]);\nconst projectWorkspaceVisibilitySchema = z.enum([\"default\", \"advanced\"]);\n\nconst projectWorkspaceFields = {\n name: z.string().min(1).optional(),\n sourceType: projectWorkspaceSourceTypeSchema.optional(),\n cwd: z.string().min(1).optional().nullable(),\n repoUrl: z.string().url().optional().nullable(),\n repoRef: z.string().optional().nullable(),\n defaultRef: z.string().optional().nullable(),\n visibility: projectWorkspaceVisibilitySchema.optional(),\n setupCommand: z.string().optional().nullable(),\n cleanupCommand: z.string().optional().nullable(),\n remoteProvider: z.string().optional().nullable(),\n remoteWorkspaceRef: z.string().optional().nullable(),\n sharedWorkspaceKey: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n};\n\nconst projectColorValues = new Set<string>(PROJECT_COLORS);\nconst legacyProjectColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/);\nconst projectColorSchema = z.string().refine(\n (value) => legacyProjectColorSchema.safeParse(value).success || projectColorValues.has(value),\n \"Color must be a 6-digit hex value or a supported project gradient\",\n);\n\nfunction validateProjectWorkspace(value: Record<string, unknown>, ctx: z.RefinementCtx) {\n const sourceType = value.sourceType ?? \"local_path\";\n const hasCwd = typeof value.cwd === \"string\" && value.cwd.trim().length > 0;\n const hasRepo = typeof value.repoUrl === \"string\" && value.repoUrl.trim().length > 0;\n const hasRemoteRef = typeof value.remoteWorkspaceRef === \"string\" && value.remoteWorkspaceRef.trim().length > 0;\n\n if (sourceType === \"remote_managed\") {\n if (!hasRemoteRef && !hasRepo) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Remote-managed workspace requires remoteWorkspaceRef or repoUrl.\",\n path: [\"remoteWorkspaceRef\"],\n });\n }\n return;\n }\n\n if (!hasCwd && !hasRepo) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Workspace requires at least one of cwd or repoUrl.\",\n path: [\"cwd\"],\n });\n }\n}\n\nexport const createProjectWorkspaceSchema = z.object({\n ...projectWorkspaceFields,\n isPrimary: z.boolean().optional().default(false),\n}).superRefine(validateProjectWorkspace);\n\nexport type CreateProjectWorkspace = z.infer<typeof createProjectWorkspaceSchema>;\n\nexport const updateProjectWorkspaceSchema = z.object({\n ...projectWorkspaceFields,\n isPrimary: z.boolean().optional(),\n}).partial();\n\nexport type UpdateProjectWorkspace = z.infer<typeof updateProjectWorkspaceSchema>;\n\nconst projectFields = {\n /** @deprecated Use goalIds instead */\n goalId: z.string().uuid().optional().nullable(),\n goalIds: z.array(z.string().uuid()).optional(),\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n status: z.enum(PROJECT_STATUSES).optional().default(\"backlog\"),\n leadAgentId: z.string().uuid().optional().nullable(),\n targetDate: z.string().optional().nullable(),\n color: projectColorSchema.optional().nullable(),\n executionWorkspacePolicy: projectExecutionWorkspacePolicySchema.optional().nullable(),\n resourceAttachments: z.array(projectResourceAttachmentInputSchema).optional(),\n newResources: z.array(createProjectInlineResourceSchema).optional(),\n archivedAt: z.string().datetime().optional().nullable(),\n};\n\nexport const createProjectSchema = z.object({\n ...projectFields,\n});\n\nexport type CreateProject = z.infer<typeof createProjectSchema>;\n\nexport const updateProjectSchema = z.object(projectFields).partial();\n\nexport type UpdateProject = z.infer<typeof updateProjectSchema>;\n\nexport type ProjectExecutionWorkspacePolicy = z.infer<typeof projectExecutionWorkspacePolicySchema>;\n", "import { z } from \"zod\";\nimport { ISSUE_PRIORITIES, ISSUE_STATUSES } from \"../constants.js\";\n\nconst executionWorkspaceStrategySchema = z\n .object({\n type: z.enum([\"project_primary\", \"git_worktree\", \"adapter_managed\", \"cloud_sandbox\"]).optional(),\n baseRef: z.string().optional().nullable(),\n branchTemplate: z.string().optional().nullable(),\n worktreeParentDir: z.string().optional().nullable(),\n provisionCommand: z.string().optional().nullable(),\n teardownCommand: z.string().optional().nullable(),\n })\n .strict();\n\nexport const issueExecutionWorkspaceSettingsSchema = z\n .object({\n mode: z.enum([\"inherit\", \"shared_workspace\", \"isolated_workspace\", \"operator_branch\", \"reuse_existing\", \"agent_default\"]).optional(),\n workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),\n workspaceRuntime: z.record(z.unknown()).optional().nullable(),\n })\n .strict();\n\nexport const issueAssigneeAdapterOverridesSchema = z\n .object({\n agentRuntimeConfig: z.record(z.unknown()).optional(),\n useProjectWorkspace: z.boolean().optional(),\n })\n .strict();\n\nexport const createIssueSchema = z.object({\n projectId: z.string().uuid().optional().nullable(),\n projectWorkspaceId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n parentId: z.string().uuid().optional().nullable(),\n title: z.string().min(1),\n description: z.string().optional().nullable(),\n status: z.enum(ISSUE_STATUSES).optional().default(\"backlog\"),\n priority: z.enum(ISSUE_PRIORITIES).optional().default(\"medium\"),\n assigneeAgentId: z.string().uuid().optional().nullable(),\n assigneeUserId: z.string().optional().nullable(),\n reviewerAgentId: z.string().uuid().optional().nullable(),\n reviewerUserId: z.string().optional().nullable(),\n requestDepth: z.number().int().nonnegative().optional().default(0),\n billingCode: z.string().optional().nullable(),\n assigneeAgentRuntimeOverrides: issueAssigneeAdapterOverridesSchema.optional().nullable(),\n executionWorkspaceId: z.string().uuid().optional().nullable(),\n executionWorkspacePreference: z.enum([\n \"inherit\",\n \"shared_workspace\",\n \"isolated_workspace\",\n \"operator_branch\",\n \"reuse_existing\",\n \"agent_default\",\n ]).optional().nullable(),\n executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),\n labelIds: z.array(z.string().uuid()).optional(),\n});\n\nexport type CreateIssue = z.infer<typeof createIssueSchema>;\n\nexport const createIssueLabelSchema = z.object({\n name: z.string().trim().min(1).max(48),\n color: z.string().regex(/^#(?:[0-9a-fA-F]{6})$/, \"Color must be a 6-digit hex value\"),\n});\n\nexport type CreateIssueLabel = z.infer<typeof createIssueLabelSchema>;\n\nexport const updateIssueLabelSchema = createIssueLabelSchema.partial().refine(\n (value) => value.name !== undefined || value.color !== undefined,\n {\n message: \"At least one label field must be provided\",\n },\n);\n\nexport type UpdateIssueLabel = z.infer<typeof updateIssueLabelSchema>;\n\nexport const updateIssueSchema = createIssueSchema.partial().extend({\n comment: z.string().min(1).optional(),\n reopen: z.boolean().optional(),\n hiddenAt: z.string().datetime().nullable().optional(),\n reviewDecision: z.enum([\"approve\", \"request_changes\", \"needs_followup\", \"blocked\"]).optional(),\n});\n\nexport type UpdateIssue = z.infer<typeof updateIssueSchema>;\nexport type IssueExecutionWorkspaceSettings = z.infer<typeof issueExecutionWorkspaceSettingsSchema>;\n\nexport const reorderIssueSchema = z\n .object({\n issueId: z.string().uuid(),\n targetStatus: z.enum(ISSUE_STATUSES),\n previousIssueId: z.string().uuid().optional().nullable(),\n nextIssueId: z.string().uuid().optional().nullable(),\n position: z.enum([\"start\", \"end\"]).optional(),\n })\n .refine(\n (value) => !(value.previousIssueId && value.nextIssueId && value.previousIssueId === value.nextIssueId),\n {\n message: \"previousIssueId and nextIssueId must be different\",\n },\n );\n\nexport type ReorderIssue = z.infer<typeof reorderIssueSchema>;\n\nexport const checkoutIssueSchema = z.object({\n agentId: z.string().uuid(),\n expectedStatuses: z.array(z.enum(ISSUE_STATUSES)).nonempty(),\n});\n\nexport type CheckoutIssue = z.infer<typeof checkoutIssueSchema>;\n\nexport const addIssueCommentSchema = z.object({\n body: z.string().min(1),\n reopen: z.boolean().optional(),\n interrupt: z.boolean().optional(),\n});\n\nexport type AddIssueComment = z.infer<typeof addIssueCommentSchema>;\n\nexport const reportIssueCommitSchema = z.object({\n sha: z.string().trim().regex(/^[0-9a-f]{7,64}$/i, \"Commit SHA must be 7 to 64 hexadecimal characters\"),\n message: z.string().trim().min(1).max(500),\n branch: z.string().trim().min(1).max(255).optional().nullable(),\n repoPath: z.string().trim().min(1).max(2048).optional().nullable(),\n workspacePath: z.string().trim().min(1).max(2048).optional().nullable(),\n commitCount: z.number().int().positive().max(1000).optional(),\n});\n\nexport type ReportIssueCommit = z.infer<typeof reportIssueCommitSchema>;\n\nexport const linkIssueApprovalSchema = z.object({\n approvalId: z.string().uuid(),\n});\n\nexport type LinkIssueApproval = z.infer<typeof linkIssueApprovalSchema>;\n\nexport const createIssueAttachmentMetadataSchema = z.object({\n issueCommentId: z.string().uuid().optional().nullable(),\n usage: z.enum([\"issue\", \"description_inline\", \"document_inline\", \"comment_inline\", \"comment_attachment\"]).optional(),\n});\n\nexport type CreateIssueAttachmentMetadata = z.infer<typeof createIssueAttachmentMetadataSchema>;\n\nexport const createIssueWorkspaceAttachmentSchema = z.object({\n path: z.string().trim().min(1).max(2048),\n});\n\nexport type CreateIssueWorkspaceAttachment = z.infer<typeof createIssueWorkspaceAttachmentSchema>;\n\nexport const ISSUE_DOCUMENT_FORMATS = [\"markdown\"] as const;\n\nexport const issueDocumentFormatSchema = z.enum(ISSUE_DOCUMENT_FORMATS);\n\nexport const issueDocumentKeySchema = z\n .string()\n .trim()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9][a-z0-9_-]*$/, \"Document key must be lowercase letters, numbers, _ or -\");\n\nexport const upsertIssueDocumentSchema = z.object({\n title: z.string().trim().max(200).nullable().optional(),\n format: issueDocumentFormatSchema,\n body: z.string().max(524288),\n changeSummary: z.string().trim().max(500).nullable().optional(),\n baseRevisionId: z.string().uuid().nullable().optional(),\n});\n\nexport type IssueDocumentFormat = z.infer<typeof issueDocumentFormatSchema>;\nexport type UpsertIssueDocument = z.infer<typeof upsertIssueDocumentSchema>;\n", "import { z } from \"zod\";\n\nexport const issueWorkProductTypeSchema = z.enum([\n \"preview_url\",\n \"runtime_service\",\n \"pull_request\",\n \"branch\",\n \"commit\",\n \"artifact\",\n \"document\",\n]);\n\nexport const issueWorkProductStatusSchema = z.enum([\n \"active\",\n \"ready_for_review\",\n \"approved\",\n \"changes_requested\",\n \"merged\",\n \"closed\",\n \"failed\",\n \"archived\",\n \"draft\",\n]);\n\nexport const issueWorkProductReviewStateSchema = z.enum([\n \"none\",\n \"needs_board_review\",\n \"approved\",\n \"changes_requested\",\n]);\n\nexport const createIssueWorkProductSchema = z.object({\n projectId: z.string().uuid().optional().nullable(),\n executionWorkspaceId: z.string().uuid().optional().nullable(),\n runtimeServiceId: z.string().uuid().optional().nullable(),\n type: issueWorkProductTypeSchema,\n provider: z.string().min(1),\n externalId: z.string().optional().nullable(),\n title: z.string().min(1),\n url: z.string().url().optional().nullable(),\n status: issueWorkProductStatusSchema.default(\"active\"),\n reviewState: issueWorkProductReviewStateSchema.optional().default(\"none\"),\n isPrimary: z.boolean().optional().default(false),\n healthStatus: z.enum([\"unknown\", \"healthy\", \"unhealthy\"]).optional().default(\"unknown\"),\n summary: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n createdByRunId: z.string().uuid().optional().nullable(),\n});\n\nexport type CreateIssueWorkProduct = z.infer<typeof createIssueWorkProductSchema>;\n\nexport const updateIssueWorkProductSchema = createIssueWorkProductSchema.partial();\n\nexport type UpdateIssueWorkProduct = z.infer<typeof updateIssueWorkProductSchema>;\n", "import { z } from \"zod\";\n\nexport const executionWorkspaceStatusSchema = z.enum([\n \"active\",\n \"idle\",\n \"in_review\",\n \"archived\",\n \"cleanup_failed\",\n]);\n\nexport const updateExecutionWorkspaceSchema = z.object({\n status: executionWorkspaceStatusSchema.optional(),\n cleanupEligibleAt: z.string().datetime().optional().nullable(),\n cleanupReason: z.string().optional().nullable(),\n metadata: z.record(z.unknown()).optional().nullable(),\n}).strict();\n\nexport type UpdateExecutionWorkspace = z.infer<typeof updateExecutionWorkspaceSchema>;\n", "import { z } from \"zod\";\n\nexport const workspaceBackupTriggerSourceSchema = z.enum([\"manual\", \"scheduled\", \"pre_restore\"]);\n\nexport const createWorkspaceBackupSchema = z.object({\n triggerSource: workspaceBackupTriggerSourceSchema.optional().default(\"manual\"),\n}).strict();\n\nexport const restoreWorkspaceBackupSchema = z.object({\n confirm: z.literal(true),\n}).strict();\n\nexport type CreateWorkspaceBackup = z.infer<typeof createWorkspaceBackupSchema>;\nexport type RestoreWorkspaceBackup = z.infer<typeof restoreWorkspaceBackupSchema>;\n", "import { z } from \"zod\";\nimport { GOAL_LEVELS, GOAL_STATUSES } from \"../constants.js\";\n\nexport const createGoalSchema = z.object({\n title: z.string().min(1),\n description: z.string().optional().nullable(),\n level: z.enum(GOAL_LEVELS).optional().default(\"task\"),\n status: z.enum(GOAL_STATUSES).optional().default(\"planned\"),\n parentId: z.string().uuid().optional().nullable(),\n ownerAgentId: z.string().uuid().optional().nullable(),\n});\n\nexport type CreateGoal = z.infer<typeof createGoalSchema>;\n\nexport const updateGoalSchema = createGoalSchema.partial();\n\nexport type UpdateGoal = z.infer<typeof updateGoalSchema>;\n", "import { z } from \"zod\";\nimport { APPROVAL_TYPES } from \"../constants.js\";\n\nexport const createApprovalSchema = z.object({\n type: z.enum(APPROVAL_TYPES),\n requestedByAgentId: z.string().uuid().optional().nullable(),\n payload: z.record(z.unknown()),\n issueIds: z.array(z.string().uuid()).optional(),\n});\n\nexport type CreateApproval = z.infer<typeof createApprovalSchema>;\n\nexport const resolveApprovalSchema = z.object({\n decisionNote: z.string().optional().nullable(),\n decidedByUserId: z.string().optional().default(\"board\"),\n});\n\nexport type ResolveApproval = z.infer<typeof resolveApprovalSchema>;\n\nexport const requestApprovalRevisionSchema = z.object({\n decisionNote: z.string().optional().nullable(),\n decidedByUserId: z.string().optional().default(\"board\"),\n});\n\nexport type RequestApprovalRevision = z.infer<typeof requestApprovalRevisionSchema>;\n\nexport const resubmitApprovalSchema = z.object({\n payload: z.record(z.unknown()).optional(),\n});\n\nexport type ResubmitApproval = z.infer<typeof resubmitApprovalSchema>;\n\nexport const addApprovalCommentSchema = z.object({\n body: z.string().min(1),\n});\n\nexport type AddApprovalComment = z.infer<typeof addApprovalCommentSchema>;\n", "import { z } from \"zod\";\nimport {\n ISSUE_PRIORITIES,\n AUTOMATION_CATCH_UP_POLICIES,\n AUTOMATION_CONCURRENCY_POLICIES,\n AUTOMATION_STATUSES,\n AUTOMATION_TRIGGER_SIGNING_MODES,\n} from \"../constants.js\";\n\nexport const createAutomationSchema = z.object({\n projectId: z.string().uuid().optional().nullable().default(null),\n goalId: z.string().uuid().optional().nullable(),\n parentIssueId: z.string().uuid().optional().nullable(),\n title: z.string().trim().min(1).max(200),\n description: z.string().optional().nullable(),\n assigneeAgentId: z.string().uuid(),\n priority: z.enum(ISSUE_PRIORITIES).optional().default(\"medium\"),\n status: z.enum(AUTOMATION_STATUSES).optional().default(\"active\"),\n concurrencyPolicy: z.enum(AUTOMATION_CONCURRENCY_POLICIES).optional().default(\"coalesce_if_active\"),\n catchUpPolicy: z.enum(AUTOMATION_CATCH_UP_POLICIES).optional().default(\"skip_missed\"),\n});\n\nexport type CreateAutomation = z.infer<typeof createAutomationSchema>;\n\nexport const updateAutomationSchema = createAutomationSchema.partial();\nexport type UpdateAutomation = z.infer<typeof updateAutomationSchema>;\n\nconst baseTriggerSchema = z.object({\n label: z.string().trim().max(120).optional().nullable(),\n enabled: z.boolean().optional().default(true),\n});\n\nexport const createAutomationTriggerSchema = z.discriminatedUnion(\"kind\", [\n baseTriggerSchema.extend({\n kind: z.literal(\"schedule\"),\n cronExpression: z.string().trim().min(1),\n timezone: z.string().trim().min(1).default(\"UTC\"),\n }),\n baseTriggerSchema.extend({\n kind: z.literal(\"webhook\"),\n signingMode: z.enum(AUTOMATION_TRIGGER_SIGNING_MODES).optional().default(\"bearer\"),\n replayWindowSec: z.number().int().min(30).max(86_400).optional().default(300),\n }),\n baseTriggerSchema.extend({\n kind: z.literal(\"api\"),\n }),\n]);\n\nexport type CreateAutomationTrigger = z.infer<typeof createAutomationTriggerSchema>;\n\nexport const updateAutomationTriggerSchema = z.object({\n label: z.string().trim().max(120).optional().nullable(),\n enabled: z.boolean().optional(),\n cronExpression: z.string().trim().min(1).optional().nullable(),\n timezone: z.string().trim().min(1).optional().nullable(),\n signingMode: z.enum(AUTOMATION_TRIGGER_SIGNING_MODES).optional().nullable(),\n replayWindowSec: z.number().int().min(30).max(86_400).optional().nullable(),\n});\n\nexport type UpdateAutomationTrigger = z.infer<typeof updateAutomationTriggerSchema>;\n\nexport const runAutomationSchema = z.object({\n triggerId: z.string().uuid().optional().nullable(),\n payload: z.record(z.unknown()).optional().nullable(),\n idempotencyKey: z.string().trim().max(255).optional().nullable(),\n source: z.enum([\"manual\", \"api\"]).optional().default(\"manual\"),\n});\n\nexport type RunAutomation = z.infer<typeof runAutomationSchema>;\n\nexport const rotateAutomationTriggerSecretSchema = z.object({});\nexport type RotateAutomationTriggerSecret = z.infer<typeof rotateAutomationTriggerSecretSchema>;\n", "import { z } from \"zod\";\nimport {\n CALENDAR_EVENT_KINDS,\n CALENDAR_EVENT_STATUSES,\n CALENDAR_OWNER_TYPES,\n CALENDAR_SOURCE_MODES,\n CALENDAR_SOURCE_STATUSES,\n CALENDAR_SOURCE_TYPES,\n CALENDAR_VISIBILITIES,\n} from \"../constants.js\";\n\nconst nullableUuid = z.string().uuid().optional().nullable();\n\nexport const createCalendarSourceSchema = z.object({\n type: z.enum(CALENDAR_SOURCE_TYPES).optional().default(\"rudder_local\"),\n name: z.string().trim().min(1).max(160),\n ownerType: z.enum(CALENDAR_OWNER_TYPES).optional().default(\"user\"),\n ownerUserId: z.string().trim().min(1).optional().nullable(),\n ownerAgentId: nullableUuid,\n externalProvider: z.string().trim().min(1).max(80).optional().nullable(),\n externalCalendarId: z.string().trim().min(1).max(512).optional().nullable(),\n visibilityDefault: z.enum(CALENDAR_VISIBILITIES).optional().default(\"full\"),\n status: z.enum(CALENDAR_SOURCE_STATUSES).optional().default(\"active\"),\n syncCursorJson: z.record(z.unknown()).optional().nullable(),\n});\n\nexport type CreateCalendarSource = z.infer<typeof createCalendarSourceSchema>;\n\nexport const updateCalendarSourceSchema = createCalendarSourceSchema.partial().extend({\n lastSyncedAt: z.coerce.date().optional().nullable(),\n});\n\nexport type UpdateCalendarSource = z.infer<typeof updateCalendarSourceSchema>;\n\nconst calendarEventBaseSchema = z.object({\n sourceId: nullableUuid,\n eventKind: z.enum(CALENDAR_EVENT_KINDS),\n eventStatus: z.enum(CALENDAR_EVENT_STATUSES).optional().default(\"planned\"),\n ownerType: z.enum(CALENDAR_OWNER_TYPES),\n ownerUserId: z.string().trim().min(1).optional().nullable(),\n ownerAgentId: nullableUuid,\n title: z.string().trim().min(1).max(240),\n description: z.string().optional().nullable(),\n startAt: z.coerce.date(),\n endAt: z.coerce.date(),\n timezone: z.string().trim().min(1).max(80).optional().default(\"UTC\"),\n allDay: z.boolean().optional().default(false),\n visibility: z.enum(CALENDAR_VISIBILITIES).optional().default(\"full\"),\n issueId: nullableUuid,\n projectId: nullableUuid,\n goalId: nullableUuid,\n approvalId: nullableUuid,\n heartbeatRunId: nullableUuid,\n activityId: nullableUuid,\n sourceMode: z.enum(CALENDAR_SOURCE_MODES).optional().default(\"manual\"),\n externalProvider: z.string().trim().min(1).max(80).optional().nullable(),\n externalCalendarId: z.string().trim().min(1).max(512).optional().nullable(),\n externalEventId: z.string().trim().min(1).max(512).optional().nullable(),\n externalEtag: z.string().trim().min(1).max(512).optional().nullable(),\n externalUpdatedAt: z.coerce.date().optional().nullable(),\n});\n\nexport const createCalendarEventSchema = calendarEventBaseSchema.refine(\n (value) => value.endAt.getTime() > value.startAt.getTime(),\n { path: [\"endAt\"], message: \"End time must be after start time\" },\n);\n\nexport type CreateCalendarEvent = z.infer<typeof createCalendarEventSchema>;\n\nexport const updateCalendarEventSchema = calendarEventBaseSchema\n .partial()\n .refine(\n (value) =>\n value.startAt === undefined ||\n value.endAt === undefined ||\n value.endAt.getTime() > value.startAt.getTime(),\n { path: [\"endAt\"], message: \"End time must be after start time\" },\n );\n\nexport type UpdateCalendarEvent = z.infer<typeof updateCalendarEventSchema>;\n\nexport const calendarEventListQuerySchema = z.object({\n start: z.coerce.date(),\n end: z.coerce.date(),\n agentIds: z.string().optional(),\n sourceIds: z.string().optional(),\n eventKinds: z.string().optional(),\n statuses: z.string().optional(),\n}).refine(\n (value) => value.end.getTime() > value.start.getTime(),\n { path: [\"end\"], message: \"End time must be after start time\" },\n);\n\nexport type CalendarEventListQuery = z.infer<typeof calendarEventListQuerySchema>;\n\nexport const googleCalendarSyncSchema = z.object({\n sourceId: z.string().uuid().optional().nullable(),\n});\n\nexport type GoogleCalendarSync = z.infer<typeof googleCalendarSyncSchema>;\n\nexport const updateGoogleCalendarOAuthConfigSchema = z.object({\n clientId: z.string().trim().min(1).max(512).optional(),\n clientSecret: z.string().trim().min(1).max(2048).optional(),\n clear: z.boolean().optional().default(false),\n}).refine(\n (value) => value.clear || value.clientId !== undefined || value.clientSecret !== undefined,\n { message: \"Provide credentials or clear the stored Google Calendar OAuth configuration\" },\n);\n\nexport type UpdateGoogleCalendarOAuthConfig = z.input<typeof updateGoogleCalendarOAuthConfigSchema>;\n", "import { z } from \"zod\";\nimport { BILLING_TYPES } from \"../constants.js\";\n\nexport const createCostEventSchema = z.object({\n agentId: z.string().uuid(),\n issueId: z.string().uuid().optional().nullable(),\n projectId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n heartbeatRunId: z.string().uuid().optional().nullable(),\n billingCode: z.string().optional().nullable(),\n provider: z.string().min(1),\n biller: z.string().min(1).optional(),\n billingType: z.enum(BILLING_TYPES).optional().default(\"unknown\"),\n model: z.string().min(1),\n inputTokens: z.number().int().nonnegative().optional().default(0),\n cachedInputTokens: z.number().int().nonnegative().optional().default(0),\n outputTokens: z.number().int().nonnegative().optional().default(0),\n costCents: z.number().int().nonnegative(),\n occurredAt: z.string().datetime(),\n}).transform((value) => ({\n ...value,\n biller: value.biller ?? value.provider,\n}));\n\nexport type CreateCostEvent = z.infer<typeof createCostEventSchema>;\n\nexport const updateBudgetSchema = z.object({\n budgetMonthlyCents: z.number().int().nonnegative(),\n});\n\nexport type UpdateBudget = z.infer<typeof updateBudgetSchema>;\n", "import { z } from \"zod\";\nimport { AGENT_RUNTIME_TYPES, FINANCE_DIRECTIONS, FINANCE_EVENT_KINDS, FINANCE_UNITS } from \"../constants.js\";\n\nexport const createFinanceEventSchema = z.object({\n agentId: z.string().uuid().optional().nullable(),\n issueId: z.string().uuid().optional().nullable(),\n projectId: z.string().uuid().optional().nullable(),\n goalId: z.string().uuid().optional().nullable(),\n heartbeatRunId: z.string().uuid().optional().nullable(),\n costEventId: z.string().uuid().optional().nullable(),\n billingCode: z.string().optional().nullable(),\n description: z.string().max(500).optional().nullable(),\n eventKind: z.enum(FINANCE_EVENT_KINDS),\n direction: z.enum(FINANCE_DIRECTIONS).optional().default(\"debit\"),\n biller: z.string().min(1),\n provider: z.string().min(1).optional().nullable(),\n executionAgentRuntimeType: z.enum(AGENT_RUNTIME_TYPES).optional().nullable(),\n pricingTier: z.string().min(1).optional().nullable(),\n region: z.string().min(1).optional().nullable(),\n model: z.string().min(1).optional().nullable(),\n quantity: z.number().int().nonnegative().optional().nullable(),\n unit: z.enum(FINANCE_UNITS).optional().nullable(),\n amountCents: z.number().int().nonnegative(),\n currency: z.string().length(3).optional().default(\"USD\"),\n estimated: z.boolean().optional().default(false),\n externalInvoiceId: z.string().optional().nullable(),\n metadataJson: z.record(z.string(), z.unknown()).optional().nullable(),\n occurredAt: z.string().datetime(),\n}).transform((value) => ({\n ...value,\n currency: value.currency.toUpperCase(),\n}));\n\nexport type CreateFinanceEvent = z.infer<typeof createFinanceEventSchema>;\n", "import { z } from \"zod\";\n\nexport const createAssetImageMetadataSchema = z.object({\n namespace: z\n .string()\n .trim()\n .min(1)\n .max(120)\n .regex(/^[a-zA-Z0-9/_-]+$/)\n .optional(),\n});\n\nexport type CreateAssetImageMetadata = z.infer<typeof createAssetImageMetadataSchema>;\n\n", "import { z } from \"zod\";\nimport {\n AGENT_RUNTIME_TYPES,\n INVITE_JOIN_TYPES,\n JOIN_REQUEST_STATUSES,\n JOIN_REQUEST_TYPES,\n PERMISSION_KEYS,\n} from \"../constants.js\";\n\nexport const createCompanyInviteSchema = z.object({\n allowedJoinTypes: z.enum(INVITE_JOIN_TYPES).default(\"both\"),\n defaultsPayload: z.record(z.string(), z.unknown()).optional().nullable(),\n agentMessage: z.string().max(4000).optional().nullable(),\n});\n\nexport type CreateCompanyInvite = z.infer<typeof createCompanyInviteSchema>;\n\nexport const createOpenClawInvitePromptSchema = z.object({\n agentMessage: z.string().max(4000).optional().nullable(),\n});\n\nexport type CreateOpenClawInvitePrompt = z.infer<\n typeof createOpenClawInvitePromptSchema\n>;\n\nexport const acceptInviteSchema = z.object({\n requestType: z.enum(JOIN_REQUEST_TYPES),\n agentName: z.string().min(1).max(120).optional(),\n agentRuntimeType: z.enum(AGENT_RUNTIME_TYPES).optional(),\n capabilities: z.string().max(4000).optional().nullable(),\n agentDefaultsPayload: z.record(z.string(), z.unknown()).optional().nullable(),\n // OpenClaw join compatibility fields accepted at top level.\n responsesWebhookUrl: z.string().max(4000).optional().nullable(),\n responsesWebhookMethod: z.string().max(32).optional().nullable(),\n responsesWebhookHeaders: z.record(z.string(), z.unknown()).optional().nullable(),\n rudderApiUrl: z.string().max(4000).optional().nullable(),\n webhookAuthHeader: z.string().max(4000).optional().nullable(),\n});\n\nexport type AcceptInvite = z.infer<typeof acceptInviteSchema>;\n\nexport const listJoinRequestsQuerySchema = z.object({\n status: z.enum(JOIN_REQUEST_STATUSES).optional(),\n requestType: z.enum(JOIN_REQUEST_TYPES).optional(),\n});\n\nexport type ListJoinRequestsQuery = z.infer<typeof listJoinRequestsQuerySchema>;\n\nexport const claimJoinRequestApiKeySchema = z.object({\n claimSecret: z.string().min(16).max(256),\n});\n\nexport type ClaimJoinRequestApiKey = z.infer<typeof claimJoinRequestApiKeySchema>;\n\nexport const boardCliAuthAccessLevelSchema = z.enum([\n \"board\",\n \"instance_admin_required\",\n]);\n\nexport type BoardCliAuthAccessLevel = z.infer<typeof boardCliAuthAccessLevelSchema>;\n\nexport const createCliAuthChallengeSchema = z.object({\n command: z.string().min(1).max(240),\n clientName: z.string().max(120).optional().nullable(),\n requestedAccess: boardCliAuthAccessLevelSchema.default(\"board\"),\n requestedCompanyId: z.string().uuid().optional().nullable(),\n});\n\nexport type CreateCliAuthChallenge = z.infer<typeof createCliAuthChallengeSchema>;\n\nexport const resolveCliAuthChallengeSchema = z.object({\n token: z.string().min(16).max(256),\n});\n\nexport type ResolveCliAuthChallenge = z.infer<typeof resolveCliAuthChallengeSchema>;\n\nexport const updateMemberPermissionsSchema = z.object({\n grants: z.array(\n z.object({\n permissionKey: z.enum(PERMISSION_KEYS),\n scope: z.record(z.string(), z.unknown()).optional().nullable(),\n }),\n ),\n});\n\nexport type UpdateMemberPermissions = z.infer<typeof updateMemberPermissionsSchema>;\n\nexport const updateUserCompanyAccessSchema = z.object({\n orgIds: z.array(z.string().uuid()).default([]),\n});\n\nexport type UpdateUserCompanyAccess = z.infer<typeof updateUserCompanyAccessSchema>;\n", "import { z } from \"zod\";\nimport {\n PLUGIN_STATUSES,\n PLUGIN_CATEGORIES,\n PLUGIN_CAPABILITIES,\n PLUGIN_UI_SLOT_TYPES,\n PLUGIN_UI_SLOT_ENTITY_TYPES,\n PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS,\n PLUGIN_LAUNCHER_PLACEMENT_ZONES,\n PLUGIN_LAUNCHER_ACTIONS,\n PLUGIN_LAUNCHER_BOUNDS,\n PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS,\n PLUGIN_STATE_SCOPE_KINDS,\n} from \"../constants.js\";\n\n// ---------------------------------------------------------------------------\n// JSON Schema placeholder \u2013 a permissive validator for JSON Schema objects\n// ---------------------------------------------------------------------------\n\n/**\n * Permissive validator for JSON Schema objects. Accepts any `Record<string, unknown>`\n * that contains at least a `type`, `$ref`, or composition keyword (`oneOf`/`anyOf`/`allOf`).\n * Empty objects are also accepted.\n *\n * Used to validate `instanceConfigSchema` and `parametersSchema` fields in the\n * plugin manifest without fully parsing JSON Schema.\n *\n * @see PLUGIN_SPEC.md \u00A710.1 \u2014 Manifest shape\n */\nexport const jsonSchemaSchema = z.record(z.unknown()).refine(\n (val) => {\n // Must have a \"type\" field if non-empty, or be a valid JSON Schema object\n if (Object.keys(val).length === 0) return true;\n return typeof val.type === \"string\" || val.$ref !== undefined || val.oneOf !== undefined || val.anyOf !== undefined || val.allOf !== undefined;\n },\n { message: \"Must be a valid JSON Schema object (requires at least a 'type', '$ref', or composition keyword)\" },\n);\n\n// ---------------------------------------------------------------------------\n// Manifest sub-type schemas\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a {@link PluginJobDeclaration} \u2014 a scheduled job declared in the\n * plugin manifest. Requires `jobKey` and `displayName`; `description` and\n * `schedule` (cron expression) are optional.\n *\n * @see PLUGIN_SPEC.md \u00A717 \u2014 Scheduled Jobs\n */\n/**\n * Validates a cron expression has exactly 5 whitespace-separated fields,\n * each containing only valid cron characters (digits, *, /, -, ,).\n *\n * Valid tokens per field: *, N, N-M, N/S, * /S, N-M/S, and comma-separated lists.\n */\nconst CRON_FIELD_PATTERN = /^(\\*(?:\\/[0-9]+)?|[0-9]+(?:-[0-9]+)?(?:\\/[0-9]+)?)(?:,(\\*(?:\\/[0-9]+)?|[0-9]+(?:-[0-9]+)?(?:\\/[0-9]+)?))*$/;\n\nfunction isValidCronExpression(expression: string): boolean {\n const trimmed = expression.trim();\n if (!trimmed) return false;\n const fields = trimmed.split(/\\s+/);\n if (fields.length !== 5) return false;\n return fields.every((f) => CRON_FIELD_PATTERN.test(f));\n}\n\nexport const pluginJobDeclarationSchema = z.object({\n jobKey: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().optional(),\n schedule: z.string().refine(\n (val) => isValidCronExpression(val),\n { message: \"schedule must be a valid 5-field cron expression (e.g. '*/15 * * * *')\" },\n ).optional(),\n});\n\nexport type PluginJobDeclarationInput = z.infer<typeof pluginJobDeclarationSchema>;\n\n/**\n * Validates a {@link PluginWebhookDeclaration} \u2014 a webhook endpoint declared\n * in the plugin manifest. Requires `endpointKey` and `displayName`.\n *\n * @see PLUGIN_SPEC.md \u00A718 \u2014 Webhooks\n */\nexport const pluginWebhookDeclarationSchema = z.object({\n endpointKey: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().optional(),\n});\n\nexport type PluginWebhookDeclarationInput = z.infer<typeof pluginWebhookDeclarationSchema>;\n\n/**\n * Validates a {@link PluginToolDeclaration} \u2014 an agent tool contributed by the\n * plugin. Requires `name`, `displayName`, `description`, and a valid\n * `parametersSchema`. Requires the `agent.tools.register` capability.\n *\n * @see PLUGIN_SPEC.md \u00A711 \u2014 Agent Tools\n */\nexport const pluginToolDeclarationSchema = z.object({\n name: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().min(1),\n parametersSchema: jsonSchemaSchema,\n});\n\nexport type PluginToolDeclarationInput = z.infer<typeof pluginToolDeclarationSchema>;\n\n/**\n * Validates a {@link PluginUiSlotDeclaration} \u2014 a UI extension slot the plugin\n * fills with a React component. Includes `superRefine` checks for slot-specific\n * requirements such as `entityTypes` for context-sensitive slots.\n *\n * @see PLUGIN_SPEC.md \u00A719 \u2014 UI Extension Model\n */\nexport const pluginUiSlotDeclarationSchema = z.object({\n type: z.enum(PLUGIN_UI_SLOT_TYPES),\n id: z.string().min(1),\n displayName: z.string().min(1),\n exportName: z.string().min(1),\n entityTypes: z.array(z.enum(PLUGIN_UI_SLOT_ENTITY_TYPES)).optional(),\n routePath: z.string().regex(/^[a-z0-9][a-z0-9-]*$/, {\n message: \"routePath must be a lowercase single-segment slug (letters, numbers, hyphens)\",\n }).optional(),\n order: z.number().int().optional(),\n}).superRefine((value, ctx) => {\n // context-sensitive slots require explicit entity targeting.\n const entityScopedTypes = [\"detailTab\", \"taskDetailView\", \"contextMenuItem\", \"commentAnnotation\", \"commentContextMenuItem\", \"projectSidebarItem\"];\n if (\n entityScopedTypes.includes(value.type)\n && (!value.entityTypes || value.entityTypes.length === 0)\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `${value.type} slots require at least one entityType`,\n path: [\"entityTypes\"],\n });\n }\n // projectSidebarItem only makes sense for entityType \"project\".\n if (value.type === \"projectSidebarItem\" && value.entityTypes && !value.entityTypes.includes(\"project\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"projectSidebarItem slots require entityTypes to include \\\"project\\\"\",\n path: [\"entityTypes\"],\n });\n }\n // commentAnnotation only makes sense for entityType \"comment\".\n if (value.type === \"commentAnnotation\" && value.entityTypes && !value.entityTypes.includes(\"comment\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"commentAnnotation slots require entityTypes to include \\\"comment\\\"\",\n path: [\"entityTypes\"],\n });\n }\n // commentContextMenuItem only makes sense for entityType \"comment\".\n if (value.type === \"commentContextMenuItem\" && value.entityTypes && !value.entityTypes.includes(\"comment\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"commentContextMenuItem slots require entityTypes to include \\\"comment\\\"\",\n path: [\"entityTypes\"],\n });\n }\n if (value.routePath && value.type !== \"page\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"routePath is only supported for page slots\",\n path: [\"routePath\"],\n });\n }\n if (value.routePath && PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS.includes(value.routePath as (typeof PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS)[number])) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `routePath \"${value.routePath}\" is reserved by the host`,\n path: [\"routePath\"],\n });\n }\n});\n\nexport type PluginUiSlotDeclarationInput = z.infer<typeof pluginUiSlotDeclarationSchema>;\n\nconst entityScopedLauncherPlacementZones = [\n \"detailTab\",\n \"taskDetailView\",\n \"contextMenuItem\",\n \"commentAnnotation\",\n \"commentContextMenuItem\",\n \"projectSidebarItem\",\n] as const;\n\nconst launcherBoundsByEnvironment: Record<\n (typeof PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS)[number],\n readonly (typeof PLUGIN_LAUNCHER_BOUNDS)[number][]\n> = {\n hostInline: [\"inline\", \"compact\", \"default\"],\n hostOverlay: [\"compact\", \"default\", \"wide\", \"full\"],\n hostRoute: [\"default\", \"wide\", \"full\"],\n external: [],\n iframe: [\"compact\", \"default\", \"wide\", \"full\"],\n};\n\n/**\n * Validates the action payload for a declarative plugin launcher.\n */\nexport const pluginLauncherActionDeclarationSchema = z.object({\n type: z.enum(PLUGIN_LAUNCHER_ACTIONS),\n target: z.string().min(1),\n params: z.record(z.unknown()).optional(),\n}).superRefine((value, ctx) => {\n if (value.type === \"performAction\" && value.target.includes(\"/\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"performAction launchers must target an action key, not a route or URL\",\n path: [\"target\"],\n });\n }\n\n if (value.type === \"navigate\" && /^https?:\\/\\//.test(value.target)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"navigate launchers must target a host route, not an absolute URL\",\n path: [\"target\"],\n });\n }\n});\n\nexport type PluginLauncherActionDeclarationInput =\n z.infer<typeof pluginLauncherActionDeclarationSchema>;\n\n/**\n * Validates optional render hints for a plugin launcher destination.\n */\nexport const pluginLauncherRenderDeclarationSchema = z.object({\n environment: z.enum(PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS),\n bounds: z.enum(PLUGIN_LAUNCHER_BOUNDS).optional(),\n}).superRefine((value, ctx) => {\n if (!value.bounds) {\n return;\n }\n\n const supportedBounds = launcherBoundsByEnvironment[value.environment];\n if (!supportedBounds.includes(value.bounds)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `bounds \"${value.bounds}\" is not supported for render environment \"${value.environment}\"`,\n path: [\"bounds\"],\n });\n }\n});\n\nexport type PluginLauncherRenderDeclarationInput =\n z.infer<typeof pluginLauncherRenderDeclarationSchema>;\n\n/**\n * Validates declarative launcher metadata in a plugin manifest.\n */\nexport const pluginLauncherDeclarationSchema = z.object({\n id: z.string().min(1),\n displayName: z.string().min(1),\n description: z.string().optional(),\n placementZone: z.enum(PLUGIN_LAUNCHER_PLACEMENT_ZONES),\n exportName: z.string().min(1).optional(),\n entityTypes: z.array(z.enum(PLUGIN_UI_SLOT_ENTITY_TYPES)).optional(),\n order: z.number().int().optional(),\n action: pluginLauncherActionDeclarationSchema,\n render: pluginLauncherRenderDeclarationSchema.optional(),\n}).superRefine((value, ctx) => {\n if (\n entityScopedLauncherPlacementZones.some((zone) => zone === value.placementZone)\n && (!value.entityTypes || value.entityTypes.length === 0)\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `${value.placementZone} launchers require at least one entityType`,\n path: [\"entityTypes\"],\n });\n }\n\n if (\n value.placementZone === \"projectSidebarItem\"\n && value.entityTypes\n && !value.entityTypes.includes(\"project\")\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"projectSidebarItem launchers require entityTypes to include \\\"project\\\"\",\n path: [\"entityTypes\"],\n });\n }\n\n if (value.action.type === \"performAction\" && value.render) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"performAction launchers cannot declare render hints\",\n path: [\"render\"],\n });\n }\n\n if (\n [\"openModal\", \"openDrawer\", \"openPopover\"].includes(value.action.type)\n && !value.render\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `${value.action.type} launchers require render metadata`,\n path: [\"render\"],\n });\n }\n\n if (value.action.type === \"openModal\" && value.render?.environment === \"hostInline\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"openModal launchers cannot use the hostInline render environment\",\n path: [\"render\", \"environment\"],\n });\n }\n\n if (\n value.action.type === \"openDrawer\"\n && value.render\n && ![\"hostOverlay\", \"iframe\"].includes(value.render.environment)\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"openDrawer launchers must use hostOverlay or iframe render environments\",\n path: [\"render\", \"environment\"],\n });\n }\n\n if (value.action.type === \"openPopover\" && value.render?.environment === \"hostRoute\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"openPopover launchers cannot use the hostRoute render environment\",\n path: [\"render\", \"environment\"],\n });\n }\n});\n\nexport type PluginLauncherDeclarationInput = z.infer<typeof pluginLauncherDeclarationSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin Manifest V1 schema\n// ---------------------------------------------------------------------------\n\n/**\n * Zod schema for {@link PaperclipPluginManifestV1} \u2014 the complete runtime\n * validator for plugin manifests read at install time.\n *\n * Field-level constraints (see PLUGIN_SPEC.md \u00A710.1 for the normative rules):\n *\n * | Field | Type | Constraints |\n * |--------------------------|------------|----------------------------------------------|\n * | `id` | string | `^[a-z0-9][a-z0-9._-]*$` |\n * | `apiVersion` | literal 1 | must equal `PLUGIN_API_VERSION` |\n * | `version` | string | semver (`\\d+\\.\\d+\\.\\d+`) |\n * | `displayName` | string | 1\u2013100 chars |\n * | `description` | string | 1\u2013500 chars |\n * | `author` | string | 1\u2013200 chars |\n * | `categories` | enum[] | at least one; values from PLUGIN_CATEGORIES |\n * | `minimumHostVersion` | string? | semver lower bound if present, no leading `v`|\n * | `minimumPaperclipVersion`| string? | legacy alias of `minimumHostVersion` |\n * | `capabilities` | enum[] | at least one; values from PLUGIN_CAPABILITIES|\n * | `entrypoints.worker` | string | min 1 char |\n * | `entrypoints.ui` | string? | required when `ui.slots` is declared |\n *\n * Cross-field rules enforced via `superRefine`:\n * - `entrypoints.ui` required when `ui.slots` declared\n * - `agent.tools.register` capability required when `tools` declared\n * - `jobs.schedule` capability required when `jobs` declared\n * - `webhooks.receive` capability required when `webhooks` declared\n * - duplicate `jobs[].jobKey` values are rejected\n * - duplicate `webhooks[].endpointKey` values are rejected\n * - duplicate `tools[].name` values are rejected\n * - duplicate `ui.slots[].id` values are rejected\n *\n * @see PLUGIN_SPEC.md \u00A710.1 \u2014 Manifest shape\n * @see {@link PaperclipPluginManifestV1} \u2014 the inferred TypeScript type\n */\nexport const pluginManifestV1Schema = z.object({\n id: z.string().min(1).regex(\n /^[a-z0-9][a-z0-9._-]*$/,\n \"Plugin id must start with a lowercase alphanumeric and contain only lowercase letters, digits, dots, hyphens, or underscores\",\n ),\n apiVersion: z.literal(1),\n version: z.string().min(1).regex(\n /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$/,\n \"Version must follow semver (e.g. 1.0.0 or 1.0.0-beta.1)\",\n ),\n displayName: z.string().min(1).max(100),\n description: z.string().min(1).max(500),\n author: z.string().min(1).max(200),\n categories: z.array(z.enum(PLUGIN_CATEGORIES)).min(1),\n minimumHostVersion: z.string().regex(\n /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$/,\n \"minimumHostVersion must follow semver (e.g. 1.0.0)\",\n ).optional(),\n minimumPaperclipVersion: z.string().regex(\n /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$/,\n \"minimumPaperclipVersion must follow semver (e.g. 1.0.0)\",\n ).optional(),\n capabilities: z.array(z.enum(PLUGIN_CAPABILITIES)).min(1),\n entrypoints: z.object({\n worker: z.string().min(1),\n ui: z.string().min(1).optional(),\n }),\n instanceConfigSchema: jsonSchemaSchema.optional(),\n jobs: z.array(pluginJobDeclarationSchema).optional(),\n webhooks: z.array(pluginWebhookDeclarationSchema).optional(),\n tools: z.array(pluginToolDeclarationSchema).optional(),\n launchers: z.array(pluginLauncherDeclarationSchema).optional(),\n ui: z.object({\n slots: z.array(pluginUiSlotDeclarationSchema).min(1).optional(),\n launchers: z.array(pluginLauncherDeclarationSchema).optional(),\n }).optional(),\n}).superRefine((manifest, ctx) => {\n // \u2500\u2500 Entrypoint \u2194 UI slot consistency \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Plugins that declare UI slots must also declare a UI entrypoint so the\n // host knows where to load the bundle from (PLUGIN_SPEC.md \u00A710.1).\n const hasUiSlots = (manifest.ui?.slots?.length ?? 0) > 0;\n const hasUiLaunchers = (manifest.ui?.launchers?.length ?? 0) > 0;\n if ((hasUiSlots || hasUiLaunchers) && !manifest.entrypoints.ui) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"entrypoints.ui is required when ui.slots or ui.launchers are declared\",\n path: [\"entrypoints\", \"ui\"],\n });\n }\n\n if (\n manifest.minimumHostVersion\n && manifest.minimumPaperclipVersion\n && manifest.minimumHostVersion !== manifest.minimumPaperclipVersion\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"minimumHostVersion and minimumPaperclipVersion must match when both are declared\",\n path: [\"minimumHostVersion\"],\n });\n }\n\n // \u2500\u2500 Capability \u2194 feature declaration consistency \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The host enforces capabilities at install and runtime. A plugin must\n // declare every capability it needs up-front; silently having more features\n // than capabilities would cause runtime rejections.\n\n // tools require agent.tools.register (PLUGIN_SPEC.md \u00A711)\n if (manifest.tools && manifest.tools.length > 0) {\n if (!manifest.capabilities.includes(\"agent.tools.register\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Capability 'agent.tools.register' is required when tools are declared\",\n path: [\"capabilities\"],\n });\n }\n }\n\n // jobs require jobs.schedule (PLUGIN_SPEC.md \u00A717)\n if (manifest.jobs && manifest.jobs.length > 0) {\n if (!manifest.capabilities.includes(\"jobs.schedule\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Capability 'jobs.schedule' is required when jobs are declared\",\n path: [\"capabilities\"],\n });\n }\n }\n\n // webhooks require webhooks.receive (PLUGIN_SPEC.md \u00A718)\n if (manifest.webhooks && manifest.webhooks.length > 0) {\n if (!manifest.capabilities.includes(\"webhooks.receive\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Capability 'webhooks.receive' is required when webhooks are declared\",\n path: [\"capabilities\"],\n });\n }\n }\n\n // \u2500\u2500 Uniqueness checks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Duplicate keys within a plugin's own manifest are always a bug. The host\n // would not know which declaration takes precedence, so we reject early.\n\n // job keys must be unique within the plugin (used as identifiers in the DB)\n if (manifest.jobs) {\n const jobKeys = manifest.jobs.map((j) => j.jobKey);\n const duplicates = jobKeys.filter((key, i) => jobKeys.indexOf(key) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate job keys: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"jobs\"],\n });\n }\n }\n\n // webhook endpoint keys must be unique within the plugin (used in routes)\n if (manifest.webhooks) {\n const endpointKeys = manifest.webhooks.map((w) => w.endpointKey);\n const duplicates = endpointKeys.filter((key, i) => endpointKeys.indexOf(key) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate webhook endpoint keys: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"webhooks\"],\n });\n }\n }\n\n // tool names must be unique within the plugin (namespaced at runtime)\n if (manifest.tools) {\n const toolNames = manifest.tools.map((t) => t.name);\n const duplicates = toolNames.filter((name, i) => toolNames.indexOf(name) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate tool names: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"tools\"],\n });\n }\n }\n\n // UI slot ids must be unique within the plugin (namespaced at runtime)\n if (manifest.ui) {\n if (manifest.ui.slots) {\n const slotIds = manifest.ui.slots.map((s) => s.id);\n const duplicates = slotIds.filter((id, i) => slotIds.indexOf(id) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate UI slot ids: ${[...new Set(duplicates)].join(\", \")}`,\n path: [\"ui\", \"slots\"],\n });\n }\n }\n }\n\n // launcher ids must be unique within the plugin\n const allLaunchers = [\n ...(manifest.launchers ?? []),\n ...(manifest.ui?.launchers ?? []),\n ];\n if (allLaunchers.length > 0) {\n const launcherIds = allLaunchers.map((launcher) => launcher.id);\n const duplicates = launcherIds.filter((id, i) => launcherIds.indexOf(id) !== i);\n if (duplicates.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate launcher ids: ${[...new Set(duplicates)].join(\", \")}`,\n path: manifest.ui?.launchers ? [\"ui\", \"launchers\"] : [\"launchers\"],\n });\n }\n }\n});\n\nexport type PluginManifestV1Input = z.infer<typeof pluginManifestV1Schema>;\n\n// ---------------------------------------------------------------------------\n// Plugin installation / registration request\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for installing (registering) a plugin.\n * The server receives the packageName and resolves the manifest from the\n * installed package.\n */\nexport const installPluginSchema = z.object({\n packageName: z.string().min(1),\n version: z.string().min(1).optional(),\n /** Set by loader for local-path installs so the worker can be resolved. */\n packagePath: z.string().min(1).optional(),\n});\n\nexport type InstallPlugin = z.infer<typeof installPluginSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin config (instance configuration) schemas\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for creating or updating a plugin's instance configuration.\n * configJson is validated permissively here; runtime validation against\n * the plugin's instanceConfigSchema is done at the service layer.\n */\nexport const upsertPluginConfigSchema = z.object({\n configJson: z.record(z.unknown()),\n});\n\nexport type UpsertPluginConfig = z.infer<typeof upsertPluginConfigSchema>;\n\n/**\n * Schema for partially updating a plugin's instance configuration.\n * Allows a partial merge of config values.\n */\nexport const patchPluginConfigSchema = z.object({\n configJson: z.record(z.unknown()),\n});\n\nexport type PatchPluginConfig = z.infer<typeof patchPluginConfigSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin status update\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for updating a plugin's lifecycle status. Used by the lifecycle\n * manager to persist state transitions.\n *\n * @see {@link PLUGIN_STATUSES} for the valid status values\n */\nexport const updatePluginStatusSchema = z.object({\n status: z.enum(PLUGIN_STATUSES),\n lastError: z.string().nullable().optional(),\n});\n\nexport type UpdatePluginStatus = z.infer<typeof updatePluginStatusSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin uninstall\n// ---------------------------------------------------------------------------\n\n/** Schema for the uninstall request. `removeData` controls hard vs soft delete. */\nexport const uninstallPluginSchema = z.object({\n removeData: z.boolean().optional().default(false),\n});\n\nexport type UninstallPlugin = z.infer<typeof uninstallPluginSchema>;\n\n// ---------------------------------------------------------------------------\n// Plugin state (key-value storage) schemas\n// ---------------------------------------------------------------------------\n\n/**\n * Schema for a plugin state scope key \u2014 identifies the exact location where\n * state is stored. Used by the `ctx.state.get()`, `ctx.state.set()`, and\n * `ctx.state.delete()` SDK methods.\n *\n * @see PLUGIN_SPEC.md \u00A721.3 `plugin_state`\n */\nexport const pluginStateScopeKeySchema = z.object({\n scopeKind: z.enum(PLUGIN_STATE_SCOPE_KINDS),\n scopeId: z.string().min(1).optional(),\n namespace: z.string().min(1).optional(),\n stateKey: z.string().min(1),\n});\n\nexport type PluginStateScopeKey = z.infer<typeof pluginStateScopeKeySchema>;\n\n/**\n * Schema for setting a plugin state value.\n */\nexport const setPluginStateSchema = z.object({\n scopeKind: z.enum(PLUGIN_STATE_SCOPE_KINDS),\n scopeId: z.string().min(1).optional(),\n namespace: z.string().min(1).optional(),\n stateKey: z.string().min(1),\n /** JSON-serializable value to store. */\n value: z.unknown(),\n});\n\nexport type SetPluginState = z.infer<typeof setPluginStateSchema>;\n\n/**\n * Schema for querying plugin state entries. All fields are optional to allow\n * flexible list queries (e.g. all state for a plugin within a scope).\n */\nexport const listPluginStateSchema = z.object({\n scopeKind: z.enum(PLUGIN_STATE_SCOPE_KINDS).optional(),\n scopeId: z.string().min(1).optional(),\n namespace: z.string().min(1).optional(),\n});\n\nexport type ListPluginState = z.infer<typeof listPluginStateSchema>;\n", "export {\n instanceLocaleSchema,\n type InstanceLocale,\n instanceGeneralSettingsSchema,\n patchInstanceGeneralSettingsSchema,\n type InstanceGeneralSettings,\n type PatchInstanceGeneralSettings,\n instanceNotificationSettingsSchema,\n patchInstanceNotificationSettingsSchema,\n type InstanceNotificationSettings,\n type PatchInstanceNotificationSettings,\n instanceLangfuseSettingsSchema,\n patchInstanceLangfuseSettingsSchema,\n type InstanceLangfuseSettings,\n type PatchInstanceLangfuseSettings,\n OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH,\n operatorProfileSettingsSchema,\n patchOperatorProfileSettingsSchema,\n type OperatorProfileSettings,\n type PatchOperatorProfileSettings,\n instancePathPickerSelectionTypeSchema,\n instancePathPickerRequestSchema,\n instancePathPickerResultSchema,\n type InstancePathPickerSelectionType,\n type InstancePathPickerRequest,\n type InstancePathPickerResult,\n} from \"./instance.js\";\n\nexport {\n upsertBudgetPolicySchema,\n resolveBudgetIncidentSchema,\n type UpsertBudgetPolicy,\n type ResolveBudgetIncident,\n} from \"./budget.js\";\n\nexport {\n createOrganizationSchema,\n updateOrganizationSchema,\n updateOrganizationBrandingSchema,\n updateOrganizationWorkspaceFileSchema,\n type CreateOrganization,\n type UpdateOrganization,\n type UpdateOrganizationBranding,\n type UpdateOrganizationWorkspaceFile,\n} from \"./organization.js\";\nexport {\n organizationResourceKindSchema,\n projectResourceAttachmentRoleSchema,\n createOrganizationResourceSchema,\n updateOrganizationResourceSchema,\n projectResourceAttachmentInputSchema,\n updateProjectResourceAttachmentSchema,\n createProjectInlineResourceSchema,\n type CreateOrganizationResource,\n type UpdateOrganizationResource,\n type ProjectResourceAttachmentInputPayload,\n type UpdateProjectResourceAttachment,\n type CreateProjectInlineResource,\n} from \"./resource.js\";\nexport {\n chatConversationStatusSchema,\n chatIssueCreationModeSchema,\n chatMessageRoleSchema,\n chatMessageKindSchema,\n chatContextEntityTypeSchema,\n createChatContextLinkSchema,\n createChatConversationSchema,\n setChatProjectContextSchema,\n updateChatConversationSchema,\n updateChatConversationUserStateSchema,\n addChatMessageSchema,\n chatAskUserOptionSchema,\n chatAskUserQuestionSchema,\n chatAskUserRequestSchema,\n chatAskUserRequestFromStructuredPayload,\n chatRichReferenceSchema,\n chatRichReferencesSchema,\n chatRichReferencesFromStructuredPayload,\n sanitizeChatStructuredPayload,\n createChatAttachmentMetadataSchema,\n convertChatToIssueSchema,\n chatOperationProposalSchema,\n resolveChatOperationProposalSchema,\n type CreateChatContextLink,\n type CreateChatConversation,\n type SetChatProjectContext,\n type UpdateChatConversation,\n type UpdateChatConversationUserState,\n type AddChatMessage,\n type ChatAskUserOption,\n type ChatAskUserQuestion,\n type ChatAskUserRequest,\n type ChatRichReference,\n type CreateChatAttachmentMetadata,\n type ConvertChatToIssue,\n type ChatOperationProposal,\n type ResolveChatOperationProposal,\n} from \"./chat.js\";\nexport {\n organizationSkillSourceTypeSchema,\n organizationSkillTrustLevelSchema,\n organizationSkillCompatibilitySchema,\n organizationSkillSourceBadgeSchema,\n organizationSkillFileInventoryEntrySchema,\n organizationSkillSchema,\n organizationSkillListItemSchema,\n organizationSkillUsageAgentSchema,\n organizationSkillDetailSchema,\n organizationSkillUpdateStatusSchema,\n organizationSkillImportSchema,\n organizationSkillProjectScanRequestSchema,\n organizationSkillProjectScanSkippedSchema,\n organizationSkillProjectScanConflictSchema,\n organizationSkillProjectScanResultSchema,\n organizationSkillLocalScanRequestSchema,\n organizationSkillLocalScanSkippedSchema,\n organizationSkillLocalScanConflictSchema,\n organizationSkillLocalScanResultSchema,\n organizationSkillCreateSchema,\n organizationSkillFileDetailSchema,\n organizationSkillFileUpdateSchema,\n type OrganizationSkillImport,\n type OrganizationSkillProjectScan,\n type OrganizationSkillLocalScan,\n type OrganizationSkillCreate,\n type OrganizationSkillFileUpdate,\n} from \"./organization-skill.js\";\nexport {\n agentSkillStateSchema,\n agentSkillOriginSchema,\n agentSkillSourceClassSchema,\n agentSkillSyncModeSchema,\n agentSkillEntrySchema,\n agentSkillSnapshotSchema,\n agentSkillSyncSchema,\n agentSkillEnableSchema,\n type AgentSkillSync,\n type AgentSkillEnable,\n} from \"./adapter-skills.js\";\nexport {\n portabilityIncludeSchema,\n portabilityEnvInputSchema,\n portabilityOrganizationManifestEntrySchema,\n portabilitySidebarOrderSchema,\n portabilityAgentManifestEntrySchema,\n portabilitySkillManifestEntrySchema,\n portabilityManifestSchema,\n portabilitySourceSchema,\n portabilityTargetSchema,\n portabilityAgentSelectionSchema,\n portabilityCollisionStrategySchema,\n organizationPortabilityExportSchema,\n organizationPortabilityPreviewSchema,\n organizationPortabilityImportSchema,\n type OrganizationPortabilityExport,\n type OrganizationPortabilityPreview,\n type OrganizationPortabilityImport,\n} from \"./organization-portability.js\";\n\nexport {\n agentIconSchema,\n customAgentIconSchema,\n createAgentSchema,\n createAgentHireSchema,\n updateAgentSchema,\n uploadedAgentIconSchema,\n agentInstructionsBundleModeSchema,\n updateAgentInstructionsBundleSchema,\n upsertAgentInstructionsFileSchema,\n updateAgentInstructionsPathSchema,\n createAgentKeySchema,\n wakeAgentSchema,\n resetAgentSessionSchema,\n testAgentRuntimeEnvironmentSchema,\n agentPermissionsSchema,\n updateAgentPermissionsSchema,\n type CreateAgent,\n type CreateAgentHire,\n type UpdateAgent,\n type UpdateAgentInstructionsBundle,\n type UpsertAgentInstructionsFile,\n type UpdateAgentInstructionsPath,\n type CreateAgentKey,\n type WakeAgent,\n type ResetAgentSession,\n type TestAgentRuntimeEnvironment,\n type UpdateAgentPermissions,\n} from \"./agent.js\";\n\nexport {\n createProjectSchema,\n updateProjectSchema,\n projectExecutionWorkspacePolicySchema,\n type CreateProject,\n type UpdateProject,\n type ProjectExecutionWorkspacePolicy,\n} from \"./project.js\";\n\nexport {\n createIssueSchema,\n createIssueLabelSchema,\n updateIssueLabelSchema,\n updateIssueSchema,\n reorderIssueSchema,\n issueExecutionWorkspaceSettingsSchema,\n checkoutIssueSchema,\n addIssueCommentSchema,\n reportIssueCommitSchema,\n linkIssueApprovalSchema,\n createIssueAttachmentMetadataSchema,\n createIssueWorkspaceAttachmentSchema,\n issueDocumentFormatSchema,\n issueDocumentKeySchema,\n upsertIssueDocumentSchema,\n type CreateIssue,\n type CreateIssueLabel,\n type UpdateIssueLabel,\n type UpdateIssue,\n type ReorderIssue,\n type IssueExecutionWorkspaceSettings,\n type CheckoutIssue,\n type AddIssueComment,\n type ReportIssueCommit,\n type LinkIssueApproval,\n type CreateIssueAttachmentMetadata,\n type CreateIssueWorkspaceAttachment,\n type IssueDocumentFormat,\n type UpsertIssueDocument,\n} from \"./issue.js\";\n\nexport {\n createIssueWorkProductSchema,\n updateIssueWorkProductSchema,\n issueWorkProductTypeSchema,\n issueWorkProductStatusSchema,\n issueWorkProductReviewStateSchema,\n type CreateIssueWorkProduct,\n type UpdateIssueWorkProduct,\n} from \"./work-product.js\";\n\nexport {\n updateExecutionWorkspaceSchema,\n executionWorkspaceStatusSchema,\n type UpdateExecutionWorkspace,\n} from \"./execution-workspace.js\";\n\nexport {\n workspaceBackupTriggerSourceSchema,\n createWorkspaceBackupSchema,\n restoreWorkspaceBackupSchema,\n type CreateWorkspaceBackup,\n type RestoreWorkspaceBackup,\n} from \"./workspace-backup.js\";\n\nexport {\n createGoalSchema,\n updateGoalSchema,\n type CreateGoal,\n type UpdateGoal,\n} from \"./goal.js\";\n\nexport {\n createApprovalSchema,\n resolveApprovalSchema,\n requestApprovalRevisionSchema,\n resubmitApprovalSchema,\n addApprovalCommentSchema,\n type CreateApproval,\n type ResolveApproval,\n type RequestApprovalRevision,\n type ResubmitApproval,\n type AddApprovalComment,\n} from \"./approval.js\";\n\nexport {\n envBindingPlainSchema,\n envBindingSecretRefSchema,\n envBindingSchema,\n envConfigSchema,\n createSecretSchema,\n rotateSecretSchema,\n updateSecretSchema,\n type CreateSecret,\n type RotateSecret,\n type UpdateSecret,\n} from \"./secret.js\";\n\nexport {\n createAutomationSchema,\n updateAutomationSchema,\n createAutomationTriggerSchema,\n updateAutomationTriggerSchema,\n runAutomationSchema,\n rotateAutomationTriggerSecretSchema,\n type CreateAutomation,\n type UpdateAutomation,\n type CreateAutomationTrigger,\n type UpdateAutomationTrigger,\n type RunAutomation,\n type RotateAutomationTriggerSecret,\n} from \"./automation.js\";\n\nexport {\n createCalendarSourceSchema,\n updateCalendarSourceSchema,\n createCalendarEventSchema,\n updateCalendarEventSchema,\n calendarEventListQuerySchema,\n googleCalendarSyncSchema,\n updateGoogleCalendarOAuthConfigSchema,\n type CreateCalendarSource,\n type UpdateCalendarSource,\n type CreateCalendarEvent,\n type UpdateCalendarEvent,\n type CalendarEventListQuery,\n type GoogleCalendarSync,\n type UpdateGoogleCalendarOAuthConfig,\n} from \"./calendar.js\";\n\nexport {\n createCostEventSchema,\n updateBudgetSchema,\n type CreateCostEvent,\n type UpdateBudget,\n} from \"./cost.js\";\n\nexport {\n createFinanceEventSchema,\n type CreateFinanceEvent,\n} from \"./finance.js\";\n\nexport {\n createAssetImageMetadataSchema,\n type CreateAssetImageMetadata,\n} from \"./asset.js\";\n\nexport {\n createCompanyInviteSchema,\n createOpenClawInvitePromptSchema,\n acceptInviteSchema,\n listJoinRequestsQuerySchema,\n claimJoinRequestApiKeySchema,\n boardCliAuthAccessLevelSchema,\n createCliAuthChallengeSchema,\n resolveCliAuthChallengeSchema,\n updateMemberPermissionsSchema,\n updateUserCompanyAccessSchema,\n type CreateCompanyInvite,\n type CreateOpenClawInvitePrompt,\n type AcceptInvite,\n type ListJoinRequestsQuery,\n type ClaimJoinRequestApiKey,\n type BoardCliAuthAccessLevel,\n type CreateCliAuthChallenge,\n type ResolveCliAuthChallenge,\n type UpdateMemberPermissions,\n type UpdateUserCompanyAccess,\n} from \"./access.js\";\n\nexport {\n jsonSchemaSchema,\n pluginJobDeclarationSchema,\n pluginWebhookDeclarationSchema,\n pluginToolDeclarationSchema,\n pluginUiSlotDeclarationSchema,\n pluginLauncherActionDeclarationSchema,\n pluginLauncherRenderDeclarationSchema,\n pluginLauncherDeclarationSchema,\n pluginManifestV1Schema,\n installPluginSchema,\n upsertPluginConfigSchema,\n patchPluginConfigSchema,\n updatePluginStatusSchema,\n uninstallPluginSchema,\n pluginStateScopeKeySchema,\n setPluginStateSchema,\n listPluginStateSchema,\n type PluginJobDeclarationInput,\n type PluginWebhookDeclarationInput,\n type PluginToolDeclarationInput,\n type PluginUiSlotDeclarationInput,\n type PluginLauncherActionDeclarationInput,\n type PluginLauncherRenderDeclarationInput,\n type PluginLauncherDeclarationInput,\n type PluginManifestV1Input,\n type InstallPlugin,\n type UpsertPluginConfig,\n type PatchPluginConfig,\n type UpdatePluginStatus,\n type UninstallPlugin,\n type PluginStateScopeKey,\n type SetPluginState,\n type ListPluginState,\n} from \"./plugin.js\";\n", "export const API_PREFIX = \"/api\";\n\nexport const API = {\n health: `${API_PREFIX}/health`,\n organizations: `${API_PREFIX}/orgs`,\n agents: `${API_PREFIX}/agents`,\n projects: `${API_PREFIX}/projects`,\n issues: `${API_PREFIX}/issues`,\n chats: `${API_PREFIX}/chats`,\n messenger: `${API_PREFIX}/messenger`,\n calendar: `${API_PREFIX}/calendar`,\n goals: `${API_PREFIX}/goals`,\n approvals: `${API_PREFIX}/approvals`,\n secrets: `${API_PREFIX}/secrets`,\n costs: `${API_PREFIX}/costs`,\n activity: `${API_PREFIX}/activity`,\n dashboard: `${API_PREFIX}/dashboard`,\n sidebarBadges: `${API_PREFIX}/sidebar-badges`,\n invites: `${API_PREFIX}/invites`,\n joinRequests: `${API_PREFIX}/join-requests`,\n members: `${API_PREFIX}/members`,\n admin: `${API_PREFIX}/admin`,\n} as const;\n", "const AGENT_URL_KEY_DELIM_RE = /[^a-z0-9]+/g;\nconst AGENT_URL_KEY_TRIM_RE = /^-+|-+$/g;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport function isUuidLike(value: string | null | undefined): boolean {\n if (typeof value !== \"string\") return false;\n return UUID_RE.test(value.trim());\n}\n\nexport function normalizeAgentUrlKey(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(AGENT_URL_KEY_DELIM_RE, \"-\")\n .replace(AGENT_URL_KEY_TRIM_RE, \"\");\n return normalized.length > 0 ? normalized : null;\n}\n\nexport function deriveAgentUrlKey(name: string | null | undefined, fallback?: string | null): string {\n return normalizeAgentUrlKey(name) ?? normalizeAgentUrlKey(fallback) ?? \"agent\";\n}\n", "const ORGANIZATION_URL_KEY_DELIM_RE = /[^a-z0-9]+/g;\nconst ORGANIZATION_URL_KEY_TRIM_RE = /^-+|-+$/g;\n\nexport function normalizeOrganizationUrlKey(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(ORGANIZATION_URL_KEY_DELIM_RE, \"-\")\n .replace(ORGANIZATION_URL_KEY_TRIM_RE, \"\");\n return normalized.length > 0 ? normalized : null;\n}\n\nexport function deriveOrganizationUrlKey(name: string | null | undefined, fallback?: string | null): string {\n return normalizeOrganizationUrlKey(name) ?? normalizeOrganizationUrlKey(fallback) ?? \"organization\";\n}\n", "const PROJECT_URL_KEY_DELIM_RE = /[^a-z0-9]+/g;\nconst PROJECT_URL_KEY_TRIM_RE = /^-+|-+$/g;\n\nexport function normalizeProjectUrlKey(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(PROJECT_URL_KEY_DELIM_RE, \"-\")\n .replace(PROJECT_URL_KEY_TRIM_RE, \"\");\n return normalized.length > 0 ? normalized : null;\n}\n\nexport function deriveProjectUrlKey(name: string | null | undefined, fallback?: string | null): string {\n return normalizeProjectUrlKey(name) ?? normalizeProjectUrlKey(fallback) ?? \"project\";\n}\n", "export interface MessengerPreviewOptions {\n max?: number;\n}\n\nconst URL_PATTERN = /(?:https?:\\/\\/|www\\.)[^\\s<>()\\]]+/giu;\n\nconst NAMED_HTML_ENTITIES: Record<string, string> = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n nbsp: \" \",\n quot: '\"',\n};\n\nfunction truncateText(value: string, max: number) {\n if (value.length <= max) return value;\n return `${value.slice(0, Math.max(0, max - 1))}\u2026`;\n}\n\nfunction decodeHtmlEntities(value: string) {\n return value\n .replace(/&#x([\\da-f]+);/giu, (_entity, codePoint: string) => {\n const parsed = Number.parseInt(codePoint, 16);\n return Number.isFinite(parsed) ? String.fromCodePoint(parsed) : _entity;\n })\n .replace(/&#(\\d+);/gu, (_entity, codePoint: string) => {\n const parsed = Number.parseInt(codePoint, 10);\n return Number.isFinite(parsed) ? String.fromCodePoint(parsed) : _entity;\n })\n .replace(/&([a-z]+);/giu, (entity, name: string) => NAMED_HTML_ENTITIES[name.toLowerCase()] ?? entity);\n}\n\nfunction trimUrlToken(value: string) {\n return value.replace(/[\\].,!?;:\uFF0C\u3002\uFF01\uFF1F\uFF1B\uFF1A]+$/u, \"\");\n}\n\nfunction compactUrlLabel(value: string | null | undefined) {\n const raw = trimUrlToken(value?.trim() ?? \"\");\n if (!raw) return null;\n const normalized = raw.startsWith(\"www.\") ? `https://${raw}` : raw;\n\n try {\n const parsed = new URL(normalized);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") return null;\n const hostname = parsed.hostname.replace(/^www\\./iu, \"\");\n const pathParts = parsed.pathname.split(\"/\").map((part) => part.trim()).filter(Boolean);\n const lastPathPart = pathParts.at(-1)\n ?.replace(/[-_]+/gu, \" \")\n .replace(/\\.html?$/iu, \"\")\n .trim();\n return lastPathPart ? `${hostname} \u00B7 ${lastPathPart}` : hostname;\n } catch {\n return null;\n }\n}\n\nfunction stripBareUrlNoise(value: string) {\n const urls = Array.from(value.matchAll(URL_PATTERN), (match) => match[0]);\n if (urls.length === 0) return value;\n\n const withoutUrls = value\n .replace(URL_PATTERN, \" \")\n .replace(/\\[\\s*\\]/gu, \" \")\n .replace(/\\(\\s*\\)/gu, \" \")\n .replace(/\\s+/gu, \" \")\n .trim();\n if (withoutUrls) return withoutUrls;\n\n return compactUrlLabel(urls[0]) ?? \"\";\n}\n\nfunction markdownHeadingText(line: string) {\n const match = decodeHtmlEntities(line).match(/^#{1,6}\\s*(.*?)\\s*#*$/);\n const text = match?.[1]?.trim();\n return text ? text.replace(/[:\uFF1A]\\s*$/, \"\") : null;\n}\n\nfunction plainPreviewLine(line: string) {\n return stripBareUrlNoise(decodeHtmlEntities(line)\n .trim()\n .replace(/^#{1,6}\\s*(.*?)\\s*#*$/, \"$1\")\n .replace(/^>\\s*/, \"\")\n .replace(/^(?:[-*+]|\\d+[.)])\\s+/, \"\")\n .replace(/^\\[[ xX]\\]\\s+/, \"\")\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/\\[\\s*((?:https?:\\/\\/|www\\.)[^\\]\\s]+)\\s*\\]/giu, \"$1\")\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"$1\")\n .replace(/__([^_]+)__/g, \"$1\")\n .replace(/\\*([^*]+)\\*/g, \"$1\")\n .replace(/_([^_]+)_/g, \"$1\")\n .replace(/\\s+/g, \" \")\n .trim())\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function formatMessengerPreview(value: string | null | undefined, options: MessengerPreviewOptions = {}) {\n const max = options.max ?? 140;\n const lines = (value ?? \"\")\n .split(/\\r?\\n/)\n .map((part) => part.trim())\n .filter(Boolean);\n if (lines.length === 0) return null;\n\n const heading = markdownHeadingText(lines[0] ?? \"\");\n if (heading) {\n const detail = lines.slice(1).map(plainPreviewLine).find(Boolean);\n return truncateText(detail ? `${plainPreviewLine(heading)}: ${detail}` : plainPreviewLine(heading), max);\n }\n\n const first = plainPreviewLine(lines[0] ?? \"\");\n return first ? truncateText(first, max) : null;\n}\n\nexport function formatMessengerTitle(value: string | null | undefined, options: MessengerPreviewOptions = {}) {\n const max = options.max ?? 80;\n const lines = (value ?? \"\")\n .split(/\\r?\\n/)\n .map((part) => part.trim())\n .filter(Boolean);\n\n for (const line of lines) {\n const heading = markdownHeadingText(line);\n const title = plainPreviewLine(heading ?? line);\n if (title) return truncateText(title, max);\n }\n\n return null;\n}\n", "export type CachedInputTokenSemantics = \"included_in_input\" | \"additional_to_input\";\n\nexport const ADDITIONAL_CACHED_INPUT_TOKEN_PROVIDERS = [\"anthropic\", \"claude\"] as const;\n\nexport interface TokenUsageParts {\n inputTokens?: number | null;\n cachedInputTokens?: number | null;\n outputTokens?: number | null;\n cachedInputTokenSemantics?: CachedInputTokenSemantics | null;\n provider?: string | null;\n}\n\nexport interface TokenUsageSummary {\n inputTokens: number;\n cachedInputTokens: number;\n outputTokens: number;\n cachedInputTokenSemantics: CachedInputTokenSemantics;\n uncachedInputTokens: number;\n promptTokens: number;\n totalTokens: number;\n}\n\nfunction tokenCount(value: number | null | undefined): number {\n return Math.max(0, Math.floor(typeof value === \"number\" && Number.isFinite(value) ? value : 0));\n}\n\nexport function cachedInputTokenSemanticsForProvider(\n provider: string | null | undefined,\n): CachedInputTokenSemantics {\n const normalized = provider?.trim().toLowerCase();\n if (normalized && ADDITIONAL_CACHED_INPUT_TOKEN_PROVIDERS.some((value) => (\n normalized === value || normalized.startsWith(`${value}:`) || normalized.startsWith(`${value}/`)\n ))) {\n return \"additional_to_input\";\n }\n return \"included_in_input\";\n}\n\nexport function summarizeTokenUsage(parts: TokenUsageParts): TokenUsageSummary {\n const inputTokens = tokenCount(parts.inputTokens);\n const cachedInputTokens = tokenCount(parts.cachedInputTokens);\n const outputTokens = tokenCount(parts.outputTokens);\n const cacheSemantics =\n parts.cachedInputTokenSemantics ?? cachedInputTokenSemanticsForProvider(parts.provider);\n const cachedIsInputSubset = cacheSemantics === \"included_in_input\";\n const uncachedInputTokens = cachedIsInputSubset\n ? Math.max(0, inputTokens - cachedInputTokens)\n : inputTokens;\n const promptTokens = cachedIsInputSubset\n ? inputTokens\n : inputTokens + cachedInputTokens;\n\n return {\n inputTokens,\n cachedInputTokens,\n outputTokens,\n cachedInputTokenSemantics: cacheSemantics,\n uncachedInputTokens,\n promptTokens,\n totalTokens: promptTokens + outputTokens,\n };\n}\n\nexport function tokenUsageCacheRatio(parts: TokenUsageParts): number | null {\n const summary = summarizeTokenUsage(parts);\n if (summary.promptTokens <= 0) return null;\n return summary.cachedInputTokens / summary.promptTokens;\n}\n\nexport function hasTokenUsage(parts: TokenUsageParts): boolean {\n const summary = summarizeTokenUsage(parts);\n return summary.totalTokens > 0 || summary.cachedInputTokens > 0;\n}\n", "import { normalizeAgentUrlKey } from \"./agent-url-key.js\";\nimport { normalizeOrganizationUrlKey } from \"./organization-url-key.js\";\nimport type {\n OrganizationSkillListItem,\n OrganizationSkillSourceType,\n} from \"./types/organization-skill.js\";\n\ntype SkillReferenceSource = Pick<\n OrganizationSkillListItem,\n \"key\" | \"slug\" | \"name\" | \"sourceType\" | \"sourceLocator\"\n> & Partial<Pick<OrganizationSkillListItem, \"sourceBadge\" | \"sourceLabel\" | \"sourcePath\">>;\n\nexport type OrganizationSkillPublicRefScope = \"organization\" | \"agent\";\n\nexport interface OrganizationSkillPublicRefContext {\n orgUrlKey: string;\n agentUrlKey?: string | null;\n scope?: OrganizationSkillPublicRefScope;\n}\n\nexport type ParsedOrganizationSkillReferenceKind =\n | \"raw_slug\"\n | \"organization\"\n | \"rudder\"\n | \"github\"\n | \"url\"\n | \"other\";\n\nexport interface ParsedOrganizationSkillReference {\n kind: ParsedOrganizationSkillReferenceKind;\n normalized: string;\n slug: string | null;\n segments: string[];\n}\n\nexport interface ResolveOrganizationSkillReferenceContext {\n orgId: string;\n}\n\nexport interface ResolveOrganizationSkillReferenceResult<TSkill> {\n skill: TSkill | null;\n ambiguous: boolean;\n}\n\nfunction normalizeSkillSlug(value: string | null | undefined) {\n return value ? normalizeAgentUrlKey(value) ?? null : null;\n}\n\nexport const RUDDER_BUNDLED_SKILL_SLUGS = [\n \"para-memory-files\",\n \"rudder\",\n \"rudder-create-agent\",\n \"rudder-create-plugin\",\n \"skill-creator\",\n \"skill-optimizer\",\n \"conversation-to-skill\",\n] as const;\n\nconst RUDDER_BUNDLED_SKILL_KEYS = new Set(\n RUDDER_BUNDLED_SKILL_SLUGS.map((slug) => `rudder/${slug}`),\n);\n\nexport function getBundledRudderSkillSlug(value: string | null | undefined) {\n if (!value) return null;\n const segments = value\n .trim()\n .split(\"/\")\n .map((segment) => normalizeSkillSlug(segment))\n .filter((segment): segment is string => Boolean(segment));\n\n if (segments.length === 2 && segments[0] === \"rudder\") {\n return segments[1] ?? null;\n }\n\n if (segments.length === 3 && segments[0] === \"rudder\" && segments[1] === \"rudder\") {\n return segments[2] ?? null;\n }\n\n return null;\n}\n\nexport function toBundledRudderSkillKey(value: string | null | undefined) {\n const slug = normalizeSkillSlug(value);\n if (!slug) return null;\n return `rudder/${slug}`;\n}\n\nexport function isCanonicalBundledRudderSkillKey(value: string | null | undefined) {\n return RUDDER_BUNDLED_SKILL_KEYS.has(value ?? \"\");\n}\n\nexport function normalizeOrganizationSkillKey(value: string | null | undefined) {\n if (!value) return null;\n const normalized = value\n .trim()\n .split(\"/\")\n .map((segment) => normalizeSkillSlug(segment))\n .filter((segment): segment is string => Boolean(segment))\n .join(\"/\");\n return normalized.length > 0 ? normalized : null;\n}\n\nfunction isOrganizationScopedSkill(skill: { sourceType?: OrganizationSkillSourceType | null; key: string }) {\n return skill.sourceType !== \"github\" && skill.sourceType !== \"skills_sh\" && skill.sourceType !== \"url\";\n}\n\nfunction isRudderSkill(skill: SkillReferenceSource) {\n return getBundledRudderSkillSlug(skill.key) !== null || skill.sourceBadge === \"rudder\";\n}\n\nfunction normalizeSegmentList(reference: string) {\n return reference\n .trim()\n .split(\"/\")\n .map((segment) => normalizeSkillSlug(segment))\n .filter((segment): segment is string => Boolean(segment));\n}\n\nfunction parseRepositoryLocator(sourceLocator: string | null | undefined, sourceLabel: string | null | undefined) {\n const tryParse = (value: string | null | undefined) => {\n if (!value) return null;\n try {\n const url = new URL(value);\n const parts = url.pathname.split(\"/\").filter(Boolean);\n if (parts.length >= 2) {\n return {\n owner: normalizeSkillSlug(parts[0]) ?? parts[0]!,\n repo: normalizeSkillSlug(parts[1]) ?? parts[1]!,\n };\n }\n } catch {\n const parts = value.split(\"/\").map((part) => part.trim()).filter(Boolean);\n if (parts.length >= 2) {\n return {\n owner: normalizeSkillSlug(parts[0]) ?? parts[0]!,\n repo: normalizeSkillSlug(parts[1]) ?? parts[1]!,\n };\n }\n }\n return null;\n };\n\n return tryParse(sourceLocator) ?? tryParse(sourceLabel);\n}\n\nexport function formatOrganizationSkillPublicRef(\n skill: SkillReferenceSource,\n context: OrganizationSkillPublicRefContext,\n) {\n const normalizedKey = normalizeOrganizationSkillKey(skill.key) ?? skill.key.trim();\n const slug = (normalizeSkillSlug(skill.slug) ?? skill.slug.trim()) || \"skill\";\n const orgUrlKey = normalizeOrganizationUrlKey(context.orgUrlKey) ?? \"organization\";\n const agentUrlKey = normalizeAgentUrlKey(context.agentUrlKey ?? null);\n\n if (isRudderSkill(skill)) {\n return `rudder/${slug}`;\n }\n\n if (normalizedKey.startsWith(\"organization/\") || normalizedKey.startsWith(\"local/\") || normalizedKey.startsWith(\"catalog/\")) {\n if (context.scope === \"agent\" && agentUrlKey) {\n return `org/${orgUrlKey}/${agentUrlKey}/${slug}`;\n }\n return `org/${orgUrlKey}/${slug}`;\n }\n\n if (skill.sourceType === \"github\" || skill.sourceType === \"skills_sh\") {\n const repo = parseRepositoryLocator(skill.sourceLocator, skill.sourceLabel);\n if (repo) {\n return `${repo.owner}/${repo.repo}/${slug}`;\n }\n }\n\n if (normalizedKey.startsWith(\"url/\")) {\n return normalizedKey;\n }\n\n return normalizedKey;\n}\n\nexport function buildOrganizationSkillSearchText(\n skill: SkillReferenceSource,\n context: OrganizationSkillPublicRefContext,\n) {\n return [\n formatOrganizationSkillPublicRef(skill, context),\n skill.name,\n skill.slug,\n skill.sourceLabel ?? \"\",\n skill.sourceBadge ?? \"\",\n skill.sourcePath ?? \"\",\n ]\n .join(\" \")\n .toLowerCase();\n}\n\nexport function parseOrganizationSkillReference(reference: string): ParsedOrganizationSkillReference {\n const normalized = reference.trim();\n const segments = normalizeSegmentList(normalized);\n if (segments.length === 0) {\n return {\n kind: \"other\",\n normalized: \"\",\n slug: null,\n segments: [],\n };\n }\n\n if (segments[0] === \"org\" || segments[0] === \"organization\") {\n return {\n kind: \"organization\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments[0] === \"rudder\") {\n return {\n kind: \"rudder\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments[0] === \"url\" && segments.length >= 4) {\n return {\n kind: \"url\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments[0] === \"local\" && segments.length >= 3) {\n return {\n kind: \"other\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n if (segments.length >= 3) {\n return {\n kind: \"github\",\n normalized: segments.join(\"/\"),\n slug: segments.at(-1) ?? null,\n segments,\n };\n }\n\n return {\n kind: \"raw_slug\",\n normalized: segments.join(\"/\"),\n slug: segments[0] ?? null,\n segments,\n };\n}\n\nexport function resolveOrganizationSkillReference<TSkill extends SkillReferenceSource>(\n skills: TSkill[],\n reference: string,\n context: ResolveOrganizationSkillReferenceContext,\n): ResolveOrganizationSkillReferenceResult<TSkill> {\n const trimmed = reference.trim();\n if (!trimmed) {\n return { skill: null, ambiguous: false };\n }\n\n const normalizedKey = normalizeOrganizationSkillKey(trimmed);\n if (normalizedKey) {\n const byKey = skills.find((skill) => normalizeOrganizationSkillKey(skill.key) === normalizedKey);\n if (byKey) {\n return { skill: byKey, ambiguous: false };\n }\n }\n\n const parsed = parseOrganizationSkillReference(trimmed);\n if (parsed.kind === \"organization\") {\n const slug = parsed.slug;\n if (!slug) return { skill: null, ambiguous: false };\n const exactKey = `organization/${context.orgId}/${slug}`;\n const byExactOrgKey = skills.find((skill) => skill.key === exactKey);\n if (byExactOrgKey) {\n return { skill: byExactOrgKey, ambiguous: false };\n }\n\n const orgScoped = skills.filter((skill) => isOrganizationScopedSkill(skill) && skill.slug === slug);\n if (orgScoped.length === 1) {\n return { skill: orgScoped[0] ?? null, ambiguous: false };\n }\n if (orgScoped.length > 1) {\n return { skill: null, ambiguous: true };\n }\n\n const bySlug = skills.filter((skill) => skill.slug === slug);\n if (bySlug.length === 1) {\n return { skill: bySlug[0] ?? null, ambiguous: false };\n }\n if (bySlug.length > 1) {\n return { skill: null, ambiguous: true };\n }\n return { skill: null, ambiguous: false };\n }\n\n if (parsed.kind === \"rudder\") {\n const slug = parsed.slug;\n if (!slug) return { skill: null, ambiguous: false };\n const canonicalKey = toBundledRudderSkillKey(slug);\n const legacyKey = canonicalKey ? `rudder/${canonicalKey}` : null;\n for (const exactKey of [canonicalKey, legacyKey]) {\n if (!exactKey) continue;\n const byExactKey = skills.find((skill) => skill.key === exactKey);\n if (byExactKey) {\n return { skill: byExactKey, ambiguous: false };\n }\n }\n\n const rudderSkills = skills.filter((skill) => isRudderSkill(skill) && skill.slug === slug);\n if (rudderSkills.length === 1) {\n return { skill: rudderSkills[0] ?? null, ambiguous: false };\n }\n if (rudderSkills.length > 1) {\n return { skill: null, ambiguous: true };\n }\n return { skill: null, ambiguous: false };\n }\n\n if (parsed.kind === \"raw_slug\") {\n const slug = parsed.slug;\n if (!slug) return { skill: null, ambiguous: false };\n const bySlug = skills.filter((skill) => skill.slug === slug);\n if (bySlug.length === 1) {\n return { skill: bySlug[0] ?? null, ambiguous: false };\n }\n if (bySlug.length > 1) {\n return { skill: null, ambiguous: true };\n }\n }\n\n return { skill: null, ambiguous: false };\n}\n", "import { PROJECT_COLORS } from \"./constants.js\";\n\nexport const PROJECT_MENTION_SCHEME = \"project://\";\nexport const AGENT_MENTION_SCHEME = \"agent://\";\nexport const ISSUE_MENTION_SCHEME = \"issue://\";\n\nconst HEX_COLOR_RE = /^[0-9a-f]{6}$/i;\nconst HEX_COLOR_SHORT_RE = /^[0-9a-f]{3}$/i;\nconst HEX_COLOR_WITH_HASH_RE = /^#[0-9a-f]{6}$/i;\nconst HEX_COLOR_SHORT_WITH_HASH_RE = /^#[0-9a-f]{3}$/i;\nconst PROJECT_MENTION_LINK_RE = /\\[[^\\]]*]\\((project:\\/\\/[^)\\s]+)\\)/gi;\nconst AGENT_MENTION_LINK_RE = /\\[[^\\]]*]\\((agent:\\/\\/[^)\\s]+)\\)/gi;\nconst ISSUE_MENTION_LINK_RE = /\\[[^\\]]*]\\((issue:\\/\\/[^)\\s]+)\\)/gi;\nconst AGENT_ICON_NAME_RE = /^[a-z0-9-]+$/i;\nconst PROJECT_COLOR_VALUES = new Set<string>(PROJECT_COLORS);\n\nexport interface ParsedProjectMention {\n projectId: string;\n color: string | null;\n}\n\nexport interface ParsedAgentMention {\n agentId: string;\n icon: string | null;\n}\n\nexport interface ParsedIssueMention {\n issueId: string;\n ref: string | null;\n}\n\nfunction normalizeHexColor(input: string | null | undefined): string | null {\n if (!input) return null;\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n if (HEX_COLOR_WITH_HASH_RE.test(trimmed)) {\n return trimmed.toLowerCase();\n }\n if (HEX_COLOR_RE.test(trimmed)) {\n return `#${trimmed.toLowerCase()}`;\n }\n if (HEX_COLOR_SHORT_WITH_HASH_RE.test(trimmed)) {\n const raw = trimmed.slice(1).toLowerCase();\n return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}`;\n }\n if (HEX_COLOR_SHORT_RE.test(trimmed)) {\n const raw = trimmed.toLowerCase();\n return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}`;\n }\n return null;\n}\n\nfunction normalizeProjectMentionColor(input: string | null | undefined): string | null {\n const hex = normalizeHexColor(input);\n if (hex) return hex;\n const trimmed = input?.trim();\n if (trimmed && PROJECT_COLOR_VALUES.has(trimmed)) return trimmed;\n return null;\n}\n\nfunction encodeMentionParam(value: string): string {\n return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);\n}\n\nfunction stripMarkdownCode(markdown: string): string {\n return markdown\n .replace(/```[\\s\\S]*?```/g, \"\")\n .replace(/`[^`\\n]*`/g, \"\");\n}\n\nexport function buildProjectMentionHref(projectId: string, color?: string | null): string {\n const trimmedProjectId = projectId.trim();\n const normalizedColor = normalizeProjectMentionColor(color ?? null);\n if (!normalizedColor) {\n return `${PROJECT_MENTION_SCHEME}${trimmedProjectId}`;\n }\n const colorParam = normalizedColor.startsWith(\"#\") ? normalizedColor.slice(1) : normalizedColor;\n return `${PROJECT_MENTION_SCHEME}${trimmedProjectId}?c=${encodeMentionParam(colorParam)}`;\n}\n\nexport function parseProjectMentionHref(href: string): ParsedProjectMention | null {\n if (!href.startsWith(PROJECT_MENTION_SCHEME)) return null;\n\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"project:\") return null;\n\n const projectId = `${url.hostname}${url.pathname}`.replace(/^\\/+/, \"\").trim();\n if (!projectId) return null;\n\n const color = normalizeProjectMentionColor(url.searchParams.get(\"c\") ?? url.searchParams.get(\"color\"));\n\n return {\n projectId,\n color,\n };\n}\n\nexport function buildAgentMentionHref(agentId: string, icon?: string | null): string {\n const trimmedAgentId = agentId.trim();\n const normalizedIcon = normalizeAgentIcon(icon ?? null);\n if (!normalizedIcon) {\n return `${AGENT_MENTION_SCHEME}${trimmedAgentId}`;\n }\n return `${AGENT_MENTION_SCHEME}${trimmedAgentId}?i=${encodeURIComponent(normalizedIcon)}`;\n}\n\nexport function parseAgentMentionHref(href: string): ParsedAgentMention | null {\n if (!href.startsWith(AGENT_MENTION_SCHEME)) return null;\n\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"agent:\") return null;\n\n const agentId = `${url.hostname}${url.pathname}`.replace(/^\\/+/, \"\").trim();\n if (!agentId) return null;\n\n return {\n agentId,\n icon: normalizeAgentIcon(url.searchParams.get(\"i\") ?? url.searchParams.get(\"icon\")),\n };\n}\n\nexport function buildIssueMentionHref(issueId: string, ref?: string | null): string {\n const trimmedIssueId = issueId.trim();\n const trimmedRef = ref?.trim();\n if (!trimmedRef) return `${ISSUE_MENTION_SCHEME}${trimmedIssueId}`;\n return `${ISSUE_MENTION_SCHEME}${trimmedIssueId}?r=${encodeURIComponent(trimmedRef)}`;\n}\n\nexport function parseIssueMentionHref(href: string): ParsedIssueMention | null {\n if (!href.startsWith(ISSUE_MENTION_SCHEME)) return null;\n\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"issue:\") return null;\n\n const issueId = `${url.hostname}${url.pathname}`.replace(/^\\/+/, \"\").trim();\n if (!issueId) return null;\n\n const ref = (url.searchParams.get(\"r\") ?? url.searchParams.get(\"ref\") ?? \"\").trim() || null;\n\n return {\n issueId,\n ref,\n };\n}\n\nexport function extractProjectMentionIds(markdown: string): string[] {\n if (!markdown) return [];\n const ids = new Set<string>();\n const re = new RegExp(PROJECT_MENTION_LINK_RE);\n const source = stripMarkdownCode(markdown);\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const parsed = parseProjectMentionHref(match[1]);\n if (parsed) ids.add(parsed.projectId);\n }\n return [...ids];\n}\n\nexport function extractAgentMentionIds(markdown: string): string[] {\n if (!markdown) return [];\n const ids = new Set<string>();\n const re = new RegExp(AGENT_MENTION_LINK_RE);\n const source = stripMarkdownCode(markdown);\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const parsed = parseAgentMentionHref(match[1]);\n if (parsed) ids.add(parsed.agentId);\n }\n return [...ids];\n}\n\nexport function extractIssueMentionIds(markdown: string): string[] {\n if (!markdown) return [];\n const ids = new Set<string>();\n const re = new RegExp(ISSUE_MENTION_LINK_RE);\n const source = stripMarkdownCode(markdown);\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const parsed = parseIssueMentionHref(match[1]);\n if (parsed) ids.add(parsed.issueId);\n }\n return [...ids];\n}\n\nfunction normalizeAgentIcon(input: string | null | undefined): string | null {\n if (!input) return null;\n const trimmed = input.trim().toLowerCase();\n if (!trimmed || !AGENT_ICON_NAME_RE.test(trimmed)) return null;\n return trimmed;\n}\n", "import { z } from \"zod\";\nimport {\n AUTH_BASE_URL_MODES,\n DEPLOYMENT_EXPOSURES,\n DEPLOYMENT_MODES,\n SECRET_PROVIDERS,\n STORAGE_PROVIDERS,\n} from \"./constants.js\";\n\nexport const configMetaSchema = z.object({\n version: z.literal(1),\n updatedAt: z.string(),\n source: z.enum([\"onboard\", \"configure\", \"doctor\"]),\n});\n\nexport const llmConfigSchema = z.object({\n provider: z.enum([\"claude\", \"openai\"]),\n apiKey: z.string().optional(),\n});\n\nexport const databaseBackupConfigSchema = z.object({\n enabled: z.boolean().default(true),\n intervalMinutes: z.number().int().min(1).max(7 * 24 * 60).default(60),\n retentionDays: z.number().int().min(1).max(3650).default(30),\n dir: z.string().default(\"~/.rudder/instances/default/data/backups\"),\n});\n\nexport const databaseConfigSchema = z.object({\n mode: z.enum([\"embedded-postgres\", \"postgres\"]).default(\"embedded-postgres\"),\n connectionString: z.string().optional(),\n embeddedPostgresDataDir: z.string().default(\"~/.rudder/instances/default/db\"),\n embeddedPostgresPort: z.number().int().min(1).max(65535).default(54329),\n backup: databaseBackupConfigSchema.default({\n enabled: true,\n intervalMinutes: 60,\n retentionDays: 30,\n dir: \"~/.rudder/instances/default/data/backups\",\n }),\n});\n\nexport const loggingConfigSchema = z.object({\n mode: z.enum([\"file\", \"cloud\"]),\n logDir: z.string().default(\"~/.rudder/instances/default/logs\"),\n});\n\nexport const serverConfigSchema = z.object({\n deploymentMode: z.enum(DEPLOYMENT_MODES).default(\"local_trusted\"),\n exposure: z.enum(DEPLOYMENT_EXPOSURES).default(\"private\"),\n host: z.string().default(\"127.0.0.1\"),\n port: z.number().int().min(1).max(65535).default(3100),\n allowedHostnames: z.array(z.string().min(1)).default([]),\n serveUi: z.boolean().default(true),\n});\n\nexport const authConfigSchema = z.object({\n baseUrlMode: z.enum(AUTH_BASE_URL_MODES).default(\"auto\"),\n publicBaseUrl: z.string().url().optional(),\n disableSignUp: z.boolean().default(false),\n});\n\nexport const storageLocalDiskConfigSchema = z.object({\n baseDir: z.string().default(\"~/.rudder/instances/default/data/storage\"),\n});\n\nexport const storageS3ConfigSchema = z.object({\n bucket: z.string().min(1).default(\"rudder\"),\n region: z.string().min(1).default(\"us-east-1\"),\n endpoint: z.string().optional(),\n prefix: z.string().default(\"\"),\n forcePathStyle: z.boolean().default(false),\n});\n\nexport const storageConfigSchema = z.object({\n provider: z.enum(STORAGE_PROVIDERS).default(\"local_disk\"),\n localDisk: storageLocalDiskConfigSchema.default({\n baseDir: \"~/.rudder/instances/default/data/storage\",\n }),\n s3: storageS3ConfigSchema.default({\n bucket: \"rudder\",\n region: \"us-east-1\",\n prefix: \"\",\n forcePathStyle: false,\n }),\n});\n\nexport const secretsLocalEncryptedConfigSchema = z.object({\n keyFilePath: z.string().default(\"~/.rudder/instances/default/secrets/master.key\"),\n});\n\nexport const secretsConfigSchema = z.object({\n provider: z.enum(SECRET_PROVIDERS).default(\"local_encrypted\"),\n strictMode: z.boolean().default(false),\n localEncrypted: secretsLocalEncryptedConfigSchema.default({\n keyFilePath: \"~/.rudder/instances/default/secrets/master.key\",\n }),\n});\n\nexport const langfuseConfigSchema = z.object({\n enabled: z.boolean().default(false),\n baseUrl: z.string().url().default(\"http://localhost:3000\"),\n publicKey: z.string().optional(),\n secretKey: z.string().optional(),\n environment: z.string().optional(),\n});\n\nexport const rudderConfigSchema = z\n .object({\n $meta: configMetaSchema,\n llm: llmConfigSchema.optional(),\n database: databaseConfigSchema,\n logging: loggingConfigSchema,\n server: serverConfigSchema,\n auth: authConfigSchema.default({\n baseUrlMode: \"auto\",\n disableSignUp: false,\n }),\n storage: storageConfigSchema.default({\n provider: \"local_disk\",\n localDisk: {\n baseDir: \"~/.rudder/instances/default/data/storage\",\n },\n s3: {\n bucket: \"rudder\",\n region: \"us-east-1\",\n prefix: \"\",\n forcePathStyle: false,\n },\n }),\n secrets: secretsConfigSchema.default({\n provider: \"local_encrypted\",\n strictMode: false,\n localEncrypted: {\n keyFilePath: \"~/.rudder/instances/default/secrets/master.key\",\n },\n }),\n langfuse: langfuseConfigSchema.optional(),\n })\n .superRefine((value, ctx) => {\n if (value.server.deploymentMode === \"local_trusted\") {\n if (value.server.exposure !== \"private\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"server.exposure must be private when deploymentMode is local_trusted\",\n path: [\"server\", \"exposure\"],\n });\n }\n return;\n }\n\n if (value.auth.baseUrlMode === \"explicit\" && !value.auth.publicBaseUrl) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"auth.publicBaseUrl is required when auth.baseUrlMode is explicit\",\n path: [\"auth\", \"publicBaseUrl\"],\n });\n }\n\n if (value.server.exposure === \"public\" && value.auth.baseUrlMode !== \"explicit\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"auth.baseUrlMode must be explicit when deploymentMode=authenticated and exposure=public\",\n path: [\"auth\", \"baseUrlMode\"],\n });\n }\n\n if (value.server.exposure === \"public\" && !value.auth.publicBaseUrl) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"auth.publicBaseUrl is required when deploymentMode=authenticated and exposure=public\",\n path: [\"auth\", \"publicBaseUrl\"],\n });\n }\n });\n\nexport type RudderConfig = z.infer<typeof rudderConfigSchema>;\nexport type LlmConfig = z.infer<typeof llmConfigSchema>;\nexport type DatabaseConfig = z.infer<typeof databaseConfigSchema>;\nexport type LoggingConfig = z.infer<typeof loggingConfigSchema>;\nexport type ServerConfig = z.infer<typeof serverConfigSchema>;\nexport type StorageConfig = z.infer<typeof storageConfigSchema>;\nexport type StorageLocalDiskConfig = z.infer<typeof storageLocalDiskConfigSchema>;\nexport type StorageS3Config = z.infer<typeof storageS3ConfigSchema>;\nexport type SecretsConfig = z.infer<typeof secretsConfigSchema>;\nexport type SecretsLocalEncryptedConfig = z.infer<typeof secretsLocalEncryptedConfigSchema>;\nexport type LangfuseConfig = z.infer<typeof langfuseConfigSchema>;\nexport type AuthConfig = z.infer<typeof authConfigSchema>;\nexport type ConfigMeta = z.infer<typeof configMetaSchema>;\nexport type DatabaseBackupConfig = z.infer<typeof databaseBackupConfigSchema>;\n", "export {\n ORGANIZATION_STATUSES,\n DEPLOYMENT_MODES,\n DEPLOYMENT_EXPOSURES,\n AUTH_BASE_URL_MODES,\n AGENT_STATUSES,\n AGENT_RUN_CONCURRENCY_DEFAULT,\n AGENT_RUN_CONCURRENCY_MIN,\n AGENT_RUN_CONCURRENCY_MAX,\n AGENT_RUNTIME_TYPES,\n AGENT_ROLES,\n AGENT_ROLE_LABELS,\n AGENT_ICON_NAMES,\n ISSUE_STATUSES,\n ISSUE_PRIORITIES,\n ISSUE_ORIGIN_KINDS,\n CALENDAR_SOURCE_TYPES,\n CALENDAR_OWNER_TYPES,\n CALENDAR_VISIBILITIES,\n CALENDAR_SOURCE_STATUSES,\n CALENDAR_EVENT_KINDS,\n CALENDAR_EVENT_STATUSES,\n CALENDAR_SOURCE_MODES,\n CHAT_CONVERSATION_STATUSES,\n CHAT_ISSUE_CREATION_MODES,\n CHAT_MESSAGE_ROLES,\n CHAT_MESSAGE_KINDS,\n CHAT_MESSAGE_STATUSES,\n CHAT_CONTEXT_ENTITY_TYPES,\n MESSENGER_THREAD_KINDS,\n MESSENGER_SYSTEM_THREAD_KINDS,\n GOAL_LEVELS,\n GOAL_STATUSES,\n PROJECT_STATUSES,\n ORGANIZATION_RESOURCE_KINDS,\n PROJECT_RESOURCE_ATTACHMENT_ROLES,\n AUTOMATION_STATUSES,\n AUTOMATION_CONCURRENCY_POLICIES,\n AUTOMATION_CATCH_UP_POLICIES,\n AUTOMATION_TRIGGER_KINDS,\n AUTOMATION_TRIGGER_SIGNING_MODES,\n AUTOMATION_RUN_STATUSES,\n AUTOMATION_RUN_SOURCES,\n PAUSE_REASONS,\n PROJECT_COLORS,\n APPROVAL_TYPES,\n APPROVAL_STATUSES,\n SECRET_PROVIDERS,\n STORAGE_PROVIDERS,\n BILLING_TYPES,\n FINANCE_EVENT_KINDS,\n FINANCE_DIRECTIONS,\n FINANCE_UNITS,\n BUDGET_SCOPE_TYPES,\n BUDGET_METRICS,\n BUDGET_WINDOW_KINDS,\n BUDGET_THRESHOLD_TYPES,\n BUDGET_INCIDENT_STATUSES,\n BUDGET_INCIDENT_RESOLUTION_ACTIONS,\n HEARTBEAT_INVOCATION_SOURCES,\n HEARTBEAT_RUN_STATUSES,\n WAKEUP_TRIGGER_DETAILS,\n WAKEUP_REQUEST_STATUSES,\n LIVE_EVENT_TYPES,\n PRINCIPAL_TYPES,\n MEMBERSHIP_STATUSES,\n INSTANCE_USER_ROLES,\n INVITE_TYPES,\n INVITE_JOIN_TYPES,\n JOIN_REQUEST_TYPES,\n JOIN_REQUEST_STATUSES,\n PERMISSION_KEYS,\n PLUGIN_API_VERSION,\n PLUGIN_STATUSES,\n PLUGIN_CATEGORIES,\n PLUGIN_CAPABILITIES,\n PLUGIN_UI_SLOT_TYPES,\n PLUGIN_UI_SLOT_ENTITY_TYPES,\n PLUGIN_LAUNCHER_PLACEMENT_ZONES,\n PLUGIN_LAUNCHER_ACTIONS,\n PLUGIN_LAUNCHER_BOUNDS,\n PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS,\n PLUGIN_STATE_SCOPE_KINDS,\n PLUGIN_JOB_STATUSES,\n PLUGIN_JOB_RUN_STATUSES,\n PLUGIN_JOB_RUN_TRIGGERS,\n PLUGIN_WEBHOOK_DELIVERY_STATUSES,\n PLUGIN_EVENT_TYPES,\n PLUGIN_BRIDGE_ERROR_CODES,\n type OrganizationStatus,\n type DeploymentMode,\n type DeploymentExposure,\n type AuthBaseUrlMode,\n type AgentStatus,\n type AgentRuntimeType,\n type AgentRole,\n type AgentIconName,\n type IssueStatus,\n type IssuePriority,\n type IssueOriginKind,\n type CalendarSourceType,\n type CalendarOwnerType,\n type CalendarVisibility,\n type CalendarSourceStatus,\n type CalendarEventKind,\n type CalendarEventStatus,\n type CalendarSourceMode,\n type ChatConversationStatus,\n type ChatIssueCreationMode,\n type ChatMessageRole,\n type ChatMessageKind,\n type ChatMessageStatus,\n type ChatContextEntityType,\n type MessengerThreadKind,\n type MessengerSystemThreadKind,\n type GoalLevel,\n type GoalStatus,\n type ProjectStatus,\n type OrganizationResourceKind,\n type ProjectResourceAttachmentRole,\n type AutomationStatus,\n type AutomationConcurrencyPolicy,\n type AutomationCatchUpPolicy,\n type AutomationTriggerKind,\n type AutomationTriggerSigningMode,\n type AutomationRunStatus,\n type AutomationRunSource,\n type PauseReason,\n type ApprovalType,\n type ApprovalStatus,\n type SecretProvider,\n type StorageProvider,\n type BillingType,\n type FinanceEventKind,\n type FinanceDirection,\n type FinanceUnit,\n type BudgetScopeType,\n type BudgetMetric,\n type BudgetWindowKind,\n type BudgetThresholdType,\n type BudgetIncidentStatus,\n type BudgetIncidentResolutionAction,\n type HeartbeatInvocationSource,\n type HeartbeatRunStatus,\n type WakeupTriggerDetail,\n type WakeupRequestStatus,\n type LiveEventType,\n type PrincipalType,\n type MembershipStatus,\n type InstanceUserRole,\n type InviteType,\n type InviteJoinType,\n type JoinRequestType,\n type JoinRequestStatus,\n type PermissionKey,\n type PluginStatus,\n type PluginCategory,\n type PluginCapability,\n type PluginUiSlotType,\n type PluginUiSlotEntityType,\n type PluginLauncherPlacementZone,\n type PluginLauncherAction,\n type PluginLauncherBounds,\n type PluginLauncherRenderEnvironment,\n type PluginStateScopeKind,\n type PluginJobStatus,\n type PluginJobRunStatus,\n type PluginJobRunTrigger,\n type PluginWebhookDeliveryStatus,\n type PluginEventType,\n type PluginBridgeErrorCode,\n} from \"./constants.js\";\n\nexport { EXECUTION_OBSERVABILITY_SURFACES } from \"./types/observability.js\";\nexport {\n WORKSPACE_BACKUP_DEFAULT_INTERVAL_HOURS,\n WORKSPACE_BACKUP_DEFAULT_RETENTION_DAYS,\n} from \"./types/workspace-backup.js\";\n\n\nexport type {\n ExecutionObservabilityContext,\n ExecutionObservabilitySurface,\n ExecutionLangfuseLink,\n Organization,\n OrganizationWorkspace,\n OrganizationWorkspaceRootSource,\n OrganizationWorkspaceFileEntry,\n OrganizationWorkspaceFileList,\n OrganizationWorkspaceFileDetail,\n OrganizationWorkspaceFileUpdateRequest,\n ChatConversation,\n ChatMessage,\n ChatAttachment,\n ChatContextLink,\n ChatLinkedEntity,\n ChatPrimaryIssueSummary,\n ChatAskUserOption,\n ChatAskUserQuestion,\n ChatAskUserRequest,\n ChatRichReference,\n ChatRichReferenceDisplay,\n ChatRuntimeDescriptor,\n ChatOperationProposalDecision,\n ChatOperationProposalDecisionAction,\n ChatOperationProposalDecisionStatus,\n ChatStreamTranscriptEntry,\n ChatStreamTranscriptTodoItem,\n ChatStreamTranscriptTodoItemStatus,\n ChatStreamAckEvent,\n ChatStreamAssistantDeltaEvent,\n ChatStreamAssistantStateEvent,\n ChatStreamTranscriptEntryEvent,\n ChatStreamFinalEvent,\n ChatStreamErrorEvent,\n ChatStreamEvent,\n OrganizationSkillSourceType,\n OrganizationSkillTrustLevel,\n OrganizationSkillCompatibility,\n OrganizationSkillSourceBadge,\n OrganizationSkillFileInventoryEntry,\n OrganizationSkill,\n OrganizationSkillListItem,\n OrganizationSkillUsageAgent,\n OrganizationSkillDetail,\n OrganizationSkillUpdateStatus,\n OrganizationSkillImportRequest,\n OrganizationSkillImportResult,\n OrganizationSkillProjectScanRequest,\n OrganizationSkillProjectScanSkipped,\n OrganizationSkillProjectScanConflict,\n OrganizationSkillProjectScanResult,\n OrganizationSkillLocalScanRequest,\n OrganizationSkillLocalScanSkipped,\n OrganizationSkillLocalScanConflict,\n OrganizationSkillLocalScanResult,\n OrganizationSkillCreateRequest,\n OrganizationSkillFileDetail,\n OrganizationSkillFileUpdateRequest,\n OrganizationSkillWorkspaceEditPath,\n AgentSkillSyncMode,\n AgentSkillState,\n AgentSkillOrigin,\n AgentSkillSourceClass,\n AgentSkillEntry,\n AgentSkillSnapshot,\n AgentSkillSyncRequest,\n AgentSkillTelemetryEvidence,\n AgentSkillTelemetryEvidenceCounts,\n AgentSkillAnalyticsSkillTotal,\n AgentSkillAnalyticsDay,\n AgentSkillAnalytics,\n InstanceLocale,\n InstanceGeneralSettings,\n InstanceNotificationSettings,\n InstanceLangfuseSettings,\n OperatorProfileSettings,\n InstancePathPickerRequest,\n InstancePathPickerResult,\n InstancePathPickerSelectionType,\n InstanceSettings,\n Agent,\n AgentAccessState,\n AgentChainOfCommandEntry,\n AgentDetail,\n AgentPermissions,\n AgentInstructionsBundleMode,\n AgentInstructionsFileSummary,\n AgentInstructionsFileDetail,\n AgentInstructionsBundle,\n AgentKeyCreated,\n AgentConfigRevision,\n AgentRuntimeEnvironmentCheckLevel,\n AgentRuntimeEnvironmentTestStatus,\n AgentRuntimeEnvironmentCheck,\n AgentRuntimeEnvironmentTestResult,\n AssetImage,\n Project,\n ProjectCodebase,\n ProjectCodebaseOrigin,\n ProjectCodebaseScope,\n ProjectGoalRef,\n ProjectWorkspace,\n ProjectWorkspaceSourceType,\n ProjectWorkspaceVisibility,\n OrganizationResource,\n CreateOrganizationResourceRequest,\n UpdateOrganizationResourceRequest,\n ProjectResourceAttachment,\n ProjectResourceAttachmentInput,\n UpdateProjectResourceAttachmentRequest,\n CreateProjectInlineResourceInput,\n ExecutionWorkspace,\n WorkspaceRuntimeService,\n WorkspaceOperation,\n WorkspaceOperationPhase,\n WorkspaceOperationStatus,\n WorkspaceBackupStatus,\n WorkspaceBackupTriggerSource,\n WorkspaceBackupSummary,\n WorkspaceBackupList,\n WorkspaceBackupCreateRequest,\n WorkspaceBackupRestoreRequest,\n WorkspaceBackupRestoreResult,\n WorkspaceBackupFileList,\n WorkspaceBackupFileDetail,\n ExecutionWorkspaceStrategyType,\n ExecutionWorkspaceMode,\n ExecutionWorkspaceProviderType,\n ExecutionWorkspaceStatus,\n ExecutionWorkspaceStrategy,\n ProjectExecutionWorkspacePolicy,\n ProjectExecutionWorkspaceDefaultMode,\n IssueExecutionWorkspaceSettings,\n IssueWorkProduct,\n IssueWorkProductType,\n IssueWorkProductProvider,\n IssueWorkProductStatus,\n IssueWorkProductReviewState,\n Issue,\n IssueAssigneeAgentRuntimeOverrides,\n IssueSearchMatch,\n IssueComment,\n IssueCommitReport,\n IssueDocument,\n IssueDocumentSummary,\n DocumentRevision,\n DocumentFormat,\n LegacyPlanDocument,\n IssueAttachment,\n IssueLabel,\n Goal,\n GoalDependencies,\n GoalDependencyPreview,\n Approval,\n ApprovalComment,\n IssueLinkedApproval,\n MessengerThreadUserState,\n IssueFollow,\n IssueFollowEntry,\n MessengerEvent,\n MessengerThreadAction,\n MessengerThreadSummary,\n MessengerThreadDetail,\n MessengerThreadItem,\n MessengerChatThreadDetail,\n MessengerIssueThreadItem,\n MessengerApprovalThreadItem,\n MessengerBudgetThreadItem,\n MessengerJoinRequestThreadItem,\n MessengerHeartbeatRunThreadItem,\n BudgetPolicy,\n BudgetPolicySummary,\n BudgetIncident,\n BudgetOverview,\n BudgetPolicyUpsertInput,\n BudgetIncidentResolutionInput,\n CostEvent,\n CostSummary,\n CostTrendPoint,\n CostByAgent,\n CostByProviderModel,\n CostByBiller,\n CostByAgentModel,\n CostWindowSpendRow,\n CostByProject,\n FinanceEvent,\n FinanceSummary,\n FinanceByBiller,\n FinanceByKind,\n HeartbeatRecoveryMode,\n HeartbeatRecoveryTrigger,\n HeartbeatRun,\n HeartbeatRunContextSnapshot,\n HeartbeatRunEvent,\n HeartbeatRunRecoveryContext,\n AgentRuntimeState,\n AgentTaskSession,\n AgentWakeupRequest,\n InstanceSchedulerHeartbeatAgent,\n LiveEvent,\n DashboardSummary,\n ActivityEvent,\n SidebarBadges,\n OrganizationMembership,\n PrincipalPermissionGrant,\n Invite,\n JoinRequest,\n InstanceUserRoleGrant,\n OrganizationPortabilityInclude,\n OrganizationPortabilityEnvInput,\n OrganizationPortabilityFileEntry,\n OrganizationPortabilityOrganizationManifestEntry,\n OrganizationPortabilitySidebarOrder,\n OrganizationPortabilityAgentManifestEntry,\n OrganizationPortabilitySkillManifestEntry,\n OrganizationPortabilityProjectManifestEntry,\n OrganizationPortabilityProjectWorkspaceManifestEntry,\n OrganizationPortabilityIssueAutomationTriggerManifestEntry,\n OrganizationPortabilityIssueAutomationManifestEntry,\n OrganizationPortabilityIssueManifestEntry,\n OrganizationPortabilityManifest,\n OrganizationPortabilityExportResult,\n OrganizationPortabilityExportPreviewFile,\n OrganizationPortabilityExportPreviewResult,\n OrganizationExportJobStatus,\n OrganizationExportJobStage,\n OrganizationExportJobProgress,\n OrganizationExportJob,\n OrganizationExportJobCreateResult,\n OrganizationPortabilitySource,\n OrganizationPortabilityImportTarget,\n OrganizationPortabilityAgentSelection,\n OrganizationPortabilityCollisionStrategy,\n OrganizationPortabilityPreviewRequest,\n OrganizationPortabilityPreviewAgentPlan,\n OrganizationPortabilityPreviewProjectPlan,\n OrganizationPortabilityPreviewIssuePlan,\n OrganizationPortabilityPreviewResult,\n OrganizationPortabilityAgentRuntimeOverride,\n OrganizationPortabilityImportRequest,\n OrganizationPortabilityImportResult,\n OrganizationPortabilityExportRequest,\n EnvBinding,\n AgentEnvConfig,\n OrganizationSecret,\n SecretProviderDescriptor,\n Automation,\n AutomationTrigger,\n AutomationRun,\n AutomationTriggerSecretMaterial,\n AutomationDetail,\n AutomationRunSummary,\n AutomationExecutionIssueOrigin,\n AutomationListItem,\n CalendarSource,\n CalendarEvent,\n CalendarEventLinkedAgent,\n CalendarEventLinkedIssue,\n CalendarEventListResponse,\n GoogleCalendarConnectResponse,\n GoogleCalendarSyncResponse,\n GoogleCalendarOAuthConfig,\n JsonSchema,\n PluginJobDeclaration,\n PluginWebhookDeclaration,\n PluginToolDeclaration,\n PluginUiSlotDeclaration,\n PluginLauncherActionDeclaration,\n PluginLauncherRenderDeclaration,\n PluginLauncherRenderContextSnapshot,\n PluginLauncherDeclaration,\n PluginMinimumHostVersion,\n PluginUiDeclaration,\n PaperclipPluginManifestV1,\n PluginRecord,\n PluginStateRecord,\n PluginConfig,\n PluginEntityRecord,\n PluginEntityQuery,\n PluginJobRecord,\n PluginJobRunRecord,\n PluginWebhookDeliveryRecord,\n QuotaWindow,\n ProviderQuotaResult,\n} from \"./types/index.js\";\n\nexport {\n instanceLocaleSchema,\n instanceGeneralSettingsSchema,\n patchInstanceGeneralSettingsSchema,\n type PatchInstanceGeneralSettings,\n instanceNotificationSettingsSchema,\n patchInstanceNotificationSettingsSchema,\n type PatchInstanceNotificationSettings,\n instanceLangfuseSettingsSchema,\n patchInstanceLangfuseSettingsSchema,\n type PatchInstanceLangfuseSettings,\n OPERATOR_PROFILE_MORE_ABOUT_YOU_MAX_LENGTH,\n operatorProfileSettingsSchema,\n patchOperatorProfileSettingsSchema,\n type PatchOperatorProfileSettings,\n instancePathPickerSelectionTypeSchema,\n instancePathPickerRequestSchema,\n instancePathPickerResultSchema,\n} from \"./validators/index.js\";\n\nexport {\n createOrganizationSchema,\n updateOrganizationSchema,\n updateOrganizationBrandingSchema,\n updateOrganizationWorkspaceFileSchema,\n organizationResourceKindSchema,\n projectResourceAttachmentRoleSchema,\n createOrganizationResourceSchema,\n updateOrganizationResourceSchema,\n projectResourceAttachmentInputSchema,\n updateProjectResourceAttachmentSchema,\n createProjectInlineResourceSchema,\n type CreateOrganization,\n type UpdateOrganization,\n type UpdateOrganizationBranding,\n type UpdateOrganizationWorkspaceFile,\n type CreateOrganizationResource,\n type UpdateOrganizationResource,\n type ProjectResourceAttachmentInputPayload,\n type UpdateProjectResourceAttachment,\n type CreateProjectInlineResource,\n chatConversationStatusSchema,\n chatIssueCreationModeSchema,\n chatMessageRoleSchema,\n chatMessageKindSchema,\n chatContextEntityTypeSchema,\n createChatContextLinkSchema,\n createChatConversationSchema,\n setChatProjectContextSchema,\n updateChatConversationSchema,\n addChatMessageSchema,\n chatAskUserOptionSchema,\n chatAskUserQuestionSchema,\n chatAskUserRequestSchema,\n chatAskUserRequestFromStructuredPayload,\n chatRichReferenceSchema,\n chatRichReferencesSchema,\n chatRichReferencesFromStructuredPayload,\n sanitizeChatStructuredPayload,\n createChatAttachmentMetadataSchema,\n convertChatToIssueSchema,\n chatOperationProposalSchema,\n resolveChatOperationProposalSchema,\n updateChatConversationUserStateSchema,\n type CreateChatContextLink,\n type CreateChatConversation,\n type SetChatProjectContext,\n type UpdateChatConversation,\n type AddChatMessage,\n type CreateChatAttachmentMetadata,\n type ConvertChatToIssue,\n type ChatOperationProposal,\n type ResolveChatOperationProposal,\n type UpdateChatConversationUserState,\n agentSkillStateSchema,\n agentSkillSyncModeSchema,\n agentSkillEntrySchema,\n agentSkillSnapshotSchema,\n agentSkillSyncSchema,\n agentSkillEnableSchema,\n type AgentSkillSync,\n type AgentSkillEnable,\n agentIconSchema,\n customAgentIconSchema,\n createAgentSchema,\n createAgentHireSchema,\n updateAgentSchema,\n uploadedAgentIconSchema,\n agentInstructionsBundleModeSchema,\n updateAgentInstructionsBundleSchema,\n upsertAgentInstructionsFileSchema,\n updateAgentInstructionsPathSchema,\n createAgentKeySchema,\n wakeAgentSchema,\n resetAgentSessionSchema,\n testAgentRuntimeEnvironmentSchema,\n agentPermissionsSchema,\n updateAgentPermissionsSchema,\n type CreateAgent,\n type CreateAgentHire,\n type UpdateAgent,\n type UpdateAgentInstructionsBundle,\n type UpsertAgentInstructionsFile,\n type UpdateAgentInstructionsPath,\n type CreateAgentKey,\n type WakeAgent,\n type ResetAgentSession,\n type TestAgentRuntimeEnvironment,\n type UpdateAgentPermissions,\n createProjectSchema,\n updateProjectSchema,\n type CreateProject,\n type UpdateProject,\n projectExecutionWorkspacePolicySchema,\n createIssueSchema,\n createIssueLabelSchema,\n updateIssueLabelSchema,\n updateIssueSchema,\n reorderIssueSchema,\n issueExecutionWorkspaceSettingsSchema,\n checkoutIssueSchema,\n addIssueCommentSchema,\n reportIssueCommitSchema,\n linkIssueApprovalSchema,\n createIssueAttachmentMetadataSchema,\n createIssueWorkspaceAttachmentSchema,\n createIssueWorkProductSchema,\n updateIssueWorkProductSchema,\n issueWorkProductTypeSchema,\n issueWorkProductStatusSchema,\n issueWorkProductReviewStateSchema,\n updateExecutionWorkspaceSchema,\n executionWorkspaceStatusSchema,\n issueDocumentFormatSchema,\n issueDocumentKeySchema,\n upsertIssueDocumentSchema,\n type CreateIssue,\n type CreateIssueLabel,\n type UpdateIssueLabel,\n type UpdateIssue,\n type ReorderIssue,\n type CheckoutIssue,\n type AddIssueComment,\n type ReportIssueCommit,\n type LinkIssueApproval,\n type CreateIssueAttachmentMetadata,\n type CreateIssueWorkspaceAttachment,\n type CreateIssueWorkProduct,\n type UpdateIssueWorkProduct,\n type UpdateExecutionWorkspace,\n type IssueDocumentFormat,\n type UpsertIssueDocument,\n workspaceBackupTriggerSourceSchema,\n createWorkspaceBackupSchema,\n restoreWorkspaceBackupSchema,\n type CreateWorkspaceBackup,\n type RestoreWorkspaceBackup,\n createGoalSchema,\n updateGoalSchema,\n type CreateGoal,\n type UpdateGoal,\n createApprovalSchema,\n upsertBudgetPolicySchema,\n resolveBudgetIncidentSchema,\n resolveApprovalSchema,\n requestApprovalRevisionSchema,\n resubmitApprovalSchema,\n addApprovalCommentSchema,\n type CreateApproval,\n type UpsertBudgetPolicy,\n type ResolveBudgetIncident,\n type ResolveApproval,\n type RequestApprovalRevision,\n type ResubmitApproval,\n type AddApprovalComment,\n envBindingPlainSchema,\n envBindingSecretRefSchema,\n envBindingSchema,\n envConfigSchema,\n createSecretSchema,\n rotateSecretSchema,\n updateSecretSchema,\n createAutomationSchema,\n updateAutomationSchema,\n createAutomationTriggerSchema,\n updateAutomationTriggerSchema,\n runAutomationSchema,\n rotateAutomationTriggerSecretSchema,\n createCalendarSourceSchema,\n updateCalendarSourceSchema,\n createCalendarEventSchema,\n updateCalendarEventSchema,\n calendarEventListQuerySchema,\n googleCalendarSyncSchema,\n updateGoogleCalendarOAuthConfigSchema,\n type CreateSecret,\n type RotateSecret,\n type UpdateSecret,\n type CreateAutomation,\n type UpdateAutomation,\n type CreateAutomationTrigger,\n type UpdateAutomationTrigger,\n type RunAutomation,\n type RotateAutomationTriggerSecret,\n type CreateCalendarSource,\n type UpdateCalendarSource,\n type CreateCalendarEvent,\n type UpdateCalendarEvent,\n type CalendarEventListQuery,\n type GoogleCalendarSync,\n type UpdateGoogleCalendarOAuthConfig,\n createCostEventSchema,\n createFinanceEventSchema,\n updateBudgetSchema,\n createAssetImageMetadataSchema,\n createCompanyInviteSchema,\n createOpenClawInvitePromptSchema,\n acceptInviteSchema,\n listJoinRequestsQuerySchema,\n claimJoinRequestApiKeySchema,\n boardCliAuthAccessLevelSchema,\n createCliAuthChallengeSchema,\n resolveCliAuthChallengeSchema,\n updateMemberPermissionsSchema,\n updateUserCompanyAccessSchema,\n type CreateCostEvent,\n type CreateFinanceEvent,\n type UpdateBudget,\n type CreateAssetImageMetadata,\n type CreateCompanyInvite,\n type CreateOpenClawInvitePrompt,\n type AcceptInvite,\n type ListJoinRequestsQuery,\n type ClaimJoinRequestApiKey,\n type BoardCliAuthAccessLevel,\n type CreateCliAuthChallenge,\n type ResolveCliAuthChallenge,\n type UpdateMemberPermissions,\n type UpdateUserCompanyAccess,\n organizationSkillSourceTypeSchema,\n organizationSkillTrustLevelSchema,\n organizationSkillCompatibilitySchema,\n organizationSkillSourceBadgeSchema,\n organizationSkillFileInventoryEntrySchema,\n organizationSkillSchema,\n organizationSkillListItemSchema,\n organizationSkillUsageAgentSchema,\n organizationSkillDetailSchema,\n organizationSkillUpdateStatusSchema,\n organizationSkillImportSchema,\n organizationSkillProjectScanRequestSchema,\n organizationSkillProjectScanSkippedSchema,\n organizationSkillProjectScanConflictSchema,\n organizationSkillProjectScanResultSchema,\n organizationSkillLocalScanRequestSchema,\n organizationSkillLocalScanSkippedSchema,\n organizationSkillLocalScanConflictSchema,\n organizationSkillLocalScanResultSchema,\n organizationSkillCreateSchema,\n organizationSkillFileDetailSchema,\n organizationSkillFileUpdateSchema,\n portabilityIncludeSchema,\n portabilityEnvInputSchema,\n portabilityOrganizationManifestEntrySchema,\n portabilitySidebarOrderSchema,\n portabilityAgentManifestEntrySchema,\n portabilityManifestSchema,\n portabilitySourceSchema,\n portabilityTargetSchema,\n portabilityAgentSelectionSchema,\n portabilityCollisionStrategySchema,\n organizationPortabilityExportSchema,\n organizationPortabilityPreviewSchema,\n organizationPortabilityImportSchema,\n type OrganizationPortabilityExport,\n type OrganizationPortabilityPreview,\n type OrganizationPortabilityImport,\n jsonSchemaSchema,\n pluginJobDeclarationSchema,\n pluginWebhookDeclarationSchema,\n pluginToolDeclarationSchema,\n pluginUiSlotDeclarationSchema,\n pluginLauncherActionDeclarationSchema,\n pluginLauncherRenderDeclarationSchema,\n pluginLauncherDeclarationSchema,\n pluginManifestV1Schema,\n installPluginSchema,\n upsertPluginConfigSchema,\n patchPluginConfigSchema,\n updatePluginStatusSchema,\n uninstallPluginSchema,\n pluginStateScopeKeySchema,\n setPluginStateSchema,\n listPluginStateSchema,\n type PluginJobDeclarationInput,\n type PluginWebhookDeclarationInput,\n type PluginToolDeclarationInput,\n type PluginUiSlotDeclarationInput,\n type PluginLauncherActionDeclarationInput,\n type PluginLauncherRenderDeclarationInput,\n type PluginLauncherDeclarationInput,\n type PluginManifestV1Input,\n type InstallPlugin,\n type UpsertPluginConfig,\n type PatchPluginConfig,\n type UpdatePluginStatus,\n type UninstallPlugin,\n type PluginStateScopeKey,\n type SetPluginState,\n type ListPluginState,\n} from \"./validators/index.js\";\n\nexport { API_PREFIX, API } from \"./api.js\";\nexport { normalizeAgentUrlKey, deriveAgentUrlKey, isUuidLike } from \"./agent-url-key.js\";\nexport { normalizeOrganizationUrlKey, deriveOrganizationUrlKey } from \"./organization-url-key.js\";\nexport { deriveProjectUrlKey, normalizeProjectUrlKey } from \"./project-url-key.js\";\nexport { formatMessengerPreview, formatMessengerTitle, type MessengerPreviewOptions } from \"./messenger-preview.js\";\nexport {\n summarizeTokenUsage,\n tokenUsageCacheRatio,\n hasTokenUsage,\n cachedInputTokenSemanticsForProvider,\n ADDITIONAL_CACHED_INPUT_TOKEN_PROVIDERS,\n type CachedInputTokenSemantics,\n type TokenUsageParts,\n type TokenUsageSummary,\n} from \"./token-usage.js\";\nexport {\n RUDDER_BUNDLED_SKILL_SLUGS,\n getBundledRudderSkillSlug,\n isCanonicalBundledRudderSkillKey,\n toBundledRudderSkillKey,\n normalizeOrganizationSkillKey,\n formatOrganizationSkillPublicRef,\n buildOrganizationSkillSearchText,\n parseOrganizationSkillReference,\n resolveOrganizationSkillReference,\n type OrganizationSkillPublicRefContext,\n type OrganizationSkillPublicRefScope,\n type ParsedOrganizationSkillReference,\n type ParsedOrganizationSkillReferenceKind,\n type ResolveOrganizationSkillReferenceContext,\n type ResolveOrganizationSkillReferenceResult,\n} from \"./organization-skill-reference.js\";\nexport {\n AGENT_MENTION_SCHEME,\n ISSUE_MENTION_SCHEME,\n PROJECT_MENTION_SCHEME,\n buildAgentMentionHref,\n buildIssueMentionHref,\n buildProjectMentionHref,\n extractAgentMentionIds,\n extractIssueMentionIds,\n parseAgentMentionHref,\n parseIssueMentionHref,\n parseProjectMentionHref,\n extractProjectMentionIds,\n type ParsedAgentMention,\n type ParsedIssueMention,\n type ParsedProjectMention,\n} from \"./project-mentions.js\";\n\nexport {\n rudderConfigSchema,\n configMetaSchema,\n llmConfigSchema,\n databaseBackupConfigSchema,\n databaseConfigSchema,\n loggingConfigSchema,\n serverConfigSchema,\n authConfigSchema,\n langfuseConfigSchema,\n secretsConfigSchema,\n storageConfigSchema,\n storageLocalDiskConfigSchema,\n storageS3ConfigSchema,\n secretsLocalEncryptedConfigSchema,\n type RudderConfig,\n type LlmConfig,\n type DatabaseBackupConfig,\n type DatabaseConfig,\n type LoggingConfig,\n type ServerConfig,\n type AuthConfig,\n type LangfuseConfig,\n type StorageConfig,\n type StorageLocalDiskConfig,\n type StorageS3Config,\n type SecretsConfig,\n type SecretsLocalEncryptedConfig,\n type ConfigMeta,\n} from \"./config-schema.js\";\n", "export {\n rudderConfigSchema,\n configMetaSchema,\n llmConfigSchema,\n databaseBackupConfigSchema,\n databaseConfigSchema,\n loggingConfigSchema,\n serverConfigSchema,\n authConfigSchema,\n storageConfigSchema,\n storageLocalDiskConfigSchema,\n storageS3ConfigSchema,\n secretsConfigSchema,\n secretsLocalEncryptedConfigSchema,\n type RudderConfig,\n type LlmConfig,\n type DatabaseBackupConfig,\n type DatabaseConfig,\n type LoggingConfig,\n type ServerConfig,\n type AuthConfig,\n type StorageConfig,\n type StorageLocalDiskConfig,\n type StorageS3Config,\n type SecretsConfig,\n type SecretsLocalEncryptedConfig,\n type ConfigMeta,\n} from \"@rudderhq/shared\";\n", "import os from \"node:os\";\nimport path from \"node:path\";\n\nconst DEFAULT_INSTANCE_ID = \"default\";\nconst INSTANCE_ID_RE = /^[a-zA-Z0-9_-]+$/;\n\nexport function resolveRudderHomeDir(): string {\n const envHome = process.env.RUDDER_HOME?.trim();\n if (envHome) return path.resolve(expandHomePrefix(envHome));\n return path.resolve(os.homedir(), \".rudder\");\n}\n\nexport function resolveRudderInstanceId(override?: string): string {\n const raw = override?.trim() || process.env.RUDDER_INSTANCE_ID?.trim() || DEFAULT_INSTANCE_ID;\n if (!INSTANCE_ID_RE.test(raw)) {\n throw new Error(\n `Invalid instance id '${raw}'. Allowed characters: letters, numbers, '_' and '-'.`,\n );\n }\n return raw;\n}\n\nexport function resolveRudderInstanceRoot(instanceId?: string): string {\n const id = resolveRudderInstanceId(instanceId);\n return path.resolve(resolveRudderHomeDir(), \"instances\", id);\n}\n\nexport function resolveDefaultConfigPath(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"config.json\");\n}\n\nexport function resolveDefaultContextPath(): string {\n return path.resolve(resolveRudderHomeDir(), \"context.json\");\n}\n\nexport function resolveDefaultCliAuthPath(): string {\n return path.resolve(resolveRudderHomeDir(), \"auth.json\");\n}\n\nexport function resolveDefaultEmbeddedPostgresDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"db\");\n}\n\nexport function resolveDefaultLogsDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"logs\");\n}\n\nexport function resolveDefaultSecretsKeyFilePath(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"secrets\", \"master.key\");\n}\n\nexport function resolveDefaultStorageDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"data\", \"storage\");\n}\n\nexport function resolveDefaultBackupDir(instanceId?: string): string {\n return path.resolve(resolveRudderInstanceRoot(instanceId), \"data\", \"backups\");\n}\n\nexport function expandHomePrefix(value: string): string {\n if (value === \"~\") return os.homedir();\n if (value.startsWith(\"~/\")) return path.resolve(os.homedir(), value.slice(2));\n return value;\n}\n\nexport function describeLocalInstancePaths(instanceId?: string) {\n const resolvedInstanceId = resolveRudderInstanceId(instanceId);\n const instanceRoot = resolveRudderInstanceRoot(resolvedInstanceId);\n return {\n homeDir: resolveRudderHomeDir(),\n instanceId: resolvedInstanceId,\n instanceRoot,\n configPath: resolveDefaultConfigPath(resolvedInstanceId),\n embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(resolvedInstanceId),\n backupDir: resolveDefaultBackupDir(resolvedInstanceId),\n logDir: resolveDefaultLogsDir(resolvedInstanceId),\n secretsKeyFilePath: resolveDefaultSecretsKeyFilePath(resolvedInstanceId),\n storageDir: resolveDefaultStorageDir(resolvedInstanceId),\n };\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { rudderConfigSchema, type RudderConfig } from \"./schema.js\";\nimport {\n resolveDefaultConfigPath,\n resolveRudderInstanceId,\n} from \"./home.js\";\n\nconst DEFAULT_CONFIG_BASENAME = \"config.json\";\n\nfunction findConfigFileFromAncestors(startDir: string): string | null {\n const absoluteStartDir = path.resolve(startDir);\n let currentDir = absoluteStartDir;\n\n while (true) {\n const candidate = path.resolve(currentDir, \".rudder\", DEFAULT_CONFIG_BASENAME);\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n\n const nextDir = path.resolve(currentDir, \"..\");\n if (nextDir === currentDir) break;\n currentDir = nextDir;\n }\n\n return null;\n}\n\nexport function resolveConfigPath(overridePath?: string): string {\n if (overridePath) return path.resolve(overridePath);\n if (process.env.RUDDER_CONFIG) return path.resolve(process.env.RUDDER_CONFIG);\n return findConfigFileFromAncestors(process.cwd()) ?? resolveDefaultConfigPath(resolveRudderInstanceId());\n}\n\nfunction parseJson(filePath: string): unknown {\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n } catch (err) {\n throw new Error(`Failed to parse JSON at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction migrateLegacyConfig(raw: unknown): unknown {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return raw;\n const config = { ...(raw as Record<string, unknown>) };\n const databaseRaw = config.database;\n if (typeof databaseRaw !== \"object\" || databaseRaw === null || Array.isArray(databaseRaw)) {\n return config;\n }\n\n const database = { ...(databaseRaw as Record<string, unknown>) };\n if (database.mode === \"pglite\") {\n database.mode = \"embedded-postgres\";\n\n if (typeof database.embeddedPostgresDataDir !== \"string\" && typeof database.pgliteDataDir === \"string\") {\n database.embeddedPostgresDataDir = database.pgliteDataDir;\n }\n if (\n typeof database.embeddedPostgresPort !== \"number\" &&\n typeof database.pglitePort === \"number\" &&\n Number.isFinite(database.pglitePort)\n ) {\n database.embeddedPostgresPort = database.pglitePort;\n }\n }\n\n config.database = database;\n return config;\n}\n\nfunction formatValidationError(err: unknown): string {\n const issues = (err as { issues?: Array<{ path?: unknown; message?: unknown }> })?.issues;\n if (Array.isArray(issues) && issues.length > 0) {\n return issues\n .map((issue) => {\n const pathParts = Array.isArray(issue.path) ? issue.path.map(String) : [];\n const issuePath = pathParts.length > 0 ? pathParts.join(\".\") : \"config\";\n const message = typeof issue.message === \"string\" ? issue.message : \"Invalid value\";\n return `${issuePath}: ${message}`;\n })\n .join(\"; \");\n }\n return err instanceof Error ? err.message : String(err);\n}\n\nexport function readConfig(configPath?: string): RudderConfig | null {\n const filePath = resolveConfigPath(configPath);\n if (!fs.existsSync(filePath)) return null;\n const raw = parseJson(filePath);\n const migrated = migrateLegacyConfig(raw);\n const parsed = rudderConfigSchema.safeParse(migrated);\n if (!parsed.success) {\n throw new Error(`Invalid config at ${filePath}: ${formatValidationError(parsed.error)}`);\n }\n return parsed.data;\n}\n\nexport function writeConfig(\n config: RudderConfig,\n configPath?: string,\n): void {\n const filePath = resolveConfigPath(configPath);\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n\n // Backup existing config before overwriting\n if (fs.existsSync(filePath)) {\n const backupPath = filePath + \".backup\";\n fs.copyFileSync(filePath, backupPath);\n fs.chmodSync(backupPath, 0o600);\n }\n\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\nexport function configExists(configPath?: string): boolean {\n return fs.existsSync(resolveConfigPath(configPath));\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { config as loadDotenv, parse as parseEnvFileContents } from \"dotenv\";\nimport { resolveConfigPath } from \"./store.js\";\n\nconst JWT_SECRET_ENV_KEY = \"RUDDER_AGENT_JWT_SECRET\";\nfunction resolveEnvFilePath(configPath?: string) {\n return path.resolve(path.dirname(resolveConfigPath(configPath)), \".env\");\n}\nconst loadedEnvFiles = new Set<string>();\n\nfunction isNonEmpty(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction parseEnvFile(contents: string) {\n try {\n return parseEnvFileContents(contents);\n } catch {\n return {};\n }\n}\n\nfunction formatEnvValue(value: string): string {\n if (/^[A-Za-z0-9_./:@-]+$/.test(value)) {\n return value;\n }\n return JSON.stringify(value);\n}\n\nfunction renderEnvFile(entries: Record<string, string>) {\n const lines = [\n \"# Rudder environment variables\",\n \"# Generated by Rudder CLI commands\",\n ...Object.entries(entries).map(([key, value]) => `${key}=${formatEnvValue(value)}`),\n \"\",\n ];\n return lines.join(\"\\n\");\n}\n\nexport function resolvePaperclipEnvFile(configPath?: string): string {\n return resolveEnvFilePath(configPath);\n}\n\nexport function resolveAgentJwtEnvFile(configPath?: string): string {\n return resolveEnvFilePath(configPath);\n}\n\nexport function loadRudderEnvFile(configPath?: string): void {\n loadAgentJwtEnvFile(resolveEnvFilePath(configPath));\n}\n\nexport function loadAgentJwtEnvFile(filePath = resolveEnvFilePath()): void {\n if (loadedEnvFiles.has(filePath)) return;\n\n if (!fs.existsSync(filePath)) return;\n loadedEnvFiles.add(filePath);\n loadDotenv({ path: filePath, override: false, quiet: true });\n}\n\nexport function readAgentJwtSecretFromEnv(configPath?: string): string | null {\n loadAgentJwtEnvFile(resolveEnvFilePath(configPath));\n const raw = process.env[JWT_SECRET_ENV_KEY];\n return isNonEmpty(raw) ? raw!.trim() : null;\n}\n\nexport function readAgentJwtSecretFromEnvFile(filePath = resolveEnvFilePath()): string | null {\n if (!fs.existsSync(filePath)) return null;\n\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const values = parseEnvFile(raw);\n const value = values[JWT_SECRET_ENV_KEY];\n return isNonEmpty(value) ? value!.trim() : null;\n}\n\nexport function ensureAgentJwtSecret(configPath?: string): { secret: string; created: boolean } {\n const existingEnv = readAgentJwtSecretFromEnv(configPath);\n if (existingEnv) {\n return { secret: existingEnv, created: false };\n }\n\n const envFilePath = resolveEnvFilePath(configPath);\n const existingFile = readAgentJwtSecretFromEnvFile(envFilePath);\n const secret = existingFile ?? randomBytes(32).toString(\"hex\");\n const created = !existingFile;\n\n if (!existingFile) {\n writeAgentJwtEnv(secret, envFilePath);\n }\n\n return { secret, created };\n}\n\nexport function writeAgentJwtEnv(secret: string, filePath = resolveEnvFilePath()): void {\n mergePaperclipEnvEntries({ [JWT_SECRET_ENV_KEY]: secret }, filePath);\n}\n\nexport function readPaperclipEnvEntries(filePath = resolveEnvFilePath()): Record<string, string> {\n if (!fs.existsSync(filePath)) return {};\n return parseEnvFile(fs.readFileSync(filePath, \"utf-8\"));\n}\n\nexport function writePaperclipEnvEntries(entries: Record<string, string>, filePath = resolveEnvFilePath()): void {\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(filePath, renderEnvFile(entries), {\n mode: 0o600,\n });\n}\n\nexport function mergePaperclipEnvEntries(\n entries: Record<string, string>,\n filePath = resolveEnvFilePath(),\n): Record<string, string> {\n const current = readPaperclipEnvEntries(filePath);\n const next = {\n ...current,\n ...Object.fromEntries(\n Object.entries(entries).filter(([, value]) => typeof value === \"string\" && value.trim().length > 0),\n ),\n };\n writePaperclipEnvEntries(next, filePath);\n return next;\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { expandHomePrefix } from \"../config/home.js\";\n\nfunction unique(items: string[]): string[] {\n return Array.from(new Set(items));\n}\n\nexport function resolveRuntimeLikePath(value: string, configPath?: string): string {\n const expanded = expandHomePrefix(value);\n if (path.isAbsolute(expanded)) return path.resolve(expanded);\n\n const cwd = process.cwd();\n const configDir = configPath ? path.dirname(configPath) : null;\n const workspaceRoot = configDir ? path.resolve(configDir, \"..\") : cwd;\n\n const candidates = unique([\n ...(configDir ? [path.resolve(configDir, expanded)] : []),\n path.resolve(workspaceRoot, \"server\", expanded),\n path.resolve(workspaceRoot, expanded),\n path.resolve(cwd, expanded),\n ]);\n\n return candidates.find((candidate) => fs.existsSync(candidate)) ?? candidates[0];\n}\n", "import { randomBytes } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RudderConfig } from \"./schema.js\";\nimport { resolveRuntimeLikePath } from \"../utils/path-resolver.js\";\n\nexport type EnsureSecretsKeyResult =\n | { status: \"created\"; path: string }\n | { status: \"existing\"; path: string }\n | { status: \"skipped_env\"; path: null }\n | { status: \"skipped_provider\"; path: null };\n\nexport function ensureLocalSecretsKeyFile(\n config: Pick<RudderConfig, \"secrets\">,\n configPath?: string,\n): EnsureSecretsKeyResult {\n if (config.secrets.provider !== \"local_encrypted\") {\n return { status: \"skipped_provider\", path: null };\n }\n\n const envMasterKey = process.env.RUDDER_SECRETS_MASTER_KEY;\n if (envMasterKey && envMasterKey.trim().length > 0) {\n return { status: \"skipped_env\", path: null };\n }\n\n const keyFileOverride = process.env.RUDDER_SECRETS_MASTER_KEY_FILE;\n const configuredPath =\n keyFileOverride && keyFileOverride.trim().length > 0\n ? keyFileOverride.trim()\n : config.secrets.localEncrypted.keyFilePath;\n const keyFilePath = resolveRuntimeLikePath(configuredPath, configPath);\n\n if (fs.existsSync(keyFilePath)) {\n return { status: \"existing\", path: keyFilePath };\n }\n\n fs.mkdirSync(path.dirname(keyFilePath), { recursive: true });\n fs.writeFileSync(keyFilePath, randomBytes(32).toString(\"base64\"), {\n encoding: \"utf8\",\n mode: 0o600,\n });\n try {\n fs.chmodSync(keyFilePath, 0o600);\n } catch {\n // best effort\n }\n return { status: \"created\", path: keyFilePath };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { DatabaseConfig } from \"../config/schema.js\";\nimport {\n resolveDefaultBackupDir,\n resolveDefaultEmbeddedPostgresDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\n\nfunction readEmbeddedPortFromEnv(): number {\n return Math.max(1, Number(process.env.RUDDER_EMBEDDED_POSTGRES_PORT) || 54329);\n}\n\nexport async function promptDatabase(current?: DatabaseConfig): Promise<DatabaseConfig> {\n const instanceId = resolveRudderInstanceId();\n const defaultEmbeddedDir = resolveDefaultEmbeddedPostgresDir(instanceId);\n const defaultBackupDir = resolveDefaultBackupDir(instanceId);\n const envEmbeddedPort = readEmbeddedPortFromEnv();\n const base: DatabaseConfig = current ?? {\n mode: \"embedded-postgres\",\n embeddedPostgresDataDir: defaultEmbeddedDir,\n embeddedPostgresPort: envEmbeddedPort,\n backup: {\n enabled: true,\n intervalMinutes: 60,\n retentionDays: 30,\n dir: defaultBackupDir,\n },\n };\n\n const mode = await p.select({\n message: \"Database mode\",\n options: [\n { value: \"embedded-postgres\" as const, label: \"Embedded PostgreSQL (managed locally)\", hint: \"recommended\" },\n { value: \"postgres\" as const, label: \"PostgreSQL (external server)\" },\n ],\n initialValue: base.mode,\n });\n\n if (p.isCancel(mode)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n let connectionString: string | undefined = base.connectionString;\n let embeddedPostgresDataDir = base.embeddedPostgresDataDir || defaultEmbeddedDir;\n let embeddedPostgresPort = base.embeddedPostgresPort || envEmbeddedPort;\n\n if (mode === \"postgres\") {\n const value = await p.text({\n message: \"PostgreSQL connection string\",\n defaultValue: base.connectionString ?? \"\",\n placeholder: \"postgres://user:pass@localhost:5432/rudder\",\n validate: (val) => {\n if (!val) return \"Connection string is required for PostgreSQL mode\";\n if (!val.startsWith(\"postgres\")) return \"Must be a postgres:// or postgresql:// URL\";\n },\n });\n\n if (p.isCancel(value)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n connectionString = value;\n } else {\n const dataDir = await p.text({\n message: \"Embedded PostgreSQL data directory\",\n defaultValue: base.embeddedPostgresDataDir || defaultEmbeddedDir,\n placeholder: defaultEmbeddedDir,\n });\n\n if (p.isCancel(dataDir)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n embeddedPostgresDataDir = dataDir || defaultEmbeddedDir;\n\n const portValue = await p.text({\n message: \"Embedded PostgreSQL port\",\n defaultValue: String(base.embeddedPostgresPort || envEmbeddedPort),\n placeholder: String(envEmbeddedPort),\n validate: (val) => {\n const n = Number(val);\n if (!Number.isInteger(n) || n < 1 || n > 65535) return \"Port must be an integer between 1 and 65535\";\n },\n });\n\n if (p.isCancel(portValue)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n embeddedPostgresPort = Number(portValue || String(envEmbeddedPort));\n connectionString = undefined;\n }\n\n const backupEnabled = await p.confirm({\n message: \"Enable automatic database backups?\",\n initialValue: base.backup.enabled,\n });\n if (p.isCancel(backupEnabled)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const backupDirInput = await p.text({\n message: \"Backup directory\",\n defaultValue: base.backup.dir || defaultBackupDir,\n placeholder: defaultBackupDir,\n validate: (val) => (!val || val.trim().length === 0 ? \"Backup directory is required\" : undefined),\n });\n if (p.isCancel(backupDirInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const backupIntervalInput = await p.text({\n message: \"Backup interval (minutes)\",\n defaultValue: String(base.backup.intervalMinutes || 60),\n placeholder: \"60\",\n validate: (val) => {\n const n = Number(val);\n if (!Number.isInteger(n) || n < 1) return \"Interval must be a positive integer\";\n if (n > 10080) return \"Interval must be 10080 minutes (7 days) or less\";\n return undefined;\n },\n });\n if (p.isCancel(backupIntervalInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const backupRetentionInput = await p.text({\n message: \"Backup retention (days)\",\n defaultValue: String(base.backup.retentionDays || 30),\n placeholder: \"30\",\n validate: (val) => {\n const n = Number(val);\n if (!Number.isInteger(n) || n < 1) return \"Retention must be a positive integer\";\n if (n > 3650) return \"Retention must be 3650 days or less\";\n return undefined;\n },\n });\n if (p.isCancel(backupRetentionInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return {\n mode,\n connectionString,\n embeddedPostgresDataDir,\n embeddedPostgresPort,\n backup: {\n enabled: backupEnabled,\n intervalMinutes: Number(backupIntervalInput || \"60\"),\n retentionDays: Number(backupRetentionInput || \"30\"),\n dir: backupDirInput || defaultBackupDir,\n },\n };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { LlmConfig } from \"../config/schema.js\";\n\nexport async function promptLlm(): Promise<LlmConfig | undefined> {\n const configureLlm = await p.confirm({\n message: \"Configure an LLM provider now?\",\n initialValue: false,\n });\n\n if (p.isCancel(configureLlm)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (!configureLlm) return undefined;\n\n const provider = await p.select({\n message: \"LLM provider\",\n options: [\n { value: \"claude\" as const, label: \"Claude (Anthropic)\" },\n { value: \"openai\" as const, label: \"OpenAI\" },\n ],\n });\n\n if (p.isCancel(provider)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const apiKey = await p.password({\n message: `${provider === \"claude\" ? \"Anthropic\" : \"OpenAI\"} API key`,\n validate: (val) => {\n if (!val) return \"API key is required\";\n },\n });\n\n if (p.isCancel(apiKey)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return { provider, apiKey };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { LoggingConfig } from \"../config/schema.js\";\nimport { resolveDefaultLogsDir, resolveRudderInstanceId } from \"../config/home.js\";\n\nexport async function promptLogging(): Promise<LoggingConfig> {\n const defaultLogDir = resolveDefaultLogsDir(resolveRudderInstanceId());\n const mode = await p.select({\n message: \"Logging mode\",\n options: [\n { value: \"file\" as const, label: \"File-based logging\", hint: \"recommended\" },\n { value: \"cloud\" as const, label: \"Cloud logging\", hint: \"coming soon\" },\n ],\n });\n\n if (p.isCancel(mode)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (mode === \"file\") {\n const logDir = await p.text({\n message: \"Log directory\",\n defaultValue: defaultLogDir,\n placeholder: defaultLogDir,\n });\n\n if (p.isCancel(logDir)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return { mode: \"file\", logDir: logDir || defaultLogDir };\n }\n\n p.note(\"Cloud logging is coming soon. Using file-based logging for now.\");\n return { mode: \"file\", logDir: defaultLogDir };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { SecretProvider } from \"@rudderhq/shared\";\nimport type { SecretsConfig } from \"../config/schema.js\";\nimport { resolveDefaultSecretsKeyFilePath, resolveRudderInstanceId } from \"../config/home.js\";\n\nfunction defaultKeyFilePath(): string {\n return resolveDefaultSecretsKeyFilePath(resolveRudderInstanceId());\n}\n\nexport function defaultSecretsConfig(): SecretsConfig {\n const keyFilePath = defaultKeyFilePath();\n return {\n provider: \"local_encrypted\",\n strictMode: false,\n localEncrypted: {\n keyFilePath,\n },\n };\n}\n\nexport async function promptSecrets(current?: SecretsConfig): Promise<SecretsConfig> {\n const base = current ?? defaultSecretsConfig();\n\n const provider = await p.select({\n message: \"Secrets provider\",\n options: [\n {\n value: \"local_encrypted\" as const,\n label: \"Local encrypted (recommended)\",\n hint: \"best for single-developer installs\",\n },\n {\n value: \"aws_secrets_manager\" as const,\n label: \"AWS Secrets Manager\",\n hint: \"requires external adapter integration\",\n },\n {\n value: \"gcp_secret_manager\" as const,\n label: \"GCP Secret Manager\",\n hint: \"requires external adapter integration\",\n },\n {\n value: \"vault\" as const,\n label: \"HashiCorp Vault\",\n hint: \"requires external adapter integration\",\n },\n ],\n initialValue: base.provider,\n });\n\n if (p.isCancel(provider)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const strictMode = await p.confirm({\n message: \"Require secret refs for sensitive env vars?\",\n initialValue: base.strictMode,\n });\n\n if (p.isCancel(strictMode)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const fallbackDefault = defaultKeyFilePath();\n let keyFilePath = base.localEncrypted.keyFilePath || fallbackDefault;\n if (provider === \"local_encrypted\") {\n const keyPath = await p.text({\n message: \"Local encrypted key file path\",\n defaultValue: keyFilePath,\n placeholder: fallbackDefault,\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Key file path is required\";\n },\n });\n\n if (p.isCancel(keyPath)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n keyFilePath = keyPath.trim();\n }\n\n if (provider !== \"local_encrypted\") {\n p.note(\n `${provider} is not fully wired in this build yet. Keep local_encrypted unless you are actively implementing that adapter.`,\n \"Heads up\",\n );\n }\n\n return {\n provider: provider as SecretProvider,\n strictMode,\n localEncrypted: {\n keyFilePath,\n },\n };\n}\n", "import * as p from \"@clack/prompts\";\nimport type { StorageConfig } from \"../config/schema.js\";\nimport { resolveDefaultStorageDir, resolveRudderInstanceId } from \"../config/home.js\";\n\nfunction defaultStorageBaseDir(): string {\n return resolveDefaultStorageDir(resolveRudderInstanceId());\n}\n\nexport function defaultStorageConfig(): StorageConfig {\n return {\n provider: \"local_disk\",\n localDisk: {\n baseDir: defaultStorageBaseDir(),\n },\n s3: {\n bucket: \"rudder\",\n region: \"us-east-1\",\n endpoint: undefined,\n prefix: \"\",\n forcePathStyle: false,\n },\n };\n}\n\nexport async function promptStorage(current?: StorageConfig): Promise<StorageConfig> {\n const base = current ?? defaultStorageConfig();\n\n const provider = await p.select({\n message: \"Storage provider\",\n options: [\n {\n value: \"local_disk\" as const,\n label: \"Local disk (recommended)\",\n hint: \"best for single-user local deployments\",\n },\n {\n value: \"s3\" as const,\n label: \"S3 compatible\",\n hint: \"for cloud/object storage backends\",\n },\n ],\n initialValue: base.provider,\n });\n\n if (p.isCancel(provider)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n if (provider === \"local_disk\") {\n const baseDir = await p.text({\n message: \"Local storage base directory\",\n defaultValue: base.localDisk.baseDir || defaultStorageBaseDir(),\n placeholder: defaultStorageBaseDir(),\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Storage base directory is required\";\n },\n });\n\n if (p.isCancel(baseDir)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return {\n provider: \"local_disk\",\n localDisk: {\n baseDir: baseDir.trim(),\n },\n s3: base.s3,\n };\n }\n\n const bucket = await p.text({\n message: \"S3 bucket\",\n defaultValue: base.s3.bucket || \"rudder\",\n placeholder: \"rudder\",\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Bucket is required\";\n },\n });\n\n if (p.isCancel(bucket)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const region = await p.text({\n message: \"S3 region\",\n defaultValue: base.s3.region || \"us-east-1\",\n placeholder: \"us-east-1\",\n validate: (value) => {\n if (!value || value.trim().length === 0) return \"Region is required\";\n },\n });\n\n if (p.isCancel(region)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const endpoint = await p.text({\n message: \"S3 endpoint (optional for compatible backends)\",\n defaultValue: base.s3.endpoint ?? \"\",\n placeholder: \"https://s3.amazonaws.com\",\n });\n\n if (p.isCancel(endpoint)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const prefix = await p.text({\n message: \"Object key prefix (optional)\",\n defaultValue: base.s3.prefix ?? \"\",\n placeholder: \"rudder/\",\n });\n\n if (p.isCancel(prefix)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const forcePathStyle = await p.confirm({\n message: \"Use S3 path-style URLs?\",\n initialValue: base.s3.forcePathStyle ?? false,\n });\n\n if (p.isCancel(forcePathStyle)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n return {\n provider: \"s3\",\n localDisk: base.localDisk,\n s3: {\n bucket: bucket.trim(),\n region: region.trim(),\n endpoint: endpoint.trim() || undefined,\n prefix: prefix.trim(),\n forcePathStyle,\n },\n };\n}\n\n", "export function normalizeHostnameInput(raw: string): string {\n const input = raw.trim();\n if (!input) {\n throw new Error(\"Hostname is required\");\n }\n\n try {\n const url = input.includes(\"://\") ? new URL(input) : new URL(`http://${input}`);\n const hostname = url.hostname.trim().toLowerCase();\n if (!hostname) throw new Error(\"Hostname is required\");\n return hostname;\n } catch {\n throw new Error(`Invalid hostname: ${raw}`);\n }\n}\n\nexport function parseHostnameCsv(raw: string): string[] {\n if (!raw.trim()) return [];\n const unique = new Set<string>();\n for (const part of raw.split(\",\")) {\n const hostname = normalizeHostnameInput(part);\n unique.add(hostname);\n }\n return Array.from(unique);\n}\n\n", "import * as p from \"@clack/prompts\";\nimport type { AuthConfig, ServerConfig } from \"../config/schema.js\";\nimport { parseHostnameCsv } from \"../config/hostnames.js\";\n\nexport async function promptServer(opts?: {\n currentServer?: Partial<ServerConfig>;\n currentAuth?: Partial<AuthConfig>;\n}): Promise<{ server: ServerConfig; auth: AuthConfig }> {\n const currentServer = opts?.currentServer;\n const currentAuth = opts?.currentAuth;\n\n const deploymentModeSelection = await p.select({\n message: \"Deployment mode\",\n options: [\n {\n value: \"local_trusted\",\n label: \"Local trusted\",\n hint: \"Easiest for local setup (no login, localhost-only)\",\n },\n {\n value: \"authenticated\",\n label: \"Authenticated\",\n hint: \"Login required; use for private network or public hosting\",\n },\n ],\n initialValue: currentServer?.deploymentMode ?? \"local_trusted\",\n });\n\n if (p.isCancel(deploymentModeSelection)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n const deploymentMode = deploymentModeSelection as ServerConfig[\"deploymentMode\"];\n\n let exposure: ServerConfig[\"exposure\"] = \"private\";\n if (deploymentMode === \"authenticated\") {\n const exposureSelection = await p.select({\n message: \"Exposure profile\",\n options: [\n {\n value: \"private\",\n label: \"Private network\",\n hint: \"Private access (for example Tailscale), lower setup friction\",\n },\n {\n value: \"public\",\n label: \"Public internet\",\n hint: \"Internet-facing deployment with stricter requirements\",\n },\n ],\n initialValue: currentServer?.exposure ?? \"private\",\n });\n if (p.isCancel(exposureSelection)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n exposure = exposureSelection as ServerConfig[\"exposure\"];\n }\n\n const hostDefault = deploymentMode === \"local_trusted\" ? \"127.0.0.1\" : \"0.0.0.0\";\n const hostStr = await p.text({\n message: \"Bind host\",\n defaultValue: currentServer?.host ?? hostDefault,\n placeholder: hostDefault,\n validate: (val) => {\n if (!val.trim()) return \"Host is required\";\n },\n });\n\n if (p.isCancel(hostStr)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n const portStr = await p.text({\n message: \"Server port\",\n defaultValue: String(currentServer?.port ?? 3100),\n placeholder: \"3100\",\n validate: (val) => {\n const n = Number(val);\n if (isNaN(n) || n < 1 || n > 65535 || !Number.isInteger(n)) {\n return \"Must be an integer between 1 and 65535\";\n }\n },\n });\n\n if (p.isCancel(portStr)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n\n let allowedHostnames: string[] = [];\n if (deploymentMode === \"authenticated\" && exposure === \"private\") {\n const allowedHostnamesInput = await p.text({\n message: \"Allowed hostnames (comma-separated, optional)\",\n defaultValue: (currentServer?.allowedHostnames ?? []).join(\", \"),\n placeholder: \"dotta-macbook-pro, your-host.tailnet.ts.net\",\n validate: (val) => {\n try {\n parseHostnameCsv(val);\n return;\n } catch (err) {\n return err instanceof Error ? err.message : \"Invalid hostname list\";\n }\n },\n });\n\n if (p.isCancel(allowedHostnamesInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n allowedHostnames = parseHostnameCsv(allowedHostnamesInput);\n }\n\n const port = Number(portStr) || 3100;\n let auth: AuthConfig = { baseUrlMode: \"auto\", disableSignUp: false };\n if (deploymentMode === \"authenticated\" && exposure === \"public\") {\n const urlInput = await p.text({\n message: \"Public base URL\",\n defaultValue: currentAuth?.publicBaseUrl ?? \"\",\n placeholder: \"https://rudder.example.com\",\n validate: (val) => {\n const candidate = val.trim();\n if (!candidate) return \"Public base URL is required for public exposure\";\n try {\n const url = new URL(candidate);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return \"URL must start with http:// or https://\";\n }\n return;\n } catch {\n return \"Enter a valid URL\";\n }\n },\n });\n if (p.isCancel(urlInput)) {\n p.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n auth = {\n baseUrlMode: \"explicit\",\n disableSignUp: false,\n publicBaseUrl: urlInput.trim().replace(/\\/+$/, \"\"),\n };\n } else if (currentAuth?.baseUrlMode === \"explicit\" && currentAuth.publicBaseUrl) {\n auth = {\n baseUrlMode: \"explicit\",\n disableSignUp: false,\n publicBaseUrl: currentAuth.publicBaseUrl,\n };\n }\n\n return {\n server: {\n deploymentMode,\n exposure,\n host: hostStr.trim(),\n port,\n allowedHostnames,\n serveUi: currentServer?.serveUi ?? true,\n },\n auth,\n };\n}\n", "import { spawnSync } from \"node:child_process\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolveRudderHomeDir } from \"../config/home.js\";\n\nexport const RUNTIME_NPM_PACKAGE_NAME = \"@rudderhq/server\";\nexport const RUNTIME_METADATA_FILE = \"runtime.json\";\n\nexport interface RuntimeInstallMetadata {\n version: 1;\n packageName: string;\n packageVersion: string;\n installedAt: string;\n}\n\nexport interface RuntimeInstallResult {\n status: \"hit\" | \"installed\";\n cacheDir: string;\n packageSpec: string;\n command: string;\n output: string;\n}\n\nexport interface EnsureRuntimeInstalledOptions {\n version: string;\n homeDir?: string;\n packageName?: string;\n spawnSyncImpl?: typeof spawnSync;\n}\n\nexport class RuntimeInstallError extends Error {\n readonly cacheDir: string;\n readonly command: string;\n readonly output: string;\n\n constructor(message: string, options: { cacheDir: string; command: string; output?: string }) {\n super(message);\n this.name = \"RuntimeInstallError\";\n this.cacheDir = options.cacheDir;\n this.command = options.command;\n this.output = options.output ?? \"\";\n }\n}\n\ntype SpawnSyncResultLike = ReturnType<typeof spawnSync>;\n\nfunction sanitizeRuntimeCacheSegment(value: string): string {\n return encodeURIComponent(value.trim() || \"latest\").replaceAll(\"%\", \"_\");\n}\n\nexport function resolveRuntimePackageVersion(version: string): string {\n const normalized = version.trim();\n return normalized.length > 0 ? normalized : \"latest\";\n}\n\nexport function resolveRuntimeCacheDir(\n version: string,\n homeDir: string = resolveRudderHomeDir(),\n): string {\n return path.join(homeDir, \"runtimes\", sanitizeRuntimeCacheSegment(resolveRuntimePackageVersion(version)));\n}\n\nexport function resolveRuntimePackageSpec(\n version: string,\n packageName: string = RUNTIME_NPM_PACKAGE_NAME,\n): string {\n const packageVersion = resolveRuntimePackageVersion(version);\n return packageVersion === \"latest\" ? `${packageName}@latest` : `${packageName}@${packageVersion}`;\n}\n\nexport async function readRuntimeInstallMetadata(\n cacheDir: string,\n): Promise<RuntimeInstallMetadata | null> {\n try {\n const raw = await readFile(path.join(cacheDir, RUNTIME_METADATA_FILE), \"utf8\");\n const parsed = JSON.parse(raw) as RuntimeInstallMetadata;\n if (parsed.version !== 1) return null;\n if (typeof parsed.packageName !== \"string\" || typeof parsed.packageVersion !== \"string\") return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport async function isRuntimeCacheHit(options: {\n cacheDir: string;\n version: string;\n packageName?: string;\n}): Promise<boolean> {\n const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;\n const packageVersion = resolveRuntimePackageVersion(options.version);\n const metadata = await readRuntimeInstallMetadata(options.cacheDir);\n if (!metadata || metadata.packageName !== packageName || metadata.packageVersion !== packageVersion) {\n return false;\n }\n\n try {\n const packageJsonPath = path.join(options.cacheDir, \"node_modules\", ...packageName.split(\"/\"), \"package.json\");\n const packageJson = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as { version?: string };\n return packageVersion === \"latest\" || packageJson.version === packageVersion;\n } catch {\n return false;\n }\n}\n\nexport async function ensureRuntimeInstalled(\n options: EnsureRuntimeInstalledOptions,\n): Promise<RuntimeInstallResult> {\n const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;\n const packageVersion = resolveRuntimePackageVersion(options.version);\n const cacheDir = resolveRuntimeCacheDir(packageVersion, options.homeDir);\n const packageSpec = resolveRuntimePackageSpec(packageVersion, packageName);\n const command = `npm install --prefix ${cacheDir} --omit=dev --no-audit --no-fund ${packageSpec}`;\n\n if (await isRuntimeCacheHit({ cacheDir, version: packageVersion, packageName })) {\n return { status: \"hit\", cacheDir, packageSpec, command, output: \"\" };\n }\n\n await mkdir(cacheDir, { recursive: true });\n await writeFile(path.join(cacheDir, \"package.json\"), `${JSON.stringify({ private: true, type: \"module\" }, null, 2)}\\n`, \"utf8\");\n\n const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;\n const result = runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec);\n const output = collectSpawnOutput(result);\n if (result.status !== 0) {\n throw new RuntimeInstallError(\n `Rudder runtime installation failed. Re-run manually: ${command}`,\n { cacheDir, command, output },\n );\n }\n\n const metadata: RuntimeInstallMetadata = {\n version: 1,\n packageName,\n packageVersion,\n installedAt: new Date().toISOString(),\n };\n await writeFile(path.join(cacheDir, RUNTIME_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\\n`, \"utf8\");\n\n return { status: \"installed\", cacheDir, packageSpec, command, output };\n}\n\nexport function resolveRuntimeServerEntrypoint(cacheDir: string, packageName = RUNTIME_NPM_PACKAGE_NAME): string {\n return createRequire(path.join(cacheDir, \"package.json\")).resolve(packageName);\n}\n\nexport async function importRuntimeServerModule(cacheDir: string, packageName = RUNTIME_NPM_PACKAGE_NAME): Promise<unknown> {\n const entrypoint = resolveRuntimeServerEntrypoint(cacheDir, packageName);\n return await import(pathToFileURL(entrypoint).href);\n}\n\nfunction runNpmRuntimeInstall(\n spawnSyncImpl: typeof spawnSync,\n cacheDir: string,\n packageSpec: string,\n): SpawnSyncResultLike {\n return spawnSyncImpl(\n process.platform === \"win32\" ? \"npm.cmd\" : \"npm\",\n [\"install\", \"--prefix\", cacheDir, \"--omit=dev\", \"--no-audit\", \"--no-fund\", packageSpec],\n {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n ...(process.platform === \"win32\" ? { shell: true, windowsHide: true } : {}),\n },\n );\n}\n\nfunction collectSpawnOutput(result: SpawnSyncResultLike): string {\n return [result.stdout, result.stderr, result.error instanceof Error ? result.error.message : null]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport {\n ensureRuntimeInstalled,\n importRuntimeServerModule,\n type EnsureRuntimeInstalledOptions,\n} from \"./install.js\";\n\nexport interface StartedServer {\n apiUrl: string;\n databaseUrl: string | null;\n host: string;\n listenPort: number;\n runtime: {\n mode: \"owned\" | \"attached\";\n instanceId: string;\n localEnv: string | null;\n ownerKind: string | null;\n version: string;\n };\n stop(): Promise<void>;\n dispose(): Promise<void>;\n}\n\nexport interface LoadServerRuntimeOptions {\n version: string;\n homeDir?: string;\n onRuntimeInstalled?: (result: Awaited<ReturnType<typeof ensureRuntimeInstalled>>) => void;\n}\n\nfunction formatError(err: unknown): string {\n if (err instanceof Error) {\n if (err.message && err.message.trim().length > 0) return err.message;\n return err.name;\n }\n if (typeof err === \"string\") return err;\n try {\n return JSON.stringify(err);\n } catch {\n return String(err);\n }\n}\n\nfunction maybeEnableUiDevMiddleware(entrypoint: string): void {\n if (process.env.RUDDER_UI_DEV_MIDDLEWARE !== undefined) return;\n const normalized = entrypoint.replaceAll(\"\\\\\", \"/\");\n if (normalized.endsWith(\"/server/src/index.ts\") || normalized.endsWith(\"@rudderhq/server/src/index.ts\")) {\n process.env.RUDDER_UI_DEV_MIDDLEWARE = \"true\";\n }\n}\n\nfunction resolveDevServerEntry(): string {\n const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"../../..\");\n return path.resolve(projectRoot, \"server/src/index.ts\");\n}\n\nexport async function loadServerRuntimeModule(options: LoadServerRuntimeOptions): Promise<unknown> {\n const devEntry = resolveDevServerEntry();\n if (fs.existsSync(devEntry)) {\n maybeEnableUiDevMiddleware(devEntry);\n return await import(pathToFileURL(devEntry).href);\n }\n\n const installOptions: EnsureRuntimeInstalledOptions = {\n version: options.version,\n homeDir: options.homeDir,\n };\n const runtime = await ensureRuntimeInstalled(installOptions);\n options.onRuntimeInstalled?.(runtime);\n return await importRuntimeServerModule(runtime.cacheDir);\n}\n\nexport async function startManagedServerFromRuntime(\n options: LoadServerRuntimeOptions,\n): Promise<StartedServer> {\n try {\n const mod = await loadServerRuntimeModule(options);\n return await startServerFromModule(mod);\n } catch (err) {\n throw new Error(`Rudder server failed to start.\\n${formatError(err)}`);\n }\n}\n\nasync function startServerFromModule(mod: unknown): Promise<StartedServer> {\n const startManagedLocalServer = (mod as {\n startManagedLocalServer?: (options: {\n ownerKind: \"cli\";\n takeoverOnVersionMismatch?: boolean;\n }) => Promise<StartedServer>;\n }).startManagedLocalServer;\n if (typeof startManagedLocalServer !== \"function\") {\n throw new Error(\"Rudder server runtime did not export startManagedLocalServer().\");\n }\n return await startManagedLocalServer({\n ownerKind: \"cli\",\n takeoverOnVersionMismatch: true,\n });\n}\n", "import { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\ntype PackageJson = {\n name?: string;\n version?: string;\n};\n\nconst CLI_PACKAGE_NAME = \"@rudderhq/cli\";\nconst CLI_VERSION_MANIFEST = \"rudder-cli-package.json\";\n\nfunction readPackageVersion(packagePath: string, expectedName: string): string | null {\n if (!existsSync(packagePath)) return null;\n\n try {\n const parsed = JSON.parse(readFileSync(packagePath, \"utf8\")) as PackageJson;\n if (parsed.name === expectedName && parsed.version) return parsed.version;\n } catch {\n return null;\n }\n\n return null;\n}\n\nexport function resolveCliVersion(moduleUrl = import.meta.url, env: NodeJS.ProcessEnv = process.env): string {\n if (env.npm_package_name === CLI_PACKAGE_NAME && env.npm_package_version) {\n return env.npm_package_version;\n }\n\n const moduleDir = path.dirname(fileURLToPath(moduleUrl));\n const candidates = [\n path.resolve(moduleDir, CLI_VERSION_MANIFEST),\n path.resolve(moduleDir, \"package.json\"),\n path.resolve(moduleDir, \"../package.json\"),\n path.resolve(moduleDir, \"../../package.json\"),\n ];\n\n for (const candidate of candidates) {\n const version = readPackageVersion(candidate, CLI_PACKAGE_NAME);\n if (version) return version;\n }\n\n return \"0.0.0\";\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { loadRudderEnvFile } from \"../config/env.js\";\nimport { readConfig, resolveConfigPath } from \"../config/store.js\";\nimport { loadServerRuntimeModule } from \"../runtime/server-entry.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\ntype BootstrapCeoInviteRuntimeModule = {\n createBootstrapCeoInvite?: (options: {\n dbUrl: string;\n force?: boolean;\n expiresHours?: number;\n }) => Promise<{\n token: string;\n expiresAt: Date | string;\n } | null>;\n};\n\nfunction resolveDbUrl(configPath?: string, explicitDbUrl?: string) {\n if (explicitDbUrl) return explicitDbUrl;\n const config = readConfig(configPath);\n if (process.env.DATABASE_URL) return process.env.DATABASE_URL;\n if (config?.database.mode === \"postgres\" && config.database.connectionString) {\n return config.database.connectionString;\n }\n if (config?.database.mode === \"embedded-postgres\") {\n const port = config.database.embeddedPostgresPort ?? 54329;\n return `postgres://rudder:rudder@127.0.0.1:${port}/rudder`;\n }\n return null;\n}\n\nfunction resolveBaseUrl(configPath?: string, explicitBaseUrl?: string) {\n if (explicitBaseUrl) return explicitBaseUrl.replace(/\\/+$/, \"\");\n const fromEnv =\n process.env.RUDDER_PUBLIC_URL ??\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL ??\n process.env.BETTER_AUTH_URL ??\n process.env.BETTER_AUTH_BASE_URL;\n if (fromEnv?.trim()) return fromEnv.trim().replace(/\\/+$/, \"\");\n const config = readConfig(configPath);\n if (config?.auth.baseUrlMode === \"explicit\" && config.auth.publicBaseUrl) {\n return config.auth.publicBaseUrl.replace(/\\/+$/, \"\");\n }\n const host = config?.server.host ?? \"localhost\";\n const port = config?.server.port ?? 3100;\n const publicHost = host === \"0.0.0.0\" ? \"localhost\" : host;\n return `http://${publicHost}:${port}`;\n}\n\nexport async function bootstrapCeoInvite(opts: {\n config?: string;\n force?: boolean;\n expiresHours?: number;\n baseUrl?: string;\n dbUrl?: string;\n}) {\n const configPath = resolveConfigPath(opts.config);\n loadRudderEnvFile(configPath);\n const config = readConfig(configPath);\n if (!config) {\n p.log.error(`No config found at ${configPath}. Run ${pc.cyan(\"rudder onboard\")} first.`);\n return;\n }\n\n if (config.server.deploymentMode !== \"authenticated\") {\n p.log.info(\"Deployment mode is local_trusted. Bootstrap CEO invite is only required for authenticated mode.\");\n return;\n }\n\n const dbUrl = resolveDbUrl(configPath, opts.dbUrl);\n if (!dbUrl) {\n p.log.error(\n \"Could not resolve database connection for bootstrap.\",\n );\n return;\n }\n\n try {\n const runtimeModule = await loadBootstrapRuntimeModule();\n const createBootstrapCeoInvite = runtimeModule.createBootstrapCeoInvite;\n if (typeof createBootstrapCeoInvite !== \"function\") {\n throw new Error(\"Rudder server runtime did not export createBootstrapCeoInvite().\");\n }\n\n const created = await createBootstrapCeoInvite({\n dbUrl,\n force: opts.force,\n expiresHours: opts.expiresHours,\n });\n\n if (!created) {\n p.log.info(\"Instance already has an admin user. Use --force to generate a new bootstrap invite.\");\n return;\n }\n\n const baseUrl = resolveBaseUrl(configPath, opts.baseUrl);\n const inviteUrl = `${baseUrl}/invite/${created.token}`;\n const expiresAt = created.expiresAt instanceof Date\n ? created.expiresAt\n : new Date(created.expiresAt);\n p.log.success(\"Created bootstrap CEO invite.\");\n p.log.message(`Invite URL: ${pc.cyan(inviteUrl)}`);\n p.log.message(`Expires: ${pc.dim(expiresAt.toISOString())}`);\n } catch (err) {\n p.log.error(`Could not create bootstrap invite: ${err instanceof Error ? err.message : String(err)}`);\n p.log.info(\"If using embedded-postgres, start the Rudder server and run this command again.\");\n }\n}\n\nasync function loadBootstrapRuntimeModule(): Promise<BootstrapCeoInviteRuntimeModule> {\n const version = resolveCliVersion(import.meta.url);\n return await loadServerRuntimeModule({ version: version === \"0.0.0\" ? \"latest\" : version }) as BootstrapCeoInviteRuntimeModule;\n}\n", "import { execFileSync, spawnSync } from \"node:child_process\";\n\nexport const CLI_NPM_PACKAGE_NAME = \"@rudderhq/cli\";\nexport const CLI_BIN_NAME = \"rudder\";\n\ninterface PersistentCliStateOptions {\n entryPath?: string | null | undefined;\n env?: NodeJS.ProcessEnv;\n execFileSyncImpl?: typeof execFileSync;\n}\n\ninterface InstallPersistentCliOptions {\n installSpec: string;\n spawnSyncImpl?: typeof spawnSync;\n}\n\nexport interface PersistentCliState {\n usingNpx: boolean;\n alreadyInstalled: boolean;\n installSpec: string;\n installCommand: string;\n}\n\nexport interface PersistentCliInstallResult {\n ok: boolean;\n command: string;\n output: string;\n}\n\ntype SpawnSyncResultLike = ReturnType<typeof spawnSync>;\n\nfunction normalizePath(value: string | null | undefined): string {\n return (value ?? \"\").replaceAll(\"\\\\\", \"/\").toLowerCase();\n}\n\nexport function isLikelyNpxExecutionContext(\n entryPath: string | null | undefined = process.argv[1],\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n const normalizedEntry = normalizePath(entryPath);\n if (normalizedEntry.includes(\"/_npx/\")) return true;\n\n const npmCommand = env.npm_command?.trim().toLowerCase();\n if (npmCommand === \"exec\" || npmCommand === \"npx\") return true;\n\n return false;\n}\n\nexport function resolvePersistentCliInstallSpec(env: NodeJS.ProcessEnv = process.env): string {\n const pkgName = env.npm_package_name?.trim();\n const pkgVersion = env.npm_package_version?.trim();\n\n if (pkgName === CLI_NPM_PACKAGE_NAME && pkgVersion) {\n return `${pkgName}@${pkgVersion}`;\n }\n\n return CLI_NPM_PACKAGE_NAME;\n}\n\nfunction resolveCommandLookupExecutable(): { command: string; args: string[] } {\n if (process.platform === \"win32\") {\n return { command: \"where\", args: [CLI_BIN_NAME] };\n }\n return { command: \"which\", args: [CLI_BIN_NAME] };\n}\n\nexport function isTransientBinaryPath(candidatePath: string | null | undefined): boolean {\n const normalized = normalizePath(candidatePath);\n return normalized.includes(\"/_npx/\");\n}\n\nexport function hasGlobalInstalledPackage(\n packageName: string,\n execFileSyncImpl: typeof execFileSync = execFileSync,\n): boolean {\n return getGlobalInstalledPackageVersion(packageName, execFileSyncImpl) !== null;\n}\n\nexport function getGlobalInstalledPackageVersion(\n packageName: string,\n execFileSyncImpl: typeof execFileSync = execFileSync,\n): string | null {\n try {\n const output = execFileSyncImpl(\n process.platform === \"win32\" ? \"npm.cmd\" : \"npm\",\n [\"list\", \"--global\", \"--depth=0\", \"--json\", packageName],\n {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n },\n );\n const parsed = JSON.parse(output) as {\n dependencies?: Record<string, { version?: string }>;\n };\n return parsed.dependencies?.[packageName]?.version ?? null;\n } catch {\n return null;\n }\n}\n\nexport function hasPersistentBinaryOnPath(\n execFileSyncImpl: typeof execFileSync = execFileSync,\n): boolean {\n const { command, args } = resolveCommandLookupExecutable();\n\n try {\n const output = execFileSyncImpl(command, args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n const candidate = output\n .split(/\\r?\\n/)\n .map((value) => value.trim())\n .find((value) => value.length > 0);\n return Boolean(candidate) && !isTransientBinaryPath(candidate);\n } catch {\n return false;\n }\n}\n\nexport function detectPersistentCliState(options: PersistentCliStateOptions = {}): PersistentCliState {\n const env = options.env ?? process.env;\n const execFileSyncImpl = options.execFileSyncImpl ?? execFileSync;\n const installSpec = resolvePersistentCliInstallSpec(env);\n const usingNpx = isLikelyNpxExecutionContext(options.entryPath ?? process.argv[1], env);\n\n if (!usingNpx) {\n return {\n usingNpx,\n alreadyInstalled: true,\n installSpec,\n installCommand: `npm install --global ${installSpec}`,\n };\n }\n\n const alreadyInstalled =\n hasGlobalInstalledPackage(CLI_NPM_PACKAGE_NAME, execFileSyncImpl) ||\n hasPersistentBinaryOnPath(execFileSyncImpl);\n\n return {\n usingNpx,\n alreadyInstalled,\n installSpec,\n installCommand: `npm install --global ${installSpec}`,\n };\n}\n\nexport function installPersistentCli(\n options: InstallPersistentCliOptions,\n): PersistentCliInstallResult {\n const spawnSyncImpl = options.spawnSyncImpl ?? spawnSync;\n const command = `npm install --global ${options.installSpec}`;\n const initialResult = runNpmGlobalInstall(spawnSyncImpl, [\"install\", \"--global\", options.installSpec]);\n const initialOutput = collectSpawnOutput(initialResult);\n\n if (initialResult.status === 0 || !isRudderBinConflict(initialOutput)) {\n return {\n ok: initialResult.status === 0,\n command,\n output: initialOutput,\n };\n }\n\n const forcedCommand = `npm install --global --force ${options.installSpec}`;\n const forcedResult = runNpmGlobalInstall(spawnSyncImpl, [\"install\", \"--global\", \"--force\", options.installSpec]);\n const forcedOutput = collectSpawnOutput(forcedResult);\n\n return {\n ok: forcedResult.status === 0,\n command: forcedCommand,\n output: forcedOutput || initialOutput,\n };\n}\n\nfunction runNpmGlobalInstall(\n spawnSyncImpl: typeof spawnSync,\n args: string[],\n): SpawnSyncResultLike {\n return spawnSyncImpl(process.platform === \"win32\" ? \"npm.cmd\" : \"npm\", args, {\n encoding: \"utf8\",\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n ...(process.platform === \"win32\" ? { shell: true, windowsHide: true } : {}),\n });\n}\n\nfunction collectSpawnOutput(result: SpawnSyncResultLike): string {\n return [result.stdout, result.stderr, result.error instanceof Error ? result.error.message : null]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n}\n\nfunction isRudderBinConflict(output: string): boolean {\n const normalized = output.toLowerCase().replaceAll(\"\\\\\", \"/\");\n return (\n normalized.includes(\"eexist\") &&\n (normalized.includes(`/${CLI_BIN_NAME}`) ||\n normalized.includes(`/${CLI_BIN_NAME}.cmd`) ||\n normalized.includes(`/${CLI_BIN_NAME}.ps1`))\n );\n}\n", "import { loadServerRuntimeModule } from \"./server-entry.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\ntype DatabaseRuntimeModule = {\n checkDatabaseConnection?: (dbUrl: string) => Promise<void>;\n};\n\nexport async function checkPostgresConnection(connectionString: string): Promise<void> {\n const version = resolveCliVersion(import.meta.url);\n const runtimeModule = await loadServerRuntimeModule({\n version: version === \"0.0.0\" ? \"latest\" : version,\n }) as DatabaseRuntimeModule;\n if (typeof runtimeModule.checkDatabaseConnection !== \"function\") {\n throw new Error(\"Rudder server runtime did not export checkDatabaseConnection().\");\n }\n await runtimeModule.checkDatabaseConnection(connectionString);\n}\n", "import pc from \"picocolors\";\n\nconst RUDDER_ART = [\n \"\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \",\n \"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\",\n \"\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\",\n \"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\",\n \"\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\",\n \"\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\",\n] as const;\n\nconst TAGLINE = \"Orchestration and control platform for agent work\";\nconst DESCRIPTION = [\n \"Operating layer for agent teams\",\n \"Goals, tasks, knowledge, and workflows in an executable structure\",\n] as const;\n\nexport function printRudderCliBanner(): void {\n const lines = [\n \"\",\n ...RUDDER_ART.map((line) => pc.cyan(line)),\n pc.blue(\" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\"),\n pc.bold(pc.white(` ${TAGLINE}`)),\n ...DESCRIPTION.map((line) => pc.white(` ${line}`)),\n \"\",\n ];\n\n console.log(lines.join(\"\\n\"));\n}\n", "import {\n ensureAgentJwtSecret,\n readAgentJwtSecretFromEnv,\n readAgentJwtSecretFromEnvFile,\n resolveAgentJwtEnvFile,\n} from \"../config/env.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport function agentJwtSecretCheck(configPath?: string): CheckResult {\n if (readAgentJwtSecretFromEnv(configPath)) {\n return {\n name: \"Agent JWT secret\",\n status: \"pass\",\n message: \"RUDDER_AGENT_JWT_SECRET is set in environment\",\n };\n }\n\n const envPath = resolveAgentJwtEnvFile(configPath);\n const fileSecret = readAgentJwtSecretFromEnvFile(envPath);\n\n if (fileSecret) {\n return {\n name: \"Agent JWT secret\",\n status: \"warn\",\n message: `RUDDER_AGENT_JWT_SECRET is present in ${envPath} but not loaded into environment`,\n repairHint: `Set the value from ${envPath} in your shell before starting the Rudder server`,\n };\n }\n\n return {\n name: \"Agent JWT secret\",\n status: \"fail\",\n message: `RUDDER_AGENT_JWT_SECRET missing from environment and ${envPath}`,\n canRepair: true,\n repair: () => {\n ensureAgentJwtSecret(configPath);\n },\n repairHint: `Run with --repair to create ${envPath} containing RUDDER_AGENT_JWT_SECRET`,\n };\n}\n", "import { readConfig, configExists, resolveConfigPath } from \"../config/store.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport function configCheck(configPath?: string): CheckResult {\n const filePath = resolveConfigPath(configPath);\n\n if (!configExists(configPath)) {\n return {\n name: \"Config file\",\n status: \"fail\",\n message: `Config file not found at ${filePath}`,\n canRepair: false,\n repairHint: \"Run `rudder onboard` to create one\",\n };\n }\n\n try {\n readConfig(configPath);\n return {\n name: \"Config file\",\n status: \"pass\",\n message: `Valid config at ${filePath}`,\n };\n } catch (err) {\n return {\n name: \"Config file\",\n status: \"fail\",\n message: `Invalid config: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section database` (or `rudder onboard` to recreate)\",\n };\n }\n}\n", "import type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\n\nfunction isLoopbackHost(host: string) {\n const normalized = host.trim().toLowerCase();\n return normalized === \"127.0.0.1\" || normalized === \"localhost\" || normalized === \"::1\";\n}\n\nexport function deploymentAuthCheck(config: RudderConfig): CheckResult {\n const mode = config.server.deploymentMode;\n const exposure = config.server.exposure;\n const auth = config.auth;\n\n if (mode === \"local_trusted\") {\n if (!isLoopbackHost(config.server.host)) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: `local_trusted requires loopback host binding (found ${config.server.host})`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and set host to 127.0.0.1\",\n };\n }\n return {\n name: \"Deployment/auth mode\",\n status: \"pass\",\n message: \"local_trusted mode is configured for loopback-only access\",\n };\n }\n\n const secret =\n process.env.BETTER_AUTH_SECRET?.trim() ??\n process.env.RUDDER_AGENT_JWT_SECRET?.trim();\n if (!secret) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"authenticated mode requires BETTER_AUTH_SECRET (or RUDDER_AGENT_JWT_SECRET)\",\n canRepair: false,\n repairHint: \"Set BETTER_AUTH_SECRET before starting Rudder\",\n };\n }\n\n if (auth.baseUrlMode === \"explicit\" && !auth.publicBaseUrl) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"auth.baseUrlMode=explicit requires auth.publicBaseUrl\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and provide a base URL\",\n };\n }\n\n if (exposure === \"public\") {\n if (auth.baseUrlMode !== \"explicit\" || !auth.publicBaseUrl) {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"authenticated/public requires explicit auth.publicBaseUrl\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and select public exposure\",\n };\n }\n try {\n const url = new URL(auth.publicBaseUrl);\n if (url.protocol !== \"https:\") {\n return {\n name: \"Deployment/auth mode\",\n status: \"warn\",\n message: \"Public exposure should use an https:// auth.publicBaseUrl\",\n canRepair: false,\n repairHint: \"Use HTTPS in production for secure session cookies\",\n };\n }\n } catch {\n return {\n name: \"Deployment/auth mode\",\n status: \"fail\",\n message: \"auth.publicBaseUrl is not a valid URL\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section server` and provide a valid URL\",\n };\n }\n }\n\n return {\n name: \"Deployment/auth mode\",\n status: \"pass\",\n message: `Mode ${mode}/${exposure} with auth URL mode ${auth.baseUrlMode}`,\n };\n}\n", "export { resolveRuntimeLikePath } from \"../utils/path-resolver.js\";\n", "import fs from \"node:fs\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\nimport { checkPostgresConnection } from \"../runtime/database.js\";\n\nexport async function databaseCheck(config: RudderConfig, configPath?: string): Promise<CheckResult> {\n if (config.database.mode === \"postgres\") {\n if (!config.database.connectionString) {\n return {\n name: \"Database\",\n status: \"fail\",\n message: \"PostgreSQL mode selected but no connection string configured\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section database`\",\n };\n }\n\n try {\n await checkPostgresConnection(config.database.connectionString);\n return {\n name: \"Database\",\n status: \"pass\",\n message: \"PostgreSQL connection successful\",\n };\n } catch (err) {\n return {\n name: \"Database\",\n status: \"fail\",\n message: `Cannot connect to PostgreSQL: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Check your connection string and ensure PostgreSQL is running\",\n };\n }\n }\n\n if (config.database.mode === \"embedded-postgres\") {\n const dataDir = resolveRuntimeLikePath(config.database.embeddedPostgresDataDir, configPath);\n const reportedPath = dataDir;\n if (!fs.existsSync(dataDir)) {\n fs.mkdirSync(reportedPath, { recursive: true });\n }\n\n return {\n name: \"Database\",\n status: \"pass\",\n message: `Embedded PostgreSQL configured at ${dataDir} (port ${config.database.embeddedPostgresPort})`,\n };\n }\n\n return {\n name: \"Database\",\n status: \"fail\",\n message: `Unknown database mode: ${String(config.database.mode)}`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section database`\",\n };\n}\n", "import type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport async function llmCheck(config: RudderConfig): Promise<CheckResult> {\n if (!config.llm) {\n return {\n name: \"LLM provider\",\n status: \"pass\",\n message: \"No LLM provider configured (optional)\",\n };\n }\n\n if (!config.llm.apiKey) {\n return {\n name: \"LLM provider\",\n status: \"pass\",\n message: `${config.llm.provider} configured but no API key set (optional)`,\n };\n }\n\n try {\n if (config.llm.provider === \"claude\") {\n const res = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"x-api-key\": config.llm.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n model: \"claude-sonnet-4-5-20250929\",\n max_tokens: 1,\n messages: [{ role: \"user\", content: \"hi\" }],\n }),\n });\n if (res.ok || res.status === 400) {\n return { name: \"LLM provider\", status: \"pass\", message: \"Claude API key is valid\" };\n }\n if (res.status === 401) {\n return {\n name: \"LLM provider\",\n status: \"fail\",\n message: \"Claude API key is invalid (401)\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section llm`\",\n };\n }\n return {\n name: \"LLM provider\",\n status: \"warn\",\n message: `Claude API returned status ${res.status}`,\n };\n } else {\n const res = await fetch(\"https://api.openai.com/v1/models\", {\n headers: { Authorization: `Bearer ${config.llm.apiKey}` },\n });\n if (res.ok) {\n return { name: \"LLM provider\", status: \"pass\", message: \"OpenAI API key is valid\" };\n }\n if (res.status === 401) {\n return {\n name: \"LLM provider\",\n status: \"fail\",\n message: \"OpenAI API key is invalid (401)\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section llm`\",\n };\n }\n return {\n name: \"LLM provider\",\n status: \"warn\",\n message: `OpenAI API returned status ${res.status}`,\n };\n }\n } catch {\n return {\n name: \"LLM provider\",\n status: \"warn\",\n message: \"Could not reach API to validate key\",\n };\n }\n}\n", "import fs from \"node:fs\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\n\nexport function logCheck(config: RudderConfig, configPath?: string): CheckResult {\n const logDir = resolveRuntimeLikePath(config.logging.logDir, configPath);\n const reportedDir = logDir;\n\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(reportedDir, { recursive: true });\n }\n\n try {\n fs.accessSync(reportedDir, fs.constants.W_OK);\n return {\n name: \"Log directory\",\n status: \"pass\",\n message: `Log directory is writable: ${reportedDir}`,\n };\n } catch {\n return {\n name: \"Log directory\",\n status: \"fail\",\n message: `Log directory is not writable: ${logDir}`,\n canRepair: false,\n repairHint: \"Check file permissions on the log directory\",\n };\n }\n}\n", "import net from \"node:net\";\n\nexport function checkPort(port: number): Promise<{ available: boolean; error?: string }> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n resolve({ available: false, error: `Port ${port} is already in use` });\n } else {\n resolve({ available: false, error: err.message });\n }\n });\n server.once(\"listening\", () => {\n server.close(() => resolve({ available: true }));\n });\n server.listen(port, \"127.0.0.1\");\n });\n}\n", "import type { RudderConfig } from \"../config/schema.js\";\nimport { checkPort } from \"../utils/net.js\";\nimport type { CheckResult } from \"./index.js\";\n\nexport async function portCheck(config: RudderConfig): Promise<CheckResult> {\n const port = config.server.port;\n const result = await checkPort(port);\n\n if (result.available) {\n return {\n name: \"Server port\",\n status: \"pass\",\n message: `Port ${port} is available`,\n };\n }\n\n return {\n name: \"Server port\",\n status: \"warn\",\n message: result.error ?? `Port ${port} is not available`,\n canRepair: false,\n repairHint: `Check what's using port ${port} with: lsof -i :${port}`,\n };\n}\n", "import { randomBytes } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\n\nfunction decodeMasterKey(raw: string): Buffer | null {\n const trimmed = raw.trim();\n if (!trimmed) return null;\n\n if (/^[A-Fa-f0-9]{64}$/.test(trimmed)) {\n return Buffer.from(trimmed, \"hex\");\n }\n\n try {\n const decoded = Buffer.from(trimmed, \"base64\");\n if (decoded.length === 32) return decoded;\n } catch {\n // ignored\n }\n\n if (Buffer.byteLength(trimmed, \"utf8\") === 32) {\n return Buffer.from(trimmed, \"utf8\");\n }\n return null;\n}\n\nfunction withStrictModeNote(\n base: Pick<CheckResult, \"name\" | \"status\" | \"message\" | \"canRepair\" | \"repair\" | \"repairHint\">,\n config: RudderConfig,\n): CheckResult {\n const strictModeDisabledInDeployedSetup =\n config.database.mode === \"postgres\" && config.secrets.strictMode === false;\n if (!strictModeDisabledInDeployedSetup) return base;\n\n if (base.status === \"fail\") return base;\n return {\n ...base,\n status: \"warn\",\n message: `${base.message}; strict secret mode is disabled for postgres deployment`,\n repairHint: base.repairHint\n ? `${base.repairHint}. Consider enabling secrets.strictMode`\n : \"Consider enabling secrets.strictMode\",\n };\n}\n\nexport function secretsCheck(config: RudderConfig, configPath?: string): CheckResult {\n const provider = config.secrets.provider;\n if (provider !== \"local_encrypted\") {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message: `${provider} is configured, but this build only supports local_encrypted`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section secrets` and set provider to local_encrypted\",\n };\n }\n\n const envMasterKey = process.env.RUDDER_SECRETS_MASTER_KEY;\n if (envMasterKey && envMasterKey.trim().length > 0) {\n if (!decodeMasterKey(envMasterKey)) {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message:\n \"RUDDER_SECRETS_MASTER_KEY is invalid (expected 32-byte base64, 64-char hex, or raw 32-char string)\",\n canRepair: false,\n repairHint: \"Set RUDDER_SECRETS_MASTER_KEY to a valid key or unset it to use a key file\",\n };\n }\n\n return withStrictModeNote(\n {\n name: \"Secrets adapter\",\n status: \"pass\",\n message: \"Local encrypted provider configured via RUDDER_SECRETS_MASTER_KEY\",\n },\n config,\n );\n }\n\n const keyFileOverride = process.env.RUDDER_SECRETS_MASTER_KEY_FILE;\n const configuredPath =\n keyFileOverride && keyFileOverride.trim().length > 0\n ? keyFileOverride.trim()\n : config.secrets.localEncrypted.keyFilePath;\n const keyFilePath = resolveRuntimeLikePath(configuredPath, configPath);\n\n if (!fs.existsSync(keyFilePath)) {\n return withStrictModeNote(\n {\n name: \"Secrets adapter\",\n status: \"warn\",\n message: `Secrets key file does not exist yet: ${keyFilePath}`,\n canRepair: true,\n repair: () => {\n fs.mkdirSync(path.dirname(keyFilePath), { recursive: true });\n fs.writeFileSync(keyFilePath, randomBytes(32).toString(\"base64\"), {\n encoding: \"utf8\",\n mode: 0o600,\n });\n try {\n fs.chmodSync(keyFilePath, 0o600);\n } catch {\n // best effort\n }\n },\n repairHint: \"Run with --repair to create a local encrypted secrets key file\",\n },\n config,\n );\n }\n\n let raw: string;\n try {\n raw = fs.readFileSync(keyFilePath, \"utf8\");\n } catch (err) {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message: `Could not read secrets key file: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Check file permissions or set RUDDER_SECRETS_MASTER_KEY\",\n };\n }\n\n if (!decodeMasterKey(raw)) {\n return {\n name: \"Secrets adapter\",\n status: \"fail\",\n message: `Invalid key material in ${keyFilePath}`,\n canRepair: false,\n repairHint: \"Replace with valid key material or delete it and run doctor --repair\",\n };\n }\n\n return withStrictModeNote(\n {\n name: \"Secrets adapter\",\n status: \"pass\",\n message: `Local encrypted provider configured with key file ${keyFilePath}`,\n },\n config,\n );\n}\n", "import fs from \"node:fs\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport type { CheckResult } from \"./index.js\";\nimport { resolveRuntimeLikePath } from \"./path-resolver.js\";\n\nexport function storageCheck(config: RudderConfig, configPath?: string): CheckResult {\n if (config.storage.provider === \"local_disk\") {\n const baseDir = resolveRuntimeLikePath(config.storage.localDisk.baseDir, configPath);\n if (!fs.existsSync(baseDir)) {\n fs.mkdirSync(baseDir, { recursive: true });\n }\n\n try {\n fs.accessSync(baseDir, fs.constants.W_OK);\n return {\n name: \"Storage\",\n status: \"pass\",\n message: `Local disk storage is writable: ${baseDir}`,\n };\n } catch {\n return {\n name: \"Storage\",\n status: \"fail\",\n message: `Local storage directory is not writable: ${baseDir}`,\n canRepair: false,\n repairHint: \"Check file permissions for storage.localDisk.baseDir\",\n };\n }\n }\n\n const bucket = config.storage.s3.bucket.trim();\n const region = config.storage.s3.region.trim();\n if (!bucket || !region) {\n return {\n name: \"Storage\",\n status: \"fail\",\n message: \"S3 storage requires non-empty bucket and region\",\n canRepair: false,\n repairHint: \"Run `rudder configure --section storage`\",\n };\n }\n\n return {\n name: \"Storage\",\n status: \"warn\",\n message: `S3 storage configured (bucket=${bucket}, region=${region}). Reachability check is skipped in doctor.`,\n canRepair: false,\n repairHint: \"Verify credentials and endpoint in deployment environment\",\n };\n}\n\n", "export interface CheckResult {\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n message: string;\n canRepair?: boolean;\n repair?: () => void | Promise<void>;\n repairHint?: string;\n}\n\nexport { agentJwtSecretCheck } from \"./agent-jwt-secret-check.js\";\nexport { configCheck } from \"./config-check.js\";\nexport { deploymentAuthCheck } from \"./deployment-auth-check.js\";\nexport { databaseCheck } from \"./database-check.js\";\nexport { llmCheck } from \"./llm-check.js\";\nexport { logCheck } from \"./log-check.js\";\nexport { portCheck } from \"./port-check.js\";\nexport { secretsCheck } from \"./secrets-check.js\";\nexport { storageCheck } from \"./storage-check.js\";\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { readConfig, resolveConfigPath } from \"../config/store.js\";\nimport {\n agentJwtSecretCheck,\n configCheck,\n databaseCheck,\n deploymentAuthCheck,\n llmCheck,\n logCheck,\n portCheck,\n secretsCheck,\n storageCheck,\n type CheckResult,\n} from \"../checks/index.js\";\nimport { loadRudderEnvFile } from \"../config/env.js\";\nimport { printRudderCliBanner } from \"../utils/banner.js\";\n\nconst STATUS_ICON = {\n pass: pc.green(\"\u2713\"),\n warn: pc.yellow(\"!\"),\n fail: pc.red(\"\u2717\"),\n} as const;\n\nexport async function doctor(opts: {\n config?: string;\n repair?: boolean;\n yes?: boolean;\n}): Promise<{ passed: number; warned: number; failed: number }> {\n printRudderCliBanner();\n p.intro(pc.bgCyan(pc.black(\" rudder doctor \")));\n\n const configPath = resolveConfigPath(opts.config);\n loadRudderEnvFile(configPath);\n const results: CheckResult[] = [];\n\n // 1. Config check (must pass before others)\n const cfgResult = configCheck(opts.config);\n results.push(cfgResult);\n printResult(cfgResult);\n\n if (cfgResult.status === \"fail\") {\n return printSummary(results);\n }\n\n let config: RudderConfig;\n try {\n config = readConfig(opts.config)!;\n } catch (err) {\n const readResult: CheckResult = {\n name: \"Config file\",\n status: \"fail\",\n message: `Could not read config: ${err instanceof Error ? err.message : String(err)}`,\n canRepair: false,\n repairHint: \"Run `rudder configure --section database` or `rudder onboard`\",\n };\n results.push(readResult);\n printResult(readResult);\n return printSummary(results);\n }\n\n // 2. Deployment/auth mode check\n const deploymentAuthResult = deploymentAuthCheck(config);\n results.push(deploymentAuthResult);\n printResult(deploymentAuthResult);\n\n // 3. Agent JWT check\n results.push(\n await runRepairableCheck({\n run: () => agentJwtSecretCheck(opts.config),\n configPath,\n opts,\n }),\n );\n\n // 4. Secrets adapter check\n results.push(\n await runRepairableCheck({\n run: () => secretsCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 5. Storage check\n results.push(\n await runRepairableCheck({\n run: () => storageCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 6. Database check\n results.push(\n await runRepairableCheck({\n run: () => databaseCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 7. LLM check\n const llmResult = await llmCheck(config);\n results.push(llmResult);\n printResult(llmResult);\n\n // 8. Log directory check\n results.push(\n await runRepairableCheck({\n run: () => logCheck(config, configPath),\n configPath,\n opts,\n }),\n );\n\n // 9. Port check\n const portResult = await portCheck(config);\n results.push(portResult);\n printResult(portResult);\n\n // Summary\n return printSummary(results);\n}\n\nfunction printResult(result: CheckResult): void {\n const icon = STATUS_ICON[result.status];\n p.log.message(`${icon} ${pc.bold(result.name)}: ${result.message}`);\n if (result.status !== \"pass\" && result.repairHint) {\n p.log.message(` ${pc.dim(result.repairHint)}`);\n }\n}\n\nasync function maybeRepair(\n result: CheckResult,\n opts: { repair?: boolean; yes?: boolean },\n): Promise<boolean> {\n if (result.status === \"pass\" || !result.canRepair || !result.repair) return false;\n if (!opts.repair) return false;\n\n let shouldRepair = opts.yes;\n if (!shouldRepair) {\n const answer = await p.confirm({\n message: `Repair \"${result.name}\"?`,\n initialValue: true,\n });\n if (p.isCancel(answer)) return false;\n shouldRepair = answer;\n }\n\n if (shouldRepair) {\n try {\n await result.repair();\n p.log.success(`Repaired: ${result.name}`);\n return true;\n } catch (err) {\n p.log.error(`Repair failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n return false;\n}\n\nasync function runRepairableCheck(input: {\n run: () => CheckResult | Promise<CheckResult>;\n configPath: string;\n opts: { repair?: boolean; yes?: boolean };\n}): Promise<CheckResult> {\n let result = await input.run();\n printResult(result);\n\n const repaired = await maybeRepair(result, input.opts);\n if (!repaired) return result;\n\n // Repairs may create/update the adjacent .env file or other local resources.\n loadRudderEnvFile(input.configPath);\n result = await input.run();\n printResult(result);\n return result;\n}\n\nfunction printSummary(results: CheckResult[]): { passed: number; warned: number; failed: number } {\n const passed = results.filter((r) => r.status === \"pass\").length;\n const warned = results.filter((r) => r.status === \"warn\").length;\n const failed = results.filter((r) => r.status === \"fail\").length;\n\n const parts: string[] = [];\n parts.push(pc.green(`${passed} passed`));\n if (warned) parts.push(pc.yellow(`${warned} warnings`));\n if (failed) parts.push(pc.red(`${failed} failed`));\n\n p.note(parts.join(\", \"), \"Summary\");\n\n if (failed > 0) {\n p.outro(pc.red(\"Some checks failed. Fix the issues above and re-run doctor.\"));\n } else if (warned > 0) {\n p.outro(pc.yellow(\"All critical checks passed with some warnings.\"));\n } else {\n p.outro(pc.green(\"All checks passed!\"));\n }\n\n return { passed, warned, failed };\n}\n", "export const LOCAL_ENV_NAMES = [\"dev\", \"prod_local\", \"e2e\"] as const;\n\nexport type LocalEnvName = (typeof LOCAL_ENV_NAMES)[number];\n\nexport type LocalEnvProfile = {\n name: LocalEnvName;\n instanceId: string;\n port: number;\n embeddedPostgresPort: number;\n resettable: boolean;\n description: string;\n};\n\nconst LOCAL_ENV_PROFILES: Record<LocalEnvName, LocalEnvProfile> = {\n dev: {\n name: \"dev\",\n instanceId: \"dev\",\n port: 3100,\n embeddedPostgresPort: 54329,\n resettable: true,\n description: \"Disposable local development instance\",\n },\n prod_local: {\n name: \"prod_local\",\n instanceId: \"default\",\n port: 3200,\n embeddedPostgresPort: 54339,\n resettable: false,\n description: \"Persistent local instance\",\n },\n e2e: {\n name: \"e2e\",\n instanceId: \"e2e\",\n port: 3300,\n embeddedPostgresPort: 54349,\n resettable: true,\n description: \"Isolated end-to-end test instance\",\n },\n};\n\nexport function parseLocalEnvName(value: string | null | undefined): LocalEnvName | null {\n if (!value) return null;\n const normalized = value.trim().toLowerCase().replace(/-/g, \"_\");\n return (LOCAL_ENV_NAMES as readonly string[]).includes(normalized)\n ? (normalized as LocalEnvName)\n : null;\n}\n\nexport function resolveLocalEnvProfile(value: string | null | undefined): LocalEnvProfile | null {\n const name = parseLocalEnvName(value);\n return name ? LOCAL_ENV_PROFILES[name] : null;\n}\n\nexport function resolveActiveLocalEnvProfile(): LocalEnvProfile | null {\n return resolveLocalEnvProfile(process.env.RUDDER_LOCAL_ENV);\n}\n\nexport function applyLocalEnvProfile(input: {\n localEnv?: string | null;\n instance?: string | null;\n}): LocalEnvProfile | null {\n const profile = resolveLocalEnvProfile(input.localEnv ?? process.env.RUDDER_LOCAL_ENV);\n if (!profile) return null;\n\n process.env.RUDDER_LOCAL_ENV = profile.name;\n if (!input.instance?.trim()) {\n process.env.RUDDER_INSTANCE_ID = profile.instanceId;\n }\n if (!process.env.PORT?.trim()) {\n process.env.PORT = String(profile.port);\n }\n if (!process.env.RUDDER_EMBEDDED_POSTGRES_PORT?.trim()) {\n process.env.RUDDER_EMBEDDED_POSTGRES_PORT = String(profile.embeddedPostgresPort);\n }\n return profile;\n}\n\nexport function getDisposableLocalEnvProfiles(): LocalEnvProfile[] {\n return Object.values(LOCAL_ENV_PROFILES).filter((profile) => profile.resettable);\n}\n", "import fs from \"node:fs\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { bootstrapCeoInvite } from \"./auth-bootstrap-ceo.js\";\nimport { onboard } from \"./onboard.js\";\nimport { doctor } from \"./doctor.js\";\nimport { loadRudderEnvFile } from \"../config/env.js\";\nimport { configExists, resolveConfigPath } from \"../config/store.js\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { readConfig } from \"../config/store.js\";\nimport { applyLocalEnvProfile, resolveActiveLocalEnvProfile } from \"../config/local-env.js\";\nimport {\n describeLocalInstancePaths,\n resolveRudderHomeDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\nimport { startManagedServerFromRuntime, type StartedServer } from \"../runtime/server-entry.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\ninterface RunOptions {\n config?: string;\n instance?: string;\n repair?: boolean;\n yes?: boolean;\n}\n\nexport async function runCommand(opts: RunOptions): Promise<void> {\n let localEnvProfile = resolveActiveLocalEnvProfile();\n if (!localEnvProfile && !opts.instance?.trim() && !process.env.RUDDER_INSTANCE_ID?.trim()) {\n localEnvProfile = applyLocalEnvProfile({ localEnv: \"prod_local\" });\n }\n const instanceId = resolveRudderInstanceId(opts.instance);\n process.env.RUDDER_INSTANCE_ID = instanceId;\n\n const homeDir = resolveRudderHomeDir();\n fs.mkdirSync(homeDir, { recursive: true });\n\n const paths = describeLocalInstancePaths(instanceId);\n fs.mkdirSync(paths.instanceRoot, { recursive: true });\n\n const configPath = resolveConfigPath(opts.config);\n process.env.RUDDER_CONFIG = configPath;\n loadRudderEnvFile(configPath);\n\n p.intro(pc.bgCyan(pc.black(\" rudder run \")));\n if (localEnvProfile) {\n p.log.message(pc.dim(`Local env: ${localEnvProfile.name} (${localEnvProfile.description})`));\n }\n p.log.message(pc.dim(`Home: ${paths.homeDir}`));\n p.log.message(pc.dim(`Instance: ${paths.instanceId}`));\n p.log.message(pc.dim(`Config: ${configPath}`));\n\n if (!configExists(configPath)) {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n p.log.error(\"No config found and terminal is non-interactive.\");\n p.log.message(`Run ${pc.cyan(\"rudder onboard\")} once, then retry ${pc.cyan(\"rudder run\")}.`);\n process.exit(1);\n }\n\n p.log.step(\"No config found. Starting onboarding...\");\n await onboard({ config: configPath, invokedByRun: true });\n }\n\n p.log.step(\"Running doctor checks...\");\n const summary = await doctor({\n config: configPath,\n repair: opts.repair ?? true,\n yes: opts.yes ?? true,\n });\n\n if (summary.failed > 0) {\n p.log.error(\"Doctor found blocking issues. Not starting server.\");\n process.exit(1);\n }\n\n const config = readConfig(configPath);\n if (!config) {\n p.log.error(`No config found at ${configPath}.`);\n process.exit(1);\n }\n\n p.log.step(\"Starting Rudder server...\");\n const startedServer = await startManagedServerFromRuntime({ version: resolveRunRuntimeVersion() });\n if (startedServer.runtime.mode === \"attached\") {\n p.log.message(\n pc.dim(\n `Attached to existing ${startedServer.runtime.localEnv ?? startedServer.runtime.instanceId} runtime ` +\n `(${startedServer.runtime.ownerKind ?? \"unknown-owner\"}, v${startedServer.runtime.version}) at ${startedServer.apiUrl.replace(/\\/api$/, \"\")}`,\n ),\n );\n return;\n }\n\n if (startedServer.databaseUrl && shouldGenerateBootstrapInviteAfterStart(config)) {\n p.log.step(\"Generating bootstrap CEO invite\");\n await bootstrapCeoInvite({\n config: configPath,\n dbUrl: startedServer.databaseUrl,\n baseUrl: resolveBootstrapInviteBaseUrl(config, startedServer),\n });\n }\n\n // Keep running until the server is stopped\n await new Promise<void>((resolve) => {\n const checkInterval = setInterval(() => {\n // Server will be stopped via SIGTERM/SIGINT which triggers dispose()\n // We keep this promise pending until explicitly resolved via signal handler\n }, 1000);\n\n const cleanup = () => {\n clearInterval(checkInterval);\n resolve();\n };\n\n process.once(\"SIGINT\", cleanup);\n process.once(\"SIGTERM\", cleanup);\n });\n\n p.log.step(\"Shutting down...\");\n await startedServer.dispose();\n}\n\nfunction resolveBootstrapInviteBaseUrl(\n config: RudderConfig,\n startedServer: StartedServer,\n): string {\n const explicitBaseUrl =\n process.env.RUDDER_PUBLIC_URL ??\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL ??\n process.env.BETTER_AUTH_URL ??\n process.env.BETTER_AUTH_BASE_URL ??\n (config.auth.baseUrlMode === \"explicit\" ? config.auth.publicBaseUrl : undefined);\n\n if (typeof explicitBaseUrl === \"string\" && explicitBaseUrl.trim().length > 0) {\n return explicitBaseUrl.trim().replace(/\\/+$/, \"\");\n }\n\n return startedServer.apiUrl.replace(/\\/api$/, \"\");\n}\n\nfunction shouldGenerateBootstrapInviteAfterStart(config: RudderConfig): boolean {\n return config.server.deploymentMode === \"authenticated\" && config.database.mode === \"embedded-postgres\";\n}\n\nfunction resolveRunRuntimeVersion(): string {\n const version = resolveCliVersion(import.meta.url);\n return version === \"0.0.0\" ? \"latest\" : version;\n}\n", "import * as p from \"@clack/prompts\";\nimport path from \"node:path\";\nimport pc from \"picocolors\";\nimport {\n AUTH_BASE_URL_MODES,\n DEPLOYMENT_EXPOSURES,\n DEPLOYMENT_MODES,\n SECRET_PROVIDERS,\n STORAGE_PROVIDERS,\n type AuthBaseUrlMode,\n type DeploymentExposure,\n type DeploymentMode,\n type SecretProvider,\n type StorageProvider,\n} from \"@rudderhq/shared\";\nimport { configExists, readConfig, resolveConfigPath, writeConfig } from \"../config/store.js\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { ensureAgentJwtSecret, resolveAgentJwtEnvFile } from \"../config/env.js\";\nimport { ensureLocalSecretsKeyFile } from \"../config/secrets-key.js\";\nimport { promptDatabase } from \"../prompts/database.js\";\nimport { promptLlm } from \"../prompts/llm.js\";\nimport { promptLogging } from \"../prompts/logging.js\";\nimport { defaultSecretsConfig } from \"../prompts/secrets.js\";\nimport { defaultStorageConfig, promptStorage } from \"../prompts/storage.js\";\nimport { promptServer } from \"../prompts/server.js\";\nimport {\n describeLocalInstancePaths,\n expandHomePrefix,\n resolveDefaultBackupDir,\n resolveDefaultEmbeddedPostgresDir,\n resolveDefaultLogsDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\nimport { bootstrapCeoInvite } from \"./auth-bootstrap-ceo.js\";\nimport { detectPersistentCliState, installPersistentCli } from \"../install.js\";\nimport { checkPostgresConnection } from \"../runtime/database.js\";\nimport { printRudderCliBanner } from \"../utils/banner.js\";\n\ntype SetupMode = \"quickstart\" | \"advanced\";\n\ntype OnboardOptions = {\n config?: string;\n run?: boolean;\n yes?: boolean;\n invokedByRun?: boolean;\n};\n\ntype OnboardDefaults = Pick<RudderConfig, \"database\" | \"logging\" | \"server\" | \"auth\" | \"storage\" | \"secrets\">;\n\nconst ONBOARD_ENV_KEYS = [\n \"RUDDER_PUBLIC_URL\",\n \"DATABASE_URL\",\n \"RUDDER_DB_BACKUP_ENABLED\",\n \"RUDDER_DB_BACKUP_INTERVAL_MINUTES\",\n \"RUDDER_DB_BACKUP_RETENTION_DAYS\",\n \"RUDDER_DB_BACKUP_DIR\",\n \"RUDDER_DEPLOYMENT_MODE\",\n \"RUDDER_DEPLOYMENT_EXPOSURE\",\n \"HOST\",\n \"PORT\",\n \"RUDDER_EMBEDDED_POSTGRES_PORT\",\n \"SERVE_UI\",\n \"RUDDER_ALLOWED_HOSTNAMES\",\n \"RUDDER_AUTH_BASE_URL_MODE\",\n \"RUDDER_AUTH_PUBLIC_BASE_URL\",\n \"BETTER_AUTH_URL\",\n \"BETTER_AUTH_BASE_URL\",\n \"RUDDER_STORAGE_PROVIDER\",\n \"RUDDER_STORAGE_LOCAL_DIR\",\n \"RUDDER_STORAGE_S3_BUCKET\",\n \"RUDDER_STORAGE_S3_REGION\",\n \"RUDDER_STORAGE_S3_ENDPOINT\",\n \"RUDDER_STORAGE_S3_PREFIX\",\n \"RUDDER_STORAGE_S3_FORCE_PATH_STYLE\",\n \"RUDDER_SECRETS_PROVIDER\",\n \"RUDDER_SECRETS_STRICT_MODE\",\n \"RUDDER_SECRETS_MASTER_KEY_FILE\",\n] as const;\n\nfunction parseBooleanFromEnv(rawValue: string | undefined): boolean | null {\n if (rawValue === undefined) return null;\n const lower = rawValue.trim().toLowerCase();\n if (lower === \"true\" || lower === \"1\" || lower === \"yes\") return true;\n if (lower === \"false\" || lower === \"0\" || lower === \"no\") return false;\n return null;\n}\n\nfunction parseNumberFromEnv(rawValue: string | undefined): number | null {\n if (!rawValue) return null;\n const parsed = Number(rawValue);\n if (!Number.isFinite(parsed)) return null;\n return parsed;\n}\n\nfunction parseEnumFromEnv<T extends string>(rawValue: string | undefined, allowedValues: readonly T[]): T | null {\n if (!rawValue) return null;\n return allowedValues.includes(rawValue as T) ? (rawValue as T) : null;\n}\n\nfunction resolvePathFromEnv(rawValue: string | undefined): string | null {\n if (!rawValue || rawValue.trim().length === 0) return null;\n return path.resolve(expandHomePrefix(rawValue.trim()));\n}\n\nfunction quickstartDefaultsFromEnv(): {\n defaults: OnboardDefaults;\n usedEnvKeys: string[];\n ignoredEnvKeys: Array<{ key: string; reason: string }>;\n} {\n const instanceId = resolveRudderInstanceId();\n const defaultStorage = defaultStorageConfig();\n const defaultSecrets = defaultSecretsConfig();\n const databaseUrl = process.env.DATABASE_URL?.trim() || undefined;\n const publicUrl =\n process.env.RUDDER_PUBLIC_URL?.trim() ||\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL?.trim() ||\n process.env.BETTER_AUTH_URL?.trim() ||\n process.env.BETTER_AUTH_BASE_URL?.trim() ||\n undefined;\n const deploymentMode =\n parseEnumFromEnv<DeploymentMode>(process.env.RUDDER_DEPLOYMENT_MODE, DEPLOYMENT_MODES) ?? \"local_trusted\";\n const deploymentExposureFromEnv = parseEnumFromEnv<DeploymentExposure>(\n process.env.RUDDER_DEPLOYMENT_EXPOSURE,\n DEPLOYMENT_EXPOSURES,\n );\n const deploymentExposure =\n deploymentMode === \"local_trusted\" ? \"private\" : (deploymentExposureFromEnv ?? \"private\");\n const authPublicBaseUrl = publicUrl;\n const authBaseUrlModeFromEnv = parseEnumFromEnv<AuthBaseUrlMode>(\n process.env.RUDDER_AUTH_BASE_URL_MODE,\n AUTH_BASE_URL_MODES,\n );\n const authBaseUrlMode = authBaseUrlModeFromEnv ?? (authPublicBaseUrl ? \"explicit\" : \"auto\");\n const allowedHostnamesFromEnv = process.env.RUDDER_ALLOWED_HOSTNAMES\n ? process.env.RUDDER_ALLOWED_HOSTNAMES\n .split(\",\")\n .map((value) => value.trim().toLowerCase())\n .filter((value) => value.length > 0)\n : [];\n const hostnameFromPublicUrl = publicUrl\n ? (() => {\n try {\n return new URL(publicUrl).hostname.trim().toLowerCase();\n } catch {\n return null;\n }\n })()\n : null;\n const storageProvider =\n parseEnumFromEnv<StorageProvider>(process.env.RUDDER_STORAGE_PROVIDER, STORAGE_PROVIDERS) ??\n defaultStorage.provider;\n const secretsProvider =\n parseEnumFromEnv<SecretProvider>(process.env.RUDDER_SECRETS_PROVIDER, SECRET_PROVIDERS) ??\n defaultSecrets.provider;\n const databaseBackupEnabled = parseBooleanFromEnv(process.env.RUDDER_DB_BACKUP_ENABLED) ?? true;\n const databaseBackupIntervalMinutes = Math.max(\n 1,\n parseNumberFromEnv(process.env.RUDDER_DB_BACKUP_INTERVAL_MINUTES) ?? 60,\n );\n const databaseBackupRetentionDays = Math.max(\n 1,\n parseNumberFromEnv(process.env.RUDDER_DB_BACKUP_RETENTION_DAYS) ?? 30,\n );\n const defaults: OnboardDefaults = {\n database: {\n mode: databaseUrl ? \"postgres\" : \"embedded-postgres\",\n ...(databaseUrl ? { connectionString: databaseUrl } : {}),\n embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(instanceId),\n embeddedPostgresPort: Math.max(\n 1,\n parseNumberFromEnv(process.env.RUDDER_EMBEDDED_POSTGRES_PORT) ?? 54329,\n ),\n backup: {\n enabled: databaseBackupEnabled,\n intervalMinutes: databaseBackupIntervalMinutes,\n retentionDays: databaseBackupRetentionDays,\n dir: resolvePathFromEnv(process.env.RUDDER_DB_BACKUP_DIR) ?? resolveDefaultBackupDir(instanceId),\n },\n },\n logging: {\n mode: \"file\",\n logDir: resolveDefaultLogsDir(instanceId),\n },\n server: {\n deploymentMode,\n exposure: deploymentExposure,\n host: process.env.HOST ?? \"127.0.0.1\",\n port: Number(process.env.PORT) || 3100,\n allowedHostnames: Array.from(new Set([...allowedHostnamesFromEnv, ...(hostnameFromPublicUrl ? [hostnameFromPublicUrl] : [])])),\n serveUi: parseBooleanFromEnv(process.env.SERVE_UI) ?? true,\n },\n auth: {\n baseUrlMode: authBaseUrlMode,\n disableSignUp: false,\n ...(authPublicBaseUrl ? { publicBaseUrl: authPublicBaseUrl } : {}),\n },\n storage: {\n provider: storageProvider,\n localDisk: {\n baseDir:\n resolvePathFromEnv(process.env.RUDDER_STORAGE_LOCAL_DIR) ?? defaultStorage.localDisk.baseDir,\n },\n s3: {\n bucket: process.env.RUDDER_STORAGE_S3_BUCKET ?? defaultStorage.s3.bucket,\n region: process.env.RUDDER_STORAGE_S3_REGION ?? defaultStorage.s3.region,\n endpoint: process.env.RUDDER_STORAGE_S3_ENDPOINT ?? defaultStorage.s3.endpoint,\n prefix: process.env.RUDDER_STORAGE_S3_PREFIX ?? defaultStorage.s3.prefix,\n forcePathStyle:\n parseBooleanFromEnv(process.env.RUDDER_STORAGE_S3_FORCE_PATH_STYLE) ??\n defaultStorage.s3.forcePathStyle,\n },\n },\n secrets: {\n provider: secretsProvider,\n strictMode: parseBooleanFromEnv(process.env.RUDDER_SECRETS_STRICT_MODE) ?? defaultSecrets.strictMode,\n localEncrypted: {\n keyFilePath:\n resolvePathFromEnv(process.env.RUDDER_SECRETS_MASTER_KEY_FILE) ??\n defaultSecrets.localEncrypted.keyFilePath,\n },\n },\n };\n const ignoredEnvKeys: Array<{ key: string; reason: string }> = [];\n if (deploymentMode === \"local_trusted\" && process.env.RUDDER_DEPLOYMENT_EXPOSURE !== undefined) {\n ignoredEnvKeys.push({\n key: \"RUDDER_DEPLOYMENT_EXPOSURE\",\n reason: \"Ignored because deployment mode local_trusted always forces private exposure\",\n });\n }\n\n const ignoredKeySet = new Set(ignoredEnvKeys.map((entry) => entry.key));\n const usedEnvKeys = ONBOARD_ENV_KEYS.filter(\n (key) => process.env[key] !== undefined && !ignoredKeySet.has(key),\n );\n return { defaults, usedEnvKeys, ignoredEnvKeys };\n}\n\nfunction canCreateBootstrapInviteImmediately(config: Pick<RudderConfig, \"database\" | \"server\">): boolean {\n return config.server.deploymentMode === \"authenticated\" && config.database.mode !== \"embedded-postgres\";\n}\n\nexport async function onboard(opts: OnboardOptions): Promise<void> {\n printRudderCliBanner();\n p.intro(pc.bgCyan(pc.black(\" rudder onboard \")));\n const configPath = resolveConfigPath(opts.config);\n const instance = describeLocalInstancePaths(resolveRudderInstanceId());\n p.log.message(\n pc.dim(\n `Local home: ${instance.homeDir} | instance: ${instance.instanceId} | config: ${configPath}`,\n ),\n );\n\n if (configExists(opts.config)) {\n p.log.message(pc.dim(`${configPath} exists, updating config`));\n\n try {\n readConfig(opts.config);\n } catch (err) {\n p.log.message(\n pc.yellow(\n `Existing config appears invalid and will be updated.\\n${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n }\n }\n\n let setupMode: SetupMode = \"quickstart\";\n if (opts.yes) {\n p.log.message(pc.dim(\"`--yes` enabled: using Quickstart defaults.\"));\n } else {\n const setupModeChoice = await p.select({\n message: \"Choose setup path\",\n options: [\n {\n value: \"quickstart\" as const,\n label: \"Quickstart\",\n hint: \"Recommended: local defaults + ready to run\",\n },\n {\n value: \"advanced\" as const,\n label: \"Advanced setup\",\n hint: \"Customize database, server, storage, and more\",\n },\n ],\n initialValue: \"quickstart\",\n });\n if (p.isCancel(setupModeChoice)) {\n p.cancel(\"Setup cancelled.\");\n return;\n }\n setupMode = setupModeChoice as SetupMode;\n }\n\n let llm: RudderConfig[\"llm\"] | undefined;\n const { defaults: derivedDefaults, usedEnvKeys, ignoredEnvKeys } = quickstartDefaultsFromEnv();\n let {\n database,\n logging,\n server,\n auth,\n storage,\n secrets,\n } = derivedDefaults;\n\n if (setupMode === \"advanced\") {\n p.log.step(pc.bold(\"Database\"));\n database = await promptDatabase(database);\n\n if (database.mode === \"postgres\" && database.connectionString) {\n const s = p.spinner();\n s.start(\"Testing database connection...\");\n try {\n await checkPostgresConnection(database.connectionString);\n s.stop(\"Database connection successful\");\n } catch {\n s.stop(pc.yellow(\"Could not connect to database \u2014 you can fix this later with `rudder doctor`\"));\n }\n }\n\n p.log.step(pc.bold(\"LLM Provider\"));\n llm = await promptLlm();\n\n if (llm?.apiKey) {\n const s = p.spinner();\n s.start(\"Validating API key...\");\n try {\n if (llm.provider === \"claude\") {\n const res = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"x-api-key\": llm.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n model: \"claude-sonnet-4-5-20250929\",\n max_tokens: 1,\n messages: [{ role: \"user\", content: \"hi\" }],\n }),\n });\n if (res.ok || res.status === 400) {\n s.stop(\"API key is valid\");\n } else if (res.status === 401) {\n s.stop(pc.yellow(\"API key appears invalid \u2014 you can update it later\"));\n } else {\n s.stop(pc.yellow(\"Could not validate API key \u2014 continuing anyway\"));\n }\n } else {\n const res = await fetch(\"https://api.openai.com/v1/models\", {\n headers: { Authorization: `Bearer ${llm.apiKey}` },\n });\n if (res.ok) {\n s.stop(\"API key is valid\");\n } else if (res.status === 401) {\n s.stop(pc.yellow(\"API key appears invalid \u2014 you can update it later\"));\n } else {\n s.stop(pc.yellow(\"Could not validate API key \u2014 continuing anyway\"));\n }\n }\n } catch {\n s.stop(pc.yellow(\"Could not reach API \u2014 continuing anyway\"));\n }\n }\n\n p.log.step(pc.bold(\"Logging\"));\n logging = await promptLogging();\n\n p.log.step(pc.bold(\"Server\"));\n ({ server, auth } = await promptServer({ currentServer: server, currentAuth: auth }));\n\n p.log.step(pc.bold(\"Storage\"));\n storage = await promptStorage(storage);\n\n p.log.step(pc.bold(\"Secrets\"));\n const secretsDefaults = defaultSecretsConfig();\n secrets = {\n provider: secrets.provider ?? secretsDefaults.provider,\n strictMode: secrets.strictMode ?? secretsDefaults.strictMode,\n localEncrypted: {\n keyFilePath: secrets.localEncrypted?.keyFilePath ?? secretsDefaults.localEncrypted.keyFilePath,\n },\n };\n p.log.message(\n pc.dim(\n `Using defaults: provider=${secrets.provider}, strictMode=${secrets.strictMode}, keyFile=${secrets.localEncrypted.keyFilePath}`,\n ),\n );\n } else {\n p.log.step(pc.bold(\"Quickstart\"));\n p.log.message(pc.dim(\"Using quickstart defaults.\"));\n if (usedEnvKeys.length > 0) {\n p.log.message(pc.dim(`Environment-aware defaults active (${usedEnvKeys.length} env var(s) detected).`));\n } else {\n p.log.message(\n pc.dim(\"No environment overrides detected: embedded database, file storage, local encrypted secrets.\"),\n );\n }\n for (const ignored of ignoredEnvKeys) {\n p.log.message(pc.dim(`Ignored ${ignored.key}: ${ignored.reason}`));\n }\n }\n\n const jwtSecret = ensureAgentJwtSecret(configPath);\n const envFilePath = resolveAgentJwtEnvFile(configPath);\n if (jwtSecret.created) {\n p.log.success(`Created ${pc.cyan(\"RUDDER_AGENT_JWT_SECRET\")} in ${pc.dim(envFilePath)}`);\n } else if (process.env.RUDDER_AGENT_JWT_SECRET?.trim()) {\n p.log.info(`Using existing ${pc.cyan(\"RUDDER_AGENT_JWT_SECRET\")} from environment`);\n } else {\n p.log.info(`Using existing ${pc.cyan(\"RUDDER_AGENT_JWT_SECRET\")} in ${pc.dim(envFilePath)}`);\n }\n\n const config: RudderConfig = {\n $meta: {\n version: 1,\n updatedAt: new Date().toISOString(),\n source: \"onboard\",\n },\n ...(llm && { llm }),\n database,\n logging,\n server,\n auth,\n storage,\n secrets,\n };\n\n const keyResult = ensureLocalSecretsKeyFile(config, configPath);\n if (keyResult.status === \"created\") {\n p.log.success(`Created local secrets key file at ${pc.dim(keyResult.path)}`);\n } else if (keyResult.status === \"existing\") {\n p.log.message(pc.dim(`Using existing local secrets key file at ${keyResult.path}`));\n }\n\n writeConfig(config, opts.config);\n\n const persistentCliState = detectPersistentCliState();\n let persistentCliAvailable = !persistentCliState.usingNpx || persistentCliState.alreadyInstalled;\n\n p.note(\n [\n `Database: ${database.mode}`,\n llm ? `LLM: ${llm.provider}` : \"LLM: not configured\",\n `Logging: ${logging.mode} -> ${logging.logDir}`,\n `Server: ${server.deploymentMode}/${server.exposure} @ ${server.host}:${server.port}`,\n `Allowed hosts: ${server.allowedHostnames.length > 0 ? server.allowedHostnames.join(\", \") : \"(loopback only)\"}`,\n `Auth URL mode: ${auth.baseUrlMode}${auth.publicBaseUrl ? ` (${auth.publicBaseUrl})` : \"\"}`,\n `Storage: ${storage.provider}`,\n `Secrets: ${secrets.provider} (strict mode ${secrets.strictMode ? \"on\" : \"off\"})`,\n \"Agent auth: RUDDER_AGENT_JWT_SECRET configured\",\n ].join(\"\\n\"),\n \"Configuration saved\",\n );\n\n if (persistentCliState.usingNpx && !persistentCliState.alreadyInstalled) {\n p.log.step(\"Persistent CLI install\");\n\n let shouldInstallPersistentCli = Boolean(opts.yes);\n\n if (opts.yes) {\n p.log.message(pc.dim(\"`--yes` enabled: installing the persistent Rudder CLI.\"));\n } else if (process.stdin.isTTY && process.stdout.isTTY) {\n const answer = await p.confirm({\n message: `Install ${pc.cyan(\"rudder\")} globally now so you can use ${pc.cyan(\"rudder ...\")} next time?`,\n initialValue: true,\n });\n if (!p.isCancel(answer)) {\n shouldInstallPersistentCli = answer;\n }\n }\n\n if (shouldInstallPersistentCli) {\n p.log.message(pc.dim(`Running: ${persistentCliState.installCommand}`));\n const installResult = installPersistentCli({ installSpec: persistentCliState.installSpec });\n if (installResult.ok) {\n persistentCliAvailable = true;\n p.log.success(\n `${pc.cyan(\"rudder\")} is now installed. Open a new shell if the command is not visible immediately.`,\n );\n } else {\n p.log.error(\"Global CLI installation failed.\");\n if (installResult.output) {\n p.log.message(pc.dim(installResult.output));\n }\n p.log.message(`Install later with: ${pc.cyan(installResult.command)}`);\n }\n } else {\n p.log.message(`Install later with: ${pc.cyan(persistentCliState.installCommand)}`);\n }\n }\n\n p.note(\n [\n `Run: ${pc.cyan(persistentCliAvailable ? \"rudder run\" : \"npx @rudderhq/cli run\")}`,\n persistentCliAvailable\n ? `Fallback without install context: ${pc.cyan(\"npx @rudderhq/cli run\")}`\n : `Install later for direct use: ${pc.cyan(persistentCliState.installCommand)}`,\n `Reconfigure later: ${pc.cyan(persistentCliAvailable ? \"rudder configure\" : \"npx @rudderhq/cli configure\")}`,\n `Diagnose setup: ${pc.cyan(persistentCliAvailable ? \"rudder doctor\" : \"npx @rudderhq/cli doctor\")}`,\n ].join(\"\\n\"),\n \"Next commands\",\n );\n\n if (canCreateBootstrapInviteImmediately({ database, server })) {\n p.log.step(\"Generating bootstrap CEO invite\");\n await bootstrapCeoInvite({ config: configPath });\n }\n\n let shouldRunNow = opts.run === true || opts.yes === true;\n if (!shouldRunNow && !opts.invokedByRun && process.stdin.isTTY && process.stdout.isTTY) {\n const answer = await p.confirm({\n message: \"Start Rudder now?\",\n initialValue: true,\n });\n if (!p.isCancel(answer)) {\n shouldRunNow = answer;\n }\n }\n\n if (shouldRunNow && !opts.invokedByRun) {\n process.env.RUDDER_OPEN_ON_LISTEN = \"true\";\n const { runCommand } = await import(\"./run.js\");\n await runCommand({ config: configPath, repair: true, yes: true });\n return;\n }\n\n if (server.deploymentMode === \"authenticated\" && database.mode === \"embedded-postgres\") {\n p.log.info(\n [\n \"Bootstrap CEO invite will be created after the server starts.\",\n `Next: ${pc.cyan(\"rudder run\")}`,\n `Then: ${pc.cyan(\"rudder auth bootstrap-ceo\")}`,\n ].join(\"\\n\"),\n );\n }\n\n p.outro(\"You're all set!\");\n}\n", "import { Command, CommanderError } from \"commander\";\nimport { onboard } from \"./commands/onboard.js\";\nimport { doctor } from \"./commands/doctor.js\";\nimport { envCommand } from \"./commands/env.js\";\nimport { configure } from \"./commands/configure.js\";\nimport { startCommand } from \"./commands/start.js\";\nimport { addAllowedHostname } from \"./commands/allowed-hostname.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { heartbeatRun } from \"./commands/heartbeat-run.js\";\nimport { bootstrapCeoInvite } from \"./commands/auth-bootstrap-ceo.js\";\nimport { registerContextCommands } from \"./commands/client/context.js\";\nimport { registerCompanyCommands } from \"./commands/client/company.js\";\nimport { registerIssueCommands } from \"./commands/client/issue.js\";\nimport { registerAgentCommands } from \"./commands/client/agent.js\";\nimport { registerApprovalCommands } from \"./commands/client/approval.js\";\nimport { registerActivityCommands } from \"./commands/client/activity.js\";\nimport { registerDashboardCommands } from \"./commands/client/dashboard.js\";\nimport { registerSkillCommands } from \"./commands/client/skill.js\";\nimport { applyDataDirOverride, type DataDirOptionLike } from \"./config/data-dir.js\";\nimport { loadRudderEnvFile } from \"./config/env.js\";\nimport { applyLocalEnvProfile } from \"./config/local-env.js\";\nimport { registerPluginCommands } from \"./commands/client/plugin.js\";\nimport { registerClientAuthCommands } from \"./commands/client/auth.js\";\nimport { resolveCliVersion } from \"./version.js\";\n\nconst DATA_DIR_OPTION_HELP =\n \"Rudder data directory root (isolates state from ~/.rudder)\";\nconst LOCAL_ENV_OPTION_HELP =\n \"Local environment profile (dev, prod_local, e2e)\";\nconst DEFAULT_WORKTREE_HOME = \"~/.rudder-worktrees\";\n\nasync function importLazyCommandModule<T>(specifier: string, commandName: string): Promise<T> {\n try {\n return await import(specifier) as T;\n } catch (error) {\n if (isMissingLazyCommandModule(error, specifier)) {\n throw new Error(\n `${commandName} is not bundled in the thin Rudder CLI. Run it from a Rudder source checkout or a full runtime install.`,\n );\n }\n throw error;\n }\n}\n\nfunction isMissingLazyCommandModule(error: unknown, specifier: string): boolean {\n if (!(error instanceof Error)) return false;\n const code = (error as { code?: unknown }).code;\n return code === \"ERR_MODULE_NOT_FOUND\" && error.message.includes(specifier);\n}\n\nfunction numberOption(value: string): number {\n return Number(value);\n}\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"rudder\")\n .description(\"Rudder CLI \u2014 setup, diagnose, and configure your instance\")\n .version(resolveCliVersion());\n\n program.option(\"--local-env <name>\", LOCAL_ENV_OPTION_HELP);\n\n program.hook(\"preAction\", (_thisCommand, actionCommand) => {\n const options = actionCommand.optsWithGlobals() as DataDirOptionLike;\n applyLocalEnvProfile(options);\n const optionNames = new Set(actionCommand.options.map((option) => option.attributeName()));\n applyDataDirOverride(options, {\n hasConfigOption: optionNames.has(\"config\"),\n hasContextOption: optionNames.has(\"context\"),\n });\n loadRudderEnvFile(options.config);\n });\n\n program\n .command(\"start\")\n .description(\"Start Rudder Desktop and prepare the matching persistent CLI\")\n .option(\"--no-cli\", \"Skip persistent CLI installation\")\n .option(\"--no-runtime\", \"Skip Rudder runtime installation\")\n .option(\"--no-desktop\", \"Skip desktop app installation\")\n .option(\"--version <version>\", \"Rudder version to start (default: current CLI version)\")\n .option(\"--target-version <version>\", \"Rudder version to start; avoids the root CLI version flag\")\n .option(\"--repo <owner/repo>\", \"GitHub repository that hosts desktop releases\")\n .option(\"--output-dir <path>\", \"Directory for downloaded desktop release assets\")\n .option(\"--desktop-install-dir <path>\", \"Directory for the portable Desktop install\")\n .option(\"--no-open\", \"Install Desktop without launching it\")\n .option(\"--wait-for-active-runs\", \"Wait for active Rudder runs to finish before replacing Desktop\", false)\n .option(\"--desktop-progress-json\", \"Emit newline-delimited Desktop update progress events\")\n .option(\"--desktop-wait-for-apply\", \"Wait for an apply signal after downloading and verifying the Desktop update\", false)\n .option(\"--no-version-check\", \"Skip checking npm for a newer Rudder CLI version\")\n .option(\"--dry-run\", \"Print the start actions without changing the machine\", false)\n .action(startCommand);\n\n program\n .command(\"onboard\")\n .description(\"Interactive first-run setup wizard\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"-y, --yes\", \"Accept defaults (quickstart + start immediately)\", false)\n .option(\"--run\", \"Start Rudder immediately after saving config\", false)\n .action(onboard);\n\n program\n .command(\"doctor\")\n .description(\"Run diagnostic checks on your Rudder setup\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--repair\", \"Attempt to repair issues automatically\")\n .alias(\"--fix\")\n .option(\"-y, --yes\", \"Skip repair confirmation prompts\")\n .action(async (opts) => {\n await doctor(opts);\n });\n\n program\n .command(\"env\")\n .description(\"Print environment variables for deployment\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .action(envCommand);\n\n program\n .command(\"configure\")\n .description(\"Update configuration sections\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"-s, --section <section>\", \"Section to configure (llm, database, logging, server, storage, secrets)\")\n .action(configure);\n\n program\n .command(\"db:backup\")\n .description(\"Create a one-off database backup using current config\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--dir <path>\", \"Backup output directory (overrides config)\")\n .option(\"--retention-days <days>\", \"Retention window used for pruning\", (value) => Number(value))\n .option(\"--filename-prefix <prefix>\", \"Backup filename prefix\", \"rudder\")\n .option(\"--json\", \"Print backup metadata as JSON\")\n .action(async (opts) => {\n const { dbBackupCommand } = await importLazyCommandModule<typeof import(\"./commands/db-backup.js\")>(\n \"./commands/db-backup.js\",\n \"rudder db:backup\",\n );\n await dbBackupCommand(opts);\n });\n\n program\n .command(\"allowed-hostname\")\n .description(\"Allow a hostname for authenticated/private mode access\")\n .argument(\"<host>\", \"Hostname to allow (for example dotta-macbook-pro)\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .action(addAllowedHostname);\n\n program\n .command(\"run\")\n .description(\"Bootstrap local setup (onboard + doctor) and run Rudder\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"-i, --instance <id>\", \"Local instance id (default: default)\")\n .option(\"--repair\", \"Attempt automatic repairs during doctor\", true)\n .option(\"--no-repair\", \"Disable automatic repairs during doctor\")\n .action(runCommand);\n\n const heartbeat = program.command(\"heartbeat\").description(\"Heartbeat utilities\");\n\n heartbeat\n .command(\"run\")\n .description(\"Run one agent heartbeat and stream live logs\")\n .requiredOption(\"-a, --agent-id <agentId>\", \"Agent ID to invoke\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"CLI context profile name\")\n .option(\"--api-base <url>\", \"Base URL for the Rudder server API\")\n .option(\"--api-key <token>\", \"Bearer token for agent-authenticated calls\")\n .option(\n \"--source <source>\",\n \"Invocation source (timer | assignment | on_demand | automation)\",\n \"on_demand\",\n )\n .option(\"--trigger <trigger>\", \"Trigger detail (manual | ping | callback | system)\", \"manual\")\n .option(\"--timeout-ms <ms>\", \"Max time to wait before giving up\", \"0\")\n .option(\"--json\", \"Output raw JSON where applicable\")\n .option(\"--debug\", \"Show raw adapter stdout/stderr JSON chunks\")\n .action(heartbeatRun);\n\n registerContextCommands(program);\n registerCompanyCommands(program);\n registerIssueCommands(program);\n registerAgentCommands(program);\n registerApprovalCommands(program);\n registerActivityCommands(program);\n registerDashboardCommands(program);\n registerSkillCommands(program);\n registerLazyWorktreeCommands(program);\n registerPluginCommands(program);\n registerLazyBenchmarkCommands(program);\n\n const auth = program.command(\"auth\").description(\"Authentication and bootstrap utilities\");\n\n auth\n .command(\"bootstrap-ceo\")\n .description(\"Create a one-time bootstrap invite URL for first instance admin\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"-d, --data-dir <path>\", DATA_DIR_OPTION_HELP)\n .option(\"--force\", \"Create new invite even if admin already exists\", false)\n .option(\"--expires-hours <hours>\", \"Invite expiration window in hours\", numberOption)\n .option(\"--base-url <url>\", \"Public base URL used to print invite link\")\n .action(bootstrapCeoInvite);\n\n registerClientAuthCommands(auth);\n\n return program;\n}\n\nfunction registerLazyWorktreeCommands(program: Command): void {\n const load = () => importLazyCommandModule<typeof import(\"./commands/worktree.js\")>(\n \"./commands/worktree.js\",\n \"rudder worktree\",\n );\n const worktree = program.command(\"worktree\").description(\"Worktree-local Rudder instance helpers\");\n\n program\n .command(\"worktree:make\")\n .description(\"Create ~/NAME as a git worktree, then initialize an isolated Rudder instance inside it\")\n .argument(\"<name>\", \"Worktree name \u2014 auto-prefixed with rudder- if needed (created at ~/rudder-NAME)\")\n .option(\"--start-point <ref>\", \"Remote ref to base the new branch on (env: RUDDER_WORKTREE_START_POINT)\")\n .option(\"--instance <id>\", \"Explicit isolated instance id\")\n .option(\"--home <path>\", `Home root for worktree instances (env: RUDDER_WORKTREES_DIR, default: ${DEFAULT_WORKTREE_HOME})`)\n .option(\"--from-config <path>\", \"Source config.json to seed from\")\n .option(\"--from-data-dir <path>\", \"Source RUDDER_HOME used when deriving the source config\")\n .option(\"--from-instance <id>\", \"Source instance id when deriving the source config\", \"default\")\n .option(\"--server-port <port>\", \"Preferred server port\", numberOption)\n .option(\"--db-port <port>\", \"Preferred embedded Postgres port\", numberOption)\n .option(\"--seed-mode <mode>\", \"Seed profile: minimal or full (default: minimal)\", \"minimal\")\n .option(\"--no-seed\", \"Skip database seeding from the source instance\")\n .option(\"--force\", \"Replace existing repo-local config and isolated instance data\", false)\n .action(async (nameArg: string, opts) => (await load()).worktreeMakeCommand(nameArg, opts));\n\n worktree\n .command(\"init\")\n .description(\"Create repo-local config/env and an isolated instance for this worktree\")\n .option(\"--name <name>\", \"Display name used to derive the instance id\")\n .option(\"--instance <id>\", \"Explicit isolated instance id\")\n .option(\"--home <path>\", `Home root for worktree instances (env: RUDDER_WORKTREES_DIR, default: ${DEFAULT_WORKTREE_HOME})`)\n .option(\"--from-config <path>\", \"Source config.json to seed from\")\n .option(\"--from-data-dir <path>\", \"Source RUDDER_HOME used when deriving the source config\")\n .option(\"--from-instance <id>\", \"Source instance id when deriving the source config\", \"default\")\n .option(\"--server-port <port>\", \"Preferred server port\", numberOption)\n .option(\"--db-port <port>\", \"Preferred embedded Postgres port\", numberOption)\n .option(\"--seed-mode <mode>\", \"Seed profile: minimal or full (default: minimal)\", \"minimal\")\n .option(\"--no-seed\", \"Skip database seeding from the source instance\")\n .option(\"--force\", \"Replace existing repo-local config and isolated instance data\", false)\n .action(async (opts) => (await load()).worktreeInitCommand(opts));\n\n worktree\n .command(\"env\")\n .description(\"Print shell exports for the current worktree-local Rudder instance\")\n .option(\"-c, --config <path>\", \"Path to config file\")\n .option(\"--json\", \"Print JSON instead of shell exports\")\n .action(async (opts) => (await load()).worktreeEnvCommand(opts));\n\n program\n .command(\"worktree:list\")\n .description(\"List git worktrees visible from this repo and whether they look like Rudder worktrees\")\n .option(\"--json\", \"Print JSON instead of text output\")\n .action(async (opts) => (await load()).worktreeListCommand(opts));\n\n program\n .command(\"worktree:merge-history\")\n .description(\"Preview or import issue/comment history from another worktree into the current instance\")\n .argument(\"[source]\", \"Optional source worktree path, directory name, or branch name (back-compat alias for --from)\")\n .option(\"--from <worktree>\", \"Source worktree path, directory name, branch name, or current\")\n .option(\"--to <worktree>\", \"Target worktree path, directory name, branch name, or current (defaults to current)\")\n .option(\"--company <id-or-prefix>\", \"Shared company id or issue prefix inside the chosen source/target instances\")\n .option(\"--scope <items>\", \"Comma-separated scopes to import (issues, comments)\", \"issues,comments\")\n .option(\"--apply\", \"Apply the import after previewing the plan\", false)\n .option(\"--dry\", \"Preview only and do not import anything\", false)\n .option(\"--yes\", \"Skip the interactive confirmation prompt when applying\", false)\n .action(async (sourceArg: string | undefined, opts) => (await load()).worktreeMergeHistoryCommand(sourceArg, opts));\n\n program\n .command(\"worktree:cleanup\")\n .description(\"Safely remove a worktree, its branch, and its isolated instance data\")\n .argument(\"<name>\", \"Worktree name \u2014 auto-prefixed with rudder- if needed\")\n .option(\"--instance <id>\", \"Explicit instance id (if different from the worktree name)\")\n .option(\"--home <path>\", `Home root for worktree instances (env: RUDDER_WORKTREES_DIR, default: ${DEFAULT_WORKTREE_HOME})`)\n .option(\"--force\", \"Bypass safety checks (uncommitted changes, unique commits)\", false)\n .action(async (nameArg: string, opts) => (await load()).worktreeCleanupCommand(nameArg, opts));\n}\n\nfunction registerLazyBenchmarkCommands(program: Command): void {\n const benchmark = program.command(\"benchmark\").description(\"Benchmark and evaluation utilities\");\n benchmark\n .command(\"create-agent\")\n .description(\"Run create-agent benchmark cases\")\n .action(() => {\n throw new Error(\"Benchmark commands require a Rudder source checkout because they use development-only evaluation dependencies.\");\n });\n}\n\nexport async function runCli(argv: string[] = process.argv): Promise<number> {\n const program = createProgram();\n program.exitOverride();\n\n try {\n await program.parseAsync(argv);\n return 0;\n } catch (error) {\n if (error instanceof CommanderError) {\n if (error.code === \"commander.helpDisplayed\" || error.code === \"commander.version\") {\n return error.exitCode;\n }\n if (error.code === \"commander.executeSubCommandAsync\") {\n return error.exitCode;\n }\n if (error.exitCode > 0 && error.message) {\n console.error(error.message);\n return error.exitCode;\n }\n return error.exitCode;\n }\n\n console.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { configExists, readConfig, resolveConfigPath } from \"../config/store.js\";\nimport {\n readAgentJwtSecretFromEnv,\n readAgentJwtSecretFromEnvFile,\n resolveAgentJwtEnvFile,\n} from \"../config/env.js\";\nimport {\n resolveDefaultSecretsKeyFilePath,\n resolveDefaultStorageDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\n\ntype EnvSource = \"env\" | \"config\" | \"file\" | \"default\" | \"missing\";\n\ntype EnvVarRow = {\n key: string;\n value: string;\n source: EnvSource;\n required: boolean;\n note: string;\n};\n\nconst DEFAULT_AGENT_JWT_TTL_SECONDS = \"172800\";\nconst DEFAULT_AGENT_JWT_ISSUER = \"rudder\";\nconst DEFAULT_AGENT_JWT_AUDIENCE = \"rudder-api\";\nconst DEFAULT_HEARTBEAT_SCHEDULER_INTERVAL_MS = \"30000\";\nconst DEFAULT_SECRETS_PROVIDER = \"local_encrypted\";\nconst DEFAULT_STORAGE_PROVIDER = \"local_disk\";\nfunction defaultSecretsKeyFilePath(): string {\n return resolveDefaultSecretsKeyFilePath(resolveRudderInstanceId());\n}\nfunction defaultStorageBaseDir(): string {\n return resolveDefaultStorageDir(resolveRudderInstanceId());\n}\n\nexport async function envCommand(opts: { config?: string }): Promise<void> {\n p.intro(pc.bgCyan(pc.black(\" rudder env \")));\n\n const configPath = resolveConfigPath(opts.config);\n let config: RudderConfig | null = null;\n let configReadError: string | null = null;\n\n if (configExists(opts.config)) {\n p.log.message(pc.dim(`Config file: ${configPath}`));\n try {\n config = readConfig(opts.config);\n } catch (err) {\n configReadError = err instanceof Error ? err.message : String(err);\n p.log.message(pc.yellow(`Could not parse config: ${configReadError}`));\n }\n } else {\n p.log.message(pc.dim(`Config file missing: ${configPath}`));\n }\n\n const rows = collectDeploymentEnvRows(config, configPath);\n const missingRequired = rows.filter((row) => row.required && row.source === \"missing\");\n const sortedRows = rows.sort((a, b) => Number(b.required) - Number(a.required) || a.key.localeCompare(b.key));\n\n const requiredRows = sortedRows.filter((row) => row.required);\n const optionalRows = sortedRows.filter((row) => !row.required);\n\n const formatSection = (title: string, entries: EnvVarRow[]) => {\n if (entries.length === 0) return;\n\n p.log.message(pc.bold(title));\n for (const entry of entries) {\n const status = entry.source === \"missing\" ? pc.red(\"missing\") : entry.source === \"default\" ? pc.yellow(\"default\") : pc.green(\"set\");\n const sourceNote = {\n env: \"environment\",\n config: \"config\",\n file: \"file\",\n default: \"default\",\n missing: \"missing\",\n }[entry.source];\n p.log.message(\n `${pc.cyan(entry.key)} ${status.padEnd(7)} ${pc.dim(`[${sourceNote}] ${entry.note}`)}${entry.source === \"missing\" ? \"\" : ` ${pc.dim(\"=>\")} ${pc.white(quoteShellValue(entry.value))}`}`,\n );\n }\n };\n\n formatSection(\"Required environment variables\", requiredRows);\n formatSection(\"Optional environment variables\", optionalRows);\n\n const exportRows = rows.map((row) => (row.source === \"missing\" ? { ...row, value: \"<set-this-value>\" } : row));\n const uniqueRows = uniqueByKey(exportRows);\n const exportBlock = uniqueRows.map((row) => `export ${row.key}=${quoteShellValue(row.value)}`).join(\"\\n\");\n\n if (configReadError) {\n p.log.error(`Could not load config cleanly: ${configReadError}`);\n }\n\n p.note(\n exportBlock || \"No values detected. Set required variables manually.\",\n \"Deployment export block\",\n );\n\n if (missingRequired.length > 0) {\n p.log.message(\n pc.yellow(\n `Missing required values: ${missingRequired.map((row) => row.key).join(\", \")}. Set these before deployment.`,\n ),\n );\n } else {\n p.log.message(pc.green(\"All required deployment variables are present.\"));\n }\n p.outro(\"Done\");\n}\n\nfunction collectDeploymentEnvRows(config: RudderConfig | null, configPath: string): EnvVarRow[] {\n const agentJwtEnvFile = resolveAgentJwtEnvFile(configPath);\n const jwtEnv = readAgentJwtSecretFromEnv(configPath);\n const jwtFile = jwtEnv ? null : readAgentJwtSecretFromEnvFile(agentJwtEnvFile);\n const jwtSource = jwtEnv ? \"env\" : jwtFile ? \"file\" : \"missing\";\n\n const dbUrl = process.env.DATABASE_URL ?? config?.database?.connectionString ?? \"\";\n const databaseMode = config?.database?.mode ?? \"embedded-postgres\";\n const dbUrlSource: EnvSource = process.env.DATABASE_URL ? \"env\" : config?.database?.connectionString ? \"config\" : \"missing\";\n const publicUrl =\n process.env.RUDDER_PUBLIC_URL ??\n process.env.RUDDER_AUTH_PUBLIC_BASE_URL ??\n process.env.BETTER_AUTH_URL ??\n process.env.BETTER_AUTH_BASE_URL ??\n config?.auth?.publicBaseUrl ??\n \"\";\n const publicUrlSource: EnvSource =\n process.env.RUDDER_PUBLIC_URL\n ? \"env\"\n : process.env.RUDDER_AUTH_PUBLIC_BASE_URL || process.env.BETTER_AUTH_URL || process.env.BETTER_AUTH_BASE_URL\n ? \"env\"\n : config?.auth?.publicBaseUrl\n ? \"config\"\n : \"missing\";\n let trustedOriginsDefault = \"\";\n if (publicUrl) {\n try {\n trustedOriginsDefault = new URL(publicUrl).origin;\n } catch {\n trustedOriginsDefault = \"\";\n }\n }\n\n const heartbeatInterval = process.env.HEARTBEAT_SCHEDULER_INTERVAL_MS ?? DEFAULT_HEARTBEAT_SCHEDULER_INTERVAL_MS;\n const heartbeatEnabled = process.env.HEARTBEAT_SCHEDULER_ENABLED ?? \"true\";\n const secretsProvider =\n process.env.RUDDER_SECRETS_PROVIDER ??\n config?.secrets?.provider ??\n DEFAULT_SECRETS_PROVIDER;\n const secretsStrictMode =\n process.env.RUDDER_SECRETS_STRICT_MODE ??\n String(config?.secrets?.strictMode ?? false);\n const secretsKeyFilePath =\n process.env.RUDDER_SECRETS_MASTER_KEY_FILE ??\n config?.secrets?.localEncrypted?.keyFilePath ??\n defaultSecretsKeyFilePath();\n const storageProvider =\n process.env.RUDDER_STORAGE_PROVIDER ??\n config?.storage?.provider ??\n DEFAULT_STORAGE_PROVIDER;\n const storageLocalDir =\n process.env.RUDDER_STORAGE_LOCAL_DIR ??\n config?.storage?.localDisk?.baseDir ??\n defaultStorageBaseDir();\n const storageS3Bucket =\n process.env.RUDDER_STORAGE_S3_BUCKET ??\n config?.storage?.s3?.bucket ??\n \"rudder\";\n const storageS3Region =\n process.env.RUDDER_STORAGE_S3_REGION ??\n config?.storage?.s3?.region ??\n \"us-east-1\";\n const storageS3Endpoint =\n process.env.RUDDER_STORAGE_S3_ENDPOINT ??\n config?.storage?.s3?.endpoint ??\n \"\";\n const storageS3Prefix =\n process.env.RUDDER_STORAGE_S3_PREFIX ??\n config?.storage?.s3?.prefix ??\n \"\";\n const storageS3ForcePathStyle =\n process.env.RUDDER_STORAGE_S3_FORCE_PATH_STYLE ??\n String(config?.storage?.s3?.forcePathStyle ?? false);\n\n const rows: EnvVarRow[] = [\n {\n key: \"RUDDER_LOCAL_ENV\",\n value: process.env.RUDDER_LOCAL_ENV ?? \"\",\n source: process.env.RUDDER_LOCAL_ENV ? \"env\" : \"missing\",\n required: false,\n note: \"Local environment profile selector (dev, prod_local, e2e)\",\n },\n {\n key: \"RUDDER_INSTANCE_ID\",\n value: process.env.RUDDER_INSTANCE_ID ?? resolveRudderInstanceId(),\n source: process.env.RUDDER_INSTANCE_ID ? \"env\" : \"default\",\n required: false,\n note: \"Local instance identifier used for per-instance config and storage paths\",\n },\n {\n key: \"RUDDER_AGENT_JWT_SECRET\",\n value: jwtEnv ?? jwtFile ?? \"\",\n source: jwtSource,\n required: true,\n note:\n jwtSource === \"missing\"\n ? \"Generate during onboard or set manually (required for local adapter authentication)\"\n : jwtSource === \"env\"\n ? \"Set in process environment\"\n : `Set in ${agentJwtEnvFile}`,\n },\n {\n key: \"DATABASE_URL\",\n value: dbUrl,\n source: dbUrlSource,\n required: true,\n note:\n databaseMode === \"postgres\"\n ? \"Configured for postgres mode (required)\"\n : \"Required for live deployment with managed PostgreSQL\",\n },\n {\n key: \"PORT\",\n value:\n process.env.PORT ??\n (config?.server?.port !== undefined ? String(config.server.port) : \"3100\"),\n source: process.env.PORT ? \"env\" : config?.server?.port !== undefined ? \"config\" : \"default\",\n required: false,\n note: \"HTTP listen port\",\n },\n {\n key: \"RUDDER_EMBEDDED_POSTGRES_PORT\",\n value:\n process.env.RUDDER_EMBEDDED_POSTGRES_PORT ??\n (config?.database?.embeddedPostgresPort !== undefined\n ? String(config.database.embeddedPostgresPort)\n : \"54329\"),\n source:\n process.env.RUDDER_EMBEDDED_POSTGRES_PORT\n ? \"env\"\n : config?.database?.embeddedPostgresPort !== undefined\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Embedded PostgreSQL listen port\",\n },\n {\n key: \"RUDDER_PUBLIC_URL\",\n value: publicUrl,\n source: publicUrlSource,\n required: false,\n note: \"Canonical public URL for auth/callback/invite origin wiring\",\n },\n {\n key: \"BETTER_AUTH_TRUSTED_ORIGINS\",\n value: process.env.BETTER_AUTH_TRUSTED_ORIGINS ?? trustedOriginsDefault,\n source: process.env.BETTER_AUTH_TRUSTED_ORIGINS\n ? \"env\"\n : trustedOriginsDefault\n ? \"default\"\n : \"missing\",\n required: false,\n note: \"Comma-separated auth origin allowlist (auto-derived from RUDDER_PUBLIC_URL when possible)\",\n },\n {\n key: \"RUDDER_AGENT_JWT_TTL_SECONDS\",\n value: process.env.RUDDER_AGENT_JWT_TTL_SECONDS ?? DEFAULT_AGENT_JWT_TTL_SECONDS,\n source: process.env.RUDDER_AGENT_JWT_TTL_SECONDS ? \"env\" : \"default\",\n required: false,\n note: \"JWT lifetime in seconds\",\n },\n {\n key: \"RUDDER_AGENT_JWT_ISSUER\",\n value: process.env.RUDDER_AGENT_JWT_ISSUER ?? DEFAULT_AGENT_JWT_ISSUER,\n source: process.env.RUDDER_AGENT_JWT_ISSUER ? \"env\" : \"default\",\n required: false,\n note: \"JWT issuer\",\n },\n {\n key: \"RUDDER_AGENT_JWT_AUDIENCE\",\n value: process.env.RUDDER_AGENT_JWT_AUDIENCE ?? DEFAULT_AGENT_JWT_AUDIENCE,\n source: process.env.RUDDER_AGENT_JWT_AUDIENCE ? \"env\" : \"default\",\n required: false,\n note: \"JWT audience\",\n },\n {\n key: \"HEARTBEAT_SCHEDULER_INTERVAL_MS\",\n value: heartbeatInterval,\n source: process.env.HEARTBEAT_SCHEDULER_INTERVAL_MS ? \"env\" : \"default\",\n required: false,\n note: \"Heartbeat worker interval in ms\",\n },\n {\n key: \"HEARTBEAT_SCHEDULER_ENABLED\",\n value: heartbeatEnabled,\n source: process.env.HEARTBEAT_SCHEDULER_ENABLED ? \"env\" : \"default\",\n required: false,\n note: \"Set to `false` to disable timer scheduling\",\n },\n {\n key: \"RUDDER_SECRETS_PROVIDER\",\n value: secretsProvider,\n source: process.env.RUDDER_SECRETS_PROVIDER\n ? \"env\"\n : config?.secrets?.provider\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Default provider for new secrets\",\n },\n {\n key: \"RUDDER_SECRETS_STRICT_MODE\",\n value: secretsStrictMode,\n source: process.env.RUDDER_SECRETS_STRICT_MODE\n ? \"env\"\n : config?.secrets?.strictMode !== undefined\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Require secret refs for sensitive env keys\",\n },\n {\n key: \"RUDDER_SECRETS_MASTER_KEY_FILE\",\n value: secretsKeyFilePath,\n source: process.env.RUDDER_SECRETS_MASTER_KEY_FILE\n ? \"env\"\n : config?.secrets?.localEncrypted?.keyFilePath\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Path to local encrypted secrets key file\",\n },\n {\n key: \"RUDDER_STORAGE_PROVIDER\",\n value: storageProvider,\n source: process.env.RUDDER_STORAGE_PROVIDER\n ? \"env\"\n : config?.storage?.provider\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Storage provider (local_disk or s3)\",\n },\n {\n key: \"RUDDER_STORAGE_LOCAL_DIR\",\n value: storageLocalDir,\n source: process.env.RUDDER_STORAGE_LOCAL_DIR\n ? \"env\"\n : config?.storage?.localDisk?.baseDir\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Local storage base directory for local_disk provider\",\n },\n {\n key: \"RUDDER_STORAGE_S3_BUCKET\",\n value: storageS3Bucket,\n source: process.env.RUDDER_STORAGE_S3_BUCKET\n ? \"env\"\n : config?.storage?.s3?.bucket\n ? \"config\"\n : \"default\",\n required: false,\n note: \"S3 bucket name for s3 provider\",\n },\n {\n key: \"RUDDER_STORAGE_S3_REGION\",\n value: storageS3Region,\n source: process.env.RUDDER_STORAGE_S3_REGION\n ? \"env\"\n : config?.storage?.s3?.region\n ? \"config\"\n : \"default\",\n required: false,\n note: \"S3 region for s3 provider\",\n },\n {\n key: \"RUDDER_STORAGE_S3_ENDPOINT\",\n value: storageS3Endpoint,\n source: process.env.RUDDER_STORAGE_S3_ENDPOINT\n ? \"env\"\n : config?.storage?.s3?.endpoint\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Optional custom endpoint for S3-compatible providers\",\n },\n {\n key: \"RUDDER_STORAGE_S3_PREFIX\",\n value: storageS3Prefix,\n source: process.env.RUDDER_STORAGE_S3_PREFIX\n ? \"env\"\n : config?.storage?.s3?.prefix\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Optional object key prefix\",\n },\n {\n key: \"RUDDER_STORAGE_S3_FORCE_PATH_STYLE\",\n value: storageS3ForcePathStyle,\n source: process.env.RUDDER_STORAGE_S3_FORCE_PATH_STYLE\n ? \"env\"\n : config?.storage?.s3?.forcePathStyle !== undefined\n ? \"config\"\n : \"default\",\n required: false,\n note: \"Set true for path-style access on compatible providers\",\n },\n ];\n\n const defaultConfigPath = resolveConfigPath();\n if (process.env.RUDDER_CONFIG || configPath !== defaultConfigPath) {\n rows.push({\n key: \"RUDDER_CONFIG\",\n value: process.env.RUDDER_CONFIG ?? configPath,\n source: process.env.RUDDER_CONFIG ? \"env\" : \"default\",\n required: false,\n note: \"Optional path override for config file\",\n });\n }\n\n return rows;\n}\n\nfunction uniqueByKey(rows: EnvVarRow[]): EnvVarRow[] {\n const seen = new Set<string>();\n const result: EnvVarRow[] = [];\n for (const row of rows) {\n if (seen.has(row.key)) continue;\n seen.add(row.key);\n result.push(row);\n }\n return result;\n}\n\nfunction quoteShellValue(value: string): string {\n if (value === \"\") return \"\\\"\\\"\";\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { readConfig, writeConfig, configExists, resolveConfigPath } from \"../config/store.js\";\nimport type { RudderConfig } from \"../config/schema.js\";\nimport { ensureLocalSecretsKeyFile } from \"../config/secrets-key.js\";\nimport { promptDatabase } from \"../prompts/database.js\";\nimport { promptLlm } from \"../prompts/llm.js\";\nimport { promptLogging } from \"../prompts/logging.js\";\nimport { defaultSecretsConfig, promptSecrets } from \"../prompts/secrets.js\";\nimport { defaultStorageConfig, promptStorage } from \"../prompts/storage.js\";\nimport { promptServer } from \"../prompts/server.js\";\nimport {\n resolveDefaultBackupDir,\n resolveDefaultEmbeddedPostgresDir,\n resolveDefaultLogsDir,\n resolveRudderInstanceId,\n} from \"../config/home.js\";\nimport { printRudderCliBanner } from \"../utils/banner.js\";\n\ntype Section = \"llm\" | \"database\" | \"logging\" | \"server\" | \"storage\" | \"secrets\";\n\nconst SECTION_LABELS: Record<Section, string> = {\n llm: \"LLM Provider\",\n database: \"Database\",\n logging: \"Logging\",\n server: \"Server\",\n storage: \"Storage\",\n secrets: \"Secrets\",\n};\n\nfunction defaultConfig(): RudderConfig {\n const instanceId = resolveRudderInstanceId();\n const embeddedPostgresPort = Math.max(1, Number(process.env.RUDDER_EMBEDDED_POSTGRES_PORT) || 54329);\n const serverPort = Math.max(1, Number(process.env.PORT) || 3100);\n return {\n $meta: {\n version: 1,\n updatedAt: new Date().toISOString(),\n source: \"configure\",\n },\n database: {\n mode: \"embedded-postgres\",\n embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(instanceId),\n embeddedPostgresPort,\n backup: {\n enabled: true,\n intervalMinutes: 60,\n retentionDays: 30,\n dir: resolveDefaultBackupDir(instanceId),\n },\n },\n logging: {\n mode: \"file\",\n logDir: resolveDefaultLogsDir(instanceId),\n },\n server: {\n deploymentMode: \"local_trusted\",\n exposure: \"private\",\n host: \"127.0.0.1\",\n port: serverPort,\n allowedHostnames: [],\n serveUi: true,\n },\n auth: {\n baseUrlMode: \"auto\",\n disableSignUp: false,\n },\n storage: defaultStorageConfig(),\n secrets: defaultSecretsConfig(),\n };\n}\n\nexport async function configure(opts: {\n config?: string;\n section?: string;\n}): Promise<void> {\n printRudderCliBanner();\n p.intro(pc.bgCyan(pc.black(\" rudder configure \")));\n const configPath = resolveConfigPath(opts.config);\n\n if (!configExists(opts.config)) {\n p.log.error(\"No config file found. Run `rudder onboard` first.\");\n p.outro(\"\");\n return;\n }\n\n let config: RudderConfig;\n try {\n config = readConfig(opts.config) ?? defaultConfig();\n } catch (err) {\n p.log.message(\n pc.yellow(\n `Existing config is invalid. Loading defaults so you can repair it now.\\n${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n config = defaultConfig();\n }\n\n let section: Section | undefined = opts.section as Section | undefined;\n\n if (section && !SECTION_LABELS[section]) {\n p.log.error(`Unknown section: ${section}. Choose from: ${Object.keys(SECTION_LABELS).join(\", \")}`);\n p.outro(\"\");\n return;\n }\n\n // Section selection loop\n let continueLoop = true;\n while (continueLoop) {\n if (!section) {\n const choice = await p.select({\n message: \"Which section do you want to configure?\",\n options: Object.entries(SECTION_LABELS).map(([value, label]) => ({\n value: value as Section,\n label,\n })),\n });\n\n if (p.isCancel(choice)) {\n p.cancel(\"Configuration cancelled.\");\n return;\n }\n\n section = choice;\n }\n\n p.log.step(pc.bold(SECTION_LABELS[section]));\n\n switch (section) {\n case \"database\":\n config.database = await promptDatabase(config.database);\n break;\n case \"llm\": {\n const llm = await promptLlm();\n if (llm) {\n config.llm = llm;\n } else {\n delete config.llm;\n }\n break;\n }\n case \"logging\":\n config.logging = await promptLogging();\n break;\n case \"server\":\n {\n const { server, auth } = await promptServer({\n currentServer: config.server,\n currentAuth: config.auth,\n });\n config.server = server;\n config.auth = auth;\n }\n break;\n case \"storage\":\n config.storage = await promptStorage(config.storage);\n break;\n case \"secrets\":\n config.secrets = await promptSecrets(config.secrets);\n {\n const keyResult = ensureLocalSecretsKeyFile(config, configPath);\n if (keyResult.status === \"created\") {\n p.log.success(`Created local secrets key file at ${pc.dim(keyResult.path)}`);\n } else if (keyResult.status === \"existing\") {\n p.log.message(pc.dim(`Using existing local secrets key file at ${keyResult.path}`));\n } else if (keyResult.status === \"skipped_provider\") {\n p.log.message(pc.dim(\"Skipping local key file management for non-local provider\"));\n } else {\n p.log.message(pc.dim(\"Skipping local key file management because RUDDER_SECRETS_MASTER_KEY is set\"));\n }\n }\n break;\n }\n\n config.$meta.updatedAt = new Date().toISOString();\n config.$meta.source = \"configure\";\n\n writeConfig(config, opts.config);\n p.log.success(`${SECTION_LABELS[section]} configuration updated.`);\n\n // If section was provided via CLI flag, don't loop\n if (opts.section) {\n continueLoop = false;\n } else {\n const another = await p.confirm({\n message: \"Configure another section?\",\n initialValue: false,\n });\n\n if (p.isCancel(another) || !another) {\n continueLoop = false;\n } else {\n section = undefined; // Reset to show picker again\n }\n }\n }\n\n p.outro(\"Configuration saved.\");\n}\n", "import { spawn, spawnSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { constants as fsConstants, createWriteStream, mkdirSync, readFileSync } from \"node:fs\";\nimport { access, chmod, copyFile, cp, mkdtemp, mkdir, readFile, readdir, rm, writeFile } from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { Readable, Transform } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport {\n CLI_NPM_PACKAGE_NAME,\n getGlobalInstalledPackageVersion,\n installPersistentCli,\n resolvePersistentCliInstallSpec,\n} from \"../install.js\";\nimport { ensureRuntimeInstalled, RuntimeInstallError } from \"../runtime/install.js\";\nimport { createByteProgress, type ByteProgressReporter } from \"../utils/progress.js\";\nimport { resolveCliVersion } from \"../version.js\";\n\nexport const DEFAULT_DESKTOP_RELEASE_REPO = \"Undertone0809/rudder\";\nexport const DESKTOP_UPDATE_QUIT_ARG = \"--rudder-update-quit\";\n\ntype SupportedPlatform = \"macos\" | \"windows\" | \"linux\";\n\nexport interface DesktopAssetTarget {\n platform: SupportedPlatform;\n arch: \"x64\" | \"arm64\";\n extension: \".zip\" | \".AppImage\";\n}\n\nexport interface DesktopInstallPaths {\n installRoot: string;\n appPath: string;\n executablePath: string;\n metadataPath: string;\n}\n\nexport interface GithubReleaseAsset {\n name: string;\n browser_download_url: string;\n url?: string;\n}\n\ninterface GithubRelease {\n tag_name: string;\n assets: GithubReleaseAsset[];\n}\n\ninterface StartCommandOptions {\n cli?: boolean;\n desktop?: boolean;\n runtime?: boolean;\n version?: string;\n targetVersion?: string;\n repo?: string;\n outputDir?: string;\n desktopInstallDir?: string;\n open?: boolean;\n waitForActiveRuns?: boolean;\n desktopProgressJson?: boolean;\n desktopWaitForApply?: boolean;\n dryRun?: boolean;\n versionCheck?: boolean;\n}\n\nexport interface DesktopInstallMetadata {\n version: 1;\n releaseTag: string;\n assetName: string;\n assetChecksum: string;\n installedAt: string;\n}\n\ntype UpdateQuitResponse =\n | { ok: true; status: \"quitting\" | \"not_running\" }\n | { ok: false; status: \"active_runs\"; totalRuns: number }\n | { ok: false; status: \"failed\"; message: string };\n\nexport type ProgressReporterFactory = (label: string) => ByteProgressReporter;\n\ntype DesktopUpdateProgressPhase =\n | \"starting\"\n | \"resolving_release\"\n | \"downloading_checksums\"\n | \"downloading_asset\"\n | \"verifying_checksum\"\n | \"ready_to_install\"\n | \"waiting_for_active_runs\"\n | \"preparing_restart\"\n | \"closing\"\n | \"failed\";\n\ntype DesktopUpdateProgressEvent = {\n source: \"rudder-desktop-update\";\n phase: DesktopUpdateProgressPhase;\n message: string;\n percent?: number;\n transferredBytes?: number;\n totalBytes?: number;\n error?: string;\n at: string;\n};\n\nconst STABLE_SEMVER_RE = /^[0-9]+\\.[0-9]+\\.[0-9]+$/;\nconst CANARY_SEMVER_RE = /^[0-9]+\\.[0-9]+\\.[0-9]+-canary\\.[0-9]+$/;\nconst CLI_REGISTRY_LATEST_URL = \"https://registry.npmjs.org/@rudderhq%2fcli/latest\";\nconst DESKTOP_APP_NAME = \"Rudder\";\nconst DESKTOP_METADATA_FILE = \".rudder-desktop-install.json\";\nconst DESKTOP_CHECKSUM_ASSET_NAME = \"SHASUMS256.txt\";\nconst GITHUB_ASSET_DOWNLOAD_ACCEPT = \"application/octet-stream\";\n\nfunction normalizeProgressTotal(totalBytes: number | null | undefined): number | null {\n return typeof totalBytes === \"number\" && Number.isFinite(totalBytes) && totalBytes > 0 ? totalBytes : null;\n}\n\nfunction writeDesktopProgress(event: Omit<DesktopUpdateProgressEvent, \"source\" | \"at\">): void {\n const payload: DesktopUpdateProgressEvent = {\n source: \"rudder-desktop-update\",\n ...event,\n at: new Date().toISOString(),\n };\n try {\n process.stdout.write(`${JSON.stringify(payload)}\\n`);\n } catch (error) {\n const code = typeof error === \"object\" && error && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : \"\";\n if (code !== \"EPIPE\") throw error;\n }\n}\n\nfunction desktopDownloadPhase(label: string): DesktopUpdateProgressPhase {\n return label.toLowerCase().includes(\"shasums\")\n ? \"downloading_checksums\"\n : \"downloading_asset\";\n}\n\nfunction createDesktopProgressFactory(): ProgressReporterFactory {\n return (label: string) => {\n const phase = desktopDownloadPhase(label);\n let latestReceivedBytes = 0;\n let latestTotalBytes: number | null | undefined = null;\n\n function emitByteProgress(\n message: string,\n receivedBytes: number,\n totalBytes: number | null | undefined,\n ): void {\n const total = normalizeProgressTotal(totalBytes);\n writeDesktopProgress({\n phase,\n message,\n transferredBytes: Math.max(0, receivedBytes),\n ...(total === null\n ? {}\n : {\n totalBytes: total,\n percent: Math.max(0, Math.min(100, Math.floor((Math.max(0, receivedBytes) / total) * 100))),\n }),\n });\n }\n\n return {\n start(totalBytes?: number | null) {\n latestReceivedBytes = 0;\n latestTotalBytes = totalBytes;\n emitByteProgress(label, 0, totalBytes);\n },\n update(receivedBytes: number, totalBytes?: number | null) {\n latestReceivedBytes = receivedBytes;\n latestTotalBytes = totalBytes;\n emitByteProgress(label, receivedBytes, totalBytes);\n },\n finish(receivedBytes = latestReceivedBytes, totalBytes = latestTotalBytes) {\n latestReceivedBytes = receivedBytes;\n latestTotalBytes = totalBytes;\n emitByteProgress(`${label} complete`, receivedBytes, totalBytes);\n },\n fail() {\n writeDesktopProgress({\n phase,\n message: `${label} failed`,\n transferredBytes: Math.max(0, latestReceivedBytes),\n error: `${label} failed`,\n });\n },\n };\n };\n}\n\nasync function waitForDesktopApplySignal(): Promise<void> {\n process.stdin.setEncoding(\"utf8\");\n process.stdin.resume();\n\n await new Promise<void>((resolve, reject) => {\n let buffer = \"\";\n const cleanup = () => {\n process.stdin.off(\"data\", onData);\n process.stdin.off(\"end\", onEnd);\n process.stdin.off(\"error\", onError);\n };\n const onData = (chunk: string) => {\n buffer += chunk;\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n if (lines.some((line) => line.trim() === \"apply\")) {\n cleanup();\n resolve();\n }\n };\n const onEnd = () => {\n cleanup();\n reject(new Error(\"Desktop update apply signal ended before confirmation.\"));\n };\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n process.stdin.on(\"data\", onData);\n process.stdin.on(\"end\", onEnd);\n process.stdin.on(\"error\", onError);\n });\n}\n\nexport function resolveCurrentCliVersion(env: NodeJS.ProcessEnv = process.env): string {\n const version = resolveCliVersion(import.meta.url, env);\n return version === \"0.0.0\" ? \"latest\" : version;\n}\n\nexport function resolveCliInstallSpec(version: string, env: NodeJS.ProcessEnv = process.env): string {\n if (version && version !== \"latest\") return `${CLI_NPM_PACKAGE_NAME}@${version}`;\n return resolvePersistentCliInstallSpec(env);\n}\n\nexport function isPersistentCliVersionCurrent(version: string, installedVersion: string | null): boolean {\n return Boolean(version && version !== \"latest\" && installedVersion === version);\n}\n\nexport function compareStableSemver(a: string, b: string): number {\n const aMatch = a.match(/^([0-9]+)\\.([0-9]+)\\.([0-9]+)$/);\n const bMatch = b.match(/^([0-9]+)\\.([0-9]+)\\.([0-9]+)$/);\n if (!aMatch || !bMatch) return 0;\n\n for (let index = 1; index <= 3; index += 1) {\n const diff = Number(aMatch[index]) - Number(bMatch[index]);\n if (diff !== 0) return diff;\n }\n\n return 0;\n}\n\nasync function fetchLatestCliVersion(): Promise<string | null> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2_000);\n\n try {\n const response = await fetch(CLI_REGISTRY_LATEST_URL, {\n signal: controller.signal,\n headers: { \"User-Agent\": \"rudder-cli-version-check\" },\n });\n if (!response.ok) return null;\n const parsed = (await response.json()) as { version?: string };\n return parsed.version?.trim() || null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nexport async function getCliUpdateNotice(currentVersion: string): Promise<string | null> {\n if (!STABLE_SEMVER_RE.test(currentVersion)) return null;\n const latestVersion = await fetchLatestCliVersion();\n if (!latestVersion || !STABLE_SEMVER_RE.test(latestVersion)) return null;\n if (compareStableSemver(latestVersion, currentVersion) <= 0) return null;\n\n return `Rudder ${latestVersion} is available. Update with ${pc.cyan(`npx ${CLI_NPM_PACKAGE_NAME}@latest start`)}.`;\n}\n\nexport function resolveDesktopReleaseTag(version: string): string {\n if (!version || version === \"latest\") return \"latest\";\n if (STABLE_SEMVER_RE.test(version)) return `v${version}`;\n if (CANARY_SEMVER_RE.test(version)) return `canary/v${version}`;\n\n throw new Error(\n `Desktop release lookup requires a release version like 0.1.0 or 0.1.0-canary.0. Received ${version}.`,\n );\n}\n\nexport function resolveDesktopAssetTarget(\n platform: NodeJS.Platform = process.platform,\n arch: NodeJS.Architecture = process.arch,\n): DesktopAssetTarget {\n if (platform === \"darwin\") {\n if (arch !== \"x64\" && arch !== \"arm64\") {\n throw new Error(`Rudder Desktop does not publish portable assets for ${platform}/${arch}.`);\n }\n return { platform: \"macos\", arch, extension: \".zip\" };\n }\n if (platform === \"win32\") return { platform: \"windows\", arch: \"x64\", extension: \".zip\" };\n if (platform === \"linux\") {\n if (arch !== \"x64\") {\n throw new Error(`Rudder Desktop does not publish portable assets for ${platform}/${arch}.`);\n }\n return { platform: \"linux\", arch: \"x64\", extension: \".AppImage\" };\n }\n\n throw new Error(`Rudder Desktop does not publish portable assets for ${platform}.`);\n}\n\nexport function resolveDefaultDesktopInstallRoot(\n target: DesktopAssetTarget,\n env: NodeJS.ProcessEnv = process.env,\n homeDir: string = homedir(),\n): string {\n if (target.platform === \"macos\") return path.join(homeDir, \"Applications\");\n if (target.platform === \"windows\") {\n const localAppData = env.LOCALAPPDATA?.trim() || path.join(homeDir, \"AppData\", \"Local\");\n return path.join(localAppData, \"Programs\", DESKTOP_APP_NAME);\n }\n return path.join(homeDir, \".local\", \"share\", \"rudder\");\n}\n\nexport function resolveDesktopInstallPaths(\n target: DesktopAssetTarget,\n installRoot: string,\n): DesktopInstallPaths {\n const root = path.resolve(installRoot);\n if (target.platform === \"macos\") {\n const appPath = path.join(root, `${DESKTOP_APP_NAME}.app`);\n return {\n installRoot: root,\n appPath,\n executablePath: path.join(appPath, \"Contents\", \"MacOS\", DESKTOP_APP_NAME),\n metadataPath: path.join(root, DESKTOP_METADATA_FILE),\n };\n }\n if (target.platform === \"windows\") {\n return {\n installRoot: root,\n appPath: root,\n executablePath: path.join(root, `${DESKTOP_APP_NAME}.exe`),\n metadataPath: path.join(root, DESKTOP_METADATA_FILE),\n };\n }\n const appPath = path.join(root, `${DESKTOP_APP_NAME}.AppImage`);\n return {\n installRoot: root,\n appPath,\n executablePath: appPath,\n metadataPath: path.join(root, DESKTOP_METADATA_FILE),\n };\n}\n\nfunction normalizeAssetName(name: string): string {\n return name.toLowerCase().replaceAll(\"_\", \"-\").replaceAll(\" \", \"-\");\n}\n\nfunction scoreDesktopAsset(asset: GithubReleaseAsset, target: DesktopAssetTarget): number {\n const normalized = normalizeAssetName(asset.name);\n const expectedExtension = target.extension.toLowerCase();\n if (!normalized.endsWith(expectedExtension.toLowerCase())) return -1;\n if (normalized.includes(\"blockmap\") || normalized.includes(\"shasum\")) return -1;\n\n let score = 1;\n if (normalized.includes(\"rudder\")) score += 2;\n if (normalized.includes(target.platform)) score += 4;\n if (normalized.includes(\"portable\")) score += 6;\n if (target.platform === \"macos\" && (normalized.includes(\"macos\") || normalized.includes(\"darwin\") || normalized.includes(\"mac-\"))) {\n score += 4;\n }\n if (target.platform === \"windows\" && (normalized.includes(\"windows\") || normalized.includes(\"win\"))) {\n score += 4;\n }\n if (target.arch === \"arm64\" && normalized.includes(\"arm64\")) score += 4;\n if (target.arch === \"x64\" && (normalized.includes(\"x64\") || normalized.includes(\"amd64\"))) score += 4;\n\n if (target.platform === \"macos\" && target.arch === \"x64\" && normalized.includes(\"arm64\")) score -= 10;\n if (target.arch === \"arm64\" && normalized.includes(\"x64\")) score -= 10;\n\n return score;\n}\n\nexport function selectDesktopAsset(\n assets: GithubReleaseAsset[],\n target: DesktopAssetTarget,\n): GithubReleaseAsset | null {\n const scored = assets\n .map((asset) => ({ asset, score: scoreDesktopAsset(asset, target) }))\n .filter((item) => item.score >= 0)\n .sort((a, b) => b.score - a.score || a.asset.name.localeCompare(b.asset.name));\n\n if (scored.length === 0) return null;\n\n const best = scored[0];\n if (!best) return null;\n\n const equallyGood = scored.filter((item) => item.score === best.score);\n if (equallyGood.length === 1) return best.asset;\n\n const exactArch = equallyGood.find((item) => normalizeAssetName(item.asset.name).includes(target.arch));\n return exactArch?.asset ?? best.asset;\n}\n\nexport function selectChecksumAsset(assets: GithubReleaseAsset[]): GithubReleaseAsset | null {\n return assets.find((asset) => asset.name.toLowerCase() === DESKTOP_CHECKSUM_ASSET_NAME.toLowerCase()) ?? null;\n}\n\nfunction githubApiHeaders(): HeadersInit {\n return {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"rudder-cli-installer\",\n };\n}\n\nasync function fetchGithubRelease(repo: string, tag: string): Promise<GithubRelease> {\n const endpoint =\n tag === \"latest\"\n ? `https://api.github.com/repos/${repo}/releases/latest`\n : `https://api.github.com/repos/${repo}/releases/tags/${encodeURIComponent(tag)}`;\n const response = await fetch(endpoint, { headers: githubApiHeaders() });\n if (!response.ok) {\n throw new Error(`GitHub Release ${tag} was not found in ${repo} (${response.status}).`);\n }\n return (await response.json()) as GithubRelease;\n}\n\nexport function resolveDesktopReleaseVersion(tag: string): string | null {\n if (!tag || tag === \"latest\") return null;\n\n const name = tag.split(\"/\").pop() ?? tag;\n if (!name.startsWith(\"v\")) return null;\n\n const version = name.slice(1);\n if (STABLE_SEMVER_RE.test(version) || CANARY_SEMVER_RE.test(version)) return version;\n\n return null;\n}\n\nexport function resolveDesktopAssetName(version: string, target: DesktopAssetTarget): string {\n if (target.platform === \"macos\") return `${DESKTOP_APP_NAME}-${version}-macos-${target.arch}-portable.zip`;\n if (target.platform === \"windows\") return `${DESKTOP_APP_NAME}-${version}-windows-x64-portable.zip`;\n return `${DESKTOP_APP_NAME}-${version}-linux-x64.AppImage`;\n}\n\nfunction encodeReleaseTagForDownloadUrl(tag: string): string {\n return tag.split(\"/\").map((segment) => encodeURIComponent(segment)).join(\"/\");\n}\n\nexport function buildGithubReleaseAssetDownloadUrl(repo: string, tag: string, assetName: string): string {\n const encodedTag = encodeReleaseTagForDownloadUrl(tag);\n return `https://github.com/${repo}/releases/download/${encodedTag}/${encodeURIComponent(assetName)}`;\n}\n\nfunction buildGithubReleaseAsset(repo: string, tag: string, assetName: string): GithubReleaseAsset {\n return {\n name: assetName,\n browser_download_url: buildGithubReleaseAssetDownloadUrl(repo, tag, assetName),\n };\n}\n\nfunction uniqueAssetDownloadUrls(asset: GithubReleaseAsset): string[] {\n const urls = [asset.url, asset.browser_download_url].filter((url): url is string => Boolean(url));\n return Array.from(new Set(urls));\n}\n\nfunction downloadHeadersForAssetUrl(asset: GithubReleaseAsset, url: string): HeadersInit {\n return {\n Accept: url === asset.url ? GITHUB_ASSET_DOWNLOAD_ACCEPT : \"*/*\",\n \"User-Agent\": \"rudder-cli-installer\",\n };\n}\n\nfunction formatFetchError(error: unknown): string {\n if (!(error instanceof Error)) return String(error);\n\n const cause = (error as { cause?: unknown }).cause;\n if (cause instanceof Error) {\n const code = (cause as { code?: unknown }).code;\n const suffix = typeof code === \"string\" ? ` [${code}]` : \"\";\n return `${error.message}: ${cause.message}${suffix}`;\n }\n\n return error.message;\n}\n\nfunction contentLengthFromHeaders(headers: Headers): number | null {\n const raw = headers.get(\"content-length\");\n if (!raw) return null;\n const value = Number(raw);\n return Number.isFinite(value) && value > 0 ? value : null;\n}\n\nexport async function downloadAsset(\n asset: GithubReleaseAsset,\n outputDir: string,\n progressFactory: ProgressReporterFactory = createByteProgress,\n): Promise<string> {\n mkdirSync(outputDir, { recursive: true });\n const outputPath = path.join(outputDir, path.basename(asset.name));\n\n let response: Response | null = null;\n const failures: string[] = [];\n for (const url of uniqueAssetDownloadUrls(asset)) {\n try {\n const candidate = await fetch(url, {\n headers: downloadHeadersForAssetUrl(asset, url),\n });\n if (candidate.ok && candidate.body) {\n response = candidate;\n break;\n }\n failures.push(`Failed to download ${asset.name} from ${url} (${candidate.status}).`);\n } catch (error) {\n failures.push(`Failed to download ${asset.name} from ${url}: ${formatFetchError(error)}.`);\n }\n }\n\n if (!response) {\n throw new Error(failures.join(\"\\n\"));\n }\n\n const totalBytes = contentLengthFromHeaders(response.headers);\n const progress = progressFactory(`Downloading ${asset.name}`);\n let receivedBytes = 0;\n const monitor = new Transform({\n transform(chunk: Buffer | string, _encoding, callback) {\n receivedBytes += typeof chunk === \"string\" ? Buffer.byteLength(chunk) : chunk.length;\n progress.update(receivedBytes, totalBytes);\n callback(null, chunk);\n },\n });\n\n progress.start(totalBytes);\n try {\n await pipeline(Readable.fromWeb(response.body as never), monitor, createWriteStream(outputPath));\n progress.finish(receivedBytes, totalBytes);\n } catch (error) {\n progress.fail();\n throw error;\n }\n return outputPath;\n}\n\nfunction checksumForFile(filePath: string): string {\n const hash = createHash(\"sha256\");\n hash.update(readFileSync(filePath));\n return hash.digest(\"hex\");\n}\n\nexport function parseChecksumFile(contents: string): Map<string, string> {\n const checksums = new Map<string, string>();\n for (const line of contents.split(/\\r?\\n/)) {\n const match = line.match(/^([a-fA-F0-9]{64})\\s+\\*?(.+)$/);\n if (!match) continue;\n checksums.set(match[2].trim(), match[1].toLowerCase());\n }\n return checksums;\n}\n\nexport function resolveAssetChecksum(checksums: Map<string, string>, assetName: string): string {\n const expected = checksums.get(path.basename(assetName));\n if (!expected) {\n throw new Error(`Desktop release checksums do not include ${path.basename(assetName)}.`);\n }\n return expected;\n}\n\nexport function assertChecksumMatch(filePath: string, expected: string): string {\n const actual = checksumForFile(filePath);\n if (actual !== expected.toLowerCase()) {\n throw new Error(`Checksum mismatch for ${path.basename(filePath)}.`);\n }\n return actual;\n}\n\nexport async function downloadChecksums(\n checksumAsset: GithubReleaseAsset | null,\n outputDir: string,\n progressFactory: ProgressReporterFactory = createByteProgress,\n): Promise<Map<string, string>> {\n if (!checksumAsset) {\n throw new Error(\"Desktop release is missing SHASUMS256.txt.\");\n }\n const checksumPath = await downloadAsset(checksumAsset, outputDir, progressFactory);\n return parseChecksumFile(readFileSync(checksumPath, \"utf8\"));\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await access(targetPath, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction runChecked(command: string, args: string[], options: { cwd?: string; shell?: boolean } = {}): void {\n const result = spawnSync(command, args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n ...options,\n });\n if (result.status === 0) return;\n\n const output = [result.stdout, result.stderr]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n throw new Error(`${command} ${args.join(\" \")} failed${output ? `: ${output}` : \"\"}`);\n}\n\nfunction formatCommandFailure(command: string, args: string[], stdout: unknown, stderr: unknown): string {\n const output = [stdout, stderr]\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\")\n .trim();\n return `${command} ${args.join(\" \")} failed${output ? `: ${output}` : \"\"}`;\n}\n\nfunction powershellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nexport function buildWindowsZipExtractCommand(zipPath: string, outputDir: string): { command: string; args: string[] } {\n return { command: \"tar.exe\", args: [\"-xf\", zipPath, \"-C\", outputDir] };\n}\n\nexport function buildWindowsRobocopyMirrorCommand(sourcePath: string, destinationPath: string): { command: string; args: string[] } {\n return {\n command: \"robocopy.exe\",\n args: [sourcePath, destinationPath, \"/MIR\", \"/R:2\", \"/W:1\", \"/NFL\", \"/NDL\", \"/NJH\", \"/NJS\", \"/NP\"],\n };\n}\n\nexport function isSuccessfulRobocopyExitCode(status: number | null): boolean {\n return typeof status === \"number\" && status >= 0 && status <= 7;\n}\n\nasync function extractZip(zipPath: string, outputDir: string, target: DesktopAssetTarget): Promise<void> {\n await rm(outputDir, { recursive: true, force: true });\n await mkdir(outputDir, { recursive: true });\n\n if (target.platform === \"macos\") {\n runChecked(\"ditto\", [\"-x\", \"-k\", zipPath, outputDir]);\n return;\n }\n\n if (target.platform === \"windows\") {\n const command = buildWindowsZipExtractCommand(zipPath, outputDir);\n runChecked(command.command, command.args);\n return;\n }\n\n throw new Error(`Zip assets are not supported for ${target.platform}.`);\n}\n\nasync function findPath(\n root: string,\n predicate: (filePath: string, isDirectory: boolean) => boolean,\n maxDepth = 5,\n): Promise<string | null> {\n async function visit(dir: string, depth: number): Promise<string | null> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (predicate(fullPath, entry.isDirectory())) return fullPath;\n if (entry.isDirectory() && depth < maxDepth) {\n const nested = await visit(fullPath, depth + 1);\n if (nested) return nested;\n }\n }\n return null;\n }\n\n return await visit(root, 0);\n}\n\nasync function findMacApp(extractDir: string): Promise<string> {\n const direct = path.join(extractDir, `${DESKTOP_APP_NAME}.app`);\n if (await pathExists(direct)) return direct;\n const found = await findPath(extractDir, (filePath, isDirectory) =>\n isDirectory && path.basename(filePath) === `${DESKTOP_APP_NAME}.app`);\n if (!found) throw new Error(`Portable macOS archive did not contain ${DESKTOP_APP_NAME}.app.`);\n return found;\n}\n\nasync function findWindowsAppDir(extractDir: string): Promise<string> {\n const direct = path.join(extractDir, `${DESKTOP_APP_NAME}.exe`);\n if (await pathExists(direct)) return extractDir;\n const executable = await findPath(extractDir, (filePath, isDirectory) =>\n !isDirectory && path.basename(filePath).toLowerCase() === `${DESKTOP_APP_NAME.toLowerCase()}.exe`);\n if (!executable) throw new Error(`Portable Windows archive did not contain ${DESKTOP_APP_NAME}.exe.`);\n return path.dirname(executable);\n}\n\nasync function readInstallMetadata(metadataPath: string): Promise<DesktopInstallMetadata | null> {\n try {\n const parsed = JSON.parse(await readFile(metadataPath, \"utf8\")) as DesktopInstallMetadata;\n if (parsed.version !== 1) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport function isInstalledDesktopCurrent(\n metadata: DesktopInstallMetadata | null,\n releaseTag: string,\n assetName: string,\n assetChecksum: string,\n): boolean {\n return Boolean(\n metadata &&\n metadata.releaseTag === releaseTag &&\n metadata.assetName === assetName &&\n metadata.assetChecksum === assetChecksum,\n );\n}\n\nexport function buildForceQuitCommand(target: DesktopAssetTarget): { command: string; args: string[] } {\n if (target.platform === \"windows\") return { command: \"taskkill.exe\", args: [\"/IM\", `${DESKTOP_APP_NAME}.exe`, \"/T\", \"/F\"] };\n return { command: \"pkill\", args: [\"-x\", DESKTOP_APP_NAME] };\n}\n\nfunction forceQuitDesktopProcesses(target: DesktopAssetTarget): void {\n const command = buildForceQuitCommand(target);\n spawnSync(command.command, command.args, { stdio: \"ignore\" });\n}\n\nfunction isRunningInsideDesktopExecutable(): boolean {\n return path.basename(process.execPath).toLowerCase().startsWith(DESKTOP_APP_NAME.toLowerCase());\n}\n\nasync function waitForUpdateQuitResponse(responsePath: string, timeoutMs = 8_000): Promise<UpdateQuitResponse | null> {\n const startedAt = Date.now();\n while (Date.now() - startedAt < timeoutMs) {\n if (await pathExists(responsePath)) {\n return JSON.parse(await readFile(responsePath, \"utf8\")) as UpdateQuitResponse;\n }\n await delay(200);\n }\n return null;\n}\n\nasync function requestDesktopQuit(executablePath: string, target: DesktopAssetTarget): Promise<UpdateQuitResponse | null> {\n if (!(await pathExists(executablePath))) return { ok: true, status: \"not_running\" };\n const responsePath = path.join(tmpdir(), `rudder-update-quit-${process.pid}-${Date.now()}.json`);\n const result = spawnSync(executablePath, [`${DESKTOP_UPDATE_QUIT_ARG}=${responsePath}`], {\n stdio: \"ignore\",\n timeout: 5_000,\n });\n if (result.error && target.platform === \"windows\") {\n return null;\n }\n\n try {\n return await waitForUpdateQuitResponse(responsePath);\n } finally {\n await rm(responsePath, { force: true });\n }\n}\n\nasync function removePathWithRetry(targetPath: string, attempts = 5): Promise<boolean> {\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n try {\n await rm(targetPath, { recursive: true, force: true });\n if (!(await pathExists(targetPath))) return true;\n } catch {\n // Retry below; Windows can keep files locked briefly after process exit.\n }\n await delay(500);\n }\n return false;\n}\n\nasync function prepareForDesktopReplace(\n paths: DesktopInstallPaths,\n target: DesktopAssetTarget,\n options: { waitForActiveRuns?: boolean; activeRunPollIntervalMs?: number } = {},\n): Promise<void> {\n const hasManagedExecutable = await pathExists(paths.executablePath);\n if (hasManagedExecutable) {\n let quitResponse = await requestDesktopQuit(paths.executablePath, target);\n while (quitResponse && !quitResponse.ok && quitResponse.status === \"active_runs\" && options.waitForActiveRuns) {\n p.log.warn(\n `Rudder Desktop has ${quitResponse.totalRuns} active run${quitResponse.totalRuns === 1 ? \"\" : \"s\"}; waiting before replacing Desktop.`,\n );\n await delay(options.activeRunPollIntervalMs ?? 15_000);\n quitResponse = await requestDesktopQuit(paths.executablePath, target);\n }\n if (quitResponse && !quitResponse.ok && quitResponse.status === \"active_runs\") {\n throw new Error(\n `Rudder Desktop has ${quitResponse.totalRuns} active run${quitResponse.totalRuns === 1 ? \"\" : \"s\"}. Stop active work, then rerun start.`,\n );\n }\n await delay(1_000);\n } else if (!isRunningInsideDesktopExecutable()) {\n forceQuitDesktopProcesses(target);\n }\n\n const replacePath = target.platform === \"windows\" ? paths.installRoot : paths.appPath;\n if (await removePathWithRetry(replacePath)) return;\n\n forceQuitDesktopProcesses(target);\n await delay(1_000);\n if (await removePathWithRetry(replacePath, 6)) return;\n\n throw new Error(`Failed to replace existing Rudder Desktop at ${replacePath}. Close Rudder and rerun start.`);\n}\n\nasync function installPortableDesktop(\n installerPath: string,\n paths: DesktopInstallPaths,\n target: DesktopAssetTarget,\n): Promise<void> {\n await mkdir(paths.installRoot, { recursive: true });\n\n if (target.platform === \"linux\") {\n await copyFile(installerPath, paths.appPath);\n await chmod(paths.appPath, 0o755);\n return;\n }\n\n const extractDir = await mkdtemp(path.join(tmpdir(), \"rudder-desktop-extract.\"));\n try {\n await extractZip(installerPath, extractDir, target);\n if (target.platform === \"macos\") {\n const appSource = await findMacApp(extractDir);\n await copyPortableAppBundle(appSource, paths.appPath);\n return;\n }\n\n const appSource = await findWindowsAppDir(extractDir);\n await mkdir(path.dirname(paths.installRoot), { recursive: true });\n await copyPortableAppBundle(appSource, paths.installRoot);\n } finally {\n await rm(extractDir, { recursive: true, force: true });\n }\n}\n\nexport async function copyPortableAppBundle(sourcePath: string, destinationPath: string): Promise<void> {\n if (process.platform === \"win32\") {\n await mkdir(destinationPath, { recursive: true });\n const command = buildWindowsRobocopyMirrorCommand(sourcePath, destinationPath);\n const result = spawnSync(command.command, command.args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n if (isSuccessfulRobocopyExitCode(result.status)) return;\n throw new Error(formatCommandFailure(command.command, command.args, result.stdout, result.stderr));\n }\n\n await cp(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });\n}\n\nasync function removeMacQuarantine(paths: DesktopInstallPaths, target: DesktopAssetTarget): Promise<void> {\n if (target.platform !== \"macos\") return;\n const result = spawnSync(\"xattr\", [\"-dr\", \"com.apple.quarantine\", paths.appPath], { stdio: \"ignore\" });\n if (result.status !== 0) {\n p.log.warn(`Could not remove macOS quarantine attributes from ${paths.appPath}.`);\n }\n}\n\nfunction quoteDesktopExec(value: string): string {\n return `\"${value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"\\\"\", \"\\\\\\\"\")}\"`;\n}\n\nexport function buildLinuxDesktopEntry(executablePath: string): string {\n return [\n \"[Desktop Entry]\",\n \"Type=Application\",\n \"Name=Rudder\",\n `Exec=${quoteDesktopExec(executablePath)}`,\n \"Terminal=false\",\n \"Categories=Development;\",\n \"\",\n ].join(\"\\n\");\n}\n\nasync function writeLinuxLaunchers(paths: DesktopInstallPaths): Promise<void> {\n const desktopDir = path.join(homedir(), \".local\", \"share\", \"applications\");\n await mkdir(desktopDir, { recursive: true });\n await writeFile(path.join(desktopDir, \"rudder.desktop\"), buildLinuxDesktopEntry(paths.executablePath), \"utf8\");\n\n const binDir = path.join(homedir(), \".local\", \"bin\");\n await mkdir(binDir, { recursive: true });\n const wrapperPath = path.join(binDir, \"rudder-desktop\");\n const escaped = paths.executablePath.replaceAll(\"'\", \"'\\\"'\\\"'\");\n await writeFile(wrapperPath, `#!/bin/sh\\nexec '${escaped}' \"$@\"\\n`, \"utf8\");\n await chmod(wrapperPath, 0o755);\n}\n\nfunction buildWindowsShortcutScript(executablePath: string): string {\n const appData = process.env.APPDATA?.trim() || path.join(homedir(), \"AppData\", \"Roaming\");\n const shortcutPath = path.join(appData, \"Microsoft\", \"Windows\", \"Start Menu\", \"Programs\", \"Rudder.lnk\");\n return [\n \"$shell = New-Object -ComObject WScript.Shell\",\n `$shortcut = $shell.CreateShortcut(${powershellQuote(shortcutPath)})`,\n `$shortcut.TargetPath = ${powershellQuote(executablePath)}`,\n `$shortcut.WorkingDirectory = ${powershellQuote(path.dirname(executablePath))}`,\n \"$shortcut.Save()\",\n ].join(\"; \");\n}\n\nasync function createPlatformLaunchers(paths: DesktopInstallPaths, target: DesktopAssetTarget): Promise<void> {\n if (target.platform === \"linux\") {\n await writeLinuxLaunchers(paths);\n return;\n }\n if (target.platform === \"windows\") {\n const result = spawnSync(\"powershell.exe\", [\n \"-NoProfile\",\n \"-ExecutionPolicy\",\n \"Bypass\",\n \"-Command\",\n buildWindowsShortcutScript(paths.executablePath),\n ], { stdio: \"ignore\" });\n if (result.status !== 0) p.log.warn(\"Could not create the Windows Start Menu shortcut.\");\n }\n}\n\nfunction launchDesktop(paths: DesktopInstallPaths, target: DesktopAssetTarget): void {\n if (target.platform === \"macos\") {\n spawn(\"open\", [paths.appPath], { detached: true, stdio: \"ignore\" }).unref();\n return;\n }\n if (target.platform === \"windows\") {\n spawn(\"cmd.exe\", [\"/c\", \"start\", \"\", paths.executablePath], { detached: true, stdio: \"ignore\" }).unref();\n return;\n }\n spawn(paths.executablePath, [], { detached: true, stdio: \"ignore\" }).unref();\n}\n\nasync function writeInstallMetadata(\n paths: DesktopInstallPaths,\n releaseTag: string,\n assetName: string,\n assetChecksum: string,\n): Promise<void> {\n mkdirSync(path.dirname(paths.metadataPath), { recursive: true });\n const metadata: DesktopInstallMetadata = {\n version: 1,\n releaseTag,\n assetName,\n assetChecksum,\n installedAt: new Date().toISOString(),\n };\n mkdirSync(paths.installRoot, { recursive: true });\n await writeFile(paths.metadataPath, `${JSON.stringify(metadata, null, 2)}\\n`, \"utf8\");\n}\n\nasync function runStartPhase<T>(\n message: string,\n successMessage: string,\n task: () => Promise<T> | T,\n progressPhase?: DesktopUpdateProgressPhase | null,\n): Promise<T> {\n if (progressPhase) {\n writeDesktopProgress({ phase: progressPhase, message });\n }\n const spinner = p.spinner();\n spinner.start(message);\n try {\n const result = await task();\n spinner.stop(successMessage);\n if (progressPhase) {\n writeDesktopProgress({ phase: progressPhase, message: successMessage });\n }\n return result;\n } catch (error) {\n spinner.stop(pc.red(`${message} failed.`));\n if (progressPhase) {\n writeDesktopProgress({\n phase: \"failed\",\n message: `${message} failed.`,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n throw error;\n }\n}\n\nexport async function startCommand(opts: StartCommandOptions): Promise<void> {\n const installCli = opts.cli !== false;\n const installDesktop = opts.desktop !== false;\n const installRuntime = opts.runtime !== false;\n const repo = opts.repo?.trim() || DEFAULT_DESKTOP_RELEASE_REPO;\n const version = opts.targetVersion?.trim() || opts.version?.trim() || resolveCurrentCliVersion();\n const dryRun = opts.dryRun === true;\n const desktopProgressJson = opts.desktopProgressJson === true;\n\n if (desktopProgressJson) {\n process.stdout.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code !== \"EPIPE\") throw error;\n });\n }\n\n if (!installCli && !installDesktop && !installRuntime) {\n throw new Error(\"Nothing to start. Remove --no-cli, --no-runtime, or --no-desktop.\");\n }\n\n p.intro(pc.bgCyan(pc.black(\" rudder start \")));\n\n if (opts.versionCheck !== false) {\n const updateNotice = await getCliUpdateNotice(version);\n if (updateNotice) p.log.warn(updateNotice);\n }\n\n if (installRuntime) {\n p.log.step(\"Preparing Rudder runtime\");\n if (dryRun) {\n p.log.message(`[dry-run] Would install or reuse ${pc.cyan(`@rudderhq/server@${version}`)} in the Rudder runtime cache.`);\n } else {\n const spinner = p.spinner();\n spinner.start(\"Installing or reusing Rudder runtime...\");\n try {\n const runtime = await ensureRuntimeInstalled({ version });\n spinner.stop(\n runtime.status === \"hit\"\n ? `Rudder runtime cache hit at ${pc.cyan(runtime.cacheDir)}.`\n : `Rudder runtime installed at ${pc.cyan(runtime.cacheDir)}.`,\n );\n } catch (error) {\n spinner.stop(pc.red(\"Rudder runtime installation failed.\"));\n if (error instanceof RuntimeInstallError && error.output) {\n p.log.message(pc.dim(error.output));\n }\n throw error;\n }\n }\n }\n\n if (installCli) {\n const installSpec = resolveCliInstallSpec(version);\n const command = `npm install --global ${installSpec}`;\n const installedVersion = getGlobalInstalledPackageVersion(CLI_NPM_PACKAGE_NAME);\n p.log.step(\"Preparing persistent CLI\");\n if (isPersistentCliVersionCurrent(version, installedVersion)) {\n p.log.success(`${pc.cyan(\"rudder\")} CLI ${version} is already installed.`);\n } else if (dryRun) {\n p.log.message(`[dry-run] ${command}`);\n } else {\n p.log.message(pc.dim(`Running: ${command}`));\n const spinner = p.spinner();\n spinner.start(\"Installing persistent CLI...\");\n let result: ReturnType<typeof installPersistentCli>;\n try {\n result = installPersistentCli({ installSpec });\n } catch (error) {\n spinner.stop(pc.red(\"Persistent CLI installation failed.\"));\n throw error;\n }\n if (!result.ok) {\n spinner.stop(pc.red(\"Persistent CLI installation failed.\"));\n if (result.output) p.log.message(pc.dim(result.output));\n throw new Error(`Persistent CLI installation failed. Re-run manually: ${result.command}`);\n }\n spinner.stop(`${pc.cyan(\"rudder\")} CLI installed.`);\n }\n }\n\n if (installDesktop) {\n const target = resolveDesktopAssetTarget();\n const tag = resolveDesktopReleaseTag(version);\n const installRoot = opts.desktopInstallDir\n ? path.resolve(opts.desktopInstallDir)\n : resolveDefaultDesktopInstallRoot(target);\n const installPaths = resolveDesktopInstallPaths(target, installRoot);\n const outputDir = opts.outputDir\n ? path.resolve(opts.outputDir)\n : await mkdtemp(path.join(tmpdir(), \"rudder-desktop-installer.\"));\n\n p.log.step(\"Installing desktop app\");\n p.log.message(`Release: ${pc.cyan(`${repo}@${tag}`)}`);\n p.log.message(`Target: ${pc.cyan(`${target.platform}/${target.arch}`)}`);\n p.log.message(`Install: ${pc.cyan(installPaths.appPath)}`);\n\n if (dryRun) {\n p.log.message(`[dry-run] Would resolve, download, verify, install, and ${opts.open === false ? \"not launch\" : \"launch\"} Rudder Desktop.`);\n p.outro(pc.green(\"Dry run complete.\"));\n return;\n }\n\n const directReleaseVersion = resolveDesktopReleaseVersion(tag);\n const progressFactory: ProgressReporterFactory = desktopProgressJson\n ? createDesktopProgressFactory()\n : createByteProgress;\n let release: GithubRelease | null = null;\n try {\n release = await runStartPhase(\n \"Resolving Desktop release...\",\n \"Desktop release resolved.\",\n () => fetchGithubRelease(repo, tag),\n desktopProgressJson ? \"resolving_release\" : null,\n );\n } catch (error) {\n if (!directReleaseVersion) throw error;\n p.log.warn(\n `Desktop release metadata could not be resolved; falling back to deterministic download URLs. ${formatFetchError(error)}`,\n );\n }\n\n const releaseTag = release?.tag_name ?? (directReleaseVersion ? tag : null);\n if (!releaseTag) {\n throw new Error(`Unable to resolve Rudder Desktop release tag for ${repo}@${tag}.`);\n }\n\n const asset = selectDesktopAsset(release?.assets ?? [], target)\n ?? (\n directReleaseVersion\n ? buildGithubReleaseAsset(repo, tag, resolveDesktopAssetName(directReleaseVersion, target))\n : null\n );\n if (!asset) {\n throw new Error(`No Rudder Desktop portable asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);\n }\n\n const checksumAsset = selectChecksumAsset(release?.assets ?? [])\n ?? (\n directReleaseVersion\n ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME)\n : null\n );\n const checksums = await downloadChecksums(checksumAsset, outputDir, progressFactory);\n const expectedChecksum = resolveAssetChecksum(checksums, asset.name);\n\n const metadata = await readInstallMetadata(installPaths.metadataPath);\n if (\n isInstalledDesktopCurrent(metadata, releaseTag, asset.name, expectedChecksum) &&\n await pathExists(installPaths.executablePath)\n ) {\n p.log.success(`Rudder Desktop is already installed at ${pc.cyan(installPaths.appPath)}.`);\n await runStartPhase(\n \"Refreshing Desktop launchers...\",\n \"Desktop launchers ready.\",\n async () => {\n await removeMacQuarantine(installPaths, target);\n await createPlatformLaunchers(installPaths, target);\n },\n desktopProgressJson ? \"preparing_restart\" : null,\n );\n } else {\n const installerPath = await downloadAsset(asset, outputDir, progressFactory);\n const checksum = await runStartPhase(\n \"Verifying Desktop checksum...\",\n `Verified ${pc.cyan(path.basename(installerPath))}.`,\n () => assertChecksumMatch(installerPath, expectedChecksum),\n desktopProgressJson ? \"verifying_checksum\" : null,\n );\n\n if (desktopProgressJson && opts.desktopWaitForApply === true) {\n writeDesktopProgress({\n phase: \"ready_to_install\",\n message: \"Desktop update is downloaded and verified.\",\n percent: 100,\n });\n await waitForDesktopApplySignal();\n writeDesktopProgress({\n phase: \"preparing_restart\",\n message: \"Applying Desktop update...\",\n });\n }\n\n await runStartPhase(\n \"Replacing existing Rudder Desktop if needed...\",\n \"Existing Desktop install is ready for replacement.\",\n () => prepareForDesktopReplace(installPaths, target, { waitForActiveRuns: opts.waitForActiveRuns === true }),\n desktopProgressJson ? (opts.waitForActiveRuns === true ? \"waiting_for_active_runs\" : \"preparing_restart\") : null,\n );\n await runStartPhase(\n \"Installing portable Desktop app...\",\n `Installed Rudder Desktop to ${pc.cyan(installPaths.appPath)}.`,\n () => installPortableDesktop(installerPath, installPaths, target),\n desktopProgressJson ? \"preparing_restart\" : null,\n );\n await runStartPhase(\n \"Preparing Desktop launchers...\",\n \"Desktop launchers ready.\",\n async () => {\n await removeMacQuarantine(installPaths, target);\n await createPlatformLaunchers(installPaths, target);\n },\n desktopProgressJson ? \"preparing_restart\" : null,\n );\n await writeInstallMetadata(installPaths, releaseTag, asset.name, checksum);\n }\n\n if (opts.open !== false) {\n await runStartPhase(\n \"Launching Rudder Desktop...\",\n \"Rudder Desktop launched.\",\n () => launchDesktop(installPaths, target),\n desktopProgressJson ? \"closing\" : null,\n );\n }\n }\n\n p.outro(pc.green(\"Rudder start complete.\"));\n}\n", "import type { Writable } from \"node:stream\";\n\nexport interface ByteProgressState {\n receivedBytes: number;\n totalBytes?: number | null;\n width?: number;\n}\n\nexport interface ByteProgressOptions {\n stream?: Writable;\n isTty?: boolean;\n width?: number;\n minIntervalMs?: number;\n now?: () => number;\n}\n\nexport interface ByteProgressReporter {\n start(totalBytes?: number | null): void;\n update(receivedBytes: number, totalBytes?: number | null): void;\n finish(receivedBytes?: number, totalBytes?: number | null): void;\n fail(): void;\n}\n\nconst BYTE_UNITS = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n\nexport function formatBytes(bytes: number): string {\n let value = Math.max(0, bytes);\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < BYTE_UNITS.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n if (unitIndex === 0) return `${Math.round(value)} ${BYTE_UNITS[unitIndex]}`;\n return `${value.toFixed(1)} ${BYTE_UNITS[unitIndex]}`;\n}\n\nfunction normalizeTotalBytes(totalBytes: number | null | undefined): number | null {\n if (typeof totalBytes !== \"number\" || !Number.isFinite(totalBytes) || totalBytes <= 0) {\n return null;\n }\n return totalBytes;\n}\n\nexport function formatByteProgress(state: ByteProgressState): string {\n const width = Math.max(4, state.width ?? 20);\n const receivedBytes = Math.max(0, state.receivedBytes);\n const totalBytes = normalizeTotalBytes(state.totalBytes);\n\n if (totalBytes === null) {\n return `[downloaded ${formatBytes(receivedBytes)}]`;\n }\n\n const ratio = Math.max(0, Math.min(1, receivedBytes / totalBytes));\n const filled = Math.round(ratio * width);\n const percent = Math.floor(ratio * 100);\n return `[${\"#\".repeat(filled)}${\"-\".repeat(width - filled)}] ${percent}% ${formatBytes(receivedBytes)}/${formatBytes(totalBytes)}`;\n}\n\nfunction progressSummary(receivedBytes: number, totalBytes: number | null | undefined): string {\n const total = normalizeTotalBytes(totalBytes);\n if (total === null) return formatBytes(receivedBytes);\n return `${formatBytes(receivedBytes)}/${formatBytes(total)}`;\n}\n\nexport function createByteProgress(label: string, options: ByteProgressOptions = {}): ByteProgressReporter {\n const stream = options.stream ?? process.stdout;\n const isTty = options.isTty ?? Boolean((stream as Writable & { isTTY?: boolean }).isTTY);\n const width = options.width ?? 20;\n const minIntervalMs = options.minIntervalMs ?? 80;\n const now = options.now ?? (() => Date.now());\n\n let started = false;\n let finished = false;\n let lastRenderAt = 0;\n let lastLineLength = 0;\n let latestReceivedBytes = 0;\n let latestTotalBytes: number | null | undefined = null;\n\n function render(receivedBytes: number, totalBytes: number | null | undefined, force = false): void {\n if (finished) return;\n latestReceivedBytes = receivedBytes;\n latestTotalBytes = totalBytes;\n\n if (!isTty) return;\n\n const currentTime = now();\n const total = normalizeTotalBytes(totalBytes);\n const complete = total !== null && receivedBytes >= total;\n if (!force && currentTime - lastRenderAt < minIntervalMs && !complete) return;\n\n const line = `${label} ${formatByteProgress({ receivedBytes, totalBytes, width })}`;\n const padding = lastLineLength > line.length ? \" \".repeat(lastLineLength - line.length) : \"\";\n stream.write(`\\r${line}${padding}`);\n lastLineLength = line.length;\n lastRenderAt = currentTime;\n }\n\n function start(totalBytes?: number | null): void {\n if (started || finished) return;\n started = true;\n latestTotalBytes = totalBytes;\n if (isTty) {\n render(0, totalBytes, true);\n } else {\n stream.write(`${label}...\\n`);\n }\n }\n\n function update(receivedBytes: number, totalBytes?: number | null): void {\n if (!started) start(totalBytes);\n render(receivedBytes, totalBytes, false);\n }\n\n function finish(receivedBytes = latestReceivedBytes, totalBytes = latestTotalBytes): void {\n if (finished) return;\n if (!started) start(totalBytes);\n if (isTty) {\n render(receivedBytes, totalBytes, true);\n stream.write(\"\\n\");\n } else {\n stream.write(`${label} complete (${progressSummary(receivedBytes, totalBytes)}).\\n`);\n }\n finished = true;\n }\n\n function fail(): void {\n if (finished) return;\n if (isTty && started) {\n stream.write(\"\\n\");\n } else if (!isTty && started) {\n stream.write(`${label} failed.\\n`);\n }\n finished = true;\n }\n\n return {\n start,\n update,\n finish,\n fail,\n };\n}\n", "import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { normalizeHostnameInput } from \"../config/hostnames.js\";\nimport { readConfig, resolveConfigPath, writeConfig } from \"../config/store.js\";\n\nexport async function addAllowedHostname(host: string, opts: { config?: string }): Promise<void> {\n const configPath = resolveConfigPath(opts.config);\n const config = readConfig(opts.config);\n\n if (!config) {\n p.log.error(`No config found at ${configPath}. Run ${pc.cyan(\"rudder onboard\")} first.`);\n return;\n }\n\n const normalized = normalizeHostnameInput(host);\n const current = new Set((config.server.allowedHostnames ?? []).map((value) => value.trim().toLowerCase()).filter(Boolean));\n const existed = current.has(normalized);\n current.add(normalized);\n\n config.server.allowedHostnames = Array.from(current).sort();\n config.$meta.updatedAt = new Date().toISOString();\n config.$meta.source = \"configure\";\n writeConfig(config, opts.config);\n\n if (existed) {\n p.log.info(`Hostname ${pc.cyan(normalized)} is already allowed.`);\n } else {\n p.log.success(`Added allowed hostname: ${pc.cyan(normalized)}`);\n p.log.message(\n pc.dim(\"Restart the Rudder server for this change to take effect.\"),\n );\n }\n\n if (!(config.server.deploymentMode === \"authenticated\" && config.server.exposure === \"private\")) {\n p.log.message(\n pc.dim(\"Note: allowed hostnames are enforced only in authenticated/private mode.\"),\n );\n }\n}\n\n", "import { setTimeout as delay } from \"node:timers/promises\";\nimport pc from \"picocolors\";\nimport type { Agent, HeartbeatRun, HeartbeatRunEvent, HeartbeatRunStatus } from \"@rudderhq/shared\";\nimport { getCLIAdapter } from \"../agent-runtimes/index.js\";\nimport { resolveCommandContext } from \"./client/common.js\";\n\nconst HEARTBEAT_SOURCES = [\"timer\", \"assignment\", \"on_demand\", \"automation\"] as const;\nconst HEARTBEAT_TRIGGERS = [\"manual\", \"ping\", \"callback\", \"system\"] as const;\nconst TERMINAL_STATUSES = new Set<HeartbeatRunStatus>([\"succeeded\", \"failed\", \"cancelled\", \"timed_out\"]);\nconst POLL_INTERVAL_MS = 200;\n\ntype HeartbeatSource = (typeof HEARTBEAT_SOURCES)[number];\ntype HeartbeatTrigger = (typeof HEARTBEAT_TRIGGERS)[number];\ntype InvokedHeartbeat = HeartbeatRun | { status: \"skipped\" };\ninterface HeartbeatRunEventRecord extends HeartbeatRunEvent {\n type?: string | null;\n}\n\ninterface HeartbeatRunOptions {\n config?: string;\n context?: string;\n profile?: string;\n agentId: string;\n apiBase?: string;\n apiKey?: string;\n source: string;\n trigger: string;\n timeoutMs: string;\n debug?: boolean;\n json?: boolean;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asErrorText(value: unknown): string {\n if (typeof value === \"string\") return value;\n const obj = asRecord(value);\n if (!obj) return \"\";\n const message =\n (typeof obj.message === \"string\" && obj.message) ||\n (typeof obj.error === \"string\" && obj.error) ||\n (typeof obj.code === \"string\" && obj.code) ||\n \"\";\n if (message) return message;\n try {\n return JSON.stringify(obj);\n } catch {\n return \"\";\n }\n}\n\ntype AdapterType = string;\n\nexport async function heartbeatRun(opts: HeartbeatRunOptions): Promise<void> {\n const debug = Boolean(opts.debug);\n const parsedTimeout = Number.parseInt(opts.timeoutMs, 10);\n const timeoutMs = Number.isFinite(parsedTimeout) ? parsedTimeout : 0;\n const source = HEARTBEAT_SOURCES.includes(opts.source as HeartbeatSource)\n ? (opts.source as HeartbeatSource)\n : \"on_demand\";\n const triggerDetail = HEARTBEAT_TRIGGERS.includes(opts.trigger as HeartbeatTrigger)\n ? (opts.trigger as HeartbeatTrigger)\n : \"manual\";\n\n const ctx = resolveCommandContext({\n config: opts.config,\n context: opts.context,\n profile: opts.profile,\n apiBase: opts.apiBase,\n apiKey: opts.apiKey,\n json: opts.json,\n });\n const api = ctx.api;\n\n const agent = await api.get<Agent>(`/api/agents/${opts.agentId}`);\n if (!agent || typeof agent !== \"object\" || !agent.id) {\n console.error(pc.red(`Agent not found: ${opts.agentId}`));\n return;\n }\n\n const invokeRes = await api.post<InvokedHeartbeat>(\n `/api/agents/${opts.agentId}/wakeup`,\n {\n source: source,\n triggerDetail: triggerDetail,\n },\n );\n if (!invokeRes) {\n console.error(pc.red(\"Failed to invoke heartbeat\"));\n return;\n }\n if ((invokeRes as { status?: string }).status === \"skipped\") {\n console.log(pc.yellow(\"Heartbeat invocation was skipped\"));\n return;\n }\n\n const run = invokeRes as HeartbeatRun;\n console.log(pc.cyan(`Invoked heartbeat run ${run.id} for agent ${agent.name} (${agent.id})`));\n\n const runId = run.id;\n let activeRunId: string | null = null;\n let lastEventSeq = 0;\n let logOffset = 0;\n let stdoutJsonBuffer = \"\";\n\n const printRawChunk = (stream: \"stdout\" | \"stderr\" | \"system\", chunk: string) => {\n if (stream === \"stdout\") process.stdout.write(pc.green(\"[stdout] \") + chunk);\n else if (stream === \"stderr\") process.stdout.write(pc.red(\"[stderr] \") + chunk);\n else process.stdout.write(pc.yellow(\"[system] \") + chunk);\n };\n\n const printAdapterInvoke = (payload: Record<string, unknown>) => {\n const agentRuntimeType = typeof payload.agentRuntimeType === \"string\" ? payload.agentRuntimeType : \"unknown\";\n const command = typeof payload.command === \"string\" ? payload.command : \"\";\n const cwd = typeof payload.cwd === \"string\" ? payload.cwd : \"\";\n const args =\n Array.isArray(payload.commandArgs) &&\n (payload.commandArgs as unknown[]).every((v) => typeof v === \"string\")\n ? (payload.commandArgs as string[])\n : [];\n const env =\n typeof payload.env === \"object\" && payload.env !== null && !Array.isArray(payload.env)\n ? (payload.env as Record<string, unknown>)\n : null;\n const prompt = typeof payload.prompt === \"string\" ? payload.prompt : \"\";\n const context =\n typeof payload.context === \"object\" && payload.context !== null && !Array.isArray(payload.context)\n ? (payload.context as Record<string, unknown>)\n : null;\n\n console.log(pc.cyan(`Adapter: ${agentRuntimeType}`));\n if (cwd) console.log(pc.cyan(`Working dir: ${cwd}`));\n if (command) {\n const rendered = args.length > 0 ? `${command} ${args.join(\" \")}` : command;\n console.log(pc.cyan(`Command: ${rendered}`));\n }\n if (env) {\n console.log(pc.cyan(\"Env:\"));\n console.log(pc.gray(JSON.stringify(env, null, 2)));\n }\n if (context) {\n console.log(pc.cyan(\"Context:\"));\n console.log(pc.gray(JSON.stringify(context, null, 2)));\n }\n if (prompt) {\n console.log(pc.cyan(\"Prompt:\"));\n console.log(prompt);\n }\n };\n\n const agentRuntimeType: AdapterType = agent.agentRuntimeType ?? \"claude_local\";\n const cliAdapter = getCLIAdapter(agentRuntimeType);\n\n const handleStreamChunk = (stream: \"stdout\" | \"stderr\" | \"system\", chunk: string) => {\n if (debug) {\n printRawChunk(stream, chunk);\n return;\n }\n\n if (stream !== \"stdout\") {\n printRawChunk(stream, chunk);\n return;\n }\n\n const combined = stdoutJsonBuffer + chunk;\n const lines = combined.split(/\\r?\\n/);\n stdoutJsonBuffer = lines.pop() ?? \"\";\n for (const line of lines) {\n cliAdapter.formatStdoutEvent(line, debug);\n }\n };\n\n const handleEvent = (event: HeartbeatRunEventRecord) => {\n const payload = normalizePayload(event.payload);\n if (event.runId !== runId) return;\n const eventType = typeof event.eventType === \"string\"\n ? event.eventType\n : typeof event.type === \"string\"\n ? event.type\n : \"\";\n\n if (eventType === \"heartbeat.run.status\") {\n const status = typeof payload.status === \"string\" ? payload.status : null;\n if (status) {\n console.log(pc.blue(`[status] ${status}`));\n }\n } else if (eventType === \"adapter.invoke\") {\n printAdapterInvoke(payload);\n } else if (eventType === \"heartbeat.run.log\") {\n const stream = typeof payload.stream === \"string\" ? payload.stream : \"system\";\n const chunk = typeof payload.chunk === \"string\" ? payload.chunk : \"\";\n if (!chunk) return;\n if (stream === \"stdout\" || stream === \"stderr\" || stream === \"system\") {\n handleStreamChunk(stream, chunk);\n }\n } else if (typeof event.message === \"string\") {\n console.log(pc.gray(`[event] ${eventType || \"heartbeat.run.event\"}: ${event.message}`));\n }\n\n lastEventSeq = Math.max(lastEventSeq, event.seq ?? 0);\n };\n\n activeRunId = runId;\n let finalStatus: string | null = null;\n let finalError: string | null = null;\n let finalRun: HeartbeatRun | null = null;\n\n const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : null;\n if (!activeRunId) {\n console.error(pc.red(\"Failed to capture heartbeat run id\"));\n return;\n }\n\n while (true) {\n const events = await api.get<HeartbeatRunEvent[]>(\n `/api/heartbeat-runs/${activeRunId}/events?afterSeq=${lastEventSeq}&limit=100`,\n );\n for (const event of Array.isArray(events) ? (events as HeartbeatRunEventRecord[]) : []) {\n handleEvent(event);\n }\n\n const runList = (await api.get<(HeartbeatRun | null)[]>(\n `/api/orgs/${agent.orgId}/heartbeat-runs?agentId=${agent.id}`,\n )) || [];\n const currentRun = runList.find((r) => r && r.id === activeRunId) ?? null;\n\n if (!currentRun) {\n console.error(pc.red(\"Heartbeat run disappeared\"));\n break;\n }\n\n const currentStatus = currentRun.status as HeartbeatRunStatus | undefined;\n if (currentStatus !== finalStatus && currentStatus) {\n finalStatus = currentStatus;\n console.log(pc.blue(`Status: ${currentStatus}`));\n }\n\n if (currentStatus && TERMINAL_STATUSES.has(currentStatus)) {\n finalStatus = currentRun.status;\n finalError = currentRun.error;\n finalRun = currentRun;\n break;\n }\n\n if (deadline && Date.now() >= deadline) {\n finalError = `CLI timed out after ${timeoutMs}ms`;\n finalStatus = \"timed_out\";\n console.error(pc.yellow(finalError));\n break;\n }\n\n const logResult = await api.get<{ content: string; endOffset?: number; nextOffset?: number }>(\n `/api/heartbeat-runs/${activeRunId}/log?offset=${logOffset}&limitBytes=16384`,\n { ignoreNotFound: true },\n );\n if (logResult && logResult.content) {\n for (const chunk of logResult.content.split(/\\r?\\n/)) {\n if (!chunk) continue;\n const parsed = safeParseLogLine(chunk);\n if (!parsed) continue;\n handleStreamChunk(parsed.stream, parsed.chunk);\n }\n if (typeof logResult.nextOffset === \"number\") {\n logOffset = logResult.nextOffset;\n } else if (typeof logResult.endOffset === \"number\") {\n logOffset = logResult.endOffset;\n } else if (logResult.content) {\n logOffset += Buffer.byteLength(logResult.content, \"utf8\");\n }\n }\n\n await delay(POLL_INTERVAL_MS);\n }\n\n if (finalStatus) {\n if (!debug && stdoutJsonBuffer.trim()) {\n cliAdapter.formatStdoutEvent(stdoutJsonBuffer, debug);\n stdoutJsonBuffer = \"\";\n }\n const label = `Run ${activeRunId} completed with status ${finalStatus}`;\n if (finalStatus === \"succeeded\") {\n console.log(pc.green(label));\n return;\n }\n\n console.log(pc.red(label));\n if (finalError) {\n console.log(pc.red(`Error: ${finalError}`));\n }\n if (finalRun) {\n const resultObj = asRecord(finalRun.resultJson);\n if (resultObj) {\n const subtype = typeof resultObj.subtype === \"string\" ? resultObj.subtype : \"\";\n const isError = resultObj.is_error === true;\n const errors = Array.isArray(resultObj.errors) ? resultObj.errors.map(asErrorText).filter(Boolean) : [];\n const resultText = typeof resultObj.result === \"string\" ? resultObj.result.trim() : \"\";\n if (subtype || isError || errors.length > 0 || resultText) {\n console.log(pc.red(\"Claude result details:\"));\n if (subtype) console.log(pc.red(` subtype: ${subtype}`));\n if (isError) console.log(pc.red(\" is_error: true\"));\n if (errors.length > 0) console.log(pc.red(` errors: ${errors.join(\" | \")}`));\n if (resultText) console.log(pc.red(` result: ${resultText}`));\n }\n }\n\n const stderrExcerpt = typeof finalRun.stderrExcerpt === \"string\" ? finalRun.stderrExcerpt.trim() : \"\";\n const stdoutExcerpt = typeof finalRun.stdoutExcerpt === \"string\" ? finalRun.stdoutExcerpt.trim() : \"\";\n if (stderrExcerpt) {\n console.log(pc.red(\"stderr excerpt:\"));\n console.log(stderrExcerpt);\n }\n if (stdoutExcerpt && (debug || !stderrExcerpt)) {\n console.log(pc.gray(\"stdout excerpt:\"));\n console.log(stdoutExcerpt);\n }\n }\n process.exitCode = 1;\n } else {\n process.exitCode = 1;\n console.log(pc.gray(\"Heartbeat stream ended without terminal status\"));\n }\n}\n\nfunction normalizePayload(payload: unknown): Record<string, unknown> {\n return typeof payload === \"object\" && payload !== null ? (payload as Record<string, unknown>) : {};\n}\n\nfunction safeParseLogLine(line: string): { stream: \"stdout\" | \"stderr\" | \"system\"; chunk: string } | null {\n try {\n const parsed = JSON.parse(line) as { stream?: unknown; chunk?: unknown };\n const stream =\n parsed.stream === \"stdout\" || parsed.stream === \"stderr\" || parsed.stream === \"system\"\n ? parsed.stream\n : \"system\";\n const chunk = typeof parsed.chunk === \"string\" ? parsed.chunk : \"\";\n\n if (!chunk) return null;\n return { stream, chunk };\n } catch {\n return null;\n }\n}\n", "export function printProcessStdoutEvent(raw: string, _debug: boolean): void {\n const line = raw.trim();\n if (line) console.log(line);\n}\n", "import type { CLIAgentRuntimeModule } from \"@rudderhq/agent-runtime-utils\";\nimport { printProcessStdoutEvent } from \"./format-event.js\";\n\nexport const processCLIAdapter: CLIAgentRuntimeModule = {\n type: \"process\",\n formatStdoutEvent: printProcessStdoutEvent,\n};\n", "export function printHttpStdoutEvent(raw: string, _debug: boolean): void {\n const line = raw.trim();\n if (line) console.log(line);\n}\n", "import type { CLIAgentRuntimeModule } from \"@rudderhq/agent-runtime-utils\";\nimport { printHttpStdoutEvent } from \"./format-event.js\";\n\nexport const httpCLIAdapter: CLIAgentRuntimeModule = {\n type: \"http\",\n formatStdoutEvent: printHttpStdoutEvent,\n};\n", "import type { CLIAgentRuntimeModule } from \"@rudderhq/agent-runtime-utils\";\nimport { processCLIAdapter } from \"./process/index.js\";\nimport { httpCLIAdapter } from \"./http/index.js\";\n\nconst localRuntimeTypes = [\n \"claude_local\",\n \"codex_local\",\n \"opencode_local\",\n \"pi_local\",\n \"cursor\",\n \"gemini_local\",\n \"openclaw_gateway\",\n];\n\nconst adaptersByType = new Map<string, CLIAgentRuntimeModule>([\n [processCLIAdapter.type, processCLIAdapter],\n [httpCLIAdapter.type, httpCLIAdapter],\n ...localRuntimeTypes.map((type): [string, CLIAgentRuntimeModule] => [\n type,\n { ...processCLIAdapter, type },\n ]),\n]);\n\nexport function getCLIAdapter(type: string): CLIAgentRuntimeModule {\n return adaptersByType.get(type) ?? processCLIAdapter;\n}\n", "import pc from \"picocolors\";\nimport type { Command } from \"commander\";\nimport { getStoredBoardCredential, loginBoardCli } from \"../../client/board-auth.js\";\nimport { buildCliCommandLabel } from \"../../client/command-label.js\";\nimport { readConfig } from \"../../config/store.js\";\nimport { readContext, resolveProfile, type ClientContextProfile } from \"../../client/context.js\";\nimport { ApiRequestError, RudderApiClient } from \"../../client/http.js\";\n\nexport interface BaseClientOptions {\n config?: string;\n dataDir?: string;\n context?: string;\n profile?: string;\n apiBase?: string;\n apiKey?: string;\n orgId?: string;\n companyId?: string;\n runId?: string;\n json?: boolean;\n}\n\nexport interface ResolvedClientContext {\n api: RudderApiClient;\n orgId?: string;\n agentId?: string;\n runId?: string;\n profileName: string;\n profile: ClientContextProfile;\n json: boolean;\n}\n\nexport function addCommonClientOptions(command: Command, opts?: { includeCompany?: boolean }): Command {\n command\n .option(\"-c, --config <path>\", \"Path to Rudder config file\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"CLI context profile name\")\n .option(\"--api-base <url>\", \"Base URL for the Rudder API\")\n .option(\"--api-key <token>\", \"Bearer token for agent-authenticated calls\")\n .option(\"--run-id <id>\", \"Run ID to attach on mutating agent requests\")\n .option(\"--json\", \"Output raw JSON\");\n\n if (opts?.includeCompany) {\n command.option(\"-O, --org-id <id>\", \"Organization ID (overrides context default)\");\n }\n\n return command;\n}\n\nexport function resolveCommandContext(\n options: BaseClientOptions,\n opts?: { requireCompany?: boolean },\n): ResolvedClientContext {\n const context = readContext(options.context);\n const { name: profileName, profile } = resolveProfile(context, options.profile);\n\n const apiBase =\n options.apiBase?.trim() ||\n process.env.RUDDER_API_URL?.trim() ||\n profile.apiBase ||\n inferApiBaseFromConfig(options.config);\n\n const explicitApiKey =\n options.apiKey?.trim() ||\n process.env.RUDDER_API_KEY?.trim() ||\n readKeyFromProfileEnv(profile);\n const storedBoardCredential = explicitApiKey ? null : getStoredBoardCredential(apiBase);\n const apiKey = explicitApiKey || storedBoardCredential?.token;\n\n const orgId =\n options.orgId?.trim() ||\n options.companyId?.trim() ||\n process.env.RUDDER_ORG_ID?.trim() ||\n profile.orgId;\n const agentId = process.env.RUDDER_AGENT_ID?.trim() || undefined;\n const runId = options.runId?.trim() || process.env.RUDDER_RUN_ID?.trim() || undefined;\n\n if (opts?.requireCompany && !orgId) {\n throw new Error(\n \"Organization ID is required. Pass --org-id, set RUDDER_ORG_ID, or set context profile orgId via `rudder context set`.\",\n );\n }\n\n const api = new RudderApiClient({\n apiBase,\n apiKey,\n agentId,\n runId,\n recoverAuth: explicitApiKey || !canAttemptInteractiveBoardAuth()\n ? undefined\n : async ({ error }) => {\n const requestedAccess = error.message.includes(\"Instance admin required\")\n ? \"instance_admin_required\"\n : \"board\";\n if (!shouldRecoverBoardAuth(error)) {\n return null;\n }\n const login = await loginBoardCli({\n apiBase,\n requestedAccess,\n requestedCompanyId: orgId ?? null,\n command: buildCliCommandLabel(),\n });\n return login.token;\n },\n });\n return {\n api,\n orgId,\n agentId,\n runId,\n profileName,\n profile,\n json: Boolean(options.json),\n };\n}\n\nfunction shouldRecoverBoardAuth(error: ApiRequestError): boolean {\n if (error.status === 401) return true;\n if (error.status !== 403) return false;\n return error.message.includes(\"Board access required\") || error.message.includes(\"Instance admin required\");\n}\n\nfunction canAttemptInteractiveBoardAuth(): boolean {\n return Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}\n\nexport function printOutput(data: unknown, opts: { json?: boolean; label?: string } = {}): void {\n if (opts.json) {\n const output = JSON.stringify(data, null, 2);\n process.stdout.write(output + \"\\n\");\n return;\n }\n\n if (opts.label) {\n console.log(pc.bold(opts.label));\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log(pc.dim(\"(empty)\"));\n return;\n }\n for (const item of data) {\n if (typeof item === \"object\" && item !== null) {\n console.log(formatInlineRecord(item as Record<string, unknown>));\n } else {\n console.log(String(item));\n }\n }\n return;\n }\n\n if (typeof data === \"object\" && data !== null) {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n if (data === undefined || data === null) {\n console.log(pc.dim(\"(null)\"));\n return;\n }\n\n console.log(String(data));\n}\n\nexport function formatInlineRecord(record: Record<string, unknown>): string {\n const keyOrder = [\"identifier\", \"id\", \"name\", \"status\", \"priority\", \"title\", \"action\"];\n const seen = new Set<string>();\n const parts: string[] = [];\n\n for (const key of keyOrder) {\n if (!(key in record)) continue;\n parts.push(`${key}=${renderValue(record[key])}`);\n seen.add(key);\n }\n\n for (const [key, value] of Object.entries(record)) {\n if (seen.has(key)) continue;\n if (typeof value === \"object\") continue;\n parts.push(`${key}=${renderValue(value)}`);\n }\n\n return parts.join(\" \");\n}\n\nfunction renderValue(value: unknown): string {\n if (value === null || value === undefined) return \"-\";\n if (typeof value === \"string\") {\n const compact = value.replace(/\\s+/g, \" \").trim();\n return compact.length > 90 ? `${compact.slice(0, 87)}...` : compact;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return \"[object]\";\n}\n\nfunction inferApiBaseFromConfig(configPath?: string): string {\n const envHost = process.env.RUDDER_SERVER_HOST?.trim() || \"localhost\";\n let port = Number(process.env.RUDDER_SERVER_PORT || \"\");\n\n if (!Number.isFinite(port) || port <= 0) {\n try {\n const config = readConfig(configPath);\n port = Number(config?.server?.port ?? 3100);\n } catch {\n port = 3100;\n }\n }\n\n if (!Number.isFinite(port) || port <= 0) {\n port = 3100;\n }\n\n return `http://${envHost}:${port}`;\n}\n\nfunction readKeyFromProfileEnv(profile: ClientContextProfile): string | undefined {\n if (!profile.apiKeyEnvVarName) return undefined;\n return process.env[profile.apiKeyEnvVarName]?.trim() || undefined;\n}\n\nexport function handleCommandError(error: unknown): never {\n if (process.argv.includes(\"--json\")) {\n const payload = buildCommandErrorPayload(error);\n process.stderr.write(`${JSON.stringify(payload, null, 2)}\\n`);\n process.exit(1);\n }\n\n if (error instanceof ApiRequestError) {\n const detailSuffix = error.details !== undefined ? ` details=${JSON.stringify(error.details)}` : \"\";\n console.error(pc.red(`API error ${error.status}: ${error.message}${detailSuffix}`));\n process.exit(1);\n }\n\n const message = error instanceof Error ? error.message : String(error);\n console.error(pc.red(message));\n process.exit(1);\n}\n\nfunction buildCommandErrorPayload(error: unknown) {\n if (error instanceof ApiRequestError) {\n return {\n error: error.message,\n status: error.status,\n code: error.code ?? \"api_request_error\",\n details: error.details ?? null,\n };\n }\n\n return {\n error: error instanceof Error ? error.message : String(error),\n status: null,\n code: \"cli_error\",\n details: null,\n };\n}\n", "import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport pc from \"picocolors\";\nimport { buildCliCommandLabel } from \"./command-label.js\";\nimport { resolveDefaultCliAuthPath } from \"../config/home.js\";\n\ntype RequestedAccess = \"board\" | \"instance_admin_required\";\n\ninterface BoardAuthCredential {\n apiBase: string;\n token: string;\n createdAt: string;\n updatedAt: string;\n userId?: string | null;\n}\n\ninterface BoardAuthStore {\n version: 1;\n credentials: Record<string, BoardAuthCredential>;\n}\n\ninterface CreateChallengeResponse {\n id: string;\n token: string;\n boardApiToken: string;\n approvalPath: string;\n approvalUrl: string | null;\n pollPath: string;\n expiresAt: string;\n suggestedPollIntervalMs: number;\n}\n\ninterface ChallengeStatusResponse {\n id: string;\n status: \"pending\" | \"approved\" | \"cancelled\" | \"expired\";\n command: string;\n clientName: string | null;\n requestedAccess: RequestedAccess;\n requestedCompanyId: string | null;\n requestedCompanyName: string | null;\n approvedAt: string | null;\n cancelledAt: string | null;\n expiresAt: string;\n approvedByUser: { id: string; name: string; email: string } | null;\n}\n\nfunction defaultBoardAuthStore(): BoardAuthStore {\n return {\n version: 1,\n credentials: {},\n };\n}\n\nfunction toStringOrNull(value: unknown): string | null {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : null;\n}\n\nfunction normalizeApiBase(apiBase: string): string {\n return apiBase.trim().replace(/\\/+$/, \"\");\n}\n\nexport function resolveBoardAuthStorePath(overridePath?: string): string {\n if (overridePath?.trim()) return path.resolve(overridePath.trim());\n if (process.env.RUDDER_AUTH_STORE?.trim()) return path.resolve(process.env.RUDDER_AUTH_STORE.trim());\n return resolveDefaultCliAuthPath();\n}\n\nexport function readBoardAuthStore(storePath?: string): BoardAuthStore {\n const filePath = resolveBoardAuthStorePath(storePath);\n if (!fs.existsSync(filePath)) return defaultBoardAuthStore();\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf8\")) as Partial<BoardAuthStore> | null;\n const credentials = raw?.credentials && typeof raw.credentials === \"object\" ? raw.credentials : {};\n const normalized: Record<string, BoardAuthCredential> = {};\n\n for (const [key, value] of Object.entries(credentials)) {\n if (typeof value !== \"object\" || value === null) continue;\n const record = value as unknown as Record<string, unknown>;\n const apiBase = toStringOrNull(record.apiBase);\n const token = toStringOrNull(record.token);\n const createdAt = toStringOrNull(record.createdAt);\n const updatedAt = toStringOrNull(record.updatedAt);\n if (!apiBase || !token || !createdAt || !updatedAt) continue;\n normalized[normalizeApiBase(key)] = {\n apiBase,\n token,\n createdAt,\n updatedAt,\n userId: toStringOrNull(record.userId),\n };\n }\n\n return {\n version: 1,\n credentials: normalized,\n };\n}\n\nexport function writeBoardAuthStore(store: BoardAuthStore, storePath?: string): void {\n const filePath = resolveBoardAuthStorePath(storePath);\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, `${JSON.stringify(store, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function getStoredBoardCredential(apiBase: string, storePath?: string): BoardAuthCredential | null {\n const store = readBoardAuthStore(storePath);\n return store.credentials[normalizeApiBase(apiBase)] ?? null;\n}\n\nexport function setStoredBoardCredential(input: {\n apiBase: string;\n token: string;\n userId?: string | null;\n storePath?: string;\n}): BoardAuthCredential {\n const normalizedApiBase = normalizeApiBase(input.apiBase);\n const store = readBoardAuthStore(input.storePath);\n const now = new Date().toISOString();\n const existing = store.credentials[normalizedApiBase];\n const credential: BoardAuthCredential = {\n apiBase: normalizedApiBase,\n token: input.token.trim(),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n userId: input.userId ?? existing?.userId ?? null,\n };\n store.credentials[normalizedApiBase] = credential;\n writeBoardAuthStore(store, input.storePath);\n return credential;\n}\n\nexport function removeStoredBoardCredential(apiBase: string, storePath?: string): boolean {\n const normalizedApiBase = normalizeApiBase(apiBase);\n const store = readBoardAuthStore(storePath);\n if (!store.credentials[normalizedApiBase]) return false;\n delete store.credentials[normalizedApiBase];\n writeBoardAuthStore(store, storePath);\n return true;\n}\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function requestJson<T>(url: string, init?: RequestInit): Promise<T> {\n const headers = new Headers(init?.headers ?? undefined);\n if (init?.body !== undefined && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n if (!headers.has(\"accept\")) {\n headers.set(\"accept\", \"application/json\");\n }\n\n const response = await fetch(url, {\n ...init,\n headers,\n });\n\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n const message =\n body && typeof body === \"object\" && typeof (body as { error?: unknown }).error === \"string\"\n ? (body as { error: string }).error\n : `Request failed: ${response.status}`;\n throw new Error(message);\n }\n\n return response.json() as Promise<T>;\n}\n\nexport function openUrl(url: string): boolean {\n const platform = process.platform;\n try {\n if (platform === \"darwin\") {\n const child = spawn(\"open\", [url], { detached: true, stdio: \"ignore\" });\n child.unref();\n return true;\n }\n if (platform === \"win32\") {\n const child = spawn(\"cmd\", [\"/c\", \"start\", \"\", url], { detached: true, stdio: \"ignore\" });\n child.unref();\n return true;\n }\n const child = spawn(\"xdg-open\", [url], { detached: true, stdio: \"ignore\" });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function loginBoardCli(params: {\n apiBase: string;\n requestedAccess: RequestedAccess;\n requestedCompanyId?: string | null;\n clientName?: string | null;\n command?: string;\n storePath?: string;\n print?: boolean;\n}): Promise<{ token: string; approvalUrl: string; userId?: string | null }> {\n const apiBase = normalizeApiBase(params.apiBase);\n const createUrl = `${apiBase}/api/cli-auth/challenges`;\n const command = params.command?.trim() || buildCliCommandLabel();\n\n const challenge = await requestJson<CreateChallengeResponse>(createUrl, {\n method: \"POST\",\n body: JSON.stringify({\n command,\n clientName: params.clientName?.trim() || \"rudder cli\",\n requestedAccess: params.requestedAccess,\n requestedCompanyId: params.requestedCompanyId?.trim() || null,\n }),\n });\n\n const approvalUrl = challenge.approvalUrl ?? `${apiBase}${challenge.approvalPath}`;\n if (params.print !== false) {\n console.error(pc.bold(\"Board authentication required\"));\n console.error(`Open this URL in your browser to approve CLI access:\\n${approvalUrl}`);\n }\n\n const opened = openUrl(approvalUrl);\n if (params.print !== false && opened) {\n console.error(pc.dim(\"Opened the approval page in your browser.\"));\n }\n\n const expiresAtMs = Date.parse(challenge.expiresAt);\n const pollMs = Math.max(500, challenge.suggestedPollIntervalMs || 1000);\n\n while (Number.isFinite(expiresAtMs) ? Date.now() < expiresAtMs : true) {\n const status = await requestJson<ChallengeStatusResponse>(\n `${apiBase}/api${challenge.pollPath}?token=${encodeURIComponent(challenge.token)}`,\n );\n\n if (status.status === \"approved\") {\n const me = await requestJson<{ userId: string; user?: { id: string } | null }>(\n `${apiBase}/api/cli-auth/me`,\n {\n headers: {\n authorization: `Bearer ${challenge.boardApiToken}`,\n },\n },\n );\n setStoredBoardCredential({\n apiBase,\n token: challenge.boardApiToken,\n userId: me.userId ?? me.user?.id ?? null,\n storePath: params.storePath,\n });\n return {\n token: challenge.boardApiToken,\n approvalUrl,\n userId: me.userId ?? me.user?.id ?? null,\n };\n }\n\n if (status.status === \"cancelled\") {\n throw new Error(\"CLI auth challenge was cancelled.\");\n }\n if (status.status === \"expired\") {\n throw new Error(\"CLI auth challenge expired before approval.\");\n }\n\n await sleep(pollMs);\n }\n\n throw new Error(\"CLI auth challenge expired before approval.\");\n}\n\nexport async function revokeStoredBoardCredential(params: {\n apiBase: string;\n token: string;\n}): Promise<void> {\n const apiBase = normalizeApiBase(params.apiBase);\n await requestJson<{ revoked: boolean }>(`${apiBase}/api/cli-auth/revoke-current`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${params.token}`,\n },\n body: JSON.stringify({}),\n });\n}\n", "export function buildCliCommandLabel(): string {\n const args = process.argv.slice(2);\n return args.length > 0 ? `rudder ${args.join(\" \")}` : \"rudder\";\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { resolveDefaultContextPath } from \"../config/home.js\";\n\nconst DEFAULT_CONTEXT_BASENAME = \"context.json\";\nconst DEFAULT_PROFILE = \"default\";\n\nexport interface ClientContextProfile {\n apiBase?: string;\n orgId?: string;\n apiKeyEnvVarName?: string;\n}\n\nexport interface ClientContext {\n version: 1;\n currentProfile: string;\n profiles: Record<string, ClientContextProfile>;\n}\n\nfunction findContextFileFromAncestors(startDir: string): string | null {\n const absoluteStartDir = path.resolve(startDir);\n let currentDir = absoluteStartDir;\n\n while (true) {\n const candidate = path.resolve(currentDir, \".rudder\", DEFAULT_CONTEXT_BASENAME);\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n\n const nextDir = path.resolve(currentDir, \"..\");\n if (nextDir === currentDir) break;\n currentDir = nextDir;\n }\n\n return null;\n}\n\nexport function resolveContextPath(overridePath?: string): string {\n if (overridePath) return path.resolve(overridePath);\n if (process.env.RUDDER_CONTEXT) return path.resolve(process.env.RUDDER_CONTEXT);\n return findContextFileFromAncestors(process.cwd()) ?? resolveDefaultContextPath();\n}\n\nexport function defaultClientContext(): ClientContext {\n return {\n version: 1,\n currentProfile: DEFAULT_PROFILE,\n profiles: {\n [DEFAULT_PROFILE]: {},\n },\n };\n}\n\nfunction parseJson(filePath: string): unknown {\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n } catch (err) {\n throw new Error(`Failed to parse JSON at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction toStringOrUndefined(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction normalizeProfile(value: unknown): ClientContextProfile {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return {};\n const profile = value as Record<string, unknown>;\n\n return {\n apiBase: toStringOrUndefined(profile.apiBase),\n orgId: toStringOrUndefined(profile.orgId ?? profile.companyId),\n apiKeyEnvVarName: toStringOrUndefined(profile.apiKeyEnvVarName),\n };\n}\n\nfunction normalizeContext(raw: unknown): ClientContext {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n return defaultClientContext();\n }\n\n const record = raw as Record<string, unknown>;\n const version = record.version === 1 ? 1 : 1;\n const currentProfile = toStringOrUndefined(record.currentProfile) ?? DEFAULT_PROFILE;\n\n const rawProfiles = record.profiles;\n const profiles: Record<string, ClientContextProfile> = {};\n\n if (typeof rawProfiles === \"object\" && rawProfiles !== null && !Array.isArray(rawProfiles)) {\n for (const [name, profile] of Object.entries(rawProfiles as Record<string, unknown>)) {\n if (!name.trim()) continue;\n profiles[name] = normalizeProfile(profile);\n }\n }\n\n if (!profiles[currentProfile]) {\n profiles[currentProfile] = {};\n }\n\n if (Object.keys(profiles).length === 0) {\n profiles[DEFAULT_PROFILE] = {};\n }\n\n return {\n version,\n currentProfile,\n profiles,\n };\n}\n\nexport function readContext(contextPath?: string): ClientContext {\n const filePath = resolveContextPath(contextPath);\n if (!fs.existsSync(filePath)) {\n return defaultClientContext();\n }\n\n const raw = parseJson(filePath);\n return normalizeContext(raw);\n}\n\nexport function writeContext(context: ClientContext, contextPath?: string): void {\n const filePath = resolveContextPath(contextPath);\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n\n const normalized = normalizeContext(context);\n fs.writeFileSync(filePath, `${JSON.stringify(normalized, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function upsertProfile(\n profileName: string,\n patch: Partial<ClientContextProfile>,\n contextPath?: string,\n): ClientContext {\n const context = readContext(contextPath);\n const existing = context.profiles[profileName] ?? {};\n const merged: ClientContextProfile = {\n ...existing,\n ...patch,\n };\n\n if (patch.apiBase !== undefined && patch.apiBase.trim().length === 0) {\n delete merged.apiBase;\n }\n if (patch.orgId !== undefined && patch.orgId.trim().length === 0) {\n delete merged.orgId;\n }\n if (patch.apiKeyEnvVarName !== undefined && patch.apiKeyEnvVarName.trim().length === 0) {\n delete merged.apiKeyEnvVarName;\n }\n\n context.profiles[profileName] = merged;\n context.currentProfile = context.currentProfile || profileName;\n writeContext(context, contextPath);\n return context;\n}\n\nexport function setCurrentProfile(profileName: string, contextPath?: string): ClientContext {\n const context = readContext(contextPath);\n if (!context.profiles[profileName]) {\n context.profiles[profileName] = {};\n }\n context.currentProfile = profileName;\n writeContext(context, contextPath);\n return context;\n}\n\nexport function resolveProfile(\n context: ClientContext,\n profileName?: string,\n): { name: string; profile: ClientContextProfile } {\n const name = profileName?.trim() || context.currentProfile || DEFAULT_PROFILE;\n const profile = context.profiles[name] ?? {};\n return { name, profile };\n}\n", "import { URL } from \"node:url\";\n\nexport class ApiRequestError extends Error {\n status: number;\n code?: string | null;\n details?: unknown;\n body?: unknown;\n\n constructor(status: number, message: string, details?: unknown, body?: unknown, code?: string | null) {\n super(message);\n this.status = status;\n this.code = code ?? null;\n this.details = details;\n this.body = body;\n }\n}\n\ninterface RequestOptions {\n ignoreNotFound?: boolean;\n}\n\ninterface RecoverAuthInput {\n path: string;\n method: string;\n error: ApiRequestError;\n}\n\ninterface ApiClientOptions {\n apiBase: string;\n apiKey?: string;\n agentId?: string;\n runId?: string;\n recoverAuth?: (input: RecoverAuthInput) => Promise<string | null>;\n}\n\nexport class RudderApiClient {\n readonly apiBase: string;\n apiKey?: string;\n readonly agentId?: string;\n readonly runId?: string;\n readonly recoverAuth?: (input: RecoverAuthInput) => Promise<string | null>;\n\n constructor(opts: ApiClientOptions) {\n this.apiBase = opts.apiBase.replace(/\\/+$/, \"\");\n this.apiKey = opts.apiKey?.trim() || undefined;\n this.agentId = opts.agentId?.trim() || undefined;\n this.runId = opts.runId?.trim() || undefined;\n this.recoverAuth = opts.recoverAuth;\n }\n\n get<T>(path: string, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, { method: \"GET\" }, opts);\n }\n\n post<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"POST\",\n body: body === undefined ? undefined : JSON.stringify(body),\n }, opts);\n }\n\n postForm<T>(path: string, form: FormData, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"POST\",\n body: form,\n }, opts);\n }\n\n patch<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"PATCH\",\n body: body === undefined ? undefined : JSON.stringify(body),\n }, opts);\n }\n\n put<T>(path: string, body?: unknown, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, {\n method: \"PUT\",\n body: body === undefined ? undefined : JSON.stringify(body),\n }, opts);\n }\n\n delete<T>(path: string, opts?: RequestOptions): Promise<T | null> {\n return this.request<T>(path, { method: \"DELETE\" }, opts);\n }\n\n setApiKey(apiKey: string | undefined) {\n this.apiKey = apiKey?.trim() || undefined;\n }\n\n private async request<T>(\n path: string,\n init: RequestInit,\n opts?: RequestOptions,\n hasRetriedAuth = false,\n ): Promise<T | null> {\n const url = buildUrl(this.apiBase, path);\n\n const headers: Record<string, string> = {\n accept: \"application/json\",\n ...toStringRecord(init.headers),\n };\n\n if (typeof init.body === \"string\") {\n headers[\"content-type\"] = headers[\"content-type\"] ?? \"application/json\";\n }\n\n if (this.apiKey) {\n headers.authorization = `Bearer ${this.apiKey}`;\n }\n\n if (shouldAttachAgentContext(init.method)) {\n if (this.agentId) {\n headers[\"x-rudder-agent-id\"] = this.agentId;\n }\n if (this.runId) {\n headers[\"x-rudder-run-id\"] = this.runId;\n }\n }\n\n const response = await fetch(url, {\n ...init,\n headers,\n });\n\n if (opts?.ignoreNotFound && response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n const apiError = await toApiError(response);\n if (!hasRetriedAuth && this.recoverAuth) {\n const recoveredToken = await this.recoverAuth({\n path,\n method: String(init.method ?? \"GET\").toUpperCase(),\n error: apiError,\n });\n if (recoveredToken) {\n this.setApiKey(recoveredToken);\n return this.request<T>(path, init, opts, true);\n }\n }\n throw apiError;\n }\n\n if (response.status === 204) {\n return null;\n }\n\n const text = await response.text();\n if (!text.trim()) {\n return null;\n }\n\n return safeParseJson(text) as T;\n }\n}\n\nfunction shouldAttachAgentContext(method: string | undefined): boolean {\n const normalized = String(method ?? \"GET\").toUpperCase();\n return normalized !== \"GET\" && normalized !== \"HEAD\";\n}\n\nfunction buildUrl(apiBase: string, path: string): string {\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n const [pathname, query] = normalizedPath.split(\"?\");\n const url = new URL(apiBase);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}${pathname}`;\n if (query) url.search = query;\n return url.toString();\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nasync function toApiError(response: Response): Promise<ApiRequestError> {\n const text = await response.text();\n const parsed = safeParseJson(text);\n\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n const body = parsed as Record<string, unknown>;\n const message =\n (typeof body.error === \"string\" && body.error.trim()) ||\n (typeof body.message === \"string\" && body.message.trim()) ||\n `Request failed with status ${response.status}`;\n const code = typeof body.code === \"string\" && body.code.trim().length > 0\n ? body.code.trim()\n : null;\n\n return new ApiRequestError(response.status, message, body.details, parsed, code);\n }\n\n return new ApiRequestError(\n response.status,\n `Request failed with status ${response.status}`,\n undefined,\n parsed,\n null,\n );\n}\n\nfunction toStringRecord(headers: HeadersInit | undefined): Record<string, string> {\n if (!headers) return {};\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers.map(([key, value]) => [key, String(value)]));\n }\n if (headers instanceof Headers) {\n return Object.fromEntries(headers.entries());\n }\n return Object.fromEntries(\n Object.entries(headers).map(([key, value]) => [key, String(value)]),\n );\n}\n", "import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n readContext,\n resolveContextPath,\n resolveProfile,\n setCurrentProfile,\n upsertProfile,\n} from \"../../client/context.js\";\nimport { printOutput } from \"./common.js\";\n\ninterface ContextOptions {\n dataDir?: string;\n context?: string;\n profile?: string;\n json?: boolean;\n}\n\ninterface ContextSetOptions extends ContextOptions {\n apiBase?: string;\n orgId?: string;\n apiKeyEnvVarName?: string;\n use?: boolean;\n}\n\nexport function registerContextCommands(program: Command): void {\n const context = program.command(\"context\").description(\"Manage CLI client context profiles\");\n\n context\n .command(\"show\")\n .description(\"Show current context and active profile\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"Profile to inspect\")\n .option(\"--json\", \"Output raw JSON\")\n .action((opts: ContextOptions) => {\n const contextPath = resolveContextPath(opts.context);\n const store = readContext(opts.context);\n const resolved = resolveProfile(store, opts.profile);\n const payload = {\n contextPath,\n currentProfile: store.currentProfile,\n profileName: resolved.name,\n profile: resolved.profile,\n profiles: store.profiles,\n };\n printOutput(payload, { json: opts.json });\n });\n\n context\n .command(\"list\")\n .description(\"List available context profiles\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--json\", \"Output raw JSON\")\n .action((opts: ContextOptions) => {\n const store = readContext(opts.context);\n const rows = Object.entries(store.profiles).map(([name, profile]) => ({\n name,\n current: name === store.currentProfile,\n apiBase: profile.apiBase ?? null,\n orgId: profile.orgId ?? null,\n apiKeyEnvVarName: profile.apiKeyEnvVarName ?? null,\n }));\n printOutput(rows, { json: opts.json });\n });\n\n context\n .command(\"use\")\n .description(\"Set active context profile\")\n .argument(\"<profile>\", \"Profile name\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .action((profile: string, opts: ContextOptions) => {\n setCurrentProfile(profile, opts.context);\n console.log(pc.green(`Active profile set to '${profile}'.`));\n });\n\n context\n .command(\"set\")\n .description(\"Set values on a profile\")\n .option(\"-d, --data-dir <path>\", \"Rudder data directory root (isolates state from ~/.rudder)\")\n .option(\"--context <path>\", \"Path to CLI context file\")\n .option(\"--profile <name>\", \"Profile name (default: current profile)\")\n .option(\"--api-base <url>\", \"Default API base URL\")\n .option(\"--org-id <id>\", \"Default organization ID\")\n .option(\"--api-key-env-var-name <name>\", \"Env var containing API key (recommended)\")\n .option(\"--use\", \"Set this profile as active\")\n .option(\"--json\", \"Output raw JSON\")\n .action((opts: ContextSetOptions) => {\n const existing = readContext(opts.context);\n const targetProfile = opts.profile?.trim() || existing.currentProfile || \"default\";\n\n upsertProfile(\n targetProfile,\n {\n apiBase: opts.apiBase,\n orgId: opts.orgId,\n apiKeyEnvVarName: opts.apiKeyEnvVarName,\n },\n opts.context,\n );\n\n if (opts.use) {\n setCurrentProfile(targetProfile, opts.context);\n }\n\n const updated = readContext(opts.context);\n const resolved = resolveProfile(updated, targetProfile);\n const payload = {\n contextPath: resolveContextPath(opts.context),\n currentProfile: updated.currentProfile,\n profileName: resolved.name,\n profile: resolved.profile,\n };\n\n if (!opts.json) {\n console.log(pc.green(`Updated profile '${targetProfile}'.`));\n if (opts.use) {\n console.log(pc.green(`Set '${targetProfile}' as active profile.`));\n }\n }\n printOutput(payload, { json: opts.json });\n });\n}\n", "import { Command } from \"commander\";\nimport { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type {\n Organization,\n OrganizationPortabilityFileEntry,\n OrganizationPortabilityExportResult,\n OrganizationPortabilityInclude,\n OrganizationPortabilityPreviewResult,\n OrganizationPortabilityImportResult,\n} from \"@rudderhq/shared\";\nimport { ApiRequestError } from \"../../client/http.js\";\nimport { openUrl } from \"../../client/board-auth.js\";\nimport { binaryContentTypeByExtension, readZipArchive } from \"./zip.js\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface CompanyCommandOptions extends BaseClientOptions {}\ntype CompanyDeleteSelectorMode = \"auto\" | \"id\" | \"prefix\";\ntype CompanyImportTargetMode = \"new\" | \"existing\";\ntype CompanyCollisionMode = \"rename\" | \"skip\" | \"replace\";\n\ninterface CompanyDeleteOptions extends BaseClientOptions {\n by?: CompanyDeleteSelectorMode;\n yes?: boolean;\n confirm?: string;\n}\n\ninterface CompanyExportOptions extends BaseClientOptions {\n out?: string;\n include?: string;\n skills?: string;\n projects?: string;\n issues?: string;\n projectIssues?: string;\n expandReferencedSkills?: boolean;\n}\n\ninterface CompanyImportOptions extends BaseClientOptions {\n include?: string;\n target?: CompanyImportTargetMode;\n orgId?: string;\n newOrganizationName?: string;\n agents?: string;\n collision?: CompanyCollisionMode;\n ref?: string;\n rudderUrl?: string;\n yes?: boolean;\n dryRun?: boolean;\n}\n\nconst DEFAULT_EXPORT_INCLUDE: OrganizationPortabilityInclude = {\n organization: true,\n agents: true,\n projects: false,\n issues: false,\n skills: false,\n};\n\nconst DEFAULT_IMPORT_INCLUDE: OrganizationPortabilityInclude = {\n organization: true,\n agents: true,\n projects: true,\n issues: true,\n skills: true,\n};\n\nconst IMPORT_INCLUDE_OPTIONS: Array<{\n value: keyof OrganizationPortabilityInclude;\n label: string;\n hint: string;\n}> = [\n { value: \"organization\", label: \"Organization\", hint: \"name, branding, and organization settings\" },\n { value: \"projects\", label: \"Projects\", hint: \"projects and workspace metadata\" },\n { value: \"issues\", label: \"Tasks\", hint: \"tasks and recurring automations\" },\n { value: \"agents\", label: \"Agents\", hint: \"agent records and organization structure\" },\n { value: \"skills\", label: \"Skills\", hint: \"organization skill packages and references\" },\n];\n\nconst IMPORT_PREVIEW_SAMPLE_LIMIT = 6;\n\ntype ImportSelectableGroup = \"projects\" | \"issues\" | \"agents\" | \"skills\";\n\ntype ImportSelectionCatalog = {\n organization: {\n includedByDefault: boolean;\n files: string[];\n };\n projects: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n issues: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n agents: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n skills: Array<{ key: string; label: string; hint?: string; files: string[] }>;\n extensionPath: string | null;\n};\n\ntype ImportSelectionState = {\n organization: boolean;\n projects: Set<string>;\n issues: Set<string>;\n agents: Set<string>;\n skills: Set<string>;\n};\n\nfunction readPortableFileEntry(filePath: string, contents: Buffer): OrganizationPortabilityFileEntry {\n const contentType = binaryContentTypeByExtension[path.extname(filePath).toLowerCase()];\n if (!contentType) return contents.toString(\"utf8\");\n return {\n encoding: \"base64\",\n data: contents.toString(\"base64\"),\n contentType,\n };\n}\n\nfunction portableFileEntryToWriteValue(entry: OrganizationPortabilityFileEntry): string | Uint8Array {\n if (typeof entry === \"string\") return entry;\n return Buffer.from(entry.data, \"base64\");\n}\n\nfunction isUuidLike(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n\nfunction normalizeSelector(input: string): string {\n return input.trim();\n}\n\nfunction parseInclude(\n input: string | undefined,\n fallback: OrganizationPortabilityInclude = DEFAULT_EXPORT_INCLUDE,\n): OrganizationPortabilityInclude {\n if (!input || !input.trim()) return { ...fallback };\n const values = input.split(\",\").map((part) => part.trim().toLowerCase()).filter(Boolean);\n const include = {\n organization: values.includes(\"organization\") || values.includes(\"company\"),\n agents: values.includes(\"agents\"),\n projects: values.includes(\"projects\"),\n issues: values.includes(\"issues\") || values.includes(\"tasks\"),\n skills: values.includes(\"skills\"),\n };\n if (!include.organization && !include.agents && !include.projects && !include.issues && !include.skills) {\n throw new Error(\"Invalid --include value. Use one or more of: organization,agents,projects,issues,tasks,skills\");\n }\n return include;\n}\n\nfunction parseAgents(input: string | undefined): \"all\" | string[] {\n if (!input || !input.trim()) return \"all\";\n const normalized = input.trim().toLowerCase();\n if (normalized === \"all\") return \"all\";\n const values = input.split(\",\").map((part) => part.trim()).filter(Boolean);\n if (values.length === 0) return \"all\";\n return Array.from(new Set(values));\n}\n\nfunction parseCsvValues(input: string | undefined): string[] {\n if (!input || !input.trim()) return [];\n return Array.from(new Set(input.split(\",\").map((part) => part.trim()).filter(Boolean)));\n}\n\nfunction isInteractiveTerminal(): boolean {\n return Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}\n\nfunction resolveImportInclude(input: string | undefined): OrganizationPortabilityInclude {\n return parseInclude(input, DEFAULT_IMPORT_INCLUDE);\n}\n\nfunction normalizePortablePath(filePath: string): string {\n return filePath.replace(/\\\\/g, \"/\");\n}\n\nfunction shouldIncludePortableFile(filePath: string): boolean {\n const baseName = path.basename(filePath);\n const isMarkdown = baseName.endsWith(\".md\");\n const isPaperclipYaml = baseName === \".rudder.yaml\" || baseName === \".rudder.yml\";\n const contentType = binaryContentTypeByExtension[path.extname(baseName).toLowerCase()];\n return isMarkdown || isPaperclipYaml || Boolean(contentType);\n}\n\nfunction findPortableExtensionPath(files: Record<string, OrganizationPortabilityFileEntry>): string | null {\n if (files[\".rudder.yaml\"] !== undefined) return \".rudder.yaml\";\n if (files[\".rudder.yml\"] !== undefined) return \".rudder.yml\";\n return Object.keys(files).find((entry) => entry.endsWith(\"/.rudder.yaml\") || entry.endsWith(\"/.rudder.yml\")) ?? null;\n}\n\nfunction collectFilesUnderDirectory(\n files: Record<string, OrganizationPortabilityFileEntry>,\n directory: string,\n opts?: { excludePrefixes?: string[] },\n): string[] {\n const normalizedDirectory = normalizePortablePath(directory).replace(/\\/+$/, \"\");\n if (!normalizedDirectory) return [];\n const prefix = `${normalizedDirectory}/`;\n const excluded = (opts?.excludePrefixes ?? []).map((entry) => normalizePortablePath(entry).replace(/\\/+$/, \"\")).filter(Boolean);\n return Object.keys(files)\n .map(normalizePortablePath)\n .filter((filePath) => filePath.startsWith(prefix))\n .filter((filePath) => !excluded.some((excludePrefix) => filePath.startsWith(`${excludePrefix}/`)))\n .sort((left, right) => left.localeCompare(right));\n}\n\nfunction collectEntityFiles(\n files: Record<string, OrganizationPortabilityFileEntry>,\n entryPath: string,\n opts?: { excludePrefixes?: string[] },\n): string[] {\n const normalizedPath = normalizePortablePath(entryPath);\n const directory = normalizedPath.includes(\"/\") ? normalizedPath.slice(0, normalizedPath.lastIndexOf(\"/\")) : \"\";\n const selected = new Set<string>([normalizedPath]);\n if (directory) {\n for (const filePath of collectFilesUnderDirectory(files, directory, opts)) {\n selected.add(filePath);\n }\n }\n return Array.from(selected).sort((left, right) => left.localeCompare(right));\n}\n\nexport function buildImportSelectionCatalog(preview: OrganizationPortabilityPreviewResult): ImportSelectionCatalog {\n const selectedAgentSlugs = new Set(preview.selectedAgentSlugs);\n const organizationFiles = new Set<string>();\n const organizationPath = preview.manifest.organization?.path\n ? normalizePortablePath(preview.manifest.organization.path)\n : null;\n if (organizationPath) {\n organizationFiles.add(organizationPath);\n }\n const readmePath = Object.keys(preview.files).find((entry) => normalizePortablePath(entry) === \"README.md\");\n if (readmePath) {\n organizationFiles.add(normalizePortablePath(readmePath));\n }\n const logoPath = preview.manifest.organization?.logoPath\n ? normalizePortablePath(preview.manifest.organization.logoPath)\n : null;\n if (logoPath && preview.files[logoPath] !== undefined) {\n organizationFiles.add(logoPath);\n }\n\n return {\n organization: {\n includedByDefault: preview.include.organization && preview.manifest.organization !== null,\n files: Array.from(organizationFiles).sort((left, right) => left.localeCompare(right)),\n },\n projects: preview.manifest.projects.map((project) => {\n const projectPath = normalizePortablePath(project.path);\n const projectDir = projectPath.includes(\"/\") ? projectPath.slice(0, projectPath.lastIndexOf(\"/\")) : \"\";\n return {\n key: project.slug,\n label: project.name,\n hint: project.slug,\n files: collectEntityFiles(preview.files, projectPath, {\n excludePrefixes: projectDir ? [`${projectDir}/issues`] : [],\n }),\n };\n }),\n issues: preview.manifest.issues.map((issue) => ({\n key: issue.slug,\n label: issue.title,\n hint: issue.identifier ?? issue.slug,\n files: collectEntityFiles(preview.files, normalizePortablePath(issue.path)),\n })),\n agents: preview.manifest.agents\n .filter((agent) => selectedAgentSlugs.size === 0 || selectedAgentSlugs.has(agent.slug))\n .map((agent) => ({\n key: agent.slug,\n label: agent.name,\n hint: agent.slug,\n files: collectEntityFiles(preview.files, normalizePortablePath(agent.path)),\n })),\n skills: preview.manifest.skills.map((skill) => ({\n key: skill.slug,\n label: skill.name,\n hint: skill.slug,\n files: collectEntityFiles(preview.files, normalizePortablePath(skill.path)),\n })),\n extensionPath: findPortableExtensionPath(preview.files),\n };\n}\n\nfunction toKeySet(items: Array<{ key: string }>): Set<string> {\n return new Set(items.map((item) => item.key));\n}\n\nexport function buildDefaultImportSelectionState(catalog: ImportSelectionCatalog): ImportSelectionState {\n return {\n organization: catalog.organization.includedByDefault,\n projects: toKeySet(catalog.projects),\n issues: toKeySet(catalog.issues),\n agents: toKeySet(catalog.agents),\n skills: toKeySet(catalog.skills),\n };\n}\n\nfunction countSelected(state: ImportSelectionState, group: ImportSelectableGroup): number {\n return state[group].size;\n}\n\nfunction countTotal(catalog: ImportSelectionCatalog, group: ImportSelectableGroup): number {\n return catalog[group].length;\n}\n\nfunction summarizeGroupSelection(catalog: ImportSelectionCatalog, state: ImportSelectionState, group: ImportSelectableGroup): string {\n return `${countSelected(state, group)}/${countTotal(catalog, group)} selected`;\n}\n\nfunction getGroupLabel(group: ImportSelectableGroup): string {\n switch (group) {\n case \"projects\":\n return \"Projects\";\n case \"issues\":\n return \"Tasks\";\n case \"agents\":\n return \"Agents\";\n case \"skills\":\n return \"Skills\";\n }\n}\n\nexport function buildSelectedFilesFromImportSelection(\n catalog: ImportSelectionCatalog,\n state: ImportSelectionState,\n): string[] {\n const selected = new Set<string>();\n\n if (state.organization) {\n for (const filePath of catalog.organization.files) {\n selected.add(normalizePortablePath(filePath));\n }\n }\n\n for (const group of [\"projects\", \"issues\", \"agents\", \"skills\"] as const) {\n const selectedKeys = state[group];\n for (const item of catalog[group]) {\n if (!selectedKeys.has(item.key)) continue;\n for (const filePath of item.files) {\n selected.add(normalizePortablePath(filePath));\n }\n }\n }\n\n if (selected.size > 0 && catalog.extensionPath) {\n selected.add(normalizePortablePath(catalog.extensionPath));\n }\n\n return Array.from(selected).sort((left, right) => left.localeCompare(right));\n}\n\nexport function buildDefaultImportAdapterOverrides(\n preview: Pick<OrganizationPortabilityPreviewResult, \"manifest\" | \"selectedAgentSlugs\">,\n): Record<string, { agentRuntimeType: string }> | undefined {\n const selectedAgentSlugs = new Set(preview.selectedAgentSlugs);\n const overrides = Object.fromEntries(\n preview.manifest.agents\n .filter((agent) => selectedAgentSlugs.size === 0 || selectedAgentSlugs.has(agent.slug))\n .filter((agent) => agent.agentRuntimeType === \"process\")\n .map((agent) => [\n agent.slug,\n {\n // TODO: replace this temporary claude_local fallback with adapter selection in the import TUI.\n agentRuntimeType: \"claude_local\",\n },\n ]),\n );\n return Object.keys(overrides).length > 0 ? overrides : undefined;\n}\n\nfunction buildDefaultImportAdapterMessages(\n overrides: Record<string, { agentRuntimeType: string }> | undefined,\n): string[] {\n if (!overrides) return [];\n const agentRuntimeTypes = Array.from(new Set(Object.values(overrides).map((override) => override.agentRuntimeType)))\n .map((agentRuntimeType) => agentRuntimeType.replace(/_/g, \"-\"));\n const agentCount = Object.keys(overrides).length;\n return [\n `Using ${agentRuntimeTypes.join(\", \")} adapter${agentRuntimeTypes.length === 1 ? \"\" : \"s\"} for ${agentCount} imported ${pluralize(agentCount, \"agent\")} without an explicit adapter.`,\n ];\n}\n\nasync function promptForImportSelection(preview: OrganizationPortabilityPreviewResult): Promise<string[]> {\n const catalog = buildImportSelectionCatalog(preview);\n const state = buildDefaultImportSelectionState(catalog);\n\n while (true) {\n const choice = await p.select<ImportSelectableGroup | \"organization\" | \"confirm\">({\n message: \"Select what Rudder should import\",\n options: [\n {\n value: \"organization\",\n label: state.organization ? \"Organization: included\" : \"Organization: skipped\",\n hint: catalog.organization.files.length > 0\n ? \"toggle organization metadata\"\n : \"no organization metadata in package\",\n },\n {\n value: \"projects\",\n label: \"Select Projects\",\n hint: summarizeGroupSelection(catalog, state, \"projects\"),\n },\n {\n value: \"issues\",\n label: \"Select Tasks\",\n hint: summarizeGroupSelection(catalog, state, \"issues\"),\n },\n {\n value: \"agents\",\n label: \"Select Agents\",\n hint: summarizeGroupSelection(catalog, state, \"agents\"),\n },\n {\n value: \"skills\",\n label: \"Select Skills\",\n hint: summarizeGroupSelection(catalog, state, \"skills\"),\n },\n {\n value: \"confirm\",\n label: \"Confirm\",\n hint: `${buildSelectedFilesFromImportSelection(catalog, state).length} files selected`,\n },\n ],\n initialValue: \"confirm\",\n });\n\n if (p.isCancel(choice)) {\n p.cancel(\"Import cancelled.\");\n process.exit(0);\n }\n\n if (choice === \"confirm\") {\n const selectedFiles = buildSelectedFilesFromImportSelection(catalog, state);\n if (selectedFiles.length === 0) {\n p.note(\"Select at least one import target before confirming.\", \"Nothing selected\");\n continue;\n }\n return selectedFiles;\n }\n\n if (choice === \"organization\") {\n if (catalog.organization.files.length === 0) {\n p.note(\"This package does not include organization metadata to toggle.\", \"No organization metadata\");\n continue;\n }\n state.organization = !state.organization;\n continue;\n }\n\n const group = choice;\n const groupItems = catalog[group];\n if (groupItems.length === 0) {\n p.note(`This package does not include any ${getGroupLabel(group).toLowerCase()}.`, `No ${getGroupLabel(group)}`);\n continue;\n }\n\n const selection = await p.multiselect<string>({\n message: `${getGroupLabel(group)} to import. Space toggles, enter returns to the main menu.`,\n options: groupItems.map((item) => ({\n value: item.key,\n label: item.label,\n hint: item.hint,\n })),\n initialValues: Array.from(state[group]),\n });\n\n if (p.isCancel(selection)) {\n p.cancel(\"Import cancelled.\");\n process.exit(0);\n }\n\n state[group] = new Set(selection);\n }\n}\n\nfunction summarizeInclude(include: OrganizationPortabilityInclude): string {\n const labels = IMPORT_INCLUDE_OPTIONS\n .filter((option) => include[option.value])\n .map((option) => option.label.toLowerCase());\n return labels.length > 0 ? labels.join(\", \") : \"nothing selected\";\n}\n\nfunction formatSourceLabel(source: { type: \"inline\"; rootPath?: string | null } | { type: \"github\"; url: string }): string {\n if (source.type === \"github\") {\n return `GitHub: ${source.url}`;\n }\n return `Local package: ${source.rootPath?.trim() || \"(current folder)\"}`;\n}\n\nfunction formatTargetLabel(\n target: { mode: \"existing_organization\"; orgId?: string | null } | { mode: \"new_organization\"; newOrganizationName?: string | null },\n preview?: OrganizationPortabilityPreviewResult,\n): string {\n if (target.mode === \"existing_organization\") {\n const targetName = preview?.targetOrganizationName?.trim();\n const targetId = preview?.targetOrganizationId?.trim() || target.orgId?.trim() || \"unknown-organization\";\n return targetName ? `${targetName} (${targetId})` : targetId;\n }\n return target.newOrganizationName?.trim() || preview?.manifest.organization?.name || \"new organization\";\n}\n\nfunction pluralize(count: number, singular: string, plural = `${singular}s`): string {\n return count === 1 ? singular : plural;\n}\n\nfunction summarizePlanCounts(\n plans: Array<{ action: \"create\" | \"update\" | \"skip\" }>,\n noun: string,\n): string {\n if (plans.length === 0) return `0 ${pluralize(0, noun)} selected`;\n const createCount = plans.filter((plan) => plan.action === \"create\").length;\n const updateCount = plans.filter((plan) => plan.action === \"update\").length;\n const skipCount = plans.filter((plan) => plan.action === \"skip\").length;\n const parts: string[] = [];\n if (createCount > 0) parts.push(`${createCount} create`);\n if (updateCount > 0) parts.push(`${updateCount} update`);\n if (skipCount > 0) parts.push(`${skipCount} skip`);\n return `${plans.length} ${pluralize(plans.length, noun)} total (${parts.join(\", \")})`;\n}\n\nfunction summarizeImportAgentResults(agents: OrganizationPortabilityImportResult[\"agents\"]): string {\n if (agents.length === 0) return \"0 agents changed\";\n const created = agents.filter((agent) => agent.action === \"created\").length;\n const updated = agents.filter((agent) => agent.action === \"updated\").length;\n const skipped = agents.filter((agent) => agent.action === \"skipped\").length;\n const parts: string[] = [];\n if (created > 0) parts.push(`${created} created`);\n if (updated > 0) parts.push(`${updated} updated`);\n if (skipped > 0) parts.push(`${skipped} skipped`);\n return `${agents.length} ${pluralize(agents.length, \"agent\")} total (${parts.join(\", \")})`;\n}\n\nfunction summarizeImportProjectResults(projects: OrganizationPortabilityImportResult[\"projects\"]): string {\n if (projects.length === 0) return \"0 projects changed\";\n const created = projects.filter((project) => project.action === \"created\").length;\n const updated = projects.filter((project) => project.action === \"updated\").length;\n const skipped = projects.filter((project) => project.action === \"skipped\").length;\n const parts: string[] = [];\n if (created > 0) parts.push(`${created} created`);\n if (updated > 0) parts.push(`${updated} updated`);\n if (skipped > 0) parts.push(`${skipped} skipped`);\n return `${projects.length} ${pluralize(projects.length, \"project\")} total (${parts.join(\", \")})`;\n}\n\nfunction actionChip(action: string): string {\n switch (action) {\n case \"create\":\n case \"created\":\n return pc.green(action);\n case \"update\":\n case \"updated\":\n return pc.yellow(action);\n case \"skip\":\n case \"skipped\":\n case \"none\":\n case \"unchanged\":\n return pc.dim(action);\n default:\n return action;\n }\n}\n\nfunction appendPreviewExamples(\n lines: string[],\n title: string,\n entries: Array<{ action: string; label: string; reason?: string | null }>,\n): void {\n if (entries.length === 0) return;\n lines.push(\"\");\n lines.push(pc.bold(title));\n const shown = entries.slice(0, IMPORT_PREVIEW_SAMPLE_LIMIT);\n for (const entry of shown) {\n const reason = entry.reason?.trim() ? pc.dim(` (${entry.reason.trim()})`) : \"\";\n lines.push(`- ${actionChip(entry.action)} ${entry.label}${reason}`);\n }\n if (entries.length > shown.length) {\n lines.push(pc.dim(`- +${entries.length - shown.length} more`));\n }\n}\n\nfunction appendMessageBlock(lines: string[], title: string, messages: string[]): void {\n if (messages.length === 0) return;\n lines.push(\"\");\n lines.push(pc.bold(title));\n for (const message of messages) {\n lines.push(`- ${message}`);\n }\n}\n\nexport function renderCompanyImportPreview(\n preview: OrganizationPortabilityPreviewResult,\n meta: {\n sourceLabel: string;\n targetLabel: string;\n infoMessages?: string[];\n },\n): string {\n const lines: string[] = [\n `${pc.bold(\"Source\")} ${meta.sourceLabel}`,\n `${pc.bold(\"Target\")} ${meta.targetLabel}`,\n `${pc.bold(\"Include\")} ${summarizeInclude(preview.include)}`,\n `${pc.bold(\"Mode\")} ${preview.collisionStrategy} collisions`,\n \"\",\n pc.bold(\"Package\"),\n `- organization: ${preview.manifest.organization?.name ?? preview.manifest.source?.organizationName ?? \"not included\"}`,\n `- agents: ${preview.manifest.agents.length}`,\n `- projects: ${preview.manifest.projects.length}`,\n `- tasks: ${preview.manifest.issues.length}`,\n `- skills: ${preview.manifest.skills.length}`,\n ];\n\n if (preview.envInputs.length > 0) {\n const requiredCount = preview.envInputs.filter((item) => item.requirement === \"required\").length;\n lines.push(`- env inputs: ${preview.envInputs.length} (${requiredCount} required)`);\n }\n\n lines.push(\"\");\n lines.push(pc.bold(\"Plan\"));\n lines.push(\n `- organization: ${actionChip(\n preview.plan.organizationAction === \"none\" ? \"unchanged\" : preview.plan.organizationAction,\n )}`,\n );\n lines.push(`- agents: ${summarizePlanCounts(preview.plan.agentPlans, \"agent\")}`);\n lines.push(`- projects: ${summarizePlanCounts(preview.plan.projectPlans, \"project\")}`);\n lines.push(`- tasks: ${summarizePlanCounts(preview.plan.issuePlans, \"task\")}`);\n if (preview.include.skills) {\n lines.push(`- skills: ${preview.manifest.skills.length} ${pluralize(preview.manifest.skills.length, \"skill\")} packaged`);\n }\n\n appendPreviewExamples(\n lines,\n \"Agent examples\",\n preview.plan.agentPlans.map((plan) => ({\n action: plan.action,\n label: `${plan.slug} -> ${plan.plannedName}`,\n reason: plan.reason,\n })),\n );\n appendPreviewExamples(\n lines,\n \"Project examples\",\n preview.plan.projectPlans.map((plan) => ({\n action: plan.action,\n label: `${plan.slug} -> ${plan.plannedName}`,\n reason: plan.reason,\n })),\n );\n appendPreviewExamples(\n lines,\n \"Task examples\",\n preview.plan.issuePlans.map((plan) => ({\n action: plan.action,\n label: `${plan.slug} -> ${plan.plannedTitle}`,\n reason: plan.reason,\n })),\n );\n\n appendMessageBlock(lines, pc.cyan(\"Info\"), meta.infoMessages ?? []);\n appendMessageBlock(lines, pc.yellow(\"Warnings\"), preview.warnings);\n appendMessageBlock(lines, pc.red(\"Errors\"), preview.errors);\n\n return lines.join(\"\\n\");\n}\n\nexport function renderCompanyImportResult(\n result: OrganizationPortabilityImportResult,\n meta: { targetLabel: string; organizationUrl?: string; infoMessages?: string[] },\n): string {\n const lines: string[] = [\n `${pc.bold(\"Target\")} ${meta.targetLabel}`,\n `${pc.bold(\"Organization\")} ${result.organization.name} (${actionChip(result.organization.action)})`,\n `${pc.bold(\"Agents\")} ${summarizeImportAgentResults(result.agents)}`,\n `${pc.bold(\"Projects\")} ${summarizeImportProjectResults(result.projects)}`,\n ];\n\n if (meta.organizationUrl) {\n lines.splice(1, 0, `${pc.bold(\"URL\")} ${meta.organizationUrl}`);\n }\n\n appendPreviewExamples(\n lines,\n \"Agent results\",\n result.agents.map((agent) => ({\n action: agent.action,\n label: `${agent.slug} -> ${agent.name}`,\n reason: agent.reason,\n })),\n );\n appendPreviewExamples(\n lines,\n \"Project results\",\n result.projects.map((project) => ({\n action: project.action,\n label: `${project.slug} -> ${project.name}`,\n reason: project.reason,\n })),\n );\n\n if (result.envInputs.length > 0) {\n lines.push(\"\");\n lines.push(pc.bold(\"Env inputs\"));\n lines.push(\n `- ${result.envInputs.length} ${pluralize(result.envInputs.length, \"input\")} may need values after import`,\n );\n }\n\n appendMessageBlock(lines, pc.cyan(\"Info\"), meta.infoMessages ?? []);\n appendMessageBlock(lines, pc.yellow(\"Warnings\"), result.warnings);\n\n return lines.join(\"\\n\");\n}\n\nfunction printCompanyImportView(title: string, body: string, opts?: { interactive?: boolean }): void {\n if (opts?.interactive) {\n p.note(body, title);\n return;\n }\n console.log(pc.bold(title));\n console.log(body);\n}\n\nexport function resolveCompanyImportApiPath(input: {\n dryRun: boolean;\n targetMode: \"new_organization\" | \"existing_organization\";\n orgId?: string | null;\n}): string {\n if (input.targetMode === \"existing_organization\") {\n const orgId = input.orgId?.trim();\n if (!orgId) {\n throw new Error(\"Existing-organization imports require an orgId to resolve the API route.\");\n }\n return input.dryRun\n ? `/api/orgs/${orgId}/imports/preview`\n : `/api/orgs/${orgId}/imports/apply`;\n }\n\n return input.dryRun ? \"/api/orgs/import/preview\" : \"/api/orgs/import\";\n}\n\nexport function buildCompanyDashboardUrl(apiBase: string, issuePrefix: string): string {\n const url = new URL(apiBase);\n const normalizedPrefix = issuePrefix.trim().replace(/^\\/+|\\/+$/g, \"\");\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/${normalizedPrefix}/dashboard`;\n url.search = \"\";\n url.hash = \"\";\n return url.toString();\n}\n\nexport function resolveCompanyImportApplyConfirmationMode(input: {\n yes?: boolean;\n interactive: boolean;\n json: boolean;\n}): \"skip\" | \"prompt\" {\n if (input.yes) {\n return \"skip\";\n }\n if (input.json) {\n throw new Error(\n \"Applying an organization import with --json requires --yes. Use --dry-run first to inspect the preview.\",\n );\n }\n if (!input.interactive) {\n throw new Error(\n \"Applying an organization import from a non-interactive terminal requires --yes. Use --dry-run first to inspect the preview.\",\n );\n }\n return \"prompt\";\n}\n\nexport function isHttpUrl(input: string): boolean {\n return /^https?:\\/\\//i.test(input.trim());\n}\n\nexport function isGithubUrl(input: string): boolean {\n return /^https?:\\/\\/github\\.com\\//i.test(input.trim());\n}\n\nfunction isGithubSegment(input: string): boolean {\n return /^[A-Za-z0-9._-]+$/.test(input);\n}\n\nexport function isGithubShorthand(input: string): boolean {\n const trimmed = input.trim();\n if (!trimmed || isHttpUrl(trimmed)) return false;\n if (\n trimmed.startsWith(\".\") ||\n trimmed.startsWith(\"/\") ||\n trimmed.startsWith(\"~\") ||\n trimmed.includes(\"\\\\\") ||\n /^[A-Za-z]:/.test(trimmed)\n ) {\n return false;\n }\n\n const segments = trimmed.split(\"/\").filter(Boolean);\n return segments.length >= 2 && segments.every(isGithubSegment);\n}\n\nfunction normalizeGithubImportPath(input: string | null | undefined): string | null {\n if (!input) return null;\n const trimmed = input.trim().replace(/^\\/+|\\/+$/g, \"\");\n return trimmed || null;\n}\n\nfunction buildGithubImportUrl(input: {\n owner: string;\n repo: string;\n ref?: string | null;\n path?: string | null;\n companyPath?: string | null;\n}): string {\n const url = new URL(`https://github.com/${input.owner}/${input.repo.replace(/\\.git$/i, \"\")}`);\n const ref = input.ref?.trim();\n if (ref) {\n url.searchParams.set(\"ref\", ref);\n }\n const companyPath = normalizeGithubImportPath(input.companyPath);\n if (companyPath) {\n url.searchParams.set(\"companyPath\", companyPath);\n return url.toString();\n }\n const sourcePath = normalizeGithubImportPath(input.path);\n if (sourcePath) {\n url.searchParams.set(\"path\", sourcePath);\n }\n return url.toString();\n}\n\nexport function normalizeGithubImportSource(input: string, refOverride?: string): string {\n const trimmed = input.trim();\n const ref = refOverride?.trim();\n\n if (isGithubShorthand(trimmed)) {\n const [owner, repo, ...repoPath] = trimmed.split(\"/\").filter(Boolean);\n return buildGithubImportUrl({\n owner: owner!,\n repo: repo!,\n ref: ref || \"main\",\n path: repoPath.join(\"/\"),\n });\n }\n\n if (!isGithubUrl(trimmed)) {\n throw new Error(\"GitHub source must be a github.com URL or owner/repo[/path] shorthand.\");\n }\n if (!ref) {\n return trimmed;\n }\n\n const url = new URL(trimmed);\n const parts = url.pathname.split(\"/\").filter(Boolean);\n if (parts.length < 2) {\n throw new Error(\"Invalid GitHub URL.\");\n }\n\n const owner = parts[0]!;\n const repo = parts[1]!;\n const existingPath = normalizeGithubImportPath(url.searchParams.get(\"path\"));\n const existingCompanyPath = normalizeGithubImportPath(url.searchParams.get(\"companyPath\"));\n if (existingCompanyPath) {\n return buildGithubImportUrl({ owner, repo, ref, companyPath: existingCompanyPath });\n }\n if (existingPath) {\n return buildGithubImportUrl({ owner, repo, ref, path: existingPath });\n }\n if (parts[2] === \"tree\") {\n return buildGithubImportUrl({ owner, repo, ref, path: parts.slice(4).join(\"/\") });\n }\n if (parts[2] === \"blob\") {\n return buildGithubImportUrl({ owner, repo, ref, companyPath: parts.slice(4).join(\"/\") });\n }\n return buildGithubImportUrl({ owner, repo, ref });\n}\n\nasync function pathExists(inputPath: string): Promise<boolean> {\n try {\n await stat(path.resolve(inputPath));\n return true;\n } catch {\n return false;\n }\n}\n\nasync function collectPackageFiles(\n root: string,\n current: string,\n files: Record<string, OrganizationPortabilityFileEntry>,\n): Promise<void> {\n const entries = await readdir(current, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name.startsWith(\".git\")) continue;\n const absolutePath = path.join(current, entry.name);\n if (entry.isDirectory()) {\n await collectPackageFiles(root, absolutePath, files);\n continue;\n }\n if (!entry.isFile()) continue;\n const relativePath = path.relative(root, absolutePath).replace(/\\\\/g, \"/\");\n if (!shouldIncludePortableFile(relativePath)) continue;\n files[relativePath] = readPortableFileEntry(relativePath, await readFile(absolutePath));\n }\n}\n\nexport async function resolveInlineSourceFromPath(inputPath: string): Promise<{\n rootPath: string;\n files: Record<string, OrganizationPortabilityFileEntry>;\n}> {\n const resolved = path.resolve(inputPath);\n const resolvedStat = await stat(resolved);\n if (resolvedStat.isFile() && path.extname(resolved).toLowerCase() === \".zip\") {\n const archive = await readZipArchive(await readFile(resolved));\n const filteredFiles = Object.fromEntries(\n Object.entries(archive.files).filter(([relativePath]) => shouldIncludePortableFile(relativePath)),\n );\n return {\n rootPath: archive.rootPath ?? path.basename(resolved, \".zip\"),\n files: filteredFiles,\n };\n }\n\n const rootDir = resolvedStat.isDirectory() ? resolved : path.dirname(resolved);\n const files: Record<string, OrganizationPortabilityFileEntry> = {};\n await collectPackageFiles(rootDir, rootDir, files);\n return {\n rootPath: path.basename(rootDir),\n files,\n };\n}\n\nasync function writeExportToFolder(outDir: string, exported: OrganizationPortabilityExportResult): Promise<void> {\n const root = path.resolve(outDir);\n await mkdir(root, { recursive: true });\n for (const [relativePath, content] of Object.entries(exported.files)) {\n const normalized = relativePath.replace(/\\\\/g, \"/\");\n const filePath = path.join(root, normalized);\n await mkdir(path.dirname(filePath), { recursive: true });\n const writeValue = portableFileEntryToWriteValue(content);\n if (typeof writeValue === \"string\") {\n await writeFile(filePath, writeValue, \"utf8\");\n } else {\n await writeFile(filePath, writeValue);\n }\n }\n}\n\nasync function confirmOverwriteExportDirectory(outDir: string): Promise<void> {\n const root = path.resolve(outDir);\n const stats = await stat(root).catch(() => null);\n if (!stats) return;\n if (!stats.isDirectory()) {\n throw new Error(`Export output path ${root} exists and is not a directory.`);\n }\n\n const entries = await readdir(root);\n if (entries.length === 0) return;\n\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n throw new Error(`Export output directory ${root} already contains files. Re-run interactively or choose an empty directory.`);\n }\n\n const confirmed = await p.confirm({\n message: `Overwrite existing files in ${root}?`,\n initialValue: false,\n });\n\n if (p.isCancel(confirmed) || !confirmed) {\n throw new Error(\"Export cancelled.\");\n }\n}\n\nfunction matchesPrefix(company: Organization, selector: string): boolean {\n return company.issuePrefix.toUpperCase() === selector.toUpperCase();\n}\n\nexport function resolveCompanyForDeletion(\n organizations: Organization[],\n selectorRaw: string,\n by: CompanyDeleteSelectorMode = \"auto\",\n): Organization {\n const selector = normalizeSelector(selectorRaw);\n if (!selector) {\n throw new Error(\"Organization selector is required.\");\n }\n\n const idMatch = organizations.find((company) => company.id === selector);\n const prefixMatch = organizations.find((company) => matchesPrefix(company, selector));\n\n if (by === \"id\") {\n if (!idMatch) {\n throw new Error(`No organization found by ID '${selector}'.`);\n }\n return idMatch;\n }\n\n if (by === \"prefix\") {\n if (!prefixMatch) {\n throw new Error(`No organization found by shortname/prefix '${selector}'.`);\n }\n return prefixMatch;\n }\n\n if (idMatch && prefixMatch && idMatch.id !== prefixMatch.id) {\n throw new Error(\n `Selector '${selector}' is ambiguous (matches both an ID and a shortname). Re-run with --by id or --by prefix.`,\n );\n }\n\n if (idMatch) return idMatch;\n if (prefixMatch) return prefixMatch;\n\n throw new Error(\n `No organization found for selector '${selector}'. Use organization ID or issue prefix (for example PAP).`,\n );\n}\n\nexport function assertDeleteConfirmation(company: Organization, opts: CompanyDeleteOptions): void {\n if (!opts.yes) {\n throw new Error(\"Deletion requires --yes.\");\n }\n\n const confirm = opts.confirm?.trim();\n if (!confirm) {\n throw new Error(\n \"Deletion requires --confirm <value> where value matches the company ID or issue prefix.\",\n );\n }\n\n const confirmsById = confirm === company.id;\n const confirmsByPrefix = confirm.toUpperCase() === company.issuePrefix.toUpperCase();\n if (!confirmsById && !confirmsByPrefix) {\n throw new Error(\n `Confirmation '${confirm}' does not match target organization. Expected ID '${company.id}' or prefix '${company.issuePrefix}'.`,\n );\n }\n}\n\nfunction assertDeleteFlags(opts: CompanyDeleteOptions): void {\n if (!opts.yes) {\n throw new Error(\"Deletion requires --yes.\");\n }\n if (!opts.confirm?.trim()) {\n throw new Error(\n \"Deletion requires --confirm <value> where value matches the company ID or issue prefix.\",\n );\n }\n}\n\nexport function registerCompanyCommands(program: Command): void {\n const company = program.command(\"org\").description(\"Organization operations\");\n\n addCommonClientOptions(\n company\n .command(\"list\")\n .description(\"List organizations\")\n .action(async (opts: CompanyCommandOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<Organization[]>(\"/api/orgs\")) ?? [];\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n const formatted = rows.map((row) => ({\n id: row.id,\n name: row.name,\n status: row.status,\n budgetMonthlyCents: row.budgetMonthlyCents,\n spentMonthlyCents: row.spentMonthlyCents,\n requireBoardApprovalForNewAgents: row.requireBoardApprovalForNewAgents,\n }));\n for (const row of formatted) {\n console.log(formatInlineRecord(row));\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"get\")\n .description(\"Get one organization\")\n .argument(\"<orgId>\", \"Organization ID\")\n .action(async (orgId: string, opts: CompanyCommandOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<Organization>(`/api/orgs/${orgId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"export\")\n .description(\"Export an organization into a portable markdown package\")\n .argument(\"<orgId>\", \"Organization ID\")\n .requiredOption(\"--out <path>\", \"Output directory\")\n .option(\n \"--include <values>\",\n \"Comma-separated include set: organization,agents,projects,issues,tasks,skills\",\n \"organization,agents\",\n )\n .option(\"--skills <values>\", \"Comma-separated skill slugs/keys to export\")\n .option(\"--projects <values>\", \"Comma-separated project shortnames/ids to export\")\n .option(\"--issues <values>\", \"Comma-separated issue identifiers/ids to export\")\n .option(\"--project-issues <values>\", \"Comma-separated project shortnames/ids whose issues should be exported\")\n .option(\"--expand-referenced-skills\", \"Vendor skill contents instead of exporting upstream references\", false)\n .action(async (orgId: string, opts: CompanyExportOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const include = parseInclude(opts.include);\n const exported = await ctx.api.post<OrganizationPortabilityExportResult>(\n `/api/orgs/${orgId}/export`,\n {\n include,\n skills: parseCsvValues(opts.skills),\n projects: parseCsvValues(opts.projects),\n issues: parseCsvValues(opts.issues),\n projectIssues: parseCsvValues(opts.projectIssues),\n expandReferencedSkills: Boolean(opts.expandReferencedSkills),\n },\n );\n if (!exported) {\n throw new Error(\"Export request returned no data\");\n }\n await confirmOverwriteExportDirectory(opts.out!);\n await writeExportToFolder(opts.out!, exported);\n printOutput(\n {\n ok: true,\n out: path.resolve(opts.out!),\n rootPath: exported.rootPath,\n filesWritten: Object.keys(exported.files).length,\n rudderExtensionPath: exported.rudderExtensionPath,\n warningCount: exported.warnings.length,\n },\n { json: ctx.json },\n );\n if (!ctx.json && exported.warnings.length > 0) {\n for (const warning of exported.warnings) {\n console.log(`warning=${warning}`);\n }\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"import\")\n .description(\"Import a portable markdown organization package from local path, URL, or GitHub\")\n .argument(\"<fromPathOrUrl>\", \"Source path or URL\")\n .option(\"--include <values>\", \"Comma-separated include set: organization,agents,projects,issues,tasks,skills\")\n .option(\"--target <mode>\", \"Target mode: new | existing\")\n .option(\"-O, --org-id <id>\", \"Existing target organization ID\")\n .option(\"--new-organization-name <name>\", \"Name override for --target new\")\n .option(\"--agents <list>\", \"Comma-separated agent slugs to import, or all\", \"all\")\n .option(\"--collision <mode>\", \"Collision strategy: rename | skip | replace\", \"rename\")\n .option(\"--ref <value>\", \"Git ref to use for GitHub imports (branch, tag, or commit)\")\n .option(\"--rudder-url <url>\", \"Alias for --api-base on this command\")\n .option(\"--yes\", \"Accept default selection and skip the pre-import confirmation prompt\", false)\n .option(\"--dry-run\", \"Run preview only without applying\", false)\n .action(async (fromPathOrUrl: string, opts: CompanyImportOptions) => {\n try {\n if (!opts.apiBase?.trim() && opts.rudderUrl?.trim()) {\n opts.apiBase = opts.rudderUrl.trim();\n }\n const ctx = resolveCommandContext(opts);\n const interactiveView = isInteractiveTerminal() && !ctx.json;\n const from = fromPathOrUrl.trim();\n if (!from) {\n throw new Error(\"Source path or URL is required.\");\n }\n\n const include = resolveImportInclude(opts.include);\n const agents = parseAgents(opts.agents);\n const collision = (opts.collision ?? \"rename\").toLowerCase() as CompanyCollisionMode;\n if (![\"rename\", \"skip\", \"replace\"].includes(collision)) {\n throw new Error(\"Invalid --collision value. Use: rename, skip, replace\");\n }\n\n const inferredTarget = opts.target ?? (opts.orgId || ctx.orgId ? \"existing\" : \"new\");\n const target = inferredTarget.toLowerCase() as CompanyImportTargetMode;\n if (![\"new\", \"existing\"].includes(target)) {\n throw new Error(\"Invalid --target value. Use: new | existing\");\n }\n\n const existingTargetOrganizationId = opts.orgId?.trim() || ctx.orgId;\n const targetPayload =\n target === \"existing\"\n ? {\n mode: \"existing_organization\" as const,\n orgId: existingTargetOrganizationId,\n }\n : {\n mode: \"new_organization\" as const,\n newOrganizationName: opts.newOrganizationName?.trim() || null,\n };\n\n if (targetPayload.mode === \"existing_organization\" && !targetPayload.orgId) {\n throw new Error(\"Target existing organization requires --org-id (or context default orgId).\");\n }\n\n let sourcePayload:\n | { type: \"inline\"; rootPath?: string | null; files: Record<string, OrganizationPortabilityFileEntry> }\n | { type: \"github\"; url: string };\n\n const treatAsLocalPath = !isHttpUrl(from) && await pathExists(from);\n const isGithubSource = isGithubUrl(from) || (isGithubShorthand(from) && !treatAsLocalPath);\n\n if (isHttpUrl(from) || isGithubSource) {\n if (!isGithubUrl(from) && !isGithubShorthand(from)) {\n throw new Error(\n \"Only GitHub URLs and local paths are supported for import. \" +\n \"Generic HTTP URLs are not supported. Use a GitHub URL (https://github.com/...) or a local directory path.\",\n );\n }\n sourcePayload = { type: \"github\", url: normalizeGithubImportSource(from, opts.ref) };\n } else {\n if (opts.ref?.trim()) {\n throw new Error(\"--ref is only supported for GitHub import sources.\");\n }\n const inline = await resolveInlineSourceFromPath(from);\n sourcePayload = {\n type: \"inline\",\n rootPath: inline.rootPath,\n files: inline.files,\n };\n }\n\n const sourceLabel = formatSourceLabel(sourcePayload);\n const targetLabel = formatTargetLabel(targetPayload);\n const previewApiPath = resolveCompanyImportApiPath({\n dryRun: true,\n targetMode: targetPayload.mode,\n orgId: targetPayload.mode === \"existing_organization\" ? targetPayload.orgId : null,\n });\n\n let selectedFiles: string[] | undefined;\n if (interactiveView && !opts.yes && !opts.include?.trim()) {\n const initialPreview = await ctx.api.post<OrganizationPortabilityPreviewResult>(previewApiPath, {\n source: sourcePayload,\n include,\n target: targetPayload,\n agents,\n collisionStrategy: collision,\n });\n if (!initialPreview) {\n throw new Error(\"Import preview returned no data.\");\n }\n selectedFiles = await promptForImportSelection(initialPreview);\n }\n\n const previewPayload = {\n source: sourcePayload,\n include,\n target: targetPayload,\n agents,\n collisionStrategy: collision,\n selectedFiles,\n };\n const preview = await ctx.api.post<OrganizationPortabilityPreviewResult>(previewApiPath, previewPayload);\n if (!preview) {\n throw new Error(\"Import preview returned no data.\");\n }\n const agentRuntimeOverrides = buildDefaultImportAdapterOverrides(preview);\n const adapterMessages = buildDefaultImportAdapterMessages(agentRuntimeOverrides);\n\n if (opts.dryRun) {\n if (ctx.json) {\n printOutput(preview, { json: true });\n } else {\n printCompanyImportView(\n \"Import Preview\",\n renderCompanyImportPreview(preview, {\n sourceLabel,\n targetLabel: formatTargetLabel(targetPayload, preview),\n infoMessages: adapterMessages,\n }),\n { interactive: interactiveView },\n );\n }\n return;\n }\n\n if (!ctx.json) {\n printCompanyImportView(\n \"Import Preview\",\n renderCompanyImportPreview(preview, {\n sourceLabel,\n targetLabel: formatTargetLabel(targetPayload, preview),\n infoMessages: adapterMessages,\n }),\n { interactive: interactiveView },\n );\n }\n\n const confirmationMode = resolveCompanyImportApplyConfirmationMode({\n yes: opts.yes,\n interactive: interactiveView,\n json: ctx.json,\n });\n if (confirmationMode === \"prompt\") {\n const confirmed = await p.confirm({\n message: \"Apply this import? (y/N)\",\n initialValue: false,\n });\n if (p.isCancel(confirmed) || !confirmed) {\n p.log.warn(\"Import cancelled.\");\n return;\n }\n }\n\n const importApiPath = resolveCompanyImportApiPath({\n dryRun: false,\n targetMode: targetPayload.mode,\n orgId: targetPayload.mode === \"existing_organization\" ? targetPayload.orgId : null,\n });\n const imported = await ctx.api.post<OrganizationPortabilityImportResult>(importApiPath, {\n ...previewPayload,\n agentRuntimeOverrides,\n });\n if (!imported) {\n throw new Error(\"Import request returned no data.\");\n }\n let organizationUrl: string | undefined;\n if (!ctx.json) {\n try {\n const importedOrganization = await ctx.api.get<Organization>(`/api/orgs/${imported.organization.id}`);\n const issuePrefix = importedOrganization?.issuePrefix?.trim();\n if (issuePrefix) {\n organizationUrl = buildCompanyDashboardUrl(ctx.api.apiBase, issuePrefix);\n }\n } catch {\n organizationUrl = undefined;\n }\n }\n if (ctx.json) {\n printOutput(imported, { json: true });\n } else {\n printCompanyImportView(\n \"Import Result\",\n renderCompanyImportResult(imported, {\n targetLabel,\n organizationUrl,\n infoMessages: adapterMessages,\n }),\n { interactive: interactiveView },\n );\n if (interactiveView && organizationUrl) {\n const openImportedOrganization = await p.confirm({\n message: \"Open the imported organization in your browser?\",\n initialValue: true,\n });\n if (!p.isCancel(openImportedOrganization) && openImportedOrganization) {\n if (openUrl(organizationUrl)) {\n p.log.info(`Opened ${organizationUrl}`);\n } else {\n p.log.warn(`Could not open your browser automatically. Open this URL manually:\\n${organizationUrl}`);\n }\n }\n }\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n company\n .command(\"delete\")\n .description(\"Delete an organization by ID or shortname/prefix (destructive)\")\n .argument(\"<selector>\", \"Organization ID or issue prefix (for example PAP)\")\n .option(\n \"--by <mode>\",\n \"Selector mode: auto | id | prefix\",\n \"auto\",\n )\n .option(\"--yes\", \"Required safety flag to confirm destructive action\", false)\n .option(\n \"--confirm <value>\",\n \"Required safety value: target organization ID or shortname/prefix\",\n )\n .action(async (selector: string, opts: CompanyDeleteOptions) => {\n try {\n const by = (opts.by ?? \"auto\").trim().toLowerCase() as CompanyDeleteSelectorMode;\n if (![\"auto\", \"id\", \"prefix\"].includes(by)) {\n throw new Error(`Invalid --by mode '${opts.by}'. Expected one of: auto, id, prefix.`);\n }\n\n const ctx = resolveCommandContext(opts);\n const normalizedSelector = normalizeSelector(selector);\n assertDeleteFlags(opts);\n\n let target: Organization | null = null;\n const shouldTryIdLookup = by === \"id\" || (by === \"auto\" && isUuidLike(normalizedSelector));\n if (shouldTryIdLookup) {\n const byId = await ctx.api.get<Organization>(`/api/orgs/${normalizedSelector}`, { ignoreNotFound: true });\n if (byId) {\n target = byId;\n } else if (by === \"id\") {\n throw new Error(`No organization found by ID '${normalizedSelector}'.`);\n }\n }\n\n if (!target && ctx.orgId) {\n const scoped = await ctx.api.get<Organization>(`/api/orgs/${ctx.orgId}`, { ignoreNotFound: true });\n if (scoped) {\n try {\n target = resolveCompanyForDeletion([scoped], normalizedSelector, by);\n } catch {\n // Fallback to board-wide lookup below.\n }\n }\n }\n\n if (!target) {\n try {\n const organizations = (await ctx.api.get<Organization[]>(\"/api/orgs\")) ?? [];\n target = resolveCompanyForDeletion(organizations, normalizedSelector, by);\n } catch (error) {\n if (error instanceof ApiRequestError && error.status === 403 && error.message.includes(\"Board access required\")) {\n throw new Error(\n \"Board access is required to resolve organizations across the instance. Use an organization ID/prefix for your current organization, or run with board authentication.\",\n );\n }\n throw error;\n }\n }\n\n if (!target) {\n throw new Error(`No organization found for selector '${normalizedSelector}'.`);\n }\n\n assertDeleteConfirmation(target, opts);\n\n await ctx.api.delete<{ ok: true }>(`/api/orgs/${target.id}`);\n\n printOutput(\n {\n ok: true,\n deletedOrganizationId: target.id,\n deletedOrganizationName: target.name,\n deletedOrganizationPrefix: target.issuePrefix,\n },\n { json: ctx.json },\n );\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n", "import { inflateRawSync } from \"node:zlib\";\nimport path from \"node:path\";\nimport type { OrganizationPortabilityFileEntry } from \"@rudderhq/shared\";\n\nconst textDecoder = new TextDecoder();\n\nexport const binaryContentTypeByExtension: Record<string, string> = {\n \".gif\": \"image/gif\",\n \".jpeg\": \"image/jpeg\",\n \".jpg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".svg\": \"image/svg+xml\",\n \".webp\": \"image/webp\",\n};\n\nfunction normalizeArchivePath(pathValue: string) {\n return pathValue\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .filter(Boolean)\n .join(\"/\");\n}\n\nfunction readUint16(source: Uint8Array, offset: number) {\n return source[offset]! | (source[offset + 1]! << 8);\n}\n\nfunction readUint32(source: Uint8Array, offset: number) {\n return (\n source[offset]! |\n (source[offset + 1]! << 8) |\n (source[offset + 2]! << 16) |\n (source[offset + 3]! << 24)\n ) >>> 0;\n}\n\nfunction sharedArchiveRoot(paths: string[]) {\n if (paths.length === 0) return null;\n const firstSegments = paths\n .map((entry) => normalizeArchivePath(entry).split(\"/\").filter(Boolean))\n .filter((parts) => parts.length > 0);\n if (firstSegments.length === 0) return null;\n const candidate = firstSegments[0]![0]!;\n return firstSegments.every((parts) => parts.length > 1 && parts[0] === candidate)\n ? candidate\n : null;\n}\n\nfunction bytesToPortableFileEntry(pathValue: string, bytes: Uint8Array): OrganizationPortabilityFileEntry {\n const contentType = binaryContentTypeByExtension[path.extname(pathValue).toLowerCase()];\n if (!contentType) return textDecoder.decode(bytes);\n return {\n encoding: \"base64\",\n data: Buffer.from(bytes).toString(\"base64\"),\n contentType,\n };\n}\n\nasync function inflateZipEntry(compressionMethod: number, bytes: Uint8Array) {\n if (compressionMethod === 0) return bytes;\n if (compressionMethod !== 8) {\n throw new Error(\"Unsupported zip archive: only STORE and DEFLATE entries are supported.\");\n }\n return new Uint8Array(inflateRawSync(bytes));\n}\n\nexport async function readZipArchive(source: ArrayBuffer | Uint8Array): Promise<{\n rootPath: string | null;\n files: Record<string, OrganizationPortabilityFileEntry>;\n}> {\n const bytes = source instanceof Uint8Array ? source : new Uint8Array(source);\n const entries: Array<{ path: string; body: OrganizationPortabilityFileEntry }> = [];\n let offset = 0;\n\n while (offset + 4 <= bytes.length) {\n const signature = readUint32(bytes, offset);\n if (signature === 0x02014b50 || signature === 0x06054b50) break;\n if (signature !== 0x04034b50) {\n throw new Error(\"Invalid zip archive: unsupported local file header.\");\n }\n\n if (offset + 30 > bytes.length) {\n throw new Error(\"Invalid zip archive: truncated local file header.\");\n }\n\n const generalPurposeFlag = readUint16(bytes, offset + 6);\n const compressionMethod = readUint16(bytes, offset + 8);\n const compressedSize = readUint32(bytes, offset + 18);\n const fileNameLength = readUint16(bytes, offset + 26);\n const extraFieldLength = readUint16(bytes, offset + 28);\n\n if ((generalPurposeFlag & 0x0008) !== 0) {\n throw new Error(\"Unsupported zip archive: data descriptors are not supported.\");\n }\n\n const nameOffset = offset + 30;\n const bodyOffset = nameOffset + fileNameLength + extraFieldLength;\n const bodyEnd = bodyOffset + compressedSize;\n if (bodyEnd > bytes.length) {\n throw new Error(\"Invalid zip archive: truncated file contents.\");\n }\n\n const rawArchivePath = textDecoder.decode(bytes.slice(nameOffset, nameOffset + fileNameLength));\n const archivePath = normalizeArchivePath(rawArchivePath);\n const isDirectoryEntry = /\\/$/.test(rawArchivePath.replace(/\\\\/g, \"/\"));\n if (archivePath && !isDirectoryEntry) {\n const entryBytes = await inflateZipEntry(compressionMethod, bytes.slice(bodyOffset, bodyEnd));\n entries.push({\n path: archivePath,\n body: bytesToPortableFileEntry(archivePath, entryBytes),\n });\n }\n\n offset = bodyEnd;\n }\n\n const rootPath = sharedArchiveRoot(entries.map((entry) => entry.path));\n const files: Record<string, OrganizationPortabilityFileEntry> = {};\n for (const entry of entries) {\n const normalizedPath =\n rootPath && entry.path.startsWith(`${rootPath}/`)\n ? entry.path.slice(rootPath.length + 1)\n : entry.path;\n if (!normalizedPath) continue;\n files[normalizedPath] = entry.body;\n }\n\n return { rootPath, files };\n}\n", "import { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport {\n addIssueCommentSchema,\n checkoutIssueSchema,\n createIssueSchema,\n reportIssueCommitSchema,\n updateIssueSchema,\n upsertIssueDocumentSchema,\n type DocumentRevision,\n type IssueDocument,\n type IssueDocumentSummary,\n type LegacyPlanDocument,\n type Issue,\n type IssueAttachment,\n type IssueComment,\n type IssueCommitReport,\n} from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport { getAgentCliCapabilityById } from \"../../agent-v1-registry.js\";\n\ninterface IssueBaseOptions extends BaseClientOptions {\n status?: string;\n assigneeAgentId?: string;\n projectId?: string;\n query?: string;\n match?: string;\n}\n\ninterface IssueSearchOptions extends BaseClientOptions {\n status?: string;\n assigneeAgentId?: string;\n projectId?: string;\n}\n\ninterface IssueCreateOptions extends BaseClientOptions {\n title: string;\n description?: string;\n status?: string;\n priority?: string;\n assigneeAgentId?: string;\n projectId?: string;\n goalId?: string;\n parentId?: string;\n requestDepth?: string;\n billingCode?: string;\n}\n\ninterface IssueUpdateOptions extends BaseClientOptions {\n title?: string;\n description?: string;\n status?: string;\n priority?: string;\n assigneeAgentId?: string;\n projectId?: string;\n goalId?: string;\n parentId?: string;\n requestDepth?: string;\n billingCode?: string;\n comment?: string;\n image?: string[];\n hiddenAt?: string;\n}\n\ninterface IssueCommentOptions extends BaseClientOptions {\n body: string;\n image?: string[];\n reopen?: boolean;\n}\n\ninterface IssueCommitOptions extends BaseClientOptions {\n sha: string;\n message: string;\n branch?: string;\n repoPath?: string;\n workspacePath?: string;\n count?: string;\n}\n\ninterface IssueCheckoutOptions extends BaseClientOptions {\n agentId?: string;\n expectedStatuses?: string;\n}\n\ninterface IssueStatusCommentOptions extends BaseClientOptions {\n comment: string;\n image?: string[];\n}\n\ninterface IssueReviewOptions extends BaseClientOptions {\n decision: \"approve\" | \"request_changes\" | \"needs_followup\" | \"blocked\";\n comment: string;\n}\n\ntype CommandContext = ReturnType<typeof resolveCommandContext>;\n\ninterface IssueContextOptions extends BaseClientOptions {\n wakeCommentId?: string;\n}\n\ninterface IssueCommentsListOptions extends BaseClientOptions {\n after?: string;\n order?: string;\n}\n\ninterface IssueDocumentPutOptions extends BaseClientOptions {\n body: string;\n title?: string;\n format?: string;\n changeSummary?: string;\n baseRevisionId?: string;\n}\n\ninterface IssueHeartbeatContext {\n issue: {\n id: string;\n identifier: string | null;\n title: string;\n description: string | null;\n status: string;\n priority: string;\n projectId: string | null;\n goalId: string | null;\n parentId: string | null;\n assigneeAgentId: string | null;\n assigneeUserId: string | null;\n updatedAt: string;\n };\n ancestors: Array<{\n id: string;\n identifier: string | null;\n title: string;\n status: string;\n priority: string;\n }>;\n project: {\n id: string;\n name: string;\n status: string;\n targetDate: string | null;\n } | null;\n goal: {\n id: string;\n title: string;\n status: string;\n level: string;\n parentId: string | null;\n } | null;\n commentCursor: {\n latestCommentId: string | null;\n latestCommentCreatedAt: string | null;\n commentCount: number;\n };\n planDocument: IssueDocument | null;\n documentSummaries: IssueDocumentSummary[];\n legacyPlanDocument: LegacyPlanDocument | null;\n issueDocumentsPrompt: string;\n wakeComment: IssueComment | null;\n}\n\nexport function registerIssueCommands(program: Command): void {\n const issue = program.command(\"issue\").description(\"Issue operations\");\n\n addCommonClientOptions(\n issue\n .command(\"list\")\n .description(\"List issues for an organization\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--status <csv>\", \"Comma-separated statuses\")\n .option(\"--assignee-agent-id <id>\", \"Filter by assignee agent ID\")\n .option(\"--project-id <id>\", \"Filter by project ID\")\n .option(\"--query <text>\", \"Server-side search on identifier/title/description/comments\")\n .option(\"--match <text>\", \"Local text match on identifier/title/description\")\n .action(async (opts: IssueBaseOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<Issue[]>(buildIssueListPath(ctx.orgId!, opts, opts.query))) ?? [];\n const filtered = filterIssueRows(rows, opts.match);\n printIssueRows(filtered, ctx.json);\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n issue\n .command(\"search\")\n .description(getAgentCliCapabilityById(\"issue.search\").description)\n .argument(\"<query>\", \"Server-side issue search query\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--status <csv>\", \"Comma-separated statuses\")\n .option(\"--assignee-agent-id <id>\", \"Filter by assignee agent ID\")\n .option(\"--project-id <id>\", \"Filter by project ID\")\n .action(async (query: string, opts: IssueSearchOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<Issue[]>(buildIssueListPath(ctx.orgId!, opts, query))) ?? [];\n printIssueRows(rows, ctx.json);\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n issue\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"issue.get\").description)\n .argument(\"<idOrIdentifier>\", \"Issue ID or identifier\")\n .action(async (idOrIdentifier: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<Issue>(`/api/issues/${idOrIdentifier}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"context\")\n .description(getAgentCliCapabilityById(\"issue.context\").description)\n .argument(\"<issueId>\", \"Issue ID or identifier\")\n .option(\"--wake-comment-id <id>\", \"Fetch one wake comment in the heartbeat context response\")\n .action(async (issueId: string, opts: IssueContextOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const params = new URLSearchParams();\n if (opts.wakeCommentId) params.set(\"wakeCommentId\", opts.wakeCommentId);\n const query = params.toString();\n const row = await ctx.api.get<IssueHeartbeatContext>(\n `/api/issues/${issueId}/heartbeat-context${query ? `?${query}` : \"\"}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"create\")\n .description(getAgentCliCapabilityById(\"issue.create\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--title <title>\", \"Issue title\")\n .option(\"--description <text>\", \"Issue description\")\n .option(\"--status <status>\", \"Issue status\")\n .option(\"--priority <priority>\", \"Issue priority\")\n .option(\"--assignee-agent-id <id>\", \"Assignee agent ID\")\n .option(\"--project-id <id>\", \"Project ID\")\n .option(\"--goal-id <id>\", \"Goal ID\")\n .option(\"--parent-id <id>\", \"Parent issue ID\")\n .option(\"--request-depth <n>\", \"Request depth integer\")\n .option(\"--billing-code <code>\", \"Billing code\")\n .action(async (opts: IssueCreateOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = createIssueSchema.parse({\n title: opts.title,\n description: opts.description,\n status: opts.status,\n priority: opts.priority,\n assigneeAgentId: opts.assigneeAgentId,\n projectId: opts.projectId,\n goalId: opts.goalId,\n parentId: opts.parentId,\n requestDepth: parseOptionalInt(opts.requestDepth),\n billingCode: opts.billingCode,\n });\n\n const created = await ctx.api.post<Issue>(`/api/orgs/${ctx.orgId}/issues`, payload);\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n issue\n .command(\"update\")\n .description(getAgentCliCapabilityById(\"issue.update\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .option(\"--title <title>\", \"Issue title\")\n .option(\"--description <text>\", \"Issue description\")\n .option(\"--status <status>\", \"Issue status\")\n .option(\"--priority <priority>\", \"Issue priority\")\n .option(\"--assignee-agent-id <id>\", \"Assignee agent ID\")\n .option(\"--project-id <id>\", \"Project ID\")\n .option(\"--goal-id <id>\", \"Goal ID\")\n .option(\"--parent-id <id>\", \"Parent issue ID\")\n .option(\"--request-depth <n>\", \"Request depth integer\")\n .option(\"--billing-code <code>\", \"Billing code\")\n .option(\"--comment <text>\", \"Optional comment to add with update\")\n .option(\"--image <path>\", \"Image file to upload and append to the update comment; may be repeated\", collectImagePath, [] as string[])\n .option(\"--hidden-at <iso8601|null>\", \"Set hiddenAt timestamp or literal 'null'\")\n .action(async (issueId: string, opts: IssueUpdateOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const comment = await appendUploadedIssueImages(ctx, issueId, opts.comment, opts.image);\n const payload = updateIssueSchema.parse({\n title: opts.title,\n description: opts.description,\n status: opts.status,\n priority: opts.priority,\n assigneeAgentId: opts.assigneeAgentId,\n projectId: opts.projectId,\n goalId: opts.goalId,\n parentId: opts.parentId,\n requestDepth: parseOptionalInt(opts.requestDepth),\n billingCode: opts.billingCode,\n comment,\n hiddenAt: parseHiddenAt(opts.hiddenAt),\n });\n\n const updated = await ctx.api.patch<Issue & { comment?: IssueComment | null }>(`/api/issues/${issueId}`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"comment\")\n .description(getAgentCliCapabilityById(\"issue.comment\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--body <text>\", \"Comment body\")\n .option(\"--image <path>\", \"Image file to upload and append to the comment; may be repeated\", collectImagePath, [] as string[])\n .option(\"--reopen\", \"Reopen if issue is done/cancelled\")\n .action(async (issueId: string, opts: IssueCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const body = await appendUploadedIssueImages(ctx, issueId, opts.body, opts.image);\n const payload = addIssueCommentSchema.parse({\n body,\n reopen: opts.reopen,\n });\n const comment = await ctx.api.post<IssueComment>(`/api/issues/${issueId}/comments`, payload);\n printOutput(comment, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"review\")\n .description(getAgentCliCapabilityById(\"issue.review\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\n \"--decision <decision>\",\n \"Review decision: approve, request_changes, needs_followup, or blocked\",\n )\n .requiredOption(\"--comment <text>\", \"Required review comment\")\n .action(async (issueId: string, opts: IssueReviewOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const decision = parseReviewDecision(opts.decision);\n const updated = await ctx.api.patch<Issue & { comment?: IssueComment | null }>(`/api/issues/${issueId}`, {\n reviewDecision: decision,\n comment: opts.comment,\n });\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"commit\")\n .description(getAgentCliCapabilityById(\"issue.commit\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--sha <sha>\", \"Commit SHA\")\n .requiredOption(\"--message <subject>\", \"Commit subject or message\")\n .option(\"--branch <name>\", \"Branch name\")\n .option(\"--repo-path <path>\", \"Repository path\")\n .option(\"--workspace-path <path>\", \"Workspace path\")\n .option(\"--count <n>\", \"Number of commits represented by this report\")\n .action(async (issueId: string, opts: IssueCommitOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = reportIssueCommitSchema.parse({\n sha: opts.sha,\n message: opts.message,\n branch: opts.branch,\n repoPath: opts.repoPath,\n workspacePath: opts.workspacePath,\n commitCount: parseOptionalInt(opts.count),\n });\n const reported = await ctx.api.post<IssueCommitReport>(`/api/issues/${issueId}/commit`, payload);\n printOutput(reported, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"done\")\n .description(getAgentCliCapabilityById(\"issue.done\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--comment <text>\", \"Required completion comment\")\n .option(\"--image <path>\", \"Image file to upload and append to the completion comment; may be repeated\", collectImagePath, [] as string[])\n .action(async (issueId: string, opts: IssueStatusCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const comment = await appendUploadedIssueImages(ctx, issueId, opts.comment, opts.image);\n const updated = await ctx.api.patch<Issue>(`/api/issues/${issueId}`, {\n status: \"done\",\n comment,\n });\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"block\")\n .description(getAgentCliCapabilityById(\"issue.block\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .requiredOption(\"--comment <text>\", \"Required blocker comment\")\n .option(\"--image <path>\", \"Image file to upload and append to the blocker comment; may be repeated\", collectImagePath, [] as string[])\n .action(async (issueId: string, opts: IssueStatusCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const comment = await appendUploadedIssueImages(ctx, issueId, opts.comment, opts.image);\n const updated = await ctx.api.patch<Issue>(`/api/issues/${issueId}`, {\n status: \"blocked\",\n comment,\n });\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n const comments = issue.command(\"comments\").description(\"Issue comment operations\");\n\n addCommonClientOptions(\n comments\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"issue.comments.list\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .option(\"--after <commentId>\", \"Only return comments after this comment ID\")\n .option(\"--order <order>\", \"Comment ordering (asc or desc)\", \"desc\")\n .action(async (issueId: string, opts: IssueCommentsListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const params = new URLSearchParams();\n if (opts.after) params.set(\"after\", opts.after);\n if (opts.order) params.set(\"order\", opts.order);\n const query = params.toString();\n const rows = (await ctx.api.get<IssueComment[]>(\n `/api/issues/${issueId}/comments${query ? `?${query}` : \"\"}`,\n )) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n comments\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"issue.comments.get\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<commentId>\", \"Comment ID\")\n .action(async (issueId: string, commentId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<IssueComment>(`/api/issues/${issueId}/comments/${commentId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n const documents = issue.command(\"documents\").description(\"Issue document operations\");\n\n addCommonClientOptions(\n documents\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"issue.documents.list\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .action(async (issueId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<IssueDocumentSummary[]>(`/api/issues/${issueId}/documents`)) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n documents\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"issue.documents.get\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<key>\", \"Document key\")\n .action(async (issueId: string, key: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<IssueDocument>(`/api/issues/${issueId}/documents/${key}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n documents\n .command(\"put\")\n .description(getAgentCliCapabilityById(\"issue.documents.put\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<key>\", \"Document key\")\n .requiredOption(\"--body <text>\", \"Document body\")\n .option(\"--title <text>\", \"Document title\")\n .option(\"--format <format>\", \"Document format\", \"markdown\")\n .option(\"--change-summary <text>\", \"Optional change summary\")\n .option(\"--base-revision-id <id>\", \"Latest revision id for optimistic concurrency\")\n .action(async (issueId: string, key: string, opts: IssueDocumentPutOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = upsertIssueDocumentSchema.parse({\n title: opts.title,\n format: opts.format,\n body: opts.body,\n changeSummary: opts.changeSummary,\n baseRevisionId: opts.baseRevisionId,\n });\n const row = await ctx.api.put<IssueDocument>(`/api/issues/${issueId}/documents/${key}`, payload);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n documents\n .command(\"revisions\")\n .description(getAgentCliCapabilityById(\"issue.documents.revisions\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .argument(\"<key>\", \"Document key\")\n .action(async (issueId: string, key: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<DocumentRevision[]>(`/api/issues/${issueId}/documents/${key}/revisions`)) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"checkout\")\n .description(getAgentCliCapabilityById(\"issue.checkout\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .option(\"--agent-id <id>\", \"Agent ID (defaults to RUDDER_AGENT_ID)\")\n .option(\n \"--expected-statuses <csv>\",\n \"Expected current statuses\",\n \"todo,backlog,blocked\",\n )\n .action(async (issueId: string, opts: IssueCheckoutOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const agentId = opts.agentId?.trim() || ctx.agentId;\n if (!agentId) {\n throw new Error(\"Agent ID is required. Pass --agent-id or set RUDDER_AGENT_ID.\");\n }\n const payload = checkoutIssueSchema.parse({\n agentId,\n expectedStatuses: parseCsv(opts.expectedStatuses),\n });\n const updated = await ctx.api.post<Issue>(`/api/issues/${issueId}/checkout`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n issue\n .command(\"release\")\n .description(getAgentCliCapabilityById(\"issue.release\").description)\n .argument(\"<issueId>\", \"Issue ID\")\n .action(async (issueId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const updated = await ctx.api.post<Issue>(`/api/issues/${issueId}/release`, {});\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n\nfunction collectImagePath(value: string, previous: string[]): string[] {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(\"--image path cannot be empty\");\n }\n return [...previous, trimmed];\n}\n\nasync function appendUploadedIssueImages(\n ctx: CommandContext,\n issueId: string,\n body: string | undefined,\n imagePaths: string[] | undefined,\n): Promise<string | undefined> {\n const paths = imagePaths ?? [];\n if (paths.length === 0) return body;\n\n const issue = await ctx.api.get<Issue>(`/api/issues/${issueId}`);\n if (!issue) {\n throw new Error(\"Issue not found\");\n }\n\n const links: string[] = [];\n for (const imagePath of paths) {\n const attachment = await uploadIssueCommentImage(ctx, issue, imagePath);\n links.push(formatAttachmentMarkdown(attachment));\n }\n\n const base = body?.trimEnd() ?? \"\";\n const imageBlock = links.join(\"\\n\");\n return base ? `${base}\\n\\n${imageBlock}` : imageBlock;\n}\n\nasync function uploadIssueCommentImage(\n ctx: CommandContext,\n issue: Issue,\n imagePath: string,\n): Promise<IssueAttachment> {\n const resolvedPath = path.resolve(process.cwd(), imagePath);\n const stats = await stat(resolvedPath).catch((err: unknown) => {\n throw new Error(`Unable to read image ${imagePath}: ${err instanceof Error ? err.message : String(err)}`);\n });\n if (!stats.isFile()) {\n throw new Error(`Image path must be a file: ${imagePath}`);\n }\n\n const filename = path.basename(resolvedPath);\n const contentType = inferCommentImageContentType(filename);\n const buffer = await readFile(resolvedPath);\n if (buffer.length <= 0) {\n throw new Error(`Image is empty: ${imagePath}`);\n }\n\n const form = new FormData();\n form.set(\"usage\", \"comment_inline\");\n form.set(\"file\", new Blob([buffer], { type: contentType }), filename);\n\n const attachment = await ctx.api.postForm<IssueAttachment>(\n `/api/orgs/${issue.orgId}/issues/${issue.id}/attachments`,\n form,\n );\n if (!attachment) {\n throw new Error(`Image upload returned no attachment: ${imagePath}`);\n }\n return attachment;\n}\n\nfunction inferCommentImageContentType(filename: string): string {\n const ext = path.extname(filename).toLowerCase();\n switch (ext) {\n case \".png\":\n return \"image/png\";\n case \".jpg\":\n case \".jpeg\":\n return \"image/jpeg\";\n case \".webp\":\n return \"image/webp\";\n case \".gif\":\n return \"image/gif\";\n default:\n throw new Error(`Unsupported comment image type: ${filename}. Use PNG, JPEG, WebP, or GIF.`);\n }\n}\n\nfunction formatAttachmentMarkdown(attachment: IssueAttachment): string {\n const alt = escapeMarkdownAltText(attachment.originalFilename ?? \"image\");\n return `![${alt}](${attachment.contentPath})`;\n}\n\nfunction escapeMarkdownAltText(value: string): string {\n return value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"]\", \"\\\\]\");\n}\n\nfunction parseCsv(value: string | undefined): string[] {\n if (!value) return [];\n return value.split(\",\").map((v) => v.trim()).filter(Boolean);\n}\n\nfunction parseOptionalInt(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number.parseInt(value, 10);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid integer value: ${value}`);\n }\n return parsed;\n}\n\nfunction parseHiddenAt(value: string | undefined): string | null | undefined {\n if (value === undefined) return undefined;\n if (value.trim().toLowerCase() === \"null\") return null;\n return value;\n}\n\nfunction parseReviewDecision(value: string): IssueReviewOptions[\"decision\"] {\n const normalized = value.trim();\n if (\n normalized === \"approve\" ||\n normalized === \"request_changes\" ||\n normalized === \"needs_followup\" ||\n normalized === \"blocked\"\n ) {\n return normalized;\n }\n throw new Error(\"Invalid review decision. Use approve, request_changes, needs_followup, or blocked.\");\n}\n\nfunction filterIssueRows(rows: Issue[], match: string | undefined): Issue[] {\n if (!match?.trim()) return rows;\n const needle = match.trim().toLowerCase();\n return rows.filter((row) => {\n const text = [row.identifier, row.title, row.description]\n .filter((part): part is string => Boolean(part))\n .join(\"\\n\")\n .toLowerCase();\n return text.includes(needle);\n });\n}\n\nfunction buildIssueListPath(orgId: string, opts: IssueSearchOptions, searchQuery?: string): string {\n const params = new URLSearchParams();\n if (opts.status) params.set(\"status\", opts.status);\n if (opts.assigneeAgentId) params.set(\"assigneeAgentId\", opts.assigneeAgentId);\n if (opts.projectId) params.set(\"projectId\", opts.projectId);\n if (searchQuery?.trim()) params.set(\"q\", searchQuery.trim());\n\n const query = params.toString();\n return `/api/orgs/${orgId}/issues${query ? `?${query}` : \"\"}`;\n}\n\nfunction printIssueRows(rows: Issue[], json: boolean): void {\n if (json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const item of rows) {\n console.log(\n formatInlineRecord({\n identifier: item.identifier,\n id: item.id,\n status: item.status,\n priority: item.priority,\n assigneeAgentId: item.assigneeAgentId,\n assigneeUserId: item.assigneeUserId,\n title: item.title,\n projectId: item.projectId,\n updatedAt: item.updatedAt,\n ...(item.searchMatch ? { match: formatIssueSearchMatch(item.searchMatch) } : {}),\n }),\n );\n }\n}\n\nfunction formatIssueSearchMatch(match: NonNullable<Issue[\"searchMatch\"]>): string {\n const commentSuffix = match.commentId ? `#${match.commentId}` : \"\";\n return `${match.field}${commentSuffix}: ${match.snippet}`;\n}\n", "export type AgentCliCapabilityCategory = \"agent\" | \"issue\" | \"approval\" | \"skill\";\nexport type AgentCliCapabilityContract = \"agent-v1\" | \"compat\";\n\nexport interface AgentCliCapability {\n id: string;\n command: string;\n category: AgentCliCapabilityCategory;\n description: string;\n mutating: boolean;\n contract: AgentCliCapabilityContract;\n requiresOrgId: boolean;\n requiresAgentId: boolean;\n requiresRunId: boolean;\n attachesRunIdWhenAvailable: boolean;\n}\n\nexport interface AgentCliCapabilitiesManifestEntry extends AgentCliCapability {\n agentV1: boolean;\n}\n\nexport interface AgentCliCapabilitiesManifest {\n schema: \"rudder.agent-capabilities/v1\";\n contract: AgentCliCapabilityContract | \"all\";\n defaults: {\n orgIdEnvVar: \"RUDDER_ORG_ID\";\n agentIdEnvVar: \"RUDDER_AGENT_ID\";\n runIdEnvVar: \"RUDDER_RUN_ID\";\n jsonErrors: \"stderr-error-envelope\";\n };\n capabilities: AgentCliCapabilitiesManifestEntry[];\n}\n\nconst AGENT_CLI_CAPABILITIES: AgentCliCapability[] = [\n {\n id: \"agent.me\",\n command: \"rudder agent me\",\n category: \"agent\",\n description: \"Show the authenticated agent identity, budget, and chain of command.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.inbox\",\n command: \"rudder agent inbox\",\n category: \"agent\",\n description: \"List the compact assignee and reviewer work inbox for the authenticated agent.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.capabilities\",\n command: \"rudder agent capabilities\",\n category: \"agent\",\n description: \"List the stable Rudder agent command contract.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.list\",\n command: \"rudder agent list --org-id <id>\",\n category: \"agent\",\n description: \"List agents for an organization.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.get\",\n command: \"rudder agent get <agent-id-or-shortname>\",\n category: \"agent\",\n description: \"Read one agent by id or shortname.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.skills.enable\",\n command: \"rudder agent skills enable <agent-id> <selection-ref...>\",\n category: \"agent\",\n description: \"Add skill selections to an agent without replacing existing enabled skills.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"agent.skills.sync\",\n command: \"rudder agent skills sync <agent-id>\",\n category: \"agent\",\n description: \"Sync the desired enabled skill set for an agent.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"agent.hire\",\n command: \"rudder agent hire --org-id <id> --payload <json>\",\n category: \"agent\",\n description: \"Create a new hire using the canonical hire workflow.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"agent.config.index\",\n command: \"rudder agent config index\",\n category: \"agent\",\n description: \"Read the installed agent runtime configuration index.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.config.doc\",\n command: \"rudder agent config doc <agent-runtime-type>\",\n category: \"agent\",\n description: \"Read adapter-specific configuration guidance for one runtime.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.config.list\",\n command: \"rudder agent config list --org-id <id>\",\n category: \"agent\",\n description: \"List redacted agent configuration snapshots for an organization.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.config.get\",\n command: \"rudder agent config get <agent-id-or-shortname>\",\n category: \"agent\",\n description: \"Read one redacted agent configuration snapshot by id or shortname.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"agent.icons\",\n command: \"rudder agent icons\",\n category: \"agent\",\n description: \"List allowed agent icon names for create and hire payloads.\",\n mutating: false,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.get\",\n command: \"rudder issue get <issue>\",\n category: \"issue\",\n description: \"Read a full issue by UUID or identifier.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.search\",\n command: \"rudder issue search <query> [--org-id <id>]\",\n category: \"issue\",\n description: \"Search issues with the server-side issue index across title, identifier, description, and comments.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.context\",\n command: \"rudder issue context <issue>\",\n category: \"issue\",\n description: \"Read the compact heartbeat context for an issue.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.checkout\",\n command: \"rudder issue checkout <issue>\",\n category: \"issue\",\n description: \"Atomically checkout an issue for the current or specified agent.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: true,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.comment\",\n command: \"rudder issue comment <issue> --body <text> [--image <path>]\",\n category: \"issue\",\n description: \"Add a comment to an issue, optionally uploading images and appending Markdown image links.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.comments.list\",\n command: \"rudder issue comments list <issue>\",\n category: \"issue\",\n description: \"List issue comments, optionally only newer comments after a cursor.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.comments.get\",\n command: \"rudder issue comments get <issue> <comment-id>\",\n category: \"issue\",\n description: \"Read one issue comment by id.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.update\",\n command: \"rudder issue update <issue> ... [--image <path>]\",\n category: \"issue\",\n description: \"Apply generic issue updates when workflow commands are not enough, optionally uploading images for the update comment.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.review\",\n command: \"rudder issue review <issue> --decision <decision> --comment <text>\",\n category: \"issue\",\n description: \"Record a structured reviewer decision with a required comment.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.commit\",\n command: \"rudder issue commit <issue> --sha <sha> --message <subject>\",\n category: \"issue\",\n description: \"Report a code commit created during issue work as structured issue activity.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.done\",\n command: \"rudder issue done <issue> --comment <text> [--image <path>]\",\n category: \"issue\",\n description: \"Mark an issue done with a required completion comment, optionally uploading images.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.block\",\n command: \"rudder issue block <issue> --comment <text> [--image <path>]\",\n category: \"issue\",\n description: \"Mark an issue blocked with a required blocker comment, optionally uploading images.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.release\",\n command: \"rudder issue release <issue>\",\n category: \"issue\",\n description: \"Release an issue back to todo and clear ownership.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.documents.list\",\n command: \"rudder issue documents list <issue>\",\n category: \"issue\",\n description: \"List issue documents.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.documents.get\",\n command: \"rudder issue documents get <issue> <key>\",\n category: \"issue\",\n description: \"Read one issue document by key.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.documents.put\",\n command: \"rudder issue documents put <issue> <key> --body <text>\",\n category: \"issue\",\n description: \"Create or update an issue document.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"issue.documents.revisions\",\n command: \"rudder issue documents revisions <issue> <key>\",\n category: \"issue\",\n description: \"List revisions for an issue document.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"issue.create\",\n command: \"rudder issue create --org-id <id> ...\",\n category: \"issue\",\n description: \"Create a new issue or subtask with the generic issue surface; agent-created issues default to the creating agent when no assignee is supplied.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"approval.get\",\n command: \"rudder approval get <approval-id>\",\n category: \"approval\",\n description: \"Read one approval request.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"approval.create\",\n command: \"rudder approval create --org-id <id> --type <type> --payload <json>\",\n category: \"approval\",\n description: \"Create a new approval request.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"approval.issues\",\n command: \"rudder approval issues <approval-id>\",\n category: \"approval\",\n description: \"List the issues linked to an approval.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"approval.comment\",\n command: \"rudder approval comment <approval-id> --body <text>\",\n category: \"approval\",\n description: \"Add a comment to an approval.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"approval.resubmit\",\n command: \"rudder approval resubmit <approval-id> [--payload <json>]\",\n category: \"approval\",\n description: \"Resubmit a revision-requested approval, optionally with updated payload.\",\n mutating: true,\n contract: \"compat\",\n requiresOrgId: false,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"skill.list\",\n command: \"rudder skill list --org-id <id>\",\n category: \"skill\",\n description: \"List organization-visible skills.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"skill.get\",\n command: \"rudder skill get <skill-id> --org-id <id>\",\n category: \"skill\",\n description: \"Read one organization skill detail.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"skill.file\",\n command: \"rudder skill file <skill-id> --org-id <id> [--path SKILL.md]\",\n category: \"skill\",\n description: \"Read one file from an organization skill package.\",\n mutating: false,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: false,\n },\n {\n id: \"skill.import\",\n command: \"rudder skill import --org-id <id> --source <source>\",\n category: \"skill\",\n description: \"Import a skill package into the organization skill library.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"skill.scan-local\",\n command: \"rudder skill scan-local --org-id <id> [--roots <csv>]\",\n category: \"skill\",\n description: \"Scan local roots for skill packages and import new ones.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n {\n id: \"skill.scan-projects\",\n command: \"rudder skill scan-projects --org-id <id> [--project-ids <csv>] [--workspace-ids <csv>]\",\n category: \"skill\",\n description:\n \"Scan the org workspace and any legacy project workspace records for skill packages and import new ones.\",\n mutating: true,\n contract: \"agent-v1\",\n requiresOrgId: true,\n requiresAgentId: false,\n requiresRunId: false,\n attachesRunIdWhenAvailable: true,\n },\n];\n\nconst CATEGORY_TITLES: Record<AgentCliCapabilityCategory, string> = {\n agent: \"Agent\",\n issue: \"Issue\",\n approval: \"Approval\",\n skill: \"Skill\",\n};\n\nexport function getAgentCliCapabilities(): AgentCliCapability[] {\n return AGENT_CLI_CAPABILITIES.map((entry) => ({ ...entry }));\n}\n\nexport function getAgentCliCapabilityById(id: string): AgentCliCapability {\n const entry = AGENT_CLI_CAPABILITIES.find((capability) => capability.id === id);\n if (!entry) {\n throw new Error(`Unknown agent CLI capability: ${id}`);\n }\n return entry;\n}\n\nexport function buildAgentCliCapabilitiesManifest(\n contract: AgentCliCapabilityContract | \"all\" = \"agent-v1\",\n): AgentCliCapabilitiesManifest {\n const capabilities = AGENT_CLI_CAPABILITIES\n .filter((entry) => contract === \"all\" || entry.contract === contract)\n .map((entry) => ({\n ...entry,\n agentV1: entry.contract === \"agent-v1\",\n }));\n\n return {\n schema: \"rudder.agent-capabilities/v1\",\n contract,\n defaults: {\n orgIdEnvVar: \"RUDDER_ORG_ID\",\n agentIdEnvVar: \"RUDDER_AGENT_ID\",\n runIdEnvVar: \"RUDDER_RUN_ID\",\n jsonErrors: \"stderr-error-envelope\",\n },\n capabilities,\n };\n}\n\nexport function renderAgentCliReferenceMarkdown(): string {\n const manifest = buildAgentCliCapabilitiesManifest(\"agent-v1\");\n const lines: string[] = [\n \"# Rudder Agent CLI Reference\",\n \"\",\n \"Stable CLI contract for agents using the bundled `rudder` skill. Prefer these commands over direct `/api` calls.\",\n \"\",\n \"## Defaults\",\n \"\",\n \"- All commands support `--json`.\",\n \"- `--org-id` defaults to `RUDDER_ORG_ID` when relevant.\",\n \"- `--run-id` defaults to `RUDDER_RUN_ID` and is attached to mutating requests when available.\",\n \"- `issue checkout` defaults `--agent-id` from `RUDDER_AGENT_ID`.\",\n \"\",\n \"## Agent V1 Commands\",\n \"\",\n \"| Command | Description | Mutating | Org | Agent | Run ID |\",\n \"| --- | --- | --- | --- | --- | --- |\",\n ];\n\n for (const capability of manifest.capabilities) {\n lines.push(\n `| \\`${capability.command}\\` | ${capability.description} | ${capability.mutating ? \"yes\" : \"no\"} | ${\n capability.requiresOrgId ? \"required\" : \"no\"\n } | ${capability.requiresAgentId ? \"required\" : \"no\"} | ${\n capability.requiresRunId ? \"required\" : capability.attachesRunIdWhenAvailable ? \"attached when available\" : \"no\"\n } |`,\n );\n }\n\n lines.push(\n \"\",\n \"## Issue Close-Out Signals\",\n \"\",\n \"Before a successful `todo` or `in_progress` issue run exits, leave one close-out signal with the command that matches the outcome:\",\n \"\",\n \"- progress remains: `rudder issue comment <issue> --body <text> [--image <path>]`\",\n \"- work is complete: `rudder issue done <issue> --comment <text> [--image <path>]`\",\n \"- work is blocked: `rudder issue block <issue> --comment <text> [--image <path>]`\",\n \"- ownership changes: add an explicit handoff comment before or with the assignee update\",\n \"\",\n \"If an issue has a reviewer, moving it to `blocked` is also a reviewer handoff: the reviewer should confirm the blocker, request changes, approve, or keep explicit follow-up open with `rudder issue review`.\",\n \"\",\n \"`--image` may be repeated. The CLI uploads each local PNG/JPEG/WebP/GIF as an issue attachment and appends Markdown image links to the comment text before sending it.\",\n \"\",\n \"If your issue comment cites a screenshot path or visual validation artifact, attach that file with `--image <path>` instead of leaving only the local path in the text.\",\n \"\",\n \"If `RUDDER_WAKE_REASON=issue_passive_followup`, the run is close-out governance for the same issue. Inspect current issue state first, then leave a progress comment, completion, blocker, or explicit handoff.\",\n \"\",\n \"## Git Identity Policy\",\n \"\",\n \"Local runtime `HOME` is isolated from the operator home. Codex local runs and runtime-created git worktrees are prepared with `user.useConfigOnly=true` so missing identity fails fast instead of producing `*@*.local` commits. If Git reports missing author or committer identity, configure the repository explicitly with `git config user.name <name>` and `git config user.email <safe-email>`; do not unset the guard or accept auto-detected local-host metadata.\",\n \"\",\n \"## Reviewer Close-Out Signals\",\n \"\",\n \"When the inbox row or wake context says `relationship: \\\"reviewer\\\"`, `role: \\\"reviewer\\\"`, or `wakeSource: \\\"review\\\"`, finish the review with one structured reviewer decision. Reviewer work can be either `in_review` or `blocked`; blocked reviewer work means blocker triage, not implementation takeover.\",\n \"\",\n \"- approve: `rudder issue review <issue> --decision approve --comment <text>`\",\n \"- request changes: `rudder issue review <issue> --decision request_changes --comment <text>`\",\n \"- needs follow-up: `rudder issue review <issue> --decision needs_followup --comment <text>`\",\n \"- blocked or blocker confirmed: `rudder issue review <issue> --decision blocked --comment <text>`; use this only for a confirmed human/external blocker and name the next human action.\",\n \"\",\n \"Do not rely on a free-form reject or accept comment as the review outcome. The structured decision is the durable close-out signal. A blocked reviewer decision records a human handoff and removes the issue from repeated reviewer pickup until the board changes the issue.\",\n );\n\n lines.push(\"\", \"## Compatibility Commands\", \"\");\n for (const capability of AGENT_CLI_CAPABILITIES.filter((entry) => entry.contract === \"compat\")) {\n lines.push(`- \\`${capability.command}\\` \u2014 ${capability.description}`);\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nexport function formatAgentCliCapabilitiesHumanReadable(\n capabilities: AgentCliCapability[] = getAgentCliCapabilities(),\n): string {\n const lines: string[] = [];\n\n for (const category of Object.keys(CATEGORY_TITLES) as AgentCliCapabilityCategory[]) {\n const entries = capabilities.filter((capability) => capability.category === category);\n if (entries.length === 0) continue;\n lines.push(`${CATEGORY_TITLES[category]} commands:`);\n for (const entry of entries) {\n const tags = [\n entry.contract,\n entry.mutating ? \"mutating\" : \"read-only\",\n entry.requiresOrgId ? \"org\" : null,\n entry.requiresAgentId ? \"agent\" : null,\n entry.attachesRunIdWhenAvailable ? \"run-id\" : null,\n ].filter(Boolean);\n lines.push(`- ${entry.command} \u2014 ${entry.description} [${tags.join(\", \")}]`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd();\n}\n", "import { Command } from \"commander\";\nimport {\n createAgentHireSchema,\n type Agent,\n type AgentDetail,\n type AgentSkillSnapshot,\n type Approval,\n} from \"@rudderhq/shared\";\nimport {\n removeMaintainerOnlySkillSymlinks,\n resolveRudderSkillsDir,\n} from \"@rudderhq/agent-runtime-utils/server-utils\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport {\n buildAgentCliCapabilitiesManifest,\n formatAgentCliCapabilitiesHumanReadable,\n getAgentCliCapabilityById,\n getAgentCliCapabilities,\n} from \"../../agent-v1-registry.js\";\n\ninterface AgentListOptions extends BaseClientOptions {\n orgId?: string;\n}\n\ninterface AgentInboxItem {\n id: string;\n identifier: string | null;\n title: string;\n relationship?: \"assignee\" | \"reviewer\";\n status: string;\n priority: string;\n projectId: string | null;\n goalId: string | null;\n parentId: string | null;\n updatedAt: string;\n activeRun: unknown;\n}\n\ninterface AgentLocalCliOptions extends BaseClientOptions {\n orgId?: string;\n keyName?: string;\n installSkills?: boolean;\n}\n\ninterface AgentCapabilitiesOptions extends BaseClientOptions {\n contract?: string;\n}\n\ninterface AgentHireOptions extends BaseClientOptions {\n orgId?: string;\n payload: string;\n}\n\ninterface AgentSkillSyncOptions extends BaseClientOptions {\n desiredSkills: string;\n}\n\ninterface AgentSkillEnableOptions extends BaseClientOptions {}\n\ninterface AgentConfigurationRow {\n id: string;\n orgId: string;\n name: string;\n role: string;\n title: string | null;\n status: string;\n reportsTo: string | null;\n agentRuntimeType: string;\n agentRuntimeConfig: Record<string, unknown>;\n runtimeConfig: Record<string, unknown>;\n permissions: Record<string, unknown> | null;\n updatedAt: string;\n}\n\ninterface AgentHireResult {\n agent: Agent;\n approval: Approval | null;\n}\n\ninterface CreatedAgentKey {\n id: string;\n name: string;\n token: string;\n createdAt: string;\n}\n\ninterface SkillsInstallSummary {\n tool: \"codex\" | \"claude\";\n target: string;\n linked: string[];\n removed: string[];\n skipped: string[];\n failed: Array<{ name: string; error: string }>;\n}\n\nconst __moduleDir = path.dirname(fileURLToPath(import.meta.url));\n\nfunction codexSkillsHome(): string {\n const fromEnv = process.env.CODEX_HOME?.trim();\n const base = fromEnv && fromEnv.length > 0 ? fromEnv : path.join(os.homedir(), \".codex\");\n return path.join(base, \"skills\");\n}\n\nfunction claudeSkillsHome(): string {\n const fromEnv = process.env.CLAUDE_HOME?.trim();\n const base = fromEnv && fromEnv.length > 0 ? fromEnv : path.join(os.homedir(), \".claude\");\n return path.join(base, \"skills\");\n}\n\nasync function installSkillsForTarget(\n sourceSkillsDir: string,\n targetSkillsDir: string,\n tool: \"codex\" | \"claude\",\n): Promise<SkillsInstallSummary> {\n const summary: SkillsInstallSummary = {\n tool,\n target: targetSkillsDir,\n linked: [],\n removed: [],\n skipped: [],\n failed: [],\n };\n\n await fs.mkdir(targetSkillsDir, { recursive: true });\n const entries = await fs.readdir(sourceSkillsDir, { withFileTypes: true });\n summary.removed = await removeMaintainerOnlySkillSymlinks(\n targetSkillsDir,\n entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name),\n );\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const source = path.join(sourceSkillsDir, entry.name);\n const target = path.join(targetSkillsDir, entry.name);\n const existing = await fs.lstat(target).catch(() => null);\n if (existing) {\n if (existing.isSymbolicLink()) {\n let linkedPath: string | null = null;\n try {\n linkedPath = await fs.readlink(target);\n } catch (err) {\n await fs.unlink(target);\n try {\n await fs.symlink(source, target);\n summary.linked.push(entry.name);\n continue;\n } catch (linkErr) {\n summary.failed.push({\n name: entry.name,\n error:\n err instanceof Error && linkErr instanceof Error\n ? `${err.message}; then ${linkErr.message}`\n : err instanceof Error\n ? err.message\n : `Failed to recover broken symlink: ${String(err)}`,\n });\n continue;\n }\n }\n\n const resolvedLinkedPath = path.isAbsolute(linkedPath)\n ? linkedPath\n : path.resolve(path.dirname(target), linkedPath);\n const linkedTargetExists = await fs\n .stat(resolvedLinkedPath)\n .then(() => true)\n .catch(() => false);\n\n if (!linkedTargetExists) {\n await fs.unlink(target);\n } else {\n summary.skipped.push(entry.name);\n continue;\n }\n } else {\n summary.skipped.push(entry.name);\n continue;\n }\n }\n\n try {\n await fs.symlink(source, target);\n summary.linked.push(entry.name);\n } catch (err) {\n summary.failed.push({\n name: entry.name,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return summary;\n}\n\nfunction buildAgentEnvExports(input: {\n apiBase: string;\n orgId: string;\n agentId: string;\n apiKey: string;\n}): string {\n const escaped = (value: string) => value.replace(/'/g, \"'\\\"'\\\"'\");\n return [\n `export RUDDER_API_URL='${escaped(input.apiBase)}'`,\n `export RUDDER_ORG_ID='${escaped(input.orgId)}'`,\n `export RUDDER_AGENT_ID='${escaped(input.agentId)}'`,\n `export RUDDER_API_KEY='${escaped(input.apiKey)}'`,\n ].join(\"\\n\");\n}\n\nexport function registerAgentCommands(program: Command): void {\n const agent = program.command(\"agent\").description(\"Agent operations\");\n const config = agent.command(\"config\").description(\"Agent configuration discovery and redacted snapshots\");\n\n addCommonClientOptions(\n agent\n .command(\"me\")\n .description(getAgentCliCapabilityById(\"agent.me\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<AgentDetail>(\"/api/agents/me\");\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"inbox\")\n .description(getAgentCliCapabilityById(\"agent.inbox\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<AgentInboxItem[]>(\"/api/agents/me/inbox-lite\")) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n identifier: row.identifier,\n id: row.id,\n relationship: row.relationship ?? \"assignee\",\n status: row.status,\n priority: row.priority,\n title: row.title,\n projectId: row.projectId,\n goalId: row.goalId,\n parentId: row.parentId,\n updatedAt: row.updatedAt,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"capabilities\")\n .description(getAgentCliCapabilityById(\"agent.capabilities\").description)\n .option(\"--contract <name>\", \"Capability subset to show (agent-v1 or all)\", \"agent-v1\")\n .action(async (opts: AgentCapabilitiesOptions) => {\n try {\n const contract = opts.contract === \"all\" ? \"all\" : \"agent-v1\";\n const capabilities = getAgentCliCapabilities().filter((entry) =>\n contract === \"all\" ? true : entry.contract === contract);\n\n if (opts.json) {\n printOutput(buildAgentCliCapabilitiesManifest(contract), { json: true });\n return;\n }\n\n console.log(formatAgentCliCapabilitiesHumanReadable(capabilities));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"agent.list\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<Agent[]>(`/api/orgs/${ctx.orgId}/agents`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n name: row.name,\n role: row.role,\n status: row.status,\n reportsTo: row.reportsTo,\n budgetMonthlyCents: row.budgetMonthlyCents,\n spentMonthlyCents: row.spentMonthlyCents,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n config\n .command(\"index\")\n .description(getAgentCliCapabilityById(\"agent.config.index\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const doc = await ctx.api.get<string>(\"/llms/agent-configuration.txt\");\n printOutput(doc ?? \"\", { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n config\n .command(\"doc\")\n .description(getAgentCliCapabilityById(\"agent.config.doc\").description)\n .argument(\"<agentRuntimeType>\", \"Agent runtime type\")\n .action(async (agentRuntimeType: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const doc = await ctx.api.get<string>(\n `/llms/agent-configuration/${encodeURIComponent(agentRuntimeType)}.txt`,\n );\n printOutput(doc ?? \"\", { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n config\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"agent.config.list\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows =\n (await ctx.api.get<AgentConfigurationRow[]>(`/api/orgs/${ctx.orgId}/agent-configurations`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n name: row.name,\n role: row.role,\n status: row.status,\n agentRuntimeType: row.agentRuntimeType,\n reportsTo: row.reportsTo,\n updatedAt: row.updatedAt,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n config\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"agent.config.get\").description)\n .argument(\"<agentId>\", \"Agent ID or shortname/url-key\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (agentId: string, opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const query = new URLSearchParams();\n if (ctx.orgId) query.set(\"orgId\", ctx.orgId);\n const row = await ctx.api.get<AgentConfigurationRow>(\n `/api/agents/${encodeURIComponent(agentId)}/configuration${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"icons\")\n .description(getAgentCliCapabilityById(\"agent.icons\").description)\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const doc = await ctx.api.get<string>(\"/llms/agent-icons.txt\");\n printOutput(doc ?? \"\", { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n const skills = agent.command(\"skills\").description(\"Agent skill selection operations\");\n\n addCommonClientOptions(\n skills\n .command(\"enable\")\n .description(getAgentCliCapabilityById(\"agent.skills.enable\").description)\n .argument(\"<agentId>\", \"Agent ID\")\n .argument(\"<selectionRefs...>\", \"Skill selection refs to enable\")\n .action(async (agentId: string, selectionRefs: string[], opts: AgentSkillEnableOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const snapshot = await ctx.api.post<AgentSkillSnapshot>(`/api/agents/${agentId}/skills/enable`, {\n skills: selectionRefs,\n });\n printOutput(snapshot, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n skills\n .command(\"sync\")\n .description(getAgentCliCapabilityById(\"agent.skills.sync\").description)\n .argument(\"<agentId>\", \"Agent ID\")\n .requiredOption(\n \"--desired-skills <csv>\",\n \"Comma-separated desired skill refs (for example rudder/rudder)\",\n )\n .action(async (agentId: string, opts: AgentSkillSyncOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const snapshot = await ctx.api.post<AgentSkillSnapshot>(`/api/agents/${agentId}/skills/sync`, {\n desiredSkills: parseCsv(opts.desiredSkills),\n });\n printOutput(snapshot, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"agent.get\").description)\n .argument(\"<agentId>\", \"Agent ID or shortname/url-key\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (agentId: string, opts: AgentListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const query = new URLSearchParams();\n if (ctx.orgId) query.set(\"orgId\", ctx.orgId);\n const row = await ctx.api.get<Agent>(\n `/api/agents/${encodeURIComponent(agentId)}${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n agent\n .command(\"hire\")\n .description(getAgentCliCapabilityById(\"agent.hire\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--payload <json>\", \"Hire payload as JSON object\")\n .action(async (opts: AgentHireOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payloadJson = parseJsonObject(opts.payload, \"payload\");\n const payload = createAgentHireSchema.parse(payloadJson);\n const created = await ctx.api.post<AgentHireResult>(`/api/orgs/${ctx.orgId}/agent-hires`, payload);\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n agent\n .command(\"local-cli\")\n .description(\n \"Create an agent API key, optionally install local Rudder skills for direct Codex/Claude CLI use, and print shell exports\",\n )\n .argument(\"<agentRef>\", \"Agent ID or shortname/url-key\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--key-name <name>\", \"API key label\", \"local-cli\")\n .option(\n \"--no-install-skills\",\n \"Skip the optional local Codex/Claude skill installation step\",\n )\n .action(async (agentRef: string, opts: AgentLocalCliOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const query = new URLSearchParams({ orgId: ctx.orgId ?? \"\" });\n const agentRow = await ctx.api.get<Agent>(\n `/api/agents/${encodeURIComponent(agentRef)}?${query.toString()}`,\n );\n if (!agentRow) {\n throw new Error(`Agent not found: ${agentRef}`);\n }\n\n const now = new Date().toISOString().replaceAll(\":\", \"-\");\n const keyName = opts.keyName?.trim() ? opts.keyName.trim() : `local-cli-${now}`;\n const key = await ctx.api.post<CreatedAgentKey>(`/api/agents/${agentRow.id}/keys`, { name: keyName });\n if (!key) {\n throw new Error(\"Failed to create API key\");\n }\n\n const installSummaries: SkillsInstallSummary[] = [];\n if (opts.installSkills !== false) {\n const skillsDir = await resolveRudderSkillsDir(__moduleDir, [path.resolve(process.cwd(), \"skills\")]);\n if (!skillsDir) {\n throw new Error(\n \"Could not locate local Rudder skills directory. Expected ./skills in the repo checkout.\",\n );\n }\n\n installSummaries.push(\n await installSkillsForTarget(skillsDir, codexSkillsHome(), \"codex\"),\n await installSkillsForTarget(skillsDir, claudeSkillsHome(), \"claude\"),\n );\n }\n\n const exportsText = buildAgentEnvExports({\n apiBase: ctx.api.apiBase,\n orgId: agentRow.orgId,\n agentId: agentRow.id,\n apiKey: key.token,\n });\n\n if (ctx.json) {\n printOutput(\n {\n agent: {\n id: agentRow.id,\n name: agentRow.name,\n urlKey: agentRow.urlKey,\n orgId: agentRow.orgId,\n },\n key: {\n id: key.id,\n name: key.name,\n createdAt: key.createdAt,\n token: key.token,\n },\n skills: installSummaries,\n exports: exportsText,\n },\n { json: true },\n );\n return;\n }\n\n console.log(`Agent: ${agentRow.name} (${agentRow.id})`);\n console.log(`API key created: ${key.name} (${key.id})`);\n if (installSummaries.length > 0) {\n for (const summary of installSummaries) {\n console.log(\n `${summary.tool}: linked=${summary.linked.length} removed=${summary.removed.length} skipped=${summary.skipped.length} failed=${summary.failed.length} target=${summary.target}`,\n );\n for (const failed of summary.failed) {\n console.log(` failed ${failed.name}: ${failed.error}`);\n }\n }\n }\n console.log(\"\");\n console.log(\"# Run this in your shell before launching codex/claude:\");\n console.log(exportsText);\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n\nfunction parseCsv(value: string | undefined): string[] {\n if (!value) return [];\n return value.split(\",\").map((entry) => entry.trim()).filter(Boolean);\n}\n\nfunction parseJsonObject(value: string, name: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(value) as unknown;\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${name} must be a JSON object`);\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n throw new Error(`Invalid ${name} JSON: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n", "import { createHash } from \"node:crypto\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { constants as fsConstants, promises as fs, type Dirent } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type {\n AgentRuntimeSkillEntry,\n AgentRuntimeSkillSnapshot,\n} from \"./types.js\";\n\nexport interface RunProcessResult {\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n stdout: string;\n stderr: string;\n pid: number | null;\n startedAt: string | null;\n}\n\ninterface RunningProcess {\n child: ChildProcess;\n graceSec: number;\n}\n\ninterface SpawnTarget {\n command: string;\n args: string[];\n}\n\ntype ChildProcessWithEvents = ChildProcess & {\n on(event: \"error\", listener: (err: Error) => void): ChildProcess;\n on(\n event: \"close\",\n listener: (code: number | null, signal: NodeJS.Signals | null) => void,\n ): ChildProcess;\n};\n\nexport const runningProcesses = new Map<string, RunningProcess>();\n\nfunction isChildProcessAlive(child: ChildProcessWithEvents): boolean {\n const pid = child.pid;\n if (typeof pid !== \"number\" || pid <= 0) return false;\n if (child.exitCode !== null || child.signalCode !== null) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n const code = error instanceof Error && \"code\" in error ? (error as NodeJS.ErrnoException).code : null;\n return code === \"EPERM\";\n }\n}\nexport const MAX_CAPTURE_BYTES = 4 * 1024 * 1024;\nexport const MAX_EXCERPT_BYTES = 32 * 1024;\nconst SENSITIVE_ENV_KEY = /(key|token|secret|password|passwd|authorization|cookie)/i;\nconst RUDDER_SKILL_ROOT_RELATIVE_CANDIDATES = [\n \"../../server/resources/bundled-skills\",\n \"../../skills\",\n \"../../../../../server/resources/bundled-skills\",\n];\nconst DEFAULT_LOCAL_CLI_CREDENTIAL_HOME_ENTRIES = [\n \".aws\",\n \".azure\",\n \".config/gh\",\n \".config/gcloud\",\n \".config/op\",\n \".config/vercel\",\n \".config/configstore\",\n \".docker\",\n \".fly\",\n \".git-credentials\",\n \".gnupg\",\n \".kube\",\n \".netrc\",\n \".npmrc\",\n \".ssh\",\n \".vercel\",\n \"Library/Application Support/gh\",\n \"Library/Application Support/com.heroku.cli\",\n] as const;\ntype LocalCliCredentialShimCommand = {\n command: string;\n authCheckArgs?: readonly string[];\n credentialEntries?: readonly string[];\n};\n\nconst DEFAULT_LOCAL_CLI_OPERATOR_HOME_SHIM_COMMANDS = [\n {\n command: \"gh\",\n authCheckArgs: [\"auth\", \"status\"],\n credentialEntries: [\".config/gh\", \"Library/Application Support/gh\"],\n },\n {\n command: \"vercel\",\n authCheckArgs: [\"whoami\"],\n credentialEntries: [\".config/vercel\", \".vercel\", \".config/configstore\"],\n },\n] as const satisfies readonly LocalCliCredentialShimCommand[];\n\nexport interface RudderSkillEntry {\n key: string;\n runtimeName: string;\n source: string;\n name: string | null;\n description: string | null;\n}\n\nexport interface InstalledSkillTarget {\n targetPath: string | null;\n kind: \"symlink\" | \"directory\" | \"file\";\n}\n\ninterface PersistentSkillSnapshotOptions {\n agentRuntimeType: string;\n availableEntries: RudderSkillEntry[];\n desiredSkills: string[];\n installed: Map<string, InstalledSkillTarget>;\n skillsHome: string;\n locationLabel?: string | null;\n installedDetail?: string | null;\n missingDetail: string;\n externalConflictDetail: string;\n externalDetail: string;\n warnings?: string[];\n}\n\nfunction normalizePathSlashes(value: string): string {\n return value.replaceAll(\"\\\\\", \"/\");\n}\n\nfunction isMaintainerOnlySkillTarget(candidate: string): boolean {\n const normalized = normalizePathSlashes(candidate);\n return (\n normalized.includes(\"/server/resources/bundled-skills/\")\n || normalized.includes(\"/.agents/skills/\")\n );\n}\n\nfunction skillLocationLabel(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction buildManagedSkillOrigin(): Pick<\n AgentRuntimeSkillEntry,\n \"origin\" | \"originLabel\" | \"readOnly\"\n> {\n return {\n origin: \"organization_managed\",\n readOnly: false,\n };\n}\n\nfunction compactSkillText(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") return null;\n const compacted = value\n .replace(/\\r\\n/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return compacted.length > 0 ? compacted : null;\n}\n\nfunction parseSkillFrontmatterMetadata(markdown: string): {\n name: string | null;\n description: string | null;\n} {\n const match = markdown.match(/^---\\n([\\s\\S]*?)\\n---(?:\\n|$)/);\n if (!match) {\n return { name: null, description: null };\n }\n\n const yaml = match[1];\n const nameMatch = yaml.match(/^name:\\s*[\"']?(.*?)[\"']?\\s*$/m);\n const descriptionMatch = yaml.match(\n /^description:\\s*(?:>\\s*\\n((?:\\s{2,}[^\\n]*\\n?)+)|[|]\\s*\\n((?:\\s{2,}[^\\n]*\\n?)+)|[\"']?(.*?)[\"']?\\s*$)/m,\n );\n\n return {\n name: compactSkillText(nameMatch?.[1] ?? null),\n description: compactSkillText(descriptionMatch?.[1] ?? descriptionMatch?.[2] ?? descriptionMatch?.[3] ?? null),\n };\n}\n\nasync function readSkillMetadataFromDirectory(skillDir: string): Promise<{\n name: string | null;\n description: string | null;\n}> {\n const skillFile = path.join(skillDir, \"SKILL.md\");\n try {\n const markdown = await fs.readFile(skillFile, \"utf8\");\n return parseSkillFrontmatterMetadata(markdown);\n } catch {\n return { name: null, description: null };\n }\n}\n\nexport async function readSkillMetadataFromPath(candidatePath: string | null | undefined): Promise<{\n name: string | null;\n description: string | null;\n}> {\n if (typeof candidatePath !== \"string\" || candidatePath.trim().length === 0) {\n return { name: null, description: null };\n }\n const resolvedPath = path.resolve(candidatePath);\n const skillDir = path.basename(resolvedPath).toLowerCase() === \"skill.md\"\n ? path.dirname(resolvedPath)\n : resolvedPath;\n return readSkillMetadataFromDirectory(skillDir);\n}\n\nfunction resolveInstalledEntryTarget(\n skillsHome: string,\n entryName: string,\n dirent: Dirent,\n linkedPath: string | null,\n): InstalledSkillTarget {\n const fullPath = path.join(skillsHome, entryName);\n if (dirent.isSymbolicLink()) {\n return {\n targetPath: linkedPath ? path.resolve(path.dirname(fullPath), linkedPath) : null,\n kind: \"symlink\",\n };\n }\n if (dirent.isDirectory()) {\n return { targetPath: fullPath, kind: \"directory\" };\n }\n return { targetPath: fullPath, kind: \"file\" };\n}\n\nexport function parseObject(value: unknown): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nexport function asString(value: unknown, fallback: string): string {\n return typeof value === \"string\" && value.length > 0 ? value : fallback;\n}\n\nexport function asNumber(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nexport function asBoolean(value: unknown, fallback: boolean): boolean {\n return typeof value === \"boolean\" ? value : fallback;\n}\n\nexport function asStringArray(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nexport function parseJson(value: string): Record<string, unknown> | null {\n try {\n return JSON.parse(value) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport function appendWithCap(prev: string, chunk: string, cap = MAX_CAPTURE_BYTES) {\n const combined = prev + chunk;\n return combined.length > cap ? combined.slice(combined.length - cap) : combined;\n}\n\nexport function resolvePathValue(obj: Record<string, unknown>, dottedPath: string) {\n const parts = dottedPath.split(\".\");\n let cursor: unknown = obj;\n\n for (const part of parts) {\n if (typeof cursor !== \"object\" || cursor === null || Array.isArray(cursor)) {\n return \"\";\n }\n cursor = (cursor as Record<string, unknown>)[part];\n }\n\n if (cursor === null || cursor === undefined) return \"\";\n if (typeof cursor === \"string\") return cursor;\n if (typeof cursor === \"number\" || typeof cursor === \"boolean\") return String(cursor);\n\n try {\n return JSON.stringify(cursor);\n } catch {\n return \"\";\n }\n}\n\nexport function renderTemplate(template: string, data: Record<string, unknown>) {\n return template.replace(/{{\\s*([a-zA-Z0-9_.-]+)\\s*}}/g, (_, path) => resolvePathValue(data, path));\n}\n\nconst ISSUE_DOCUMENT_PROMPT_BODY_CHAR_LIMIT = 16_000;\n\ntype IssueDocumentPromptInput = {\n planDocument?: {\n key?: string | null;\n title?: string | null;\n body?: string | null;\n issueId?: string | null;\n } | null;\n documentSummaries?: Array<{\n key?: string | null;\n title?: string | null;\n latestRevisionNumber?: number | null;\n updatedAt?: string | Date | null;\n issueId?: string | null;\n }> | null;\n legacyPlanDocument?: {\n key?: string | null;\n body?: string | null;\n source?: string | null;\n } | null;\n};\n\nfunction truncateIssueDocumentBody(body: string) {\n if (body.length <= ISSUE_DOCUMENT_PROMPT_BODY_CHAR_LIMIT) return body;\n return `${body.slice(0, ISSUE_DOCUMENT_PROMPT_BODY_CHAR_LIMIT).trimEnd()}\\n\\n[Document truncated in prompt. Fetch the full document with the Rudder CLI.]`;\n}\n\nfunction formatDocumentHeading(key: string, title?: string | null) {\n const cleanTitle = typeof title === \"string\" ? title.trim() : \"\";\n return cleanTitle ? `### ${key} \u2014 ${cleanTitle}` : `### ${key}`;\n}\n\nfunction readIssueDocumentPromptIssueId(input: IssueDocumentPromptInput) {\n const planIssueId = typeof input.planDocument?.issueId === \"string\" ? input.planDocument.issueId.trim() : \"\";\n if (planIssueId) return planIssueId;\n for (const summary of input.documentSummaries ?? []) {\n const issueId = typeof summary.issueId === \"string\" ? summary.issueId.trim() : \"\";\n if (issueId) return issueId;\n }\n return \"<issue-id>\";\n}\n\nexport function buildIssueDocumentsPrompt(input: IssueDocumentPromptInput | null | undefined) {\n if (!input) return \"\";\n\n const sections: string[] = [];\n const planKey = input.planDocument?.key?.trim() || input.legacyPlanDocument?.key?.trim() || \"plan\";\n const planBody = input.planDocument?.body?.trim() || input.legacyPlanDocument?.body?.trim() || \"\";\n if (planBody) {\n sections.push([\n formatDocumentHeading(planKey, input.planDocument?.title),\n input.legacyPlanDocument ? \"Source: legacy `<plan>` block in the issue description.\" : `Source: issue document \\`${planKey}\\`.`,\n \"\",\n truncateIssueDocumentBody(planBody),\n ].join(\"\\n\"));\n }\n\n const otherDocuments = (input.documentSummaries ?? []).filter((doc) => {\n const key = typeof doc.key === \"string\" ? doc.key.trim() : \"\";\n return key && key !== planKey;\n });\n if (otherDocuments.length > 0) {\n const issueId = readIssueDocumentPromptIssueId(input);\n sections.push([\n \"### Additional Issue Documents\",\n ...otherDocuments.map((doc) => {\n const key = doc.key?.trim() || \"document\";\n const title = doc.title?.trim();\n const revision = typeof doc.latestRevisionNumber === \"number\" ? `, revision ${doc.latestRevisionNumber}` : \"\";\n const titlePart = title ? ` \u2014 ${title}` : \"\";\n return `- \\`${key}\\`${titlePart}${revision}. Fetch with \\`rudder issue documents get ${issueId} ${key} --json\\`.`;\n }),\n ].join(\"\\n\"));\n }\n\n if (sections.length === 0) return \"\";\n return [\"## Issue Documents\", ...sections].join(\"\\n\\n\");\n}\n\n// Default prompt templates for different wake sources\nexport const DEFAULT_AGENT_PROMPT_TEMPLATE =\n `You are agent {{agent.id}} ({{agent.name}}). Continue your Rudder work.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n{{context.issueDocumentsPrompt}}`;\n\nexport const ISSUE_ASSIGN_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). You have been assigned to work on an issue.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Task Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n**Status:** {{issue.status}}\n**Priority:** {{issue.priority}}\n\n**Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\nYour task is to review this issue and begin working on it. Use the available tools to explore the codebase, understand the requirements, and implement a solution.`;\n\nexport const COMMENT_MENTION_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). You were mentioned in a comment and your attention is needed.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n\n**Issue Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\n**Comment:**\n{{comment.body}}\n\nPlease review the comment above and respond or take action as appropriate.`;\n\nexport const ISSUE_COMMENTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). There is a new comment on an issue you own.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n**Status:** {{issue.status}}\n\n**Issue Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\n**Latest Comment:**\n{{comment.body}}\n\nReview the new comment and continue the issue from the current state. Respond or take action as needed.`;\n\nexport const ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). A reviewer requested changes on an issue you own.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Context\n\n**Issue:** {{issue.title}}\n**ID:** {{issue.id}}\n**Status:** {{issue.status}}\n\n**Issue Description:**\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\n**Reviewer Comment:**\n{{comment.body}}\n\nReview the requested changes and continue the issue from the current state. Address the reviewer feedback before handing it back for review.`;\n\nexport const ISSUE_RECOVERY_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a recovery run, not a fresh task.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Recovery Context\n\n- Original Run ID: {{context.recovery.originalRunId}}\n- Failure Kind: {{context.recovery.failureKind}}\n- Failure Summary: {{context.recovery.failureSummary}}\n- Recovery Trigger: {{context.recovery.recoveryTrigger}}\n- Recovery Mode: {{context.recovery.recoveryMode}}\n\n## Current Issue Context\n\n- Issue: {{issue.title}}\n- ID: {{issue.id}}\n- Status: {{issue.status}}\n- Priority: {{issue.priority}}\n\n- Description:\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\nBefore doing anything else, inspect what the previous run already completed and any side effects it may have caused. Continue the remaining work from the current state. Avoid blindly re-running the whole task.`;\n\nexport const RECOVERY_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a recovery run, not a fresh task.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Recovery Context\n\n- Original Run ID: {{context.recovery.originalRunId}}\n- Failure Kind: {{context.recovery.failureKind}}\n- Failure Summary: {{context.recovery.failureSummary}}\n- Recovery Trigger: {{context.recovery.recoveryTrigger}}\n- Recovery Mode: {{context.recovery.recoveryMode}}\n\nBefore doing anything else, inspect what the previous run already completed and any side effects it may have caused. Continue the remaining work from the current state. Avoid blindly re-running the whole task.`;\n\nexport const ISSUE_PASSIVE_FOLLOWUP_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a passive issue follow-up, not a fresh assignment and not a failure recovery.\n\n{{context.rudderWorkspace.orgResourcesPrompt}}\n\n## Why You Were Woken\n\nThe previous run ended without sufficient issue close-out.\n\n- Origin Run ID: {{context.passiveFollowup.originRunId}}\n- Previous Run ID: {{context.passiveFollowup.previousRunId}}\n- Attempt: {{context.passiveFollowup.attempt}} / {{context.passiveFollowup.maxAttempts}}\nReason: {{context.passiveFollowup.reason}}\n\n## Current Issue Context\n\n- Issue: {{issue.title}}\n- ID: {{issue.id}}\n- Status: {{issue.status}}\n- Priority: {{issue.priority}}\n\n- Description:\n{{issue.description}}\n\n{{context.issueDocumentsPrompt}}\n\nBefore changing the issue, inspect the current issue state and any side effects from the previous run. Then do exactly one close-out action: add a progress comment, mark the issue done, block it with a reason, or hand it off explicitly with explanation.`;\n\n/**\n * Selects the base heartbeat prompt template used by runtimes before final prompt assembly.\n *\n * Prompt shape by wake trigger:\n * - assignment:\n * \"You are agent ... You have been assigned ...\"\n * Includes issue title/id/status/priority/description so the agent can start immediately.\n * - comment.mention:\n * \"You were mentioned in a comment ...\"\n * Includes issue summary plus mention comment body so the agent can respond without extra fetches.\n * - issue_changes_requested:\n * \"A reviewer requested changes on an issue you own ...\"\n * Includes issue summary plus reviewer comment body so the assignee can act on feedback immediately.\n * - issue_commented:\n * \"There is a new comment on an issue you own ...\"\n * Includes issue summary plus the newest comment body so the assignee can continue immediately.\n * - recovery:\n * \"This is a recovery run, not a fresh task ...\"\n * Includes original run id, failure metadata, and a continue-preferred instruction to\n * inspect prior progress/side effects before resuming.\n * - passive issue follow-up:\n * \"This is a passive issue follow-up, not a fresh assignment ...\"\n * Includes close-out lineage and tells the agent to comment, finish, block, or hand off.\n * - fallback:\n * Generic \"Continue your Rudder work.\"\n *\n * Concrete rendered example (comment mention):\n * \"You are agent agent-456 (Backend Worker). You were mentioned in a comment and your attention is needed.\n * Issue: Stabilize queue worker\n * Comment: @agent please check timeout handling in retry path.\"\n *\n * Reasoning:\n * - Keep backward compatibility: custom configured templates always win.\n * - Keep first-turn latency low: include the minimum task context directly in prompt text.\n * - Keep behavior deterministic across runtimes: template selection is centralized here.\n *\n * See also:\n * - doc/plans/2026-04-07-agent-prompt-context-injection.md\n * - doc/DEVELOPING.md\n */\nexport function selectPromptTemplate(\n configuredTemplate: string | undefined,\n context: Record<string, unknown>,\n): string {\n // If user configured a custom template, use it\n if (configuredTemplate?.trim()) {\n return configuredTemplate;\n }\n\n // Select based on wake source/reason\n const wakeSource = String(context.wakeSource ?? \"\");\n const wakeReason = String(context.wakeReason ?? \"\");\n const recovery = context.recovery;\n const hasRecoveryContext =\n typeof recovery === \"object\" &&\n recovery !== null &&\n !Array.isArray(recovery) &&\n typeof (recovery as Record<string, unknown>).originalRunId === \"string\";\n\n if (hasRecoveryContext || wakeReason === \"process_lost_retry\" || wakeReason === \"retry_failed_run\") {\n return typeof context.issue === \"object\" && context.issue !== null && !Array.isArray(context.issue)\n ? ISSUE_RECOVERY_PROMPT_TEMPLATE\n : RECOVERY_PROMPT_TEMPLATE;\n }\n if (wakeReason === \"issue_passive_followup\") {\n return ISSUE_PASSIVE_FOLLOWUP_PROMPT_TEMPLATE;\n }\n if (wakeReason === \"issue_changes_requested\") {\n return ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE;\n }\n if (wakeSource === \"assignment\" || wakeReason === \"issue_assigned\") {\n return ISSUE_ASSIGN_PROMPT_TEMPLATE;\n }\n if (wakeSource === \"comment.mention\" || wakeReason === \"issue_comment_mentioned\") {\n return COMMENT_MENTION_PROMPT_TEMPLATE;\n }\n if (wakeReason === \"issue_commented\") {\n return ISSUE_COMMENTED_PROMPT_TEMPLATE;\n }\n\n return DEFAULT_AGENT_PROMPT_TEMPLATE;\n}\n\nexport function joinPromptSections(\n sections: Array<string | null | undefined>,\n separator = \"\\n\\n\",\n) {\n return sections\n .map((value) => (typeof value === \"string\" ? value.trim() : \"\"))\n .filter(Boolean)\n .join(separator);\n}\n\nexport const RUDDER_AGENT_OPERATING_CONTRACT = [\n \"# Rudder Agent Operating Contract\",\n \"\",\n \"Your home directory is `$AGENT_HOME`. Everything personal to you -- life, memory, knowledge -- lives there. Other agents may have their own folders and you may update them when necessary.\",\n \"\",\n \"Use these paths consistently:\",\n \"\",\n \"- Personal instructions live under `$AGENT_HOME/instructions`.\",\n \"- Personal memory lives under `$AGENT_HOME/memory`.\",\n \"- Tacit memory instruction lives at `$AGENT_HOME/instructions/MEMORY.md` and is automatically loaded when present.\",\n \"- Personal skills live under `$AGENT_HOME/skills`.\",\n \"- Shared organization workspace root lives under `$RUDDER_ORG_WORKSPACE_ROOT`.\",\n \"- Shared organization skills live under `$RUDDER_ORG_SKILLS_DIR`.\",\n \"- Shared organization plans live under `$RUDDER_ORG_PLANS_DIR`.\",\n \"- Shared organization artifacts live under `$RUDDER_ORG_ARTIFACTS_DIR`.\",\n \"- Durable generated outputs such as screenshots, images, mockups, reports, CSVs, handoff logs, and other user-visible files should be written under `$RUDDER_ORG_ARTIFACTS_DIR` when available.\",\n \"- Use `/tmp` only for transient scratch files and temporary verification artifacts; do not put durable work product there.\",\n \"- Local trusted runtimes may expose the host operator home as `$RUDDER_OPERATOR_HOME`; use it only when a local skill or script intentionally needs operator-owned desktop app or CLI state. Do not replace `$HOME` with it.\",\n \"- Durable shared work output should prefer these managed workspace paths instead of ad-hoc top-level `projects/` folders.\",\n \"\",\n \"When you create or copy a skill under `$AGENT_HOME/skills/<slug>/`, check the agent's Skills snapshot before claiming it will load in future runs. If it is installed but not enabled, say exactly that future runs will not load it until enabled, and offer to enable it with `rudder agent skills enable <agent-id> <selection-ref>` when you have permission.\",\n \"\",\n \"When you write issue comments or chat replies, match the language of the user's or board's most recent substantive message unless they explicitly ask for a different language.\",\n \"\",\n \"When an issue comment, done comment, or blocker comment cites visual evidence from a local screenshot/image path, attach the image with the Rudder CLI `--image <path>` option instead of leaving only the filesystem path in the text.\",\n \"\",\n \"## Memory and Planning\",\n \"\",\n \"You MUST use the `para-memory-files` skill for all memory operations: storing facts, writing daily notes, creating entities, running weekly synthesis, recalling past context, and managing plans. The skill defines your three-layer memory system (knowledge graph, daily notes, tacit knowledge), the PARA folder structure, atomic fact schemas, memory decay rules, and recall/planning conventions.\",\n \"\",\n \"Keep stable preferences and operating lessons in `$AGENT_HOME/instructions/MEMORY.md`. Use `$AGENT_HOME/memory/YYYY-MM-DD.md` for daily notes and `$AGENT_HOME/life/` for structured long-term memory; those files are not auto-loaded.\",\n \"\",\n \"Invoke it whenever you need to remember, retrieve, or organize anything.\",\n \"\",\n \"## Safety Considerations\",\n \"\",\n \"- Never exfiltrate secrets or private data.\",\n \"- Do not perform any destructive commands unless explicitly requested by the board.\",\n].join(\"\\n\");\n\nexport interface LoadedAgentInstructionsPrefix {\n prefix: string;\n commandNotes: string[];\n instructionsFilePath: string;\n instructionsDir: string;\n soulFilePath: string | null;\n toolsFilePath: string | null;\n memoryFilePath: string | null;\n readFailed: boolean;\n metrics: {\n instructionsChars: number;\n operatingContractChars: number;\n instructionEntryChars: number;\n soulChars: number;\n toolsChars: number;\n memoryChars: number;\n };\n}\n\nfunction toPromptPath(pathValue: string): string {\n return pathValue.split(path.sep).join(\"/\");\n}\n\nfunction isInsidePath(parentPath: string, childPath: string): boolean {\n const relativePath = path.relative(parentPath, childPath);\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !path.isAbsolute(relativePath));\n}\n\nfunction displayInstructionPath(filePath: string, instructionsFilePath: string): string {\n const resolvedFilePath = path.resolve(filePath);\n const resolvedInstructionsPath = path.resolve(instructionsFilePath);\n const instructionsDir = path.dirname(resolvedInstructionsPath);\n if (path.basename(instructionsDir) === \"instructions\") {\n const agentHome = path.dirname(instructionsDir);\n if (isInsidePath(agentHome, resolvedFilePath)) {\n const relativePath = path.relative(agentHome, resolvedFilePath);\n return relativePath ? `$AGENT_HOME/${toPromptPath(relativePath)}` : \"$AGENT_HOME\";\n }\n }\n return filePath;\n}\n\nfunction displayInstructionDir(filePath: string, instructionsFilePath: string): string {\n const displayPath = displayInstructionPath(filePath, instructionsFilePath);\n const lastSlash = displayPath.lastIndexOf(\"/\");\n return lastSlash >= 0 ? `${displayPath.slice(0, lastSlash)}/` : \"\";\n}\n\nexport async function loadAgentInstructionsPrefix(input: {\n instructionsFilePath: string;\n onLog: (stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>;\n warningStream?: \"stdout\" | \"stderr\";\n}): Promise<LoadedAgentInstructionsPrefix> {\n const instructionsFilePath = input.instructionsFilePath.trim();\n const instructionsDir = instructionsFilePath ? `${path.dirname(instructionsFilePath)}/` : \"\";\n const displayInstructionsFilePath = instructionsFilePath\n ? displayInstructionPath(instructionsFilePath, instructionsFilePath)\n : \"\";\n const displayInstructionsDir = instructionsFilePath\n ? displayInstructionDir(instructionsFilePath, instructionsFilePath)\n : \"\";\n const warningStream = input.warningStream ?? \"stdout\";\n const operatingContractSection =\n `${RUDDER_AGENT_OPERATING_CONTRACT}\\n\\n` +\n \"The above Rudder agent operating contract was injected by Rudder at runtime.\";\n const empty = {\n prefix: operatingContractSection,\n commandNotes: [\"Loaded Rudder agent operating contract from runtime code\"],\n instructionsFilePath,\n instructionsDir,\n soulFilePath: null,\n toolsFilePath: null,\n memoryFilePath: null,\n readFailed: false,\n metrics: {\n instructionsChars: operatingContractSection.length,\n operatingContractChars: operatingContractSection.length,\n instructionEntryChars: 0,\n soulChars: 0,\n toolsChars: 0,\n memoryChars: 0,\n },\n } satisfies LoadedAgentInstructionsPrefix;\n\n if (!instructionsFilePath) return empty;\n\n const loadedPaths = new Set<string>();\n const commandNotes = [...empty.commandNotes];\n let entrySection = \"\";\n try {\n const instructionsContents = await fs.readFile(instructionsFilePath, \"utf8\");\n loadedPaths.add(path.resolve(instructionsFilePath));\n entrySection =\n `${instructionsContents}\\n\\n` +\n `The above agent instructions were loaded from ${displayInstructionsFilePath}. ` +\n `Resolve any relative file references from ${displayInstructionsDir}.`;\n await input.onLog(\n \"stdout\",\n `[rudder] Loaded agent instructions file: ${displayInstructionsFilePath}\\n`,\n );\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n await input.onLog(\n warningStream,\n `[rudder] Warning: could not read agent instructions file \"${instructionsFilePath}\": ${reason}\\n`,\n );\n commandNotes.push(\n `Configured instructionsFilePath ${displayInstructionsFilePath}, but file could not be read; continuing without injected instructions.`,\n );\n }\n\n async function loadSiblingInstructionFile(siblingInput: {\n fileName: string;\n label: string;\n logLabel: string;\n }): Promise<{ path: string | null; section: string }> {\n const filePath = path.join(path.dirname(instructionsFilePath), siblingInput.fileName);\n const resolvedPath = path.resolve(filePath);\n const displayFilePath = displayInstructionPath(filePath, instructionsFilePath);\n const displayFileDir = displayInstructionDir(filePath, instructionsFilePath);\n if (loadedPaths.has(resolvedPath)) return { path: filePath, section: \"\" };\n try {\n const contents = await fs.readFile(filePath, \"utf8\");\n loadedPaths.add(resolvedPath);\n await input.onLog(\n \"stdout\",\n `[rudder] Loaded ${siblingInput.logLabel}: ${displayFilePath}\\n`,\n );\n return {\n path: filePath,\n section:\n `${contents}\\n\\n` +\n `The above ${siblingInput.label} were loaded from ${displayFilePath}. ` +\n `Resolve any relative file references from ${displayFileDir}.`,\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n const reason = err instanceof Error ? err.message : String(err);\n await input.onLog(\n warningStream,\n `[rudder] Warning: could not read ${siblingInput.logLabel} \"${filePath}\": ${reason}\\n`,\n );\n }\n return { path: null, section: \"\" };\n }\n }\n\n const soul = await loadSiblingInstructionFile({\n fileName: \"SOUL.md\",\n label: \"agent role and persona instructions\",\n logLabel: \"agent soul instructions file\",\n });\n if (soul.section && soul.path) {\n commandNotes.push(`Loaded agent soul instructions from ${displayInstructionPath(soul.path, instructionsFilePath)}`);\n }\n\n const tools = await loadSiblingInstructionFile({\n fileName: \"TOOLS.md\",\n label: \"agent tool notes\",\n logLabel: \"agent tool notes file\",\n });\n if (tools.section && tools.path) {\n commandNotes.push(`Loaded agent tool notes from ${displayInstructionPath(tools.path, instructionsFilePath)}`);\n }\n\n const memory = await loadSiblingInstructionFile({\n fileName: \"MEMORY.md\",\n label: \"agent memory instructions\",\n logLabel: \"agent memory instructions file\",\n });\n if (memory.section && memory.path) {\n commandNotes.push(`Loaded agent memory instructions from ${displayInstructionPath(memory.path, instructionsFilePath)}`);\n }\n\n const memoryFilePath = memory.section ? memory.path : null;\n const memorySection = memory.section;\n if (entrySection) commandNotes.splice(1, 0, `Loaded agent instructions from ${displayInstructionsFilePath}`);\n\n const prefix = joinPromptSections([operatingContractSection, entrySection, soul.section, tools.section, memorySection]);\n return {\n prefix,\n commandNotes,\n instructionsFilePath,\n instructionsDir,\n soulFilePath: soul.section ? soul.path : null,\n toolsFilePath: tools.section ? tools.path : null,\n memoryFilePath,\n readFailed: !entrySection,\n metrics: {\n instructionsChars: prefix.length,\n operatingContractChars: operatingContractSection.length,\n instructionEntryChars: entrySection.length,\n soulChars: soul.section.length,\n toolsChars: tools.section.length,\n memoryChars: memorySection.length,\n },\n };\n}\n\nexport function redactEnvForLogs(env: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n redacted[key] = SENSITIVE_ENV_KEY.test(key) ? \"***REDACTED***\" : value;\n }\n return redacted;\n}\n\nexport function buildRudderEnv(agent: { id: string; orgId: string }): Record<string, string> {\n const resolveHostForUrl = (rawHost: string): string => {\n const host = rawHost.trim();\n if (!host || host === \"0.0.0.0\" || host === \"::\") return \"localhost\";\n if (host.includes(\":\") && !host.startsWith(\"[\") && !host.endsWith(\"]\")) return `[${host}]`;\n return host;\n };\n const vars: Record<string, string> = {\n RUDDER_AGENT_ID: agent.id,\n RUDDER_ORG_ID: agent.orgId,\n };\n const runtimeHost = resolveHostForUrl(\n process.env.RUDDER_LISTEN_HOST ?? process.env.HOST ?? \"localhost\",\n );\n const runtimePort = process.env.RUDDER_LISTEN_PORT ?? process.env.PORT ?? \"3100\";\n const apiUrl = process.env.RUDDER_API_URL ?? `http://${runtimeHost}:${runtimePort}`;\n vars.RUDDER_API_URL = apiUrl;\n return vars;\n}\n\nexport function defaultPathForPlatform() {\n if (process.platform === \"win32\") {\n return \"C:\\\\Windows\\\\System32;C:\\\\Windows;C:\\\\Windows\\\\System32\\\\Wbem\";\n }\n return \"/usr/local/bin:/opt/homebrew/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin\";\n}\n\nfunction windowsPathExts(env: NodeJS.ProcessEnv): string[] {\n return (env.PATHEXT ?? \".EXE;.CMD;.BAT;.COM\").split(\";\").filter(Boolean);\n}\n\nasync function pathExists(candidate: string) {\n try {\n await fs.access(candidate, process.platform === \"win32\" ? fsConstants.F_OK : fsConstants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function fileExists(candidate: string) {\n try {\n await fs.access(candidate, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function resolveCommandPath(command: string, cwd: string, env: NodeJS.ProcessEnv): Promise<string | null> {\n const hasPathSeparator = command.includes(\"/\") || command.includes(\"\\\\\");\n if (hasPathSeparator) {\n const absolute = path.isAbsolute(command) ? command : path.resolve(cwd, command);\n return (await pathExists(absolute)) ? absolute : null;\n }\n\n const pathValue = env.PATH ?? env.Path ?? \"\";\n const delimiter = process.platform === \"win32\" ? \";\" : \":\";\n const dirs = pathValue.split(delimiter).filter(Boolean);\n const exts = process.platform === \"win32\" ? windowsPathExts(env) : [\"\"];\n const hasExtension = process.platform === \"win32\" && path.extname(command).length > 0;\n\n for (const dir of dirs) {\n const candidates =\n process.platform === \"win32\"\n ? hasExtension\n ? [path.join(dir, command)]\n : exts.map((ext) => path.join(dir, `${command}${ext}`))\n : [path.join(dir, command)];\n for (const candidate of candidates) {\n if (await pathExists(candidate)) return candidate;\n }\n }\n\n return null;\n}\n\nfunction quoteForCmd(arg: string) {\n if (!arg.length) return '\"\"';\n const escaped = arg.replace(/\"/g, '\"\"');\n return /[\\s\"&<>|^()]/.test(escaped) ? `\"${escaped}\"` : escaped;\n}\n\nasync function resolveSpawnTarget(\n command: string,\n args: string[],\n cwd: string,\n env: NodeJS.ProcessEnv,\n): Promise<SpawnTarget> {\n const resolved = await resolveCommandPath(command, cwd, env);\n const executable = resolved ?? command;\n\n if (process.platform !== \"win32\") {\n return { command: executable, args };\n }\n\n if (/\\.(cmd|bat)$/i.test(executable)) {\n const shell = env.ComSpec || process.env.ComSpec || \"cmd.exe\";\n const commandLine = [quoteForCmd(executable), ...args.map(quoteForCmd)].join(\" \");\n return {\n command: shell,\n args: [\"/d\", \"/s\", \"/c\", commandLine],\n };\n }\n\n return { command: executable, args };\n}\n\nexport function ensurePathInEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n if (typeof env.PATH === \"string\" && env.PATH.length > 0) return env;\n if (typeof env.Path === \"string\" && env.Path.length > 0) return env;\n return { ...env, PATH: defaultPathForPlatform() };\n}\n\nfunction prependPathEntry(env: NodeJS.ProcessEnv, entry: string): NodeJS.ProcessEnv {\n const normalized = ensurePathInEnv(env);\n const pathKey = typeof normalized.PATH === \"string\" ? \"PATH\" : \"Path\";\n const current = normalized[pathKey] ?? \"\";\n const delimiter = process.platform === \"win32\" ? \";\" : \":\";\n const segments = current.split(delimiter).filter(Boolean);\n if (segments.includes(entry)) return normalized;\n return {\n ...normalized,\n [pathKey]: current.length > 0 ? `${entry}${delimiter}${current}` : entry,\n };\n}\n\nasync function findAncestorWithFile(\n startDir: string,\n relativePath: string,\n maxDepth = 12,\n): Promise<string | null> {\n let current = path.resolve(startDir);\n for (let depth = 0; depth <= maxDepth; depth += 1) {\n const candidate = path.join(current, relativePath);\n if (await fileExists(candidate)) return candidate;\n const parent = path.dirname(current);\n if (parent === current) break;\n current = parent;\n }\n return null;\n}\n\nfunction shellQuote(arg: string): string {\n return `'${arg.replace(/'/g, `'\\\\''`)}'`;\n}\n\nasync function resolveRudderCliShimTarget(moduleDir: string): Promise<SpawnTarget | null> {\n const packagedCli = await findAncestorWithFile(moduleDir, \"desktop-cli.js\");\n if (packagedCli) {\n return {\n command: process.execPath,\n args: [packagedCli],\n };\n }\n\n const repoRoot = await findAncestorWithFile(moduleDir, path.join(\"cli\", \"src\", \"index.ts\"));\n if (!repoRoot) return null;\n const rootDir = path.dirname(path.dirname(path.dirname(repoRoot)));\n const tsxEntry = path.join(rootDir, \"cli\", \"node_modules\", \"tsx\", \"dist\", \"cli.mjs\");\n const cliSource = path.join(rootDir, \"cli\", \"src\", \"index.ts\");\n if (await fileExists(tsxEntry)) {\n return {\n command: process.execPath,\n args: [tsxEntry, cliSource],\n };\n }\n\n const builtCliEntry = path.join(rootDir, \"cli\", \"dist\", \"index.js\");\n if (await fileExists(builtCliEntry)) {\n return {\n command: process.execPath,\n args: [builtCliEntry],\n };\n }\n\n return null;\n}\n\nasync function materializeRudderCliShim(target: SpawnTarget): Promise<string> {\n const hash = createHash(\"sha1\")\n .update(JSON.stringify({ command: target.command, args: target.args, platform: process.platform }))\n .digest(\"hex\")\n .slice(0, 12);\n const shimDir = path.join(os.tmpdir(), \"rudder-cli-shims\", hash);\n await fs.mkdir(shimDir, { recursive: true });\n\n if (process.platform === \"win32\") {\n const shimPath = path.join(shimDir, \"rudder.cmd\");\n const commandLine = [quoteForCmd(target.command), ...target.args.map(quoteForCmd), \"%*\"].join(\" \");\n await fs.writeFile(shimPath, `@echo off\\r\\n${commandLine}\\r\\n`, \"utf8\");\n return shimPath;\n }\n\n const shimPath = path.join(shimDir, \"rudder\");\n const commandLine = [target.command, ...target.args].map(shellQuote).join(\" \");\n await fs.writeFile(shimPath, `#!/bin/sh\\nexec ${commandLine} \"$@\"\\n`, \"utf8\");\n await fs.chmod(shimPath, 0o755);\n return shimPath;\n}\n\nexport async function ensureRudderCliInPath(\n moduleDir: string,\n env: NodeJS.ProcessEnv,\n): Promise<NodeJS.ProcessEnv> {\n const normalized = ensurePathInEnv(env);\n const target = await resolveRudderCliShimTarget(moduleDir);\n if (!target) {\n return normalized;\n }\n\n const shimPath = await materializeRudderCliShim(target);\n return prependPathEntry(normalized, path.dirname(shimPath));\n}\n\nexport async function ensureAbsoluteDirectory(\n cwd: string,\n opts: { createIfMissing?: boolean } = {},\n) {\n if (!path.isAbsolute(cwd)) {\n throw new Error(`Working directory must be an absolute path: \"${cwd}\"`);\n }\n\n const assertDirectory = async () => {\n const stats = await fs.stat(cwd);\n if (!stats.isDirectory()) {\n throw new Error(`Working directory is not a directory: \"${cwd}\"`);\n }\n };\n\n try {\n await assertDirectory();\n return;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (!opts.createIfMissing || code !== \"ENOENT\") {\n if (code === \"ENOENT\") {\n throw new Error(`Working directory does not exist: \"${cwd}\"`);\n }\n throw err instanceof Error ? err : new Error(String(err));\n }\n }\n\n try {\n await fs.mkdir(cwd, { recursive: true });\n await assertDirectory();\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n throw new Error(`Could not create working directory \"${cwd}\": ${reason}`);\n }\n}\n\nexport async function resolveRudderSkillsDir(\n moduleDir: string,\n additionalCandidates: string[] = [],\n): Promise<string | null> {\n const candidates = [\n ...RUDDER_SKILL_ROOT_RELATIVE_CANDIDATES.map((relativePath) => path.resolve(moduleDir, relativePath)),\n ...additionalCandidates.map((candidate) => path.resolve(candidate)),\n ];\n const seenRoots = new Set<string>();\n\n for (const root of candidates) {\n if (seenRoots.has(root)) continue;\n seenRoots.add(root);\n const isDirectory = await fs.stat(root).then((stats) => stats.isDirectory()).catch(() => false);\n if (isDirectory) return root;\n }\n\n return null;\n}\n\nexport async function listRudderSkillEntries(\n moduleDir: string,\n additionalCandidates: string[] = [],\n): Promise<RudderSkillEntry[]> {\n const root = await resolveRudderSkillsDir(moduleDir, additionalCandidates);\n if (!root) return [];\n\n try {\n const entries = await fs.readdir(root, { withFileTypes: true });\n const skillDirectories = entries\n .filter((entry) => entry.isDirectory())\n .sort((left, right) => left.name.localeCompare(right.name));\n const skillEntries = await Promise.all(\n skillDirectories.map(async (entry) => {\n const source = path.join(root, entry.name);\n const metadata = await readSkillMetadataFromDirectory(source);\n return {\n key: `rudder/${entry.name}`,\n runtimeName: entry.name,\n source,\n name: metadata.name ?? entry.name,\n description: metadata.description,\n };\n }),\n );\n return skillEntries;\n } catch {\n return [];\n }\n}\n\nexport async function readInstalledSkillTargets(skillsHome: string): Promise<Map<string, InstalledSkillTarget>> {\n const entries = await fs.readdir(skillsHome, { withFileTypes: true }).catch(() => []);\n const out = new Map<string, InstalledSkillTarget>();\n for (const entry of entries) {\n const fullPath = path.join(skillsHome, entry.name);\n const linkedPath = entry.isSymbolicLink() ? await fs.readlink(fullPath).catch(() => null) : null;\n out.set(entry.name, resolveInstalledEntryTarget(skillsHome, entry.name, entry, linkedPath));\n }\n return out;\n}\n\nexport function buildPersistentSkillSnapshot(\n options: PersistentSkillSnapshotOptions,\n): AgentRuntimeSkillSnapshot {\n const {\n agentRuntimeType,\n availableEntries,\n desiredSkills,\n installed,\n skillsHome,\n locationLabel,\n installedDetail,\n missingDetail,\n externalConflictDetail,\n externalDetail,\n } = options;\n const availableByKey = new Map(availableEntries.map((entry) => [entry.key, entry]));\n const desiredSet = new Set(desiredSkills);\n const entries: AgentRuntimeSkillEntry[] = [];\n const warnings = [...(options.warnings ?? [])];\n\n for (const available of availableEntries) {\n const installedEntry = installed.get(available.runtimeName) ?? null;\n const desired = desiredSet.has(available.key);\n let state: AgentRuntimeSkillEntry[\"state\"] = \"available\";\n let managed = false;\n let detail: string | null = null;\n\n if (installedEntry?.targetPath === available.source) {\n managed = true;\n state = desired ? \"installed\" : \"stale\";\n detail = installedDetail ?? null;\n } else if (installedEntry) {\n state = \"external\";\n detail = desired ? externalConflictDetail : externalDetail;\n } else if (desired) {\n state = \"missing\";\n detail = missingDetail;\n }\n\n entries.push({\n key: available.key,\n runtimeName: available.runtimeName,\n description: available.description ?? null,\n desired,\n managed,\n state,\n sourcePath: available.source,\n targetPath: path.join(skillsHome, available.runtimeName),\n detail,\n ...buildManagedSkillOrigin(),\n });\n }\n\n for (const desiredSkill of desiredSkills) {\n if (availableByKey.has(desiredSkill)) continue;\n warnings.push(`Desired skill \"${desiredSkill}\" is not available from the Rudder skills directory.`);\n entries.push({\n key: desiredSkill,\n runtimeName: null,\n desired: true,\n managed: true,\n state: \"missing\",\n sourcePath: null,\n targetPath: null,\n detail: \"Rudder cannot find this skill in the local runtime skills directory.\",\n origin: \"external_unknown\",\n originLabel: \"External or unavailable\",\n readOnly: false,\n });\n }\n\n for (const [name, installedEntry] of installed.entries()) {\n if (availableEntries.some((entry) => entry.runtimeName === name)) continue;\n entries.push({\n key: name,\n runtimeName: name,\n description: null,\n desired: false,\n managed: false,\n state: \"external\",\n origin: \"user_installed\",\n originLabel: \"User-installed\",\n locationLabel: skillLocationLabel(locationLabel),\n readOnly: true,\n sourcePath: null,\n targetPath: installedEntry.targetPath ?? path.join(skillsHome, name),\n detail: externalDetail,\n });\n }\n\n entries.sort((left, right) => left.key.localeCompare(right.key));\n\n return {\n agentRuntimeType,\n supported: true,\n mode: \"persistent\",\n desiredSkills,\n entries,\n warnings,\n };\n}\n\nfunction normalizeConfiguredPaperclipRuntimeSkills(value: unknown): RudderSkillEntry[] {\n if (!Array.isArray(value)) return [];\n const out: RudderSkillEntry[] = [];\n for (const rawEntry of value) {\n const entry = parseObject(rawEntry);\n const key = asString(entry.key, asString(entry.name, \"\")).trim();\n const runtimeName = asString(entry.runtimeName, asString(entry.name, \"\")).trim();\n const source = asString(entry.source, \"\").trim();\n if (!key || !runtimeName || !source) continue;\n out.push({\n key,\n runtimeName,\n source,\n name: compactSkillText(asString(entry.displayName, asString(entry.name, \"\"))) ?? runtimeName,\n description: compactSkillText(\n typeof entry.description === \"string\"\n ? entry.description\n : typeof entry.summary === \"string\"\n ? entry.summary\n : null,\n ),\n });\n }\n return out;\n}\n\nexport async function readRudderRuntimeSkillEntries(\n config: Record<string, unknown>,\n moduleDir: string,\n additionalCandidates: string[] = [],\n): Promise<RudderSkillEntry[]> {\n const configuredEntries = normalizeConfiguredPaperclipRuntimeSkills(\n config.rudderRuntimeSkills ?? config.paperclipRuntimeSkills,\n );\n if (configuredEntries.length > 0) return configuredEntries;\n return listRudderSkillEntries(moduleDir, additionalCandidates);\n}\n\nexport async function readRudderSkillMarkdown(\n moduleDir: string,\n skillKey: string,\n): Promise<string | null> {\n const normalized = skillKey.trim().toLowerCase().replace(/^rudder\\/rudder\\//, \"rudder/\");\n if (!normalized) return null;\n\n const entries = await listRudderSkillEntries(moduleDir);\n const match = entries.find((entry) => entry.key === normalized);\n if (!match) return null;\n\n try {\n return await fs.readFile(path.join(match.source, \"SKILL.md\"), \"utf8\");\n } catch {\n return null;\n }\n}\n\nexport function readRudderSkillSyncPreference(config: Record<string, unknown>): {\n explicit: boolean;\n desiredSkills: string[];\n} {\n const raw = config.rudderSkillSync ?? config.paperclipSkillSync;\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n return { explicit: false, desiredSkills: [] };\n }\n const syncConfig = raw as Record<string, unknown>;\n const desiredValues = syncConfig.desiredSkills;\n const desired = Array.isArray(desiredValues)\n ? desiredValues\n .filter((value): value is string => typeof value === \"string\")\n .map((value) => value.trim())\n .filter(Boolean)\n : [];\n return {\n explicit: Object.prototype.hasOwnProperty.call(raw, \"desiredSkills\"),\n desiredSkills: Array.from(new Set(desired)),\n };\n}\n\nfunction canonicalizeDesiredRudderSkillReference(\n reference: string,\n availableEntries: Array<{ key: string; runtimeName?: string | null }>,\n): string {\n const normalizedReference = reference.trim().toLowerCase().replace(/^rudder\\/rudder\\//, \"rudder/\");\n if (!normalizedReference) return \"\";\n\n const exactKey = availableEntries.find((entry) => entry.key.trim().toLowerCase() === normalizedReference);\n if (exactKey) return exactKey.key;\n\n const byRuntimeName = availableEntries.filter((entry) =>\n typeof entry.runtimeName === \"string\" && entry.runtimeName.trim().toLowerCase() === normalizedReference,\n );\n if (byRuntimeName.length === 1) return byRuntimeName[0]!.key;\n\n const slugMatches = availableEntries.filter((entry) =>\n entry.key.trim().toLowerCase().split(\"/\").pop() === normalizedReference,\n );\n if (slugMatches.length === 1) return slugMatches[0]!.key;\n\n return normalizedReference;\n}\n\nexport function resolveRudderDesiredSkillNames(\n config: Record<string, unknown>,\n availableEntries: Array<{ key: string; runtimeName?: string | null }>,\n): string[] {\n const preference = readRudderSkillSyncPreference(config);\n const desiredSkills = preference.desiredSkills\n .map((reference) => canonicalizeDesiredRudderSkillReference(reference, availableEntries))\n .filter(Boolean);\n return Array.from(new Set(desiredSkills));\n}\n\nexport function writeRudderSkillSyncPreference(\n config: Record<string, unknown>,\n desiredSkills: string[],\n): Record<string, unknown> {\n const next = { ...config };\n const raw = next.rudderSkillSync;\n const current =\n typeof raw === \"object\" && raw !== null && !Array.isArray(raw)\n ? { ...(raw as Record<string, unknown>) }\n : {};\n current.desiredSkills = Array.from(\n new Set(\n desiredSkills\n .map((value) => value.trim())\n .filter(Boolean),\n ),\n );\n next.rudderSkillSync = current;\n return next;\n}\n\nfunction nonEmptyEnvPath(value: string | undefined): string | null {\n return typeof value === \"string\" && value.trim().length > 0 ? path.resolve(value.trim()) : null;\n}\n\nexport function resolveLocalOperatorHome(sourceEnv: NodeJS.ProcessEnv = process.env): string {\n return (\n nonEmptyEnvPath(sourceEnv.RUDDER_OPERATOR_HOME)\n ?? nonEmptyEnvPath(process.env.RUDDER_OPERATOR_HOME)\n ?? nonEmptyEnvPath(process.env.HOME)\n ?? nonEmptyEnvPath(sourceEnv.HOME)\n ?? path.resolve(os.homedir())\n );\n}\n\nexport function applyLocalCliHomeEnv(\n targetEnv: Record<string, string>,\n sourceEnv: NodeJS.ProcessEnv = process.env,\n): void {\n const home = nonEmptyEnvPath(sourceEnv.HOME) ?? path.resolve(os.homedir());\n targetEnv.HOME = home;\n\n const userProfile = nonEmptyEnvPath(sourceEnv.USERPROFILE);\n if (userProfile) {\n targetEnv.USERPROFILE = userProfile;\n } else if (process.platform === \"win32\") {\n targetEnv.USERPROFILE = home;\n }\n}\n\nasync function localCliPathExists(candidate: string): Promise<boolean> {\n return fs.access(candidate).then(() => true).catch(() => false);\n}\n\nasync function directoryIsEmpty(target: string): Promise<boolean> {\n const entries = await fs.readdir(target).catch(() => null);\n return Array.isArray(entries) && entries.length === 0;\n}\n\nasync function ensureSymlinkToSource(target: string, source: string): Promise<\"created\" | \"repaired\" | \"skipped\"> {\n const existing = await fs.lstat(target).catch(() => null);\n if (!existing) {\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.symlink(source, target);\n return \"created\";\n }\n\n if (!existing.isSymbolicLink()) {\n if (existing.isDirectory() && await directoryIsEmpty(target)) {\n await fs.rmdir(target);\n await fs.symlink(source, target);\n return \"repaired\";\n }\n return \"skipped\";\n }\n\n const linkedPath = await fs.readlink(target).catch(() => null);\n if (!linkedPath) return \"skipped\";\n\n const resolvedLinkedPath = path.isAbsolute(linkedPath)\n ? linkedPath\n : path.resolve(path.dirname(target), linkedPath);\n if (resolvedLinkedPath === source) return \"skipped\";\n\n await fs.unlink(target);\n await fs.symlink(source, target);\n return \"repaired\";\n}\n\nexport async function syncLocalCliCredentialHomeEntries(input: {\n sourceHome?: string | null;\n targetHome: string;\n entries?: readonly string[];\n onLog?: ((stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>) | null;\n}): Promise<{ linked: string[]; skipped: string[] }> {\n const sourceHome = nonEmptyEnvPath(input.sourceHome ?? undefined) ?? path.resolve(os.homedir());\n const targetHome = path.resolve(input.targetHome);\n const linked: string[] = [];\n const skipped: string[] = [];\n if (sourceHome === targetHome) return { linked, skipped };\n\n const entries = input.entries ?? DEFAULT_LOCAL_CLI_CREDENTIAL_HOME_ENTRIES;\n for (const relativeEntry of entries) {\n const source = path.join(sourceHome, relativeEntry);\n if (!(await localCliPathExists(source))) continue;\n\n const target = path.join(targetHome, relativeEntry);\n try {\n const result = await ensureSymlinkToSource(target, source);\n if (result === \"skipped\") skipped.push(relativeEntry);\n else linked.push(relativeEntry);\n } catch {\n skipped.push(relativeEntry);\n }\n }\n\n if (input.onLog && linked.length > 0) {\n await input.onLog(\n \"stdout\",\n `[rudder] Shared ${linked.length} local CLI credential entr${linked.length === 1 ? \"y\" : \"ies\"} into managed HOME ${targetHome}: ${linked.join(\", \")}\\n`,\n );\n }\n\n return { linked, skipped };\n}\n\nasync function writeOperatorHomeShim(input: {\n shimDir: string;\n command: string;\n targetCommand: string;\n operatorHome: string;\n}): Promise<string> {\n await fs.mkdir(input.shimDir, { recursive: true });\n\n if (process.platform === \"win32\") {\n const shimPath = path.join(input.shimDir, `${input.command}.cmd`);\n const lines = [\n \"@echo off\",\n `set \"HOME=${input.operatorHome}\"`,\n `set \"USERPROFILE=${input.operatorHome}\"`,\n `${quoteForCmd(input.targetCommand)} %*`,\n \"\",\n ];\n await fs.writeFile(shimPath, lines.join(\"\\r\\n\"), \"utf8\");\n return shimPath;\n }\n\n const shimPath = path.join(input.shimDir, input.command);\n await fs.writeFile(\n shimPath,\n [\n \"#!/bin/sh\",\n `export HOME=${shellQuote(input.operatorHome)}`,\n `export USERPROFILE=${shellQuote(input.operatorHome)}`,\n `exec ${shellQuote(input.targetCommand)} \"$@\"`,\n \"\",\n ].join(\"\\n\"),\n \"utf8\",\n );\n await fs.chmod(shimPath, 0o755);\n return shimPath;\n}\n\nfunction normalizeShimCommand(input: string | LocalCliCredentialShimCommand): LocalCliCredentialShimCommand {\n return typeof input === \"string\" ? { command: input } : input;\n}\n\nasync function runCredentialShimAuthCheck(input: {\n targetCommand: string;\n args: readonly string[];\n cwd: string;\n env: NodeJS.ProcessEnv;\n home: string;\n}): Promise<boolean> {\n const env = {\n ...input.env,\n HOME: input.home,\n USERPROFILE: input.home,\n };\n return await new Promise<boolean>((resolve) => {\n const child = spawn(input.targetCommand, [...input.args], {\n cwd: input.cwd,\n env,\n stdio: [\"ignore\", \"ignore\", \"ignore\"],\n });\n const timeout = setTimeout(() => {\n child.kill(\"SIGTERM\");\n resolve(false);\n }, 1000);\n child.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(false);\n });\n child.on(\"close\", (code) => {\n clearTimeout(timeout);\n resolve(code === 0);\n });\n });\n}\n\nasync function credentialBridgeSatisfied(input: {\n operatorHome: string;\n targetHome: string;\n entries: readonly string[];\n}): Promise<boolean> {\n for (const entry of input.entries) {\n const source = path.join(input.operatorHome, entry);\n const target = path.join(input.targetHome, entry);\n if (!(await localCliPathExists(source)) || !(await localCliPathExists(target))) continue;\n const [sourceRealpath, targetRealpath] = await Promise.all([\n fs.realpath(source).catch(() => null),\n fs.realpath(target).catch(() => null),\n ]);\n if (sourceRealpath && targetRealpath && sourceRealpath === targetRealpath) return true;\n }\n return false;\n}\n\nasync function shouldPrepareOperatorHomeShim(input: {\n command: LocalCliCredentialShimCommand;\n targetCommand: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n targetHome: string;\n operatorHome: string;\n}): Promise<boolean> {\n const authCheckArgs = input.command.authCheckArgs;\n if (!authCheckArgs || authCheckArgs.length === 0) return true;\n\n if (input.command.credentialEntries && input.command.credentialEntries.length > 0) {\n const hasOperatorCredentialEntry = await Promise.all(\n input.command.credentialEntries.map((entry) => localCliPathExists(path.join(input.operatorHome, entry))),\n );\n if (!hasOperatorCredentialEntry.some(Boolean)) return false;\n if (await credentialBridgeSatisfied({\n operatorHome: input.operatorHome,\n targetHome: input.targetHome,\n entries: input.command.credentialEntries,\n })) {\n return false;\n }\n }\n\n const managedHomeWorks = await runCredentialShimAuthCheck({\n targetCommand: input.targetCommand,\n args: authCheckArgs,\n cwd: input.cwd,\n env: input.env,\n home: input.targetHome,\n });\n if (managedHomeWorks) return false;\n\n return await runCredentialShimAuthCheck({\n targetCommand: input.targetCommand,\n args: authCheckArgs,\n cwd: input.cwd,\n env: input.env,\n home: input.operatorHome,\n });\n}\n\nexport async function ensureLocalCliCredentialShimsInPath(input: {\n operatorHome?: string | null;\n targetHome: string;\n env: NodeJS.ProcessEnv;\n cwd?: string;\n commands?: readonly (string | LocalCliCredentialShimCommand)[];\n onLog?: ((stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>) | null;\n}): Promise<NodeJS.ProcessEnv> {\n const operatorHome = nonEmptyEnvPath(input.operatorHome ?? undefined);\n const targetHome = nonEmptyEnvPath(input.targetHome);\n if (!operatorHome || !targetHome || operatorHome === targetHome) {\n return ensurePathInEnv(input.env);\n }\n\n const normalized = ensurePathInEnv(input.env);\n const cwd = input.cwd ?? process.cwd();\n const commands = input.commands ?? DEFAULT_LOCAL_CLI_OPERATOR_HOME_SHIM_COMMANDS;\n const shimDir = path.join(targetHome, \".rudder\", \"local-cli-shims\");\n const prepared: string[] = [];\n\n for (const rawCommand of commands) {\n const command = normalizeShimCommand(rawCommand);\n const targetCommand = await resolveCommandPath(command.command, cwd, normalized);\n if (!targetCommand) continue;\n if (path.dirname(targetCommand) === shimDir) continue;\n if (!(await shouldPrepareOperatorHomeShim({\n command,\n targetCommand,\n cwd,\n env: normalized,\n targetHome,\n operatorHome,\n }))) {\n continue;\n }\n await writeOperatorHomeShim({ shimDir, command: command.command, targetCommand, operatorHome });\n prepared.push(command.command);\n }\n\n if (prepared.length === 0) return normalized;\n if (input.onLog) {\n await input.onLog(\n \"stdout\",\n `[rudder] Prepared local CLI credential shim${prepared.length === 1 ? \"\" : \"s\"} for: ${prepared.join(\", \")}\\n`,\n );\n }\n return prependPathEntry(normalized, shimDir);\n}\n\nexport async function ensureRudderSkillSymlink(\n source: string,\n target: string,\n linkSkill: (source: string, target: string) => Promise<void> = (linkSource, linkTarget) =>\n fs.symlink(linkSource, linkTarget),\n): Promise<\"created\" | \"repaired\" | \"skipped\"> {\n const existing = await fs.lstat(target).catch(() => null);\n if (!existing) {\n await linkSkill(source, target);\n return \"created\";\n }\n\n if (!existing.isSymbolicLink()) {\n return \"skipped\";\n }\n\n const linkedPath = await fs.readlink(target).catch(() => null);\n if (!linkedPath) return \"skipped\";\n\n const resolvedLinkedPath = path.resolve(path.dirname(target), linkedPath);\n if (resolvedLinkedPath === source) {\n return \"skipped\";\n }\n\n const linkedPathExists = await fs.stat(resolvedLinkedPath).then(() => true).catch(() => false);\n if (linkedPathExists) {\n return \"skipped\";\n }\n\n await fs.unlink(target);\n await linkSkill(source, target);\n return \"repaired\";\n}\n\nexport async function removeMaintainerOnlySkillSymlinks(\n skillsHome: string,\n allowedSkillNames: Iterable<string>,\n): Promise<string[]> {\n const allowed = new Set(Array.from(allowedSkillNames));\n try {\n const entries = await fs.readdir(skillsHome, { withFileTypes: true });\n const removed: string[] = [];\n for (const entry of entries) {\n if (allowed.has(entry.name)) continue;\n\n const target = path.join(skillsHome, entry.name);\n const existing = await fs.lstat(target).catch(() => null);\n if (!existing?.isSymbolicLink()) continue;\n\n const linkedPath = await fs.readlink(target).catch(() => null);\n if (!linkedPath) continue;\n\n const resolvedLinkedPath = path.isAbsolute(linkedPath)\n ? linkedPath\n : path.resolve(path.dirname(target), linkedPath);\n if (\n !isMaintainerOnlySkillTarget(linkedPath) &&\n !isMaintainerOnlySkillTarget(resolvedLinkedPath)\n ) {\n continue;\n }\n\n await fs.unlink(target);\n removed.push(entry.name);\n }\n\n return removed;\n } catch {\n return [];\n }\n}\n\nexport async function ensureCommandResolvable(command: string, cwd: string, env: NodeJS.ProcessEnv) {\n const resolved = await resolveCommandPath(command, cwd, env);\n if (resolved) return;\n if (command.includes(\"/\") || command.includes(\"\\\\\")) {\n const absolute = path.isAbsolute(command) ? command : path.resolve(cwd, command);\n throw new Error(`Command is not executable: \"${command}\" (resolved: \"${absolute}\")`);\n }\n throw new Error(`Command not found in PATH: \"${command}\"`);\n}\n\nexport async function runChildProcess(\n runId: string,\n command: string,\n args: string[],\n opts: {\n cwd: string;\n env: Record<string, string>;\n timeoutSec: number;\n graceSec: number;\n onLog: (stream: \"stdout\" | \"stderr\", chunk: string) => Promise<void>;\n onLogError?: (err: unknown, runId: string, message: string) => void;\n onSpawn?: (meta: { pid: number; startedAt: string }) => Promise<void>;\n stdin?: string;\n abortSignal?: AbortSignal;\n },\n): Promise<RunProcessResult> {\n const onLogError = opts.onLogError ?? ((err, id, msg) => console.warn({ err, runId: id }, msg));\n\n return new Promise<RunProcessResult>((resolve, reject) => {\n const rawMerged: NodeJS.ProcessEnv = { ...process.env, ...opts.env };\n const requestedHome =\n typeof opts.env.HOME === \"string\" && opts.env.HOME.trim().length > 0\n ? path.resolve(opts.env.HOME)\n : null;\n const inheritedHome =\n typeof process.env.HOME === \"string\" && process.env.HOME.trim().length > 0\n ? path.resolve(process.env.HOME)\n : null;\n const hasExplicitZdotdir =\n typeof opts.env.ZDOTDIR === \"string\" && opts.env.ZDOTDIR.trim().length > 0;\n\n // Strip Claude Code nesting-guard env vars so spawned `claude` processes\n // don't refuse to start with \"cannot be launched inside another session\".\n // These vars leak in when the Rudder server itself is started from\n // within a Claude Code session (e.g. `npx rudder run` in a terminal\n // owned by Claude Code) or when cron inherits a contaminated shell env.\n const CLAUDE_CODE_NESTING_VARS = [\n \"CLAUDECODE\",\n \"CLAUDE_CODE_ENTRYPOINT\",\n \"CLAUDE_CODE_SESSION\",\n \"CLAUDE_CODE_PARENT_SESSION\",\n ] as const;\n for (const key of CLAUDE_CODE_NESTING_VARS) {\n delete rawMerged[key];\n }\n\n const GIT_IDENTITY_ENV_VARS = [\n \"GIT_AUTHOR_NAME\",\n \"GIT_AUTHOR_EMAIL\",\n \"GIT_COMMITTER_NAME\",\n \"GIT_COMMITTER_EMAIL\",\n ] as const;\n for (const key of GIT_IDENTITY_ENV_VARS) {\n if (rawMerged[key] === \"\" && !Object.prototype.hasOwnProperty.call(opts.env, key)) {\n delete rawMerged[key];\n }\n }\n\n // When Rudder isolates HOME for child agents, don't let zsh keep using the\n // host user's startup dir via an inherited ZDOTDIR. That mismatch makes\n // child `zsh -lc` invocations source the host `.zshenv` with the agent HOME.\n if (requestedHome && requestedHome !== inheritedHome && !hasExplicitZdotdir) {\n delete rawMerged.ZDOTDIR;\n }\n\n const mergedEnv = ensurePathInEnv(rawMerged);\n void resolveSpawnTarget(command, args, opts.cwd, mergedEnv)\n .then((target) => {\n if (opts.abortSignal?.aborted) {\n resolve({\n exitCode: null,\n signal: \"SIGTERM\",\n timedOut: false,\n stdout: \"\",\n stderr: \"\",\n pid: null,\n startedAt: null,\n });\n return;\n }\n\n const child = spawn(target.command, target.args, {\n cwd: opts.cwd,\n env: mergedEnv,\n shell: false,\n stdio: [opts.stdin != null ? \"pipe\" : \"ignore\", \"pipe\", \"pipe\"],\n }) as ChildProcessWithEvents;\n const startedAt = new Date().toISOString();\n\n if (opts.stdin != null && child.stdin) {\n child.stdin.write(opts.stdin);\n child.stdin.end();\n }\n\n if (typeof child.pid === \"number\" && child.pid > 0 && opts.onSpawn) {\n void opts.onSpawn({ pid: child.pid, startedAt }).catch((err) => {\n onLogError(err, runId, \"failed to record child process metadata\");\n });\n }\n\n runningProcesses.set(runId, { child, graceSec: opts.graceSec });\n\n let timedOut = false;\n let aborted = false;\n let stdout = \"\";\n let stderr = \"\";\n let logChain: Promise<void> = Promise.resolve();\n\n const timeout =\n opts.timeoutSec > 0\n ? setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n if (isChildProcessAlive(child)) {\n child.kill(\"SIGKILL\");\n }\n }, Math.max(1, opts.graceSec) * 1000);\n }, opts.timeoutSec * 1000)\n : null;\n\n let abortCleanup: (() => void) | null = null;\n if (opts.abortSignal) {\n const onAbort = () => {\n aborted = true;\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n if (isChildProcessAlive(child)) {\n child.kill(\"SIGKILL\");\n }\n }, Math.max(1, opts.graceSec) * 1000);\n };\n\n opts.abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n abortCleanup = () => opts.abortSignal?.removeEventListener(\"abort\", onAbort);\n }\n\n child.stdout?.on(\"data\", (chunk: unknown) => {\n const text = String(chunk);\n stdout = appendWithCap(stdout, text);\n logChain = logChain\n .then(() => opts.onLog(\"stdout\", text))\n .catch((err) => onLogError(err, runId, \"failed to append stdout log chunk\"));\n });\n\n child.stderr?.on(\"data\", (chunk: unknown) => {\n const text = String(chunk);\n stderr = appendWithCap(stderr, text);\n logChain = logChain\n .then(() => opts.onLog(\"stderr\", text))\n .catch((err) => onLogError(err, runId, \"failed to append stderr log chunk\"));\n });\n\n child.on(\"error\", (err: Error) => {\n if (timeout) clearTimeout(timeout);\n if (abortCleanup) abortCleanup();\n runningProcesses.delete(runId);\n const errno = (err as NodeJS.ErrnoException).code;\n const pathValue = mergedEnv.PATH ?? mergedEnv.Path ?? \"\";\n const msg =\n errno === \"ENOENT\"\n ? `Failed to start command \"${command}\" in \"${opts.cwd}\". Verify adapter command, working directory, and PATH (${pathValue}).`\n : `Failed to start command \"${command}\" in \"${opts.cwd}\": ${err.message}`;\n reject(new Error(msg));\n });\n\n child.on(\"close\", (code: number | null, signal: NodeJS.Signals | null) => {\n if (timeout) clearTimeout(timeout);\n if (abortCleanup) abortCleanup();\n runningProcesses.delete(runId);\n void logChain.finally(() => {\n resolve({\n exitCode: code,\n signal: aborted ? \"SIGTERM\" : signal,\n timedOut,\n stdout,\n stderr,\n pid: child.pid ?? null,\n startedAt,\n });\n });\n });\n })\n .catch(reject);\n });\n}\n", "import { Command } from \"commander\";\nimport {\n createApprovalSchema,\n requestApprovalRevisionSchema,\n resolveApprovalSchema,\n resubmitApprovalSchema,\n type Issue,\n type Approval,\n type ApprovalComment,\n} from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport { getAgentCliCapabilityById } from \"../../agent-v1-registry.js\";\n\ninterface ApprovalListOptions extends BaseClientOptions {\n orgId?: string;\n status?: string;\n}\n\ninterface ApprovalDecisionOptions extends BaseClientOptions {\n decisionNote?: string;\n decidedByUserId?: string;\n}\n\ninterface ApprovalCreateOptions extends BaseClientOptions {\n orgId?: string;\n type: string;\n requestedByAgentId?: string;\n payload: string;\n issueIds?: string;\n}\n\ninterface ApprovalResubmitOptions extends BaseClientOptions {\n payload?: string;\n}\n\ninterface ApprovalCommentOptions extends BaseClientOptions {\n body: string;\n}\n\nexport function registerApprovalCommands(program: Command): void {\n const approval = program.command(\"approval\").description(\"Approval operations\");\n\n addCommonClientOptions(\n approval\n .command(\"list\")\n .description(\"List approvals for an organization\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--status <status>\", \"Status filter\")\n .action(async (opts: ApprovalListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const params = new URLSearchParams();\n if (opts.status) params.set(\"status\", opts.status);\n const query = params.toString();\n const rows =\n (await ctx.api.get<Approval[]>(`/api/orgs/${ctx.orgId}/approvals${query ? `?${query}` : \"\"}`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n type: row.type,\n status: row.status,\n requestedByAgentId: row.requestedByAgentId,\n requestedByUserId: row.requestedByUserId,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n approval\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"approval.get\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .action(async (approvalId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const row = await ctx.api.get<Approval>(`/api/approvals/${approvalId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"issues\")\n .description(getAgentCliCapabilityById(\"approval.issues\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .action(async (approvalId: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const rows = (await ctx.api.get<Issue[]>(`/api/approvals/${approvalId}/issues`)) ?? [];\n printOutput(rows, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"create\")\n .description(getAgentCliCapabilityById(\"approval.create\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--type <type>\", \"Approval type (hire_agent|approve_ceo_strategy)\")\n .requiredOption(\"--payload <json>\", \"Approval payload as JSON object\")\n .option(\"--requested-by-agent-id <id>\", \"Requesting agent ID\")\n .option(\"--issue-ids <csv>\", \"Comma-separated linked issue IDs\")\n .action(async (opts: ApprovalCreateOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payloadJson = parseJsonObject(opts.payload, \"payload\");\n const payload = createApprovalSchema.parse({\n type: opts.type,\n payload: payloadJson,\n requestedByAgentId: opts.requestedByAgentId,\n issueIds: parseCsv(opts.issueIds),\n });\n const created = await ctx.api.post<Approval>(`/api/orgs/${ctx.orgId}/approvals`, payload);\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n approval\n .command(\"approve\")\n .description(\"Approve an approval request\")\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--decision-note <text>\", \"Decision note\")\n .option(\"--decided-by-user-id <id>\", \"Decision actor user ID\")\n .action(async (approvalId: string, opts: ApprovalDecisionOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = resolveApprovalSchema.parse({\n decisionNote: opts.decisionNote,\n decidedByUserId: opts.decidedByUserId,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/approve`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"reject\")\n .description(\"Reject an approval request\")\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--decision-note <text>\", \"Decision note\")\n .option(\"--decided-by-user-id <id>\", \"Decision actor user ID\")\n .action(async (approvalId: string, opts: ApprovalDecisionOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = resolveApprovalSchema.parse({\n decisionNote: opts.decisionNote,\n decidedByUserId: opts.decidedByUserId,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/reject`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"request-revision\")\n .description(\"Request revision for an approval\")\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--decision-note <text>\", \"Decision note\")\n .option(\"--decided-by-user-id <id>\", \"Decision actor user ID\")\n .action(async (approvalId: string, opts: ApprovalDecisionOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = requestApprovalRevisionSchema.parse({\n decisionNote: opts.decisionNote,\n decidedByUserId: opts.decidedByUserId,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/request-revision`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"resubmit\")\n .description(getAgentCliCapabilityById(\"approval.resubmit\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .option(\"--payload <json>\", \"Payload JSON object\")\n .action(async (approvalId: string, opts: ApprovalResubmitOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const payload = resubmitApprovalSchema.parse({\n payload: opts.payload ? parseJsonObject(opts.payload, \"payload\") : undefined,\n });\n const updated = await ctx.api.post<Approval>(`/api/approvals/${approvalId}/resubmit`, payload);\n printOutput(updated, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n approval\n .command(\"comment\")\n .description(getAgentCliCapabilityById(\"approval.comment\").description)\n .argument(\"<approvalId>\", \"Approval ID\")\n .requiredOption(\"--body <text>\", \"Comment body\")\n .action(async (approvalId: string, opts: ApprovalCommentOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const created = await ctx.api.post<ApprovalComment>(`/api/approvals/${approvalId}/comments`, {\n body: opts.body,\n });\n printOutput(created, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n\nfunction parseCsv(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const rows = value.split(\",\").map((v) => v.trim()).filter(Boolean);\n return rows.length > 0 ? rows : undefined;\n}\n\nfunction parseJsonObject(value: string, name: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(value) as unknown;\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${name} must be a JSON object`);\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n throw new Error(`Invalid ${name} JSON: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n", "import { Command } from \"commander\";\nimport type { ActivityEvent } from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface ActivityListOptions extends BaseClientOptions {\n orgId?: string;\n agentId?: string;\n entityType?: string;\n entityId?: string;\n}\n\nexport function registerActivityCommands(program: Command): void {\n const activity = program.command(\"activity\").description(\"Activity log operations\");\n\n addCommonClientOptions(\n activity\n .command(\"list\")\n .description(\"List organization activity log entries\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--agent-id <id>\", \"Filter by agent ID\")\n .option(\"--entity-type <type>\", \"Filter by entity type\")\n .option(\"--entity-id <id>\", \"Filter by entity ID\")\n .action(async (opts: ActivityListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const params = new URLSearchParams();\n if (opts.agentId) params.set(\"agentId\", opts.agentId);\n if (opts.entityType) params.set(\"entityType\", opts.entityType);\n if (opts.entityId) params.set(\"entityId\", opts.entityId);\n\n const query = params.toString();\n const path = `/api/orgs/${ctx.orgId}/activity${query ? `?${query}` : \"\"}`;\n const rows = (await ctx.api.get<ActivityEvent[]>(path)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n action: row.action,\n actorType: row.actorType,\n actorId: row.actorId,\n entityType: row.entityType,\n entityId: row.entityId,\n createdAt: String(row.createdAt),\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n", "import { Command } from \"commander\";\nimport type { DashboardSummary } from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface DashboardGetOptions extends BaseClientOptions {\n orgId?: string;\n}\n\nexport function registerDashboardCommands(program: Command): void {\n const dashboard = program.command(\"dashboard\").description(\"Dashboard summary operations\");\n\n addCommonClientOptions(\n dashboard\n .command(\"get\")\n .description(\"Get dashboard summary for an organization\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: DashboardGetOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const row = await ctx.api.get<DashboardSummary>(`/api/orgs/${ctx.orgId}/dashboard`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n", "import { Command } from \"commander\";\nimport {\n organizationSkillImportSchema,\n organizationSkillLocalScanRequestSchema,\n organizationSkillProjectScanRequestSchema,\n type OrganizationSkillDetail,\n type OrganizationSkillFileDetail,\n type OrganizationSkillImportResult,\n type OrganizationSkillListItem,\n type OrganizationSkillLocalScanResult,\n type OrganizationSkillProjectScanResult,\n} from \"@rudderhq/shared\";\nimport {\n addCommonClientOptions,\n formatInlineRecord,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\nimport { getAgentCliCapabilityById } from \"../../agent-v1-registry.js\";\n\ninterface SkillListOptions extends BaseClientOptions {\n orgId?: string;\n}\n\ninterface SkillImportOptions extends BaseClientOptions {\n orgId?: string;\n source: string;\n}\n\ninterface SkillFileOptions extends BaseClientOptions {\n orgId?: string;\n path?: string;\n}\n\ninterface SkillScanLocalOptions extends BaseClientOptions {\n orgId?: string;\n roots?: string;\n}\n\ninterface SkillScanProjectsOptions extends BaseClientOptions {\n orgId?: string;\n projectIds?: string;\n workspaceIds?: string;\n}\n\nexport function registerSkillCommands(program: Command): void {\n const skill = program.command(\"skill\").description(\"Organization skill library operations\");\n\n addCommonClientOptions(\n skill\n .command(\"list\")\n .description(getAgentCliCapabilityById(\"skill.list\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (opts: SkillListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const rows = (await ctx.api.get<OrganizationSkillListItem[]>(`/api/orgs/${ctx.orgId}/skills`)) ?? [];\n\n if (ctx.json) {\n printOutput(rows, { json: true });\n return;\n }\n\n if (rows.length === 0) {\n printOutput([], { json: false });\n return;\n }\n\n for (const row of rows) {\n console.log(\n formatInlineRecord({\n id: row.id,\n key: row.key,\n slug: row.slug,\n name: row.name,\n sourceBadge: row.sourceBadge,\n compatibility: row.compatibility,\n attachedAgentCount: row.attachedAgentCount,\n }),\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"get\")\n .description(getAgentCliCapabilityById(\"skill.get\").description)\n .argument(\"<skillId>\", \"Skill ID\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .action(async (skillId: string, opts: SkillListOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const row = await ctx.api.get<OrganizationSkillDetail>(`/api/orgs/${ctx.orgId}/skills/${skillId}`);\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"file\")\n .description(getAgentCliCapabilityById(\"skill.file\").description)\n .argument(\"<skillId>\", \"Skill ID\")\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--path <path>\", \"Skill package file path\", \"SKILL.md\")\n .action(async (skillId: string, opts: SkillFileOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const query = new URLSearchParams({ path: opts.path ?? \"SKILL.md\" });\n const row = await ctx.api.get<OrganizationSkillFileDetail>(\n `/api/orgs/${ctx.orgId}/skills/${skillId}/files?${query.toString()}`,\n );\n printOutput(row, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"import\")\n .description(getAgentCliCapabilityById(\"skill.import\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .requiredOption(\"--source <source>\", \"Skill source (local path, URL, or repo ref)\")\n .action(async (opts: SkillImportOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = organizationSkillImportSchema.parse({ source: opts.source });\n const result = await ctx.api.post<OrganizationSkillImportResult>(`/api/orgs/${ctx.orgId}/skills/import`, payload);\n printOutput(result, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"scan-local\")\n .description(getAgentCliCapabilityById(\"skill.scan-local\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--roots <csv>\", \"Comma-separated local roots to scan\")\n .action(async (opts: SkillScanLocalOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = organizationSkillLocalScanRequestSchema.parse({\n roots: parseCsv(opts.roots),\n });\n const result = await ctx.api.post<OrganizationSkillLocalScanResult>(\n `/api/orgs/${ctx.orgId}/skills/scan-local`,\n payload,\n );\n printOutput(result, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n\n addCommonClientOptions(\n skill\n .command(\"scan-projects\")\n .description(getAgentCliCapabilityById(\"skill.scan-projects\").description)\n .option(\"-O, --org-id <id>\", \"Organization ID\")\n .option(\"--project-ids <csv>\", \"Comma-separated project IDs\")\n .option(\"--workspace-ids <csv>\", \"Comma-separated workspace IDs\")\n .action(async (opts: SkillScanProjectsOptions) => {\n try {\n const ctx = resolveCommandContext(opts, { requireCompany: true });\n const payload = organizationSkillProjectScanRequestSchema.parse({\n projectIds: parseCsv(opts.projectIds),\n workspaceIds: parseCsv(opts.workspaceIds),\n });\n const result = await ctx.api.post<OrganizationSkillProjectScanResult>(\n `/api/orgs/${ctx.orgId}/skills/scan-projects`,\n payload,\n );\n printOutput(result, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: false },\n );\n}\n\nfunction parseCsv(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const rows = value.split(\",\").map((entry) => entry.trim()).filter(Boolean);\n return rows.length > 0 ? rows : undefined;\n}\n", "import path from \"node:path\";\nimport {\n expandHomePrefix,\n resolveDefaultConfigPath,\n resolveDefaultContextPath,\n resolveRudderInstanceId,\n} from \"./home.js\";\n\nexport interface DataDirOptionLike {\n dataDir?: string;\n config?: string;\n context?: string;\n instance?: string;\n localEnv?: string;\n}\n\nexport interface DataDirCommandSupport {\n hasConfigOption?: boolean;\n hasContextOption?: boolean;\n}\n\nexport function applyDataDirOverride(\n options: DataDirOptionLike,\n support: DataDirCommandSupport = {},\n): string | null {\n const rawDataDir = options.dataDir?.trim();\n if (!rawDataDir) return null;\n\n const resolvedDataDir = path.resolve(expandHomePrefix(rawDataDir));\n process.env.RUDDER_HOME = resolvedDataDir;\n\n if (support.hasConfigOption) {\n const hasConfigOverride = Boolean(options.config?.trim()) || Boolean(process.env.RUDDER_CONFIG?.trim());\n if (!hasConfigOverride) {\n const instanceId = resolveRudderInstanceId(options.instance);\n process.env.RUDDER_INSTANCE_ID = instanceId;\n process.env.RUDDER_CONFIG = resolveDefaultConfigPath(instanceId);\n }\n }\n\n if (support.hasContextOption) {\n const hasContextOverride = Boolean(options.context?.trim()) || Boolean(process.env.RUDDER_CONTEXT?.trim());\n if (!hasContextOverride) {\n process.env.RUDDER_CONTEXT = resolveDefaultContextPath();\n }\n }\n\n return resolvedDataDir;\n}\n", "import path from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n addCommonClientOptions,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\n// ---------------------------------------------------------------------------\n// Types mirroring server-side shapes\n// ---------------------------------------------------------------------------\n\ninterface PluginRecord {\n id: string;\n pluginKey: string;\n packageName: string;\n version: string;\n status: string;\n displayName?: string;\n lastError?: string | null;\n installedAt: string;\n updatedAt: string;\n}\n\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\ninterface PluginListOptions extends BaseClientOptions {\n status?: string;\n}\n\ninterface PluginInstallOptions extends BaseClientOptions {\n local?: boolean;\n version?: string;\n}\n\ninterface PluginUninstallOptions extends BaseClientOptions {\n force?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a local path argument to an absolute path so the server can find the\n * plugin on disk regardless of where the user ran the CLI.\n */\nfunction resolvePackageArg(packageArg: string, isLocal: boolean): string {\n if (!isLocal) return packageArg;\n // Already absolute\n if (path.isAbsolute(packageArg)) return packageArg;\n // Expand leading ~ to home directory\n if (packageArg.startsWith(\"~\")) {\n const home = process.env.HOME ?? process.env.USERPROFILE ?? \"\";\n return path.resolve(home, packageArg.slice(1).replace(/^[\\\\/]/, \"\"));\n }\n return path.resolve(process.cwd(), packageArg);\n}\n\nfunction formatPlugin(p: PluginRecord): string {\n const statusColor =\n p.status === \"ready\"\n ? pc.green(p.status)\n : p.status === \"error\"\n ? pc.red(p.status)\n : p.status === \"disabled\"\n ? pc.dim(p.status)\n : pc.yellow(p.status);\n\n const parts = [\n `key=${pc.bold(p.pluginKey)}`,\n `status=${statusColor}`,\n `version=${p.version}`,\n `id=${pc.dim(p.id)}`,\n ];\n\n if (p.lastError) {\n parts.push(`error=${pc.red(p.lastError.slice(0, 80))}`);\n }\n\n return parts.join(\" \");\n}\n\n// ---------------------------------------------------------------------------\n// Command registration\n// ---------------------------------------------------------------------------\n\nexport function registerPluginCommands(program: Command): void {\n const plugin = program.command(\"plugin\").description(\"Plugin lifecycle management\");\n\n // -------------------------------------------------------------------------\n // plugin list\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"list\")\n .description(\"List installed plugins\")\n .option(\"--status <status>\", \"Filter by status (ready, error, disabled, installed, upgrade_pending)\")\n .action(async (opts: PluginListOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const qs = opts.status ? `?status=${encodeURIComponent(opts.status)}` : \"\";\n const plugins = await ctx.api.get<PluginRecord[]>(`/api/plugins${qs}`);\n\n if (ctx.json) {\n printOutput(plugins, { json: true });\n return;\n }\n\n const rows = plugins ?? [];\n if (rows.length === 0) {\n console.log(pc.dim(\"No plugins installed.\"));\n return;\n }\n\n for (const p of rows) {\n console.log(formatPlugin(p));\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin install <package-or-path>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"install <package>\")\n .description(\n \"Install a plugin from a local path or npm package.\\n\" +\n \" Examples:\\n\" +\n \" rudder plugin install ./my-plugin # local path\\n\" +\n \" rudder plugin install @acme/plugin-linear # npm package\\n\" +\n \" rudder plugin install @acme/plugin-linear@1.2 # pinned version\",\n )\n .option(\"-l, --local\", \"Treat <package> as a local filesystem path\", false)\n .option(\"--version <version>\", \"Specific npm version to install (npm packages only)\")\n .action(async (packageArg: string, opts: PluginInstallOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n\n // Auto-detect local paths: starts with . or / or ~ or is an absolute path\n const isLocal =\n opts.local ||\n packageArg.startsWith(\"./\") ||\n packageArg.startsWith(\"../\") ||\n packageArg.startsWith(\"/\") ||\n packageArg.startsWith(\"~\");\n\n const resolvedPackage = resolvePackageArg(packageArg, isLocal);\n\n if (!ctx.json) {\n console.log(\n pc.dim(\n isLocal\n ? `Installing plugin from local path: ${resolvedPackage}`\n : `Installing plugin: ${resolvedPackage}${opts.version ? `@${opts.version}` : \"\"}`,\n ),\n );\n }\n\n const installedPlugin = await ctx.api.post<PluginRecord>(\"/api/plugins/install\", {\n packageName: resolvedPackage,\n version: opts.version,\n isLocalPath: isLocal,\n });\n\n if (ctx.json) {\n printOutput(installedPlugin, { json: true });\n return;\n }\n\n if (!installedPlugin) {\n console.log(pc.dim(\"Install returned no plugin record.\"));\n return;\n }\n\n console.log(\n pc.green(\n `\u2713 Installed ${pc.bold(installedPlugin.pluginKey)} v${installedPlugin.version} (${installedPlugin.status})`,\n ),\n );\n\n if (installedPlugin.lastError) {\n console.log(pc.red(` Warning: ${installedPlugin.lastError}`));\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin uninstall <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"uninstall <pluginKey>\")\n .description(\n \"Uninstall a plugin by its plugin key or database ID.\\n\" +\n \" Use --force to hard-purge all state and config.\",\n )\n .option(\"--force\", \"Purge all plugin state and config (hard delete)\", false)\n .action(async (pluginKey: string, opts: PluginUninstallOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const purge = opts.force === true;\n const qs = purge ? \"?purge=true\" : \"\";\n\n if (!ctx.json) {\n console.log(\n pc.dim(\n purge\n ? `Uninstalling and purging plugin: ${pluginKey}`\n : `Uninstalling plugin: ${pluginKey}`,\n ),\n );\n }\n\n const result = await ctx.api.delete<PluginRecord | null>(\n `/api/plugins/${encodeURIComponent(pluginKey)}${qs}`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n console.log(pc.green(`\u2713 Uninstalled ${pc.bold(pluginKey)}${purge ? \" (purged)\" : \"\"}`));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin enable <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"enable <pluginKey>\")\n .description(\"Enable a disabled or errored plugin\")\n .action(async (pluginKey: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const result = await ctx.api.post<PluginRecord>(\n `/api/plugins/${encodeURIComponent(pluginKey)}/enable`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n console.log(pc.green(`\u2713 Enabled ${pc.bold(pluginKey)} \u2014 status: ${result?.status ?? \"unknown\"}`));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin disable <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"disable <pluginKey>\")\n .description(\"Disable a running plugin without uninstalling it\")\n .action(async (pluginKey: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const result = await ctx.api.post<PluginRecord>(\n `/api/plugins/${encodeURIComponent(pluginKey)}/disable`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n console.log(pc.dim(`Disabled ${pc.bold(pluginKey)} \u2014 status: ${result?.status ?? \"unknown\"}`));\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin inspect <plugin-key-or-id>\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"inspect <pluginKey>\")\n .description(\"Show full details for an installed plugin\")\n .action(async (pluginKey: string, opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const result = await ctx.api.get<PluginRecord>(\n `/api/plugins/${encodeURIComponent(pluginKey)}`,\n );\n\n if (ctx.json) {\n printOutput(result, { json: true });\n return;\n }\n\n if (!result) {\n console.log(pc.red(`Plugin not found: ${pluginKey}`));\n process.exit(1);\n }\n\n console.log(formatPlugin(result));\n if (result.lastError) {\n console.log(`\\n${pc.red(\"Last error:\")}\\n${result.lastError}`);\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n // -------------------------------------------------------------------------\n // plugin examples\n // -------------------------------------------------------------------------\n addCommonClientOptions(\n plugin\n .command(\"examples\")\n .description(\"List bundled example plugins available for local install\")\n .action(async (opts: BaseClientOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const examples = await ctx.api.get<\n Array<{\n packageName: string;\n pluginKey: string;\n displayName: string;\n description: string;\n localPath: string;\n tag: string;\n }>\n >(\"/api/plugins/examples\");\n\n if (ctx.json) {\n printOutput(examples, { json: true });\n return;\n }\n\n const rows = examples ?? [];\n if (rows.length === 0) {\n console.log(pc.dim(\"No bundled examples available.\"));\n return;\n }\n\n for (const ex of rows) {\n console.log(\n `${pc.bold(ex.displayName)} ${pc.dim(ex.pluginKey)}\\n` +\n ` ${ex.description}\\n` +\n ` ${pc.cyan(`rudder plugin install ${ex.localPath}`)}`,\n );\n }\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n", "import type { Command } from \"commander\";\nimport {\n getStoredBoardCredential,\n loginBoardCli,\n removeStoredBoardCredential,\n revokeStoredBoardCredential,\n} from \"../../client/board-auth.js\";\nimport {\n addCommonClientOptions,\n handleCommandError,\n printOutput,\n resolveCommandContext,\n type BaseClientOptions,\n} from \"./common.js\";\n\ninterface AuthLoginOptions extends BaseClientOptions {\n instanceAdmin?: boolean;\n}\n\ninterface AuthLogoutOptions extends BaseClientOptions {}\ninterface AuthWhoamiOptions extends BaseClientOptions {}\n\nexport function registerClientAuthCommands(auth: Command): void {\n addCommonClientOptions(\n auth\n .command(\"login\")\n .description(\"Authenticate the CLI for board-user access\")\n .option(\"--instance-admin\", \"Request instance-admin approval instead of plain board access\", false)\n .action(async (opts: AuthLoginOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const login = await loginBoardCli({\n apiBase: ctx.api.apiBase,\n requestedAccess: opts.instanceAdmin ? \"instance_admin_required\" : \"board\",\n requestedCompanyId: ctx.orgId ?? null,\n command: \"rudder auth login\",\n });\n printOutput(\n {\n ok: true,\n apiBase: ctx.api.apiBase,\n userId: login.userId ?? null,\n approvalUrl: login.approvalUrl,\n },\n { json: ctx.json },\n );\n } catch (err) {\n handleCommandError(err);\n }\n }),\n { includeCompany: true },\n );\n\n addCommonClientOptions(\n auth\n .command(\"logout\")\n .description(\"Remove the stored board-user credential for this API base\")\n .action(async (opts: AuthLogoutOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const credential = getStoredBoardCredential(ctx.api.apiBase);\n if (!credential) {\n printOutput({ ok: true, apiBase: ctx.api.apiBase, revoked: false, removedLocalCredential: false }, { json: ctx.json });\n return;\n }\n let revoked = false;\n try {\n await revokeStoredBoardCredential({\n apiBase: ctx.api.apiBase,\n token: credential.token,\n });\n revoked = true;\n } catch {\n // Remove the local credential even if the server-side revoke fails.\n }\n const removedLocalCredential = removeStoredBoardCredential(ctx.api.apiBase);\n printOutput(\n {\n ok: true,\n apiBase: ctx.api.apiBase,\n revoked,\n removedLocalCredential,\n },\n { json: ctx.json },\n );\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n\n addCommonClientOptions(\n auth\n .command(\"whoami\")\n .description(\"Show the current board-user identity for this API base\")\n .action(async (opts: AuthWhoamiOptions) => {\n try {\n const ctx = resolveCommandContext(opts);\n const me = await ctx.api.get<{\n user: { id: string; name: string; email: string } | null;\n userId: string;\n isInstanceAdmin: boolean;\n companyIds: string[];\n source: string;\n keyId: string | null;\n }>(\"/api/cli-auth/me\");\n printOutput(me, { json: ctx.json });\n } catch (err) {\n handleCommandError(err);\n }\n }),\n );\n}\n", "import { runCli } from \"./program.js\";\n\nexport { runCli } from \"./program.js\";\n\nvoid runCli(process.argv).then(async (exitCode) => {\n // Ensure stdout is fully flushed before exiting to prevent truncated output\n // when the CLI is invoked via spawn/exec with large JSON payloads\n if (process.stdout.writableNeedDrain) {\n await new Promise<void>((resolve) => process.stdout.once('drain', resolve));\n }\n process.exit(exitCode);\n});\n"],
5
5
  "mappings": "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",
6
6
  "names": ["z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "executionWorkspaceStrategySchema", "z", "z", "z", "init_workspace_backup", "z", "z", "z", "z", "z", "z", "z", "z", "z", "init_workspace_backup", "z", "path", "fs", "path", "fs", "path", "randomBytes", "fs", "path", "p", "p", "p", "p", "unique", "p", "path", "fs", "path", "pathToFileURL", "path", "fileURLToPath", "p", "spawnSync", "collectSpawnOutput", "init_install", "init_database", "pc", "init_path_resolver", "fs", "init_path_resolver", "init_database", "fs", "init_path_resolver", "randomBytes", "fs", "path", "init_path_resolver", "fs", "init_path_resolver", "p", "pc", "fs", "p", "pc", "p", "path", "pc", "runCommand", "init_install", "init_database", "p", "pc", "defaultStorageBaseDir", "p", "pc", "init_install", "spawnSync", "readFileSync", "mkdir", "readFile", "writeFile", "path", "p", "pc", "pc", "path", "appPath", "readFileSync", "spawnSync", "mkdir", "readFile", "appSource", "writeFile", "spinner", "p", "pc", "delay", "pc", "pc", "spawn", "fs", "path", "pc", "path", "fs", "child", "spawn", "pc", "fs", "path", "parseJson", "URL", "path", "text", "pc", "pc", "agentRuntimeType", "delay", "pc", "pc", "mkdir", "readdir", "readFile", "writeFile", "path", "p", "pc", "path", "path", "isUuidLike", "agentRuntimeTypes", "pc", "owner", "repo", "pathExists", "readdir", "readFile", "mkdir", "writeFile", "confirm", "readFile", "stat", "path", "path", "stat", "readFile", "text", "fsConstants", "fs", "path", "path", "fs", "fs", "path", "fs", "os", "path", "fileURLToPath", "path", "fileURLToPath", "os", "fs", "parseCsv", "parseJsonObject", "parseCsv", "path", "parseCsv", "path", "path", "pc", "path", "p", "pc"]
7
7
  }