@neuralnomads/codenomad-dev 0.20.0-dev-20260909-855d2ee7 → 0.20.0-dev-20260911-ea37f97b
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/api-types.js.map +1 -1
- package/dist/index.js +42 -31
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +9 -1
- package/dist/index.test.js.map +1 -1
- package/dist/opencode/pruning-installation.js +65 -0
- package/dist/opencode/pruning-installation.js.map +1 -0
- package/dist/opencode/pruning-installation.test.js +101 -0
- package/dist/opencode/pruning-installation.test.js.map +1 -0
- package/dist/opencode/pruning-lifecycle.js +66 -0
- package/dist/opencode/pruning-lifecycle.js.map +1 -0
- package/dist/opencode/session-pruning/claim-fence.js +33 -0
- package/dist/opencode/session-pruning/claim-fence.js.map +1 -0
- package/dist/opencode/session-pruning/claim-fence.test.js +104 -0
- package/dist/opencode/session-pruning/claim-fence.test.js.map +1 -0
- package/dist/opencode/session-pruning/contract.js +40 -0
- package/dist/opencode/session-pruning/contract.js.map +1 -0
- package/dist/opencode/session-pruning/database-path.js +17 -0
- package/dist/opencode/session-pruning/database-path.js.map +1 -0
- package/dist/opencode/session-pruning/database-path.test.js +22 -0
- package/dist/opencode/session-pruning/database-path.test.js.map +1 -0
- package/dist/opencode/session-pruning/desktop-plugin.js +14 -0
- package/dist/opencode/session-pruning/desktop-plugin.js.map +1 -0
- package/dist/opencode/session-pruning/index.js +2 -0
- package/dist/opencode/session-pruning/index.js.map +1 -0
- package/dist/opencode/session-pruning/isolated-store.js +18 -0
- package/dist/opencode/session-pruning/isolated-store.js.map +1 -0
- package/dist/opencode/session-pruning/planner.js +36 -0
- package/dist/opencode/session-pruning/planner.js.map +1 -0
- package/dist/opencode/session-pruning/plugin.js +45 -0
- package/dist/opencode/session-pruning/plugin.js.map +1 -0
- package/dist/opencode/session-pruning/presence.js +42 -0
- package/dist/opencode/session-pruning/presence.js.map +1 -0
- package/dist/opencode/session-pruning/preview-store.js +21 -0
- package/dist/opencode/session-pruning/preview-store.js.map +1 -0
- package/dist/opencode/session-pruning/pruning.test.js +172 -0
- package/dist/opencode/session-pruning/pruning.test.js.map +1 -0
- package/dist/opencode/session-pruning/revision.js +18 -0
- package/dist/opencode/session-pruning/revision.js.map +1 -0
- package/dist/opencode/session-pruning/service.js +56 -0
- package/dist/opencode/session-pruning/service.js.map +1 -0
- package/dist/opencode/session-pruning/service.test.js +74 -0
- package/dist/opencode/session-pruning/service.test.js.map +1 -0
- package/dist/opencode/session-pruning/storage-path.js +6 -0
- package/dist/opencode/session-pruning/storage-path.js.map +1 -0
- package/dist/opencode/session-pruning/transaction.js +53 -0
- package/dist/opencode/session-pruning/transaction.js.map +1 -0
- package/dist/opencode/session-pruning/tui-reload.js +84 -0
- package/dist/opencode/session-pruning/tui-reload.js.map +1 -0
- package/dist/opencode/session-pruning/tui-reload.native.js +269 -0
- package/dist/opencode/session-pruning/tui-reload.native.js.map +1 -0
- package/dist/opencode/session-pruning/tui-reload.test.js +71 -0
- package/dist/opencode/session-pruning/tui-reload.test.js.map +1 -0
- package/dist/opencode/session-pruning/tui.js +12 -0
- package/dist/opencode/session-pruning/tui.js.map +1 -0
- package/dist/plugins/session-pruning/plugin.mjs +26559 -0
- package/dist/server/__tests__/instance-proxy.test.js +10 -5
- package/dist/server/__tests__/instance-proxy.test.js.map +1 -1
- package/dist/server/__tests__/listener-base-url.test.js +26 -1
- package/dist/server/__tests__/listener-base-url.test.js.map +1 -1
- package/dist/server/__tests__/network-addresses.test.js +40 -0
- package/dist/server/__tests__/network-addresses.test.js.map +1 -1
- package/dist/server/__tests__/network-host.test.js +34 -0
- package/dist/server/__tests__/network-host.test.js.map +1 -0
- package/dist/server/__tests__/tls-ipv6.test.js +54 -0
- package/dist/server/__tests__/tls-ipv6.test.js.map +1 -0
- package/dist/server/http-server.js +8 -6
- package/dist/server/http-server.js.map +1 -1
- package/dist/server/listener-base-url.js +12 -3
- package/dist/server/listener-base-url.js.map +1 -1
- package/dist/server/network-addresses.js +20 -42
- package/dist/server/network-addresses.js.map +1 -1
- package/dist/server/network-host.js +62 -0
- package/dist/server/network-host.js.map +1 -0
- package/dist/server/routes/meta.js +2 -4
- package/dist/server/routes/meta.js.map +1 -1
- package/dist/server/routes/session-pruning.js +45 -0
- package/dist/server/routes/session-pruning.js.map +1 -0
- package/dist/server/routes/session-pruning.test.js +98 -0
- package/dist/server/routes/session-pruning.test.js.map +1 -0
- package/dist/server/tls.js +52 -32
- package/dist/server/tls.js.map +1 -1
- package/dist/workspaces/manager.js +1 -0
- package/dist/workspaces/manager.js.map +1 -1
- package/package.json +6 -3
- package/public/assets/App-0-FcHzPS.js +44 -0
- package/public/assets/App-0-FcHzPS.js.map +1 -0
- package/public/assets/FilesTab-CRpGDs1B.js +3 -0
- package/public/assets/{FilesTab-z7UrjcAQ.js.map → FilesTab-CRpGDs1B.js.map} +1 -1
- package/public/assets/{GitChangesTab-C04bYKhs.js → GitChangesTab-DxFebTiq.js} +3 -3
- package/public/assets/{GitChangesTab-C04bYKhs.js.map → GitChangesTab-DxFebTiq.js.map} +1 -1
- package/public/assets/{SplitFilePanel-B29MqCuU.js → SplitFilePanel-DgTMrrO-.js} +2 -2
- package/public/assets/{SplitFilePanel-B29MqCuU.js.map → SplitFilePanel-DgTMrrO-.js.map} +1 -1
- package/public/assets/{StatusTab-wUKfwnFf.js → StatusTab-LKUA9cbH.js} +2 -2
- package/public/assets/{StatusTab-wUKfwnFf.js.map → StatusTab-LKUA9cbH.js.map} +1 -1
- package/public/assets/{align-justify-glU678D9.js → align-justify-v_yPXSys.js} +2 -2
- package/public/assets/{align-justify-glU678D9.js.map → align-justify-v_yPXSys.js.map} +1 -1
- package/public/assets/{bundle-full-BrsCElYv.js → bundle-full-HzL_Jtqk.js} +2 -2
- package/public/assets/{bundle-full-BrsCElYv.js.map → bundle-full-HzL_Jtqk.js.map} +1 -1
- package/public/assets/{client-state-j9Iu7F-E.js → client-state-CF-PJ0GG.js} +2 -2
- package/public/assets/{client-state-j9Iu7F-E.js.map → client-state-CF-PJ0GG.js.map} +1 -1
- package/public/assets/{diff-viewer-B0VS1voD.js → diff-viewer-BFDQBDVy.js} +2 -2
- package/public/assets/{diff-viewer-B0VS1voD.js.map → diff-viewer-BFDQBDVy.js.map} +1 -1
- package/public/assets/index-8iPlm2r0.js +2 -0
- package/public/assets/index-8iPlm2r0.js.map +1 -0
- package/public/assets/index-B185mC7m.js +2 -0
- package/public/assets/index-B185mC7m.js.map +1 -0
- package/public/assets/index-Bbj1xF8i.js +2 -0
- package/public/assets/index-Bbj1xF8i.js.map +1 -0
- package/public/assets/index-BsmFN3k1.js +2 -0
- package/public/assets/index-BsmFN3k1.js.map +1 -0
- package/public/assets/index-Bz_OQJYA.css +1 -0
- package/public/assets/index-C52CfqK3.js +2 -0
- package/public/assets/index-C52CfqK3.js.map +1 -0
- package/public/assets/index-CHYmKl10.js +2 -0
- package/public/assets/index-CHYmKl10.js.map +1 -0
- package/public/assets/index-CTKYD_VJ.js +2 -0
- package/public/assets/index-CTKYD_VJ.js.map +1 -0
- package/public/assets/index-D2UHSOG5.js +2 -0
- package/public/assets/{index-ClaHfu-1.js.map → index-D2UHSOG5.js.map} +1 -1
- package/public/assets/index-DDoB_Z36.js +2 -0
- package/public/assets/index-DDoB_Z36.js.map +1 -0
- package/public/assets/{index-BzAEHHap.js → index-DcwAtZw-.js} +3 -3
- package/public/assets/index-DcwAtZw-.js.map +1 -0
- package/public/assets/index-DxUD3RYr.js +2 -0
- package/public/assets/index-DxUD3RYr.js.map +1 -0
- package/public/assets/{index-B6bX3AMT.js → index-RK9gf0uk.js} +2 -2
- package/public/assets/{index-B6bX3AMT.js.map → index-RK9gf0uk.js.map} +1 -1
- package/public/assets/{loading-CYiiwb08.js → loading-BSB82snY.js} +2 -2
- package/public/assets/{loading-CYiiwb08.js.map → loading-BSB82snY.js.map} +1 -1
- package/public/assets/main-CZztwrfv.js +48 -0
- package/public/assets/main-CZztwrfv.js.map +1 -0
- package/public/assets/{markdown-DWvSdCZz.js → markdown-DtidoL2Z.js} +4 -4
- package/public/assets/{markdown-DWvSdCZz.js.map → markdown-DtidoL2Z.js.map} +1 -1
- package/public/assets/{monaco-viewer-Cc9bWg7I.js → monaco-viewer-CpxDfB-6.js} +2 -2
- package/public/assets/monaco-viewer-CpxDfB-6.js.map +1 -0
- package/public/assets/{startup-state-settings-card-2KHpBL8U.js → startup-state-settings-card-BY741Rt0.js} +2 -2
- package/public/assets/{startup-state-settings-card-2KHpBL8U.js.map → startup-state-settings-card-BY741Rt0.js.map} +1 -1
- package/public/assets/{terminal-square-lzHuj_of.js → terminal-square-BdC_jwm3.js} +2 -2
- package/public/assets/{terminal-square-lzHuj_of.js.map → terminal-square-BdC_jwm3.js.map} +1 -1
- package/public/assets/{tool-call-DjkszeT4.js → tool-call-DbtCsJ4x.js} +10 -10
- package/public/assets/{tool-call-DjkszeT4.js.map → tool-call-DbtCsJ4x.js.map} +1 -1
- package/public/assets/{unified-picker-5JmIM6a0.js → unified-picker-C0eo1chJ.js} +2 -2
- package/public/assets/{unified-picker-5JmIM6a0.js.map → unified-picker-C0eo1chJ.js.map} +1 -1
- package/public/assets/{wrap-text-N0Cav2Vp.js → wrap-text-BuMtdvMx.js} +2 -2
- package/public/assets/{wrap-text-N0Cav2Vp.js.map → wrap-text-BuMtdvMx.js.map} +1 -1
- package/public/index.html +4 -4
- package/public/loading.html +4 -4
- package/public/sw.js +1 -1
- package/public/sw.js.map +1 -1
- package/public/assets/App-Nlt9zV-v.js +0 -43
- package/public/assets/App-Nlt9zV-v.js.map +0 -1
- package/public/assets/FilesTab-z7UrjcAQ.js +0 -3
- package/public/assets/index-BIRLnDWY.js +0 -2
- package/public/assets/index-BIRLnDWY.js.map +0 -1
- package/public/assets/index-BuScpzpP.js +0 -2
- package/public/assets/index-BuScpzpP.js.map +0 -1
- package/public/assets/index-BzAEHHap.js.map +0 -1
- package/public/assets/index-C-DZt-oz.css +0 -1
- package/public/assets/index-C9RXVQl9.js +0 -2
- package/public/assets/index-C9RXVQl9.js.map +0 -1
- package/public/assets/index-ClaHfu-1.js +0 -2
- package/public/assets/index-DBx5htn3.js +0 -2
- package/public/assets/index-DBx5htn3.js.map +0 -1
- package/public/assets/index-DHHMf3u1.js +0 -2
- package/public/assets/index-DHHMf3u1.js.map +0 -1
- package/public/assets/index-DN4Kstsd.js +0 -2
- package/public/assets/index-DN4Kstsd.js.map +0 -1
- package/public/assets/index-DbMyNDyo.js +0 -2
- package/public/assets/index-DbMyNDyo.js.map +0 -1
- package/public/assets/index-rcsmuqww.js +0 -2
- package/public/assets/index-rcsmuqww.js.map +0 -1
- package/public/assets/index-uz2QFRlk.js +0 -2
- package/public/assets/index-uz2QFRlk.js.map +0 -1
- package/public/assets/main-OmXs7qtG.js +0 -48
- package/public/assets/main-OmXs7qtG.js.map +0 -1
- package/public/assets/monaco-viewer-Cc9bWg7I.js.map +0 -1
package/dist/api-types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-types.js","sourceRoot":"","sources":["../src/api-types.ts"],"names":[],"mappings":"AAqQA,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAA;AA8E/C,MAAM,CAAC,MAAM,+BAA+B,GAAG,sBAA+B,CAAA","sourcesContent":["import type {\n AgentModelSelection,\n AgentModelSelections,\n ModelPreference,\n OpenCodeBinary,\n Preferences,\n RecentFolder,\n} from \"./config/schema\"\nimport type { OpenCodeEvent } from \"@opencode-ai/client\"\n\n/**\n * Canonical HTTP/SSE contract for the CLI server.\n * These types are consumed by both the CLI implementation and any UI clients.\n */\n\nexport type WorkspaceStatus = \"starting\" | \"ready\" | \"stopped\" | \"error\"\n\nexport interface WorkspaceDescriptor {\n id: string\n /** Correlates creation events with the client request that initiated them. */\n requestId?: string\n /** Absolute path on the server host. */\n path: string\n name?: string\n status: WorkspaceStatus\n /** PID/port are populated when the workspace is running. */\n pid?: number\n port?: number\n /** Canonical proxy path the CLI exposes for this instance. */\n proxyPath: string\n /** Identifier of the binary resolved from config. */\n binaryId: string\n binaryLabel: string\n binaryVersion?: string\n createdAt: string\n updatedAt: string\n /** Present when `status` is \"error\". */\n error?: string\n}\n\nexport interface WorkspaceCreateRequest {\n path: string\n name?: string\n requestId?: string\n}\n\nexport interface WorkspaceCloneRequest {\n repositoryUrl: string\n destinationPath: string\n cleanup?: boolean\n}\n\nexport interface WorkspaceCloneResponse {\n path: string\n}\n\nexport type WorkspaceCreateResponse = WorkspaceDescriptor & {\n /** True when this request did not own creation of the returned workspace. */\n reused?: true\n}\nexport type WorkspaceListResponse = WorkspaceDescriptor[]\nexport type WorkspaceDetailResponse = WorkspaceDescriptor\n\nexport interface WorkspaceDeleteResponse {\n id: string\n status: WorkspaceStatus\n}\n\nexport interface ProviderUsageWindow {\n usedPercent: number | null\n remainingPercent: number | null\n windowSeconds: number | null\n resetAt: number | null\n valueLabel?: string\n}\n\nexport interface ProviderUsageResponse {\n requestedProviderId: string\n providerId: string | null\n providerName: string\n modelId?: string\n supported: boolean\n configured: boolean\n ok: boolean\n windows: Record<string, ProviderUsageWindow>\n fetchedAt: number\n}\n\nexport type WorktreeKind = \"root\" | \"worktree\"\n\nexport interface WorktreeDescriptor {\n /** Stable identifier used by CodeNomad + clients (\"root\" for the selected workspace folder). */\n slug: string\n /** Absolute directory path on the server host. */\n directory: string\n kind: WorktreeKind\n /** Optional VCS branch name when available. */\n branch?: string\n}\n\nexport interface WorktreeListResponse {\n worktrees: WorktreeDescriptor[]\n /** True when the workspace folder resolves to a Git repository. */\n isGitRepo?: boolean\n}\n\nexport interface WorktreeCreateRequest {\n slug: string\n /** Optional branch name (defaults to slug). */\n branch?: string\n}\n\nexport type GitChangeKind = \"added\" | \"modified\" | \"deleted\" | \"renamed\" | \"copied\" | \"untracked\" | \"unmerged\"\n\nexport interface WorktreeGitStatusEntry {\n path: string\n originalPath?: string | null\n stagedStatus: GitChangeKind | null\n stagedAdditions: number\n stagedDeletions: number\n unstagedStatus: GitChangeKind | null\n unstagedAdditions: number\n unstagedDeletions: number\n}\n\nexport type WorktreeGitStatusResponse = WorktreeGitStatusEntry[]\n\nexport type WorktreeGitDiffScope = \"staged\" | \"unstaged\"\n\nexport interface WorktreeGitPathsRequest {\n paths: string[]\n}\n\nexport interface WorktreeGitMutationResponse {\n ok: true\n}\n\nexport interface WorktreeGitCommitRequest {\n message: string\n}\n\nexport interface WorktreeGitCommitResponse {\n ok: true\n commitSha?: string\n}\n\nexport interface WorktreeGitDiffResponse {\n path: string\n originalPath?: string | null\n scope: WorktreeGitDiffScope\n before: string\n after: string\n isBinary?: boolean\n}\n\nexport interface WorktreeGitDiffRequest {\n path: string\n originalPath?: string | null\n scope: WorktreeGitDiffScope\n}\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\"\n\nexport interface WorkspaceLogEntry {\n workspaceId: string\n timestamp: string\n level: LogLevel\n message: string\n}\n\nexport interface FileSystemEntry {\n name: string\n /**\n * Path identifier for the entry. Relative to the server root in restricted\n * single-root listings (\".\" represents the root itself); absolute in\n * unrestricted, drives, and multi-root top-level listings.\n */\n path: string\n /** Absolute path when available (unrestricted and multi-root listings). */\n absolutePath?: string\n type: \"file\" | \"directory\"\n size?: number\n /** ISO timestamp of last modification when available. */\n modifiedAt?: string\n}\n\nexport type FileSystemScope = \"restricted\" | \"unrestricted\"\nexport type FileSystemPathKind = \"relative\" | \"absolute\" | \"drives\"\n\nexport interface FileSystemListingMetadata {\n scope: FileSystemScope\n /**\n * Canonical identifier of the current view:\n * - \".\" for restricted single-root listings\n * - WINDOWS_DRIVES_ROOT for the Windows drives pseudo-root\n * - absolute path otherwise\n */\n currentPath: string\n /** Optional parent path if navigation upward is allowed. */\n parentPath?: string\n /** Absolute path representing the root or origin point for this listing. */\n rootPath: string\n /** Absolute home directory of the CLI host (useful defaults for unrestricted mode). */\n homePath: string\n /** Human-friendly label for the current path. */\n displayPath: string\n /** Indicates whether entry paths are relative, absolute, or represent the drive pseudo-view. */\n pathKind: FileSystemPathKind\n}\n\nexport interface FileSystemListResponse {\n entries: FileSystemEntry[]\n metadata: FileSystemListingMetadata\n}\n\nexport interface FileSystemCreateFolderRequest {\n /**\n * Path identifier for the currently browsed directory.\n * Matches the `path` parameter used for `/api/filesystem`.\n */\n parentPath?: string\n /** Single folder name (no separators). */\n name: string\n}\n\nexport interface FileSystemCreateFolderResponse {\n /**\n * Path identifier that can be passed back to `/api/filesystem` to browse the new folder.\n * Relative for restricted listings and absolute for unrestricted listings.\n */\n path: string\n /** Absolute folder path on the server host. */\n absolutePath: string\n}\n\nexport interface FileSystemFileContentResponse {\n path: string\n contents: string\n encoding: \"utf-8\" | \"base64\"\n}\n\nexport interface ConfigFileDescriptor {\n id: string\n label: string\n path: string\n language: string\n}\n\nexport type ConfigFileListResponse = ConfigFileDescriptor[]\n\nexport interface ConfigFileContentResponse {\n id: string\n path: string\n contents: string\n exists: boolean\n}\n\nexport interface ConfigFileContentRequest {\n contents: string\n}\n\nexport const WINDOWS_DRIVES_ROOT = \"__drives__\"\n\nexport interface WorkspaceFileResponse {\n workspaceId: string\n relativePath: string\n /** UTF-8 file contents; binary files should be base64 encoded by the caller. */\n contents: string\n encoding?: \"utf-8\" | \"base64\"\n}\n\nexport type WorkspaceFileSearchResponse = FileSystemEntry[]\n\nexport interface InstanceData {\n messageHistory: string[]\n agentModelSelections: AgentModelSelection\n}\n\nexport type InstanceStreamStatus = \"connecting\" | \"connected\" | \"error\" | \"disconnected\"\n\nexport type InstanceStreamEvent = OpenCodeEvent\n\nexport type SideCarKind = \"port\"\n\nexport type SideCarPrefixMode = \"strip\" | \"preserve\"\n\nexport type SideCarStatus = \"running\" | \"stopped\"\n\nexport interface SideCar {\n id: string\n kind: SideCarKind\n name: string\n port: number\n insecure: boolean\n prefixMode: SideCarPrefixMode\n status: SideCarStatus\n createdAt: string\n updatedAt: string\n}\n\nexport interface PreviewSession {\n token: string\n sessionId: string\n targetUrl: string\n proxyUrl: string\n createdAt: string\n}\n\nexport interface BinaryRecord {\n id: string\n path: string\n label: string\n version?: string\n\n /** Indicates that this binary will be picked when workspaces omit an explicit choice. */\n isDefault: boolean\n lastValidatedAt?: string\n validationError?: string\n}\n\nexport type SettingsOwner = string\nexport type SettingsBucket = Record<string, unknown>\nexport type SettingsDoc = Record<string, unknown>\n\nexport interface BinaryListResponse {\n binaries: BinaryRecord[]\n}\n\nexport interface BinaryCreateRequest {\n path: string\n label?: string\n makeDefault?: boolean\n}\n\nexport interface BinaryUpdateRequest {\n label?: string\n makeDefault?: boolean\n}\n\nexport const OPENCODE_V2_REQUIRED_ERROR_CODE = \"opencode_v2_required\" as const\n\nexport interface BinaryValidationResult {\n valid: boolean\n version?: string\n error?: string\n errorCode?: typeof OPENCODE_V2_REQUIRED_ERROR_CODE\n}\n\nexport interface OpenCodeUpdateStatus {\n currentVersion: string\n latestVersion: string | null\n updateAvailable: boolean | null\n canUpgrade: boolean\n checkError?: \"update_check_failed\"\n}\n\nexport interface OpenCodeUpdateResponse {\n success: boolean\n version: string\n}\n\nexport interface SpeechSegment {\n startMs: number\n endMs: number\n text: string\n}\n\nexport interface SpeechCapabilitiesResponse {\n available: boolean\n configured: boolean\n provider: string\n supportsStt: boolean\n supportsTts: boolean\n supportsStreamingTts: boolean\n baseUrl?: string\n sttModel: string\n ttsModel: string\n ttsVoice: string\n ttsFormats: string[]\n streamingTtsFormats: string[]\n separateProviders?: boolean\n sttConfigured?: boolean\n ttsConfigured?: boolean\n sttBaseUrl?: string\n ttsBaseUrl?: string\n}\n\nexport interface SpeechTranscriptionResponse {\n text: string\n language?: string\n durationMs?: number\n segments?: SpeechSegment[]\n}\n\nexport interface SpeechSynthesisResponse {\n audioBase64: string\n mimeType: string\n}\n\nexport interface YoloStateResponse {\n enabled: boolean\n}\n\nexport interface RemoteServerProfile {\n id: string\n name: string\n baseUrl: string\n skipTlsVerify: boolean\n createdAt: string\n updatedAt: string\n lastConnectedAt?: string\n}\n\nexport interface RemoteServerProbeRequest {\n baseUrl: string\n skipTlsVerify?: boolean\n}\n\nexport interface RemoteServerProbeResponse {\n ok: boolean\n reachable: boolean\n normalizedUrl: string\n skipTlsVerify: boolean\n requiresAuth: boolean\n authenticated: boolean\n error?: string\n errorCode?: string\n}\n\nexport interface RemoteProxySessionCreateRequest {\n baseUrl: string\n skipTlsVerify?: boolean\n}\n\nexport interface RemoteProxySessionCreateResponse {\n sessionId: string\n windowUrl: string\n}\n\nexport type WorkspaceEventType =\n | \"workspace.created\"\n | \"workspace.started\"\n | \"workspace.error\"\n | \"workspace.stopped\"\n | \"workspace.log\"\n | \"sidecar.updated\"\n | \"sidecar.removed\"\n | \"storage.configChanged\"\n | \"storage.stateChanged\"\n | \"instance.dataChanged\"\n | \"instance.event\"\n | \"instance.eventStatus\"\n | \"yolo.stateChanged\"\n | \"yolo.autoAccepted\"\n\nexport type WorkspaceEventPayload =\n | { type: \"workspace.created\"; workspace: WorkspaceDescriptor }\n | { type: \"workspace.started\"; workspace: WorkspaceDescriptor }\n | { type: \"workspace.error\"; workspace: WorkspaceDescriptor }\n | { type: \"workspace.stopped\"; workspaceId: string; reason?: \"deleted\" | \"stopped\" }\n | { type: \"workspace.log\"; entry: WorkspaceLogEntry }\n | { type: \"sidecar.updated\"; sidecar: SideCar }\n | { type: \"sidecar.removed\"; sidecarId: string }\n | { type: \"storage.configChanged\"; owner: SettingsOwner; value: SettingsBucket }\n | { type: \"storage.stateChanged\"; owner: SettingsOwner; value: SettingsBucket }\n | { type: \"instance.dataChanged\"; instanceId: string; data: InstanceData }\n | { type: \"instance.event\"; instanceId: string; event: InstanceStreamEvent }\n | { type: \"instance.eventStatus\"; instanceId: string; status: InstanceStreamStatus; generation: number; reason?: string }\n | { type: \"yolo.stateChanged\"; instanceId: string; sessionId: string; enabled: boolean }\n | { type: \"yolo.autoAccepted\"; instanceId: string; sessionId: string; permissionId: string }\n\nexport interface NetworkAddress {\n ip: string\n family: \"ipv4\" | \"ipv6\"\n scope: \"external\" | \"internal\" | \"loopback\"\n /** Remote URL using the server's remote protocol/port for this IP. */\n remoteUrl: string\n}\n\nexport interface LatestReleaseInfo {\n version: string\n tag: string\n url: string\n channel: \"stable\" | \"dev\"\n publishedAt?: string\n notes?: string\n}\n\nexport interface UiMeta {\n version?: string\n source: \"bundled\" | \"downloaded\" | \"previous\" | \"override\" | \"dev-proxy\" | \"missing\"\n}\n\nexport interface SupportMeta {\n supported: boolean\n message?: string\n minServerVersion?: string\n latestServerVersion?: string\n latestServerUrl?: string\n}\n\nexport interface ServerMeta {\n /** URL desktop apps should use to connect (prefers loopback HTTP when enabled). */\n localUrl: string\n /** URL remote clients should use (prefers HTTPS when enabled). */\n remoteUrl?: string\n /** SSE endpoint advertised to clients (`/api/events` by default). */\n eventsUrl: string\n /** Host the server is bound to (e.g., 127.0.0.1 or 0.0.0.0). */\n host: string\n /** Listening mode derived from host binding. */\n listeningMode: \"local\" | \"all\"\n /** Actual local port in use after binding. */\n localPort: number\n /** Actual remote port in use after binding (when remoteUrl is set). */\n remotePort?: number\n /** Display label for the host (e.g., hostname or friendly name). */\n hostLabel: string\n /** Absolute path of the filesystem root exposed to clients. */\n workspaceRoot: string\n /** Reachable addresses for this server, external first. */\n addresses: NetworkAddress[]\n serverVersion?: string\n ui?: UiMeta\n support?: SupportMeta\n /** Optional update info (dev channel only). */\n update?: LatestReleaseInfo | null\n}\n\nexport type {\n Preferences,\n ModelPreference,\n AgentModelSelections,\n RecentFolder,\n OpenCodeBinary,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api-types.js","sourceRoot":"","sources":["../src/api-types.ts"],"names":[],"mappings":"AAqQA,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAA;AA8E/C,MAAM,CAAC,MAAM,+BAA+B,GAAG,sBAA+B,CAAA","sourcesContent":["import type {\n AgentModelSelection,\n AgentModelSelections,\n ModelPreference,\n OpenCodeBinary,\n Preferences,\n RecentFolder,\n} from \"./config/schema\"\nimport type { OpenCodeEvent } from \"@opencode-ai/client\"\n\n/**\n * Canonical HTTP/SSE contract for the CLI server.\n * These types are consumed by both the CLI implementation and any UI clients.\n */\n\nexport type WorkspaceStatus = \"starting\" | \"ready\" | \"stopped\" | \"error\"\n\nexport interface WorkspaceDescriptor {\n id: string\n /** Correlates creation events with the client request that initiated them. */\n requestId?: string\n /** Absolute path on the server host. */\n path: string\n name?: string\n status: WorkspaceStatus\n /** PID/port are populated when the workspace is running. */\n pid?: number\n port?: number\n /** Canonical proxy path the CLI exposes for this instance. */\n proxyPath: string\n /** Identifier of the binary resolved from config. */\n binaryId: string\n binaryLabel: string\n binaryVersion?: string\n createdAt: string\n updatedAt: string\n /** Present when `status` is \"error\". */\n error?: string\n}\n\nexport interface WorkspaceCreateRequest {\n path: string\n name?: string\n requestId?: string\n}\n\nexport interface WorkspaceCloneRequest {\n repositoryUrl: string\n destinationPath: string\n cleanup?: boolean\n}\n\nexport interface WorkspaceCloneResponse {\n path: string\n}\n\nexport type WorkspaceCreateResponse = WorkspaceDescriptor & {\n /** True when this request did not own creation of the returned workspace. */\n reused?: true\n}\nexport type WorkspaceListResponse = WorkspaceDescriptor[]\nexport type WorkspaceDetailResponse = WorkspaceDescriptor\n\nexport interface WorkspaceDeleteResponse {\n id: string\n status: WorkspaceStatus\n}\n\nexport interface ProviderUsageWindow {\n usedPercent: number | null\n remainingPercent: number | null\n windowSeconds: number | null\n resetAt: number | null\n valueLabel?: string\n}\n\nexport interface ProviderUsageResponse {\n requestedProviderId: string\n providerId: string | null\n providerName: string\n modelId?: string\n supported: boolean\n configured: boolean\n ok: boolean\n windows: Record<string, ProviderUsageWindow>\n fetchedAt: number\n}\n\nexport type WorktreeKind = \"root\" | \"worktree\"\n\nexport interface WorktreeDescriptor {\n /** Stable identifier used by CodeNomad + clients (\"root\" for the selected workspace folder). */\n slug: string\n /** Absolute directory path on the server host. */\n directory: string\n kind: WorktreeKind\n /** Optional VCS branch name when available. */\n branch?: string\n}\n\nexport interface WorktreeListResponse {\n worktrees: WorktreeDescriptor[]\n /** True when the workspace folder resolves to a Git repository. */\n isGitRepo?: boolean\n}\n\nexport interface WorktreeCreateRequest {\n slug: string\n /** Optional branch name (defaults to slug). */\n branch?: string\n}\n\nexport type GitChangeKind = \"added\" | \"modified\" | \"deleted\" | \"renamed\" | \"copied\" | \"untracked\" | \"unmerged\"\n\nexport interface WorktreeGitStatusEntry {\n path: string\n originalPath?: string | null\n stagedStatus: GitChangeKind | null\n stagedAdditions: number\n stagedDeletions: number\n unstagedStatus: GitChangeKind | null\n unstagedAdditions: number\n unstagedDeletions: number\n}\n\nexport type WorktreeGitStatusResponse = WorktreeGitStatusEntry[]\n\nexport type WorktreeGitDiffScope = \"staged\" | \"unstaged\"\n\nexport interface WorktreeGitPathsRequest {\n paths: string[]\n}\n\nexport interface WorktreeGitMutationResponse {\n ok: true\n}\n\nexport interface WorktreeGitCommitRequest {\n message: string\n}\n\nexport interface WorktreeGitCommitResponse {\n ok: true\n commitSha?: string\n}\n\nexport interface WorktreeGitDiffResponse {\n path: string\n originalPath?: string | null\n scope: WorktreeGitDiffScope\n before: string\n after: string\n isBinary?: boolean\n}\n\nexport interface WorktreeGitDiffRequest {\n path: string\n originalPath?: string | null\n scope: WorktreeGitDiffScope\n}\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\"\n\nexport interface WorkspaceLogEntry {\n workspaceId: string\n timestamp: string\n level: LogLevel\n message: string\n}\n\nexport interface FileSystemEntry {\n name: string\n /**\n * Path identifier for the entry. Relative to the server root in restricted\n * single-root listings (\".\" represents the root itself); absolute in\n * unrestricted, drives, and multi-root top-level listings.\n */\n path: string\n /** Absolute path when available (unrestricted and multi-root listings). */\n absolutePath?: string\n type: \"file\" | \"directory\"\n size?: number\n /** ISO timestamp of last modification when available. */\n modifiedAt?: string\n}\n\nexport type FileSystemScope = \"restricted\" | \"unrestricted\"\nexport type FileSystemPathKind = \"relative\" | \"absolute\" | \"drives\"\n\nexport interface FileSystemListingMetadata {\n scope: FileSystemScope\n /**\n * Canonical identifier of the current view:\n * - \".\" for restricted single-root listings\n * - WINDOWS_DRIVES_ROOT for the Windows drives pseudo-root\n * - absolute path otherwise\n */\n currentPath: string\n /** Optional parent path if navigation upward is allowed. */\n parentPath?: string\n /** Absolute path representing the root or origin point for this listing. */\n rootPath: string\n /** Absolute home directory of the CLI host (useful defaults for unrestricted mode). */\n homePath: string\n /** Human-friendly label for the current path. */\n displayPath: string\n /** Indicates whether entry paths are relative, absolute, or represent the drive pseudo-view. */\n pathKind: FileSystemPathKind\n}\n\nexport interface FileSystemListResponse {\n entries: FileSystemEntry[]\n metadata: FileSystemListingMetadata\n}\n\nexport interface FileSystemCreateFolderRequest {\n /**\n * Path identifier for the currently browsed directory.\n * Matches the `path` parameter used for `/api/filesystem`.\n */\n parentPath?: string\n /** Single folder name (no separators). */\n name: string\n}\n\nexport interface FileSystemCreateFolderResponse {\n /**\n * Path identifier that can be passed back to `/api/filesystem` to browse the new folder.\n * Relative for restricted listings and absolute for unrestricted listings.\n */\n path: string\n /** Absolute folder path on the server host. */\n absolutePath: string\n}\n\nexport interface FileSystemFileContentResponse {\n path: string\n contents: string\n encoding: \"utf-8\" | \"base64\"\n}\n\nexport interface ConfigFileDescriptor {\n id: string\n label: string\n path: string\n language: string\n}\n\nexport type ConfigFileListResponse = ConfigFileDescriptor[]\n\nexport interface ConfigFileContentResponse {\n id: string\n path: string\n contents: string\n exists: boolean\n}\n\nexport interface ConfigFileContentRequest {\n contents: string\n}\n\nexport const WINDOWS_DRIVES_ROOT = \"__drives__\"\n\nexport interface WorkspaceFileResponse {\n workspaceId: string\n relativePath: string\n /** UTF-8 file contents; binary files should be base64 encoded by the caller. */\n contents: string\n encoding?: \"utf-8\" | \"base64\"\n}\n\nexport type WorkspaceFileSearchResponse = FileSystemEntry[]\n\nexport interface InstanceData {\n messageHistory: string[]\n agentModelSelections: AgentModelSelection\n}\n\nexport type InstanceStreamStatus = \"connecting\" | \"connected\" | \"error\" | \"disconnected\"\n\nexport type InstanceStreamEvent = OpenCodeEvent\n\nexport type SideCarKind = \"port\"\n\nexport type SideCarPrefixMode = \"strip\" | \"preserve\"\n\nexport type SideCarStatus = \"running\" | \"stopped\"\n\nexport interface SideCar {\n id: string\n kind: SideCarKind\n name: string\n port: number\n insecure: boolean\n prefixMode: SideCarPrefixMode\n status: SideCarStatus\n createdAt: string\n updatedAt: string\n}\n\nexport interface PreviewSession {\n token: string\n sessionId: string\n targetUrl: string\n proxyUrl: string\n createdAt: string\n}\n\nexport interface BinaryRecord {\n id: string\n path: string\n label: string\n version?: string\n\n /** Indicates that this binary will be picked when workspaces omit an explicit choice. */\n isDefault: boolean\n lastValidatedAt?: string\n validationError?: string\n}\n\nexport type SettingsOwner = string\nexport type SettingsBucket = Record<string, unknown>\nexport type SettingsDoc = Record<string, unknown>\n\nexport interface BinaryListResponse {\n binaries: BinaryRecord[]\n}\n\nexport interface BinaryCreateRequest {\n path: string\n label?: string\n makeDefault?: boolean\n}\n\nexport interface BinaryUpdateRequest {\n label?: string\n makeDefault?: boolean\n}\n\nexport const OPENCODE_V2_REQUIRED_ERROR_CODE = \"opencode_v2_required\" as const\n\nexport interface BinaryValidationResult {\n valid: boolean\n version?: string\n error?: string\n errorCode?: typeof OPENCODE_V2_REQUIRED_ERROR_CODE\n}\n\nexport interface OpenCodeUpdateStatus {\n currentVersion: string\n latestVersion: string | null\n updateAvailable: boolean | null\n canUpgrade: boolean\n checkError?: \"update_check_failed\"\n}\n\nexport interface OpenCodeUpdateResponse {\n success: boolean\n version: string\n}\n\nexport interface SpeechSegment {\n startMs: number\n endMs: number\n text: string\n}\n\nexport interface SpeechCapabilitiesResponse {\n available: boolean\n configured: boolean\n provider: string\n supportsStt: boolean\n supportsTts: boolean\n supportsStreamingTts: boolean\n baseUrl?: string\n sttModel: string\n ttsModel: string\n ttsVoice: string\n ttsFormats: string[]\n streamingTtsFormats: string[]\n separateProviders?: boolean\n sttConfigured?: boolean\n ttsConfigured?: boolean\n sttBaseUrl?: string\n ttsBaseUrl?: string\n}\n\nexport interface SpeechTranscriptionResponse {\n text: string\n language?: string\n durationMs?: number\n segments?: SpeechSegment[]\n}\n\nexport interface SpeechSynthesisResponse {\n audioBase64: string\n mimeType: string\n}\n\nexport interface YoloStateResponse {\n enabled: boolean\n}\n\nexport interface RemoteServerProfile {\n id: string\n name: string\n baseUrl: string\n skipTlsVerify: boolean\n createdAt: string\n updatedAt: string\n lastConnectedAt?: string\n}\n\nexport interface RemoteServerProbeRequest {\n baseUrl: string\n skipTlsVerify?: boolean\n}\n\nexport interface RemoteServerProbeResponse {\n ok: boolean\n reachable: boolean\n normalizedUrl: string\n skipTlsVerify: boolean\n requiresAuth: boolean\n authenticated: boolean\n error?: string\n errorCode?: string\n}\n\nexport interface RemoteProxySessionCreateRequest {\n baseUrl: string\n skipTlsVerify?: boolean\n}\n\nexport interface RemoteProxySessionCreateResponse {\n sessionId: string\n windowUrl: string\n}\n\nexport type WorkspaceEventType =\n | \"workspace.created\"\n | \"workspace.started\"\n | \"workspace.error\"\n | \"workspace.stopped\"\n | \"workspace.log\"\n | \"sidecar.updated\"\n | \"sidecar.removed\"\n | \"storage.configChanged\"\n | \"storage.stateChanged\"\n | \"instance.dataChanged\"\n | \"instance.event\"\n | \"instance.eventStatus\"\n | \"yolo.stateChanged\"\n | \"yolo.autoAccepted\"\n\nexport type WorkspaceEventPayload =\n | { type: \"workspace.created\"; workspace: WorkspaceDescriptor }\n | { type: \"workspace.started\"; workspace: WorkspaceDescriptor }\n | { type: \"workspace.error\"; workspace: WorkspaceDescriptor }\n | { type: \"workspace.stopped\"; workspaceId: string; reason?: \"deleted\" | \"stopped\" }\n | { type: \"workspace.log\"; entry: WorkspaceLogEntry }\n | { type: \"sidecar.updated\"; sidecar: SideCar }\n | { type: \"sidecar.removed\"; sidecarId: string }\n | { type: \"storage.configChanged\"; owner: SettingsOwner; value: SettingsBucket }\n | { type: \"storage.stateChanged\"; owner: SettingsOwner; value: SettingsBucket }\n | { type: \"instance.dataChanged\"; instanceId: string; data: InstanceData }\n | { type: \"instance.event\"; instanceId: string; event: InstanceStreamEvent }\n | { type: \"instance.eventStatus\"; instanceId: string; status: InstanceStreamStatus; generation: number; reason?: string }\n | { type: \"yolo.stateChanged\"; instanceId: string; sessionId: string; enabled: boolean }\n | { type: \"yolo.autoAccepted\"; instanceId: string; sessionId: string; permissionId: string }\n\nexport interface NetworkAddress {\n ip: string\n family: \"ipv4\" | \"ipv6\"\n scope: \"external\" | \"internal\" | \"loopback\"\n /** Remote URL using the server's remote protocol/port for this IP. */\n remoteUrl: string\n}\n\nexport interface LatestReleaseInfo {\n version: string\n tag: string\n url: string\n channel: \"stable\" | \"dev\"\n publishedAt?: string\n notes?: string\n}\n\nexport interface UiMeta {\n version?: string\n source: \"bundled\" | \"downloaded\" | \"previous\" | \"override\" | \"dev-proxy\" | \"missing\"\n}\n\nexport interface SupportMeta {\n supported: boolean\n message?: string\n minServerVersion?: string\n latestServerVersion?: string\n latestServerUrl?: string\n}\n\nexport interface ServerMeta {\n /** URL desktop apps should use to connect (prefers loopback HTTP when enabled). */\n localUrl: string\n /** URL remote clients should use (prefers HTTPS when enabled). */\n remoteUrl?: string\n /** SSE endpoint advertised to clients (`/api/events` by default). */\n eventsUrl: string\n /** Host the server is bound to (e.g., 127.0.0.1 or 0.0.0.0). */\n host: string\n /** Listening mode derived from host binding. */\n listeningMode: \"local\" | \"all\"\n /** Actual local port in use after binding. */\n localPort: number\n /** Actual remote port in use after binding (when remoteUrl is set). */\n remotePort?: number\n /** Display label for the host (e.g., hostname or friendly name). */\n hostLabel: string\n /** Absolute path of the filesystem root exposed to clients. */\n workspaceRoot: string\n /** Reachable addresses for this server, external first. */\n addresses: NetworkAddress[]\n serverVersion?: string\n ui?: UiMeta\n support?: SupportMeta\n /** Optional update info (dev channel only). */\n update?: LatestReleaseInfo | null\n}\n\nexport type {\n Preferences,\n ModelPreference,\n AgentModelSelections,\n RecentFolder,\n OpenCodeBinary,\n}\nexport type { PruneRequest, PruneResult } from \"./opencode/session-pruning/contract\"\n"]}
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,8 @@ import { AuthManager, BOOTSTRAP_TOKEN_STDOUT_PREFIX, DEFAULT_AUTH_COOKIE_NAME, D
|
|
|
22
22
|
import { resolveHttpsOptions } from "./server/tls";
|
|
23
23
|
import { RemoteProxySessionManager } from "./server/remote-proxy";
|
|
24
24
|
import { resolveNetworkAddresses, resolveRemoteAddresses } from "./server/network-addresses";
|
|
25
|
-
import { resolveAutomationBridgeUrl, resolvePluginBaseUrl } from "./server/listener-base-url";
|
|
25
|
+
import { resolveAutomationBridgeUrl, resolvePluginBaseUrl, resolvePreferredRemoteListener } from "./server/listener-base-url";
|
|
26
|
+
import { formatHostForUrl, hasIPv6Zone, isLoopbackHost, isWildcardHost, normalizeNetworkHost } from "./server/network-host";
|
|
26
27
|
import { startDevReleaseMonitor } from "./releases/dev-release-monitor";
|
|
27
28
|
import { SpeechService } from "./speech/service";
|
|
28
29
|
import { SideCarManager } from "./sidecars/manager";
|
|
@@ -34,6 +35,7 @@ import { AutoAcceptManager } from "./permissions/auto-accept-manager";
|
|
|
34
35
|
import { createOpencodePermissionReplier } from "./permissions/opencode-replier";
|
|
35
36
|
import { createOpencodeYoloPersistence } from "./permissions/opencode-yolo-metadata";
|
|
36
37
|
import { NativeParent } from "./native-parent";
|
|
38
|
+
import { PruningLifecycle } from "./opencode/pruning-lifecycle";
|
|
37
39
|
import { AUTOMATION_BRIDGE_PATH, createAutomationBridgeRegistration, publishAutomationBridge, removeLegacyAutomationPlugin } from "./opencode/automation-plugin";
|
|
38
40
|
const require = createRequire(import.meta.url);
|
|
39
41
|
const packageJson = require("../package.json");
|
|
@@ -166,17 +168,18 @@ function parsePort(input) {
|
|
|
166
168
|
}
|
|
167
169
|
return value;
|
|
168
170
|
}
|
|
169
|
-
function resolveHost(input) {
|
|
171
|
+
export function resolveHost(input) {
|
|
170
172
|
const trimmed = input?.trim();
|
|
171
173
|
if (!trimmed)
|
|
172
174
|
return DEFAULT_HOST;
|
|
173
|
-
if (trimmed
|
|
174
|
-
|
|
175
|
+
if (hasIPv6Zone(trimmed)) {
|
|
176
|
+
throw new InvalidArgumentError("IPv6 zone identifiers are not supported in --host");
|
|
175
177
|
}
|
|
176
|
-
|
|
178
|
+
const normalized = normalizeNetworkHost(trimmed);
|
|
179
|
+
if (normalized === "localhost") {
|
|
177
180
|
return DEFAULT_HOST;
|
|
178
181
|
}
|
|
179
|
-
return
|
|
182
|
+
return normalized;
|
|
180
183
|
}
|
|
181
184
|
export function programHasArg(argv, flag) {
|
|
182
185
|
return argv.some((argument) => argument === flag || argument.startsWith(`${flag}=`));
|
|
@@ -201,7 +204,6 @@ async function main() {
|
|
|
201
204
|
logger.warn("DANGEROUS: internal authentication is disabled (--dangerously-skip-auth / CODENOMAD_SKIP_AUTH).");
|
|
202
205
|
}
|
|
203
206
|
const eventBus = new EventBus(eventLogger);
|
|
204
|
-
const isLoopbackHost = (host) => host === "127.0.0.1" || host === "::1" || host.startsWith("127.");
|
|
205
207
|
const configLocation = resolveConfigLocation(options.configPath);
|
|
206
208
|
const configDir = configLocation.baseDir;
|
|
207
209
|
if ((options.tlsKeyPath && !options.tlsCertPath) || (!options.tlsKeyPath && options.tlsCertPath)) {
|
|
@@ -245,12 +247,23 @@ async function main() {
|
|
|
245
247
|
});
|
|
246
248
|
const settings = new SettingsService(configLocation, eventBus, configLogger);
|
|
247
249
|
const binaryResolver = new BinaryResolver(settings);
|
|
250
|
+
const pruningLifecycle = new PruningLifecycle();
|
|
251
|
+
const prepareSessionPruning = async (...args) => {
|
|
252
|
+
try {
|
|
253
|
+
await pruningLifecycle.start(...args);
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
logger.error({ err: error }, "Failed to load the bundled session-pruning plugin");
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
await prepareSessionPruning();
|
|
248
260
|
const workspaceManager = new WorkspaceManager({
|
|
249
261
|
rootDir: options.rootDir,
|
|
250
262
|
settings,
|
|
251
263
|
binaryResolver,
|
|
252
264
|
eventBus,
|
|
253
265
|
logger: workspaceLogger,
|
|
266
|
+
prepareSessionPruning,
|
|
254
267
|
});
|
|
255
268
|
const nativeParent = new NativeParent();
|
|
256
269
|
if (nativeParent.available) {
|
|
@@ -328,7 +341,6 @@ async function main() {
|
|
|
328
341
|
},
|
|
329
342
|
})
|
|
330
343
|
: null;
|
|
331
|
-
const remoteAccessEnabled = options.host === "0.0.0.0" || !isLoopbackHost(options.host);
|
|
332
344
|
const clientConnectionManager = new ClientConnectionManager(logger.child({ component: "client-connections" }));
|
|
333
345
|
const remoteProxySessionManager = new RemoteProxySessionManager({
|
|
334
346
|
authManager,
|
|
@@ -340,10 +352,9 @@ async function main() {
|
|
|
340
352
|
const httpsBindPort = httpsPortExplicit ? options.httpsPort : 0;
|
|
341
353
|
const httpBindPort = httpPortExplicit ? options.httpPort : 0;
|
|
342
354
|
// Listener binding rules:
|
|
343
|
-
// -
|
|
344
|
-
// -
|
|
345
|
-
|
|
346
|
-
const httpsBindHost = remoteAccessEnabled ? options.host : "127.0.0.1";
|
|
355
|
+
// - Native desktop HTTP and dual-listener HTTP stay on loopback.
|
|
356
|
+
// - HTTPS and non-native HTTP-only modes respect --host.
|
|
357
|
+
const httpsBindHost = options.host;
|
|
347
358
|
const httpBindHost = nativeParent.available ? "127.0.0.1" : options.http ? (options.https ? "127.0.0.1" : options.host) : "127.0.0.1";
|
|
348
359
|
const servers = [];
|
|
349
360
|
const httpServer = options.http || nativeParent.available
|
|
@@ -412,41 +423,40 @@ async function main() {
|
|
|
412
423
|
if (!localStart) {
|
|
413
424
|
throw new Error("No listeners started");
|
|
414
425
|
}
|
|
415
|
-
const
|
|
416
|
-
const
|
|
426
|
+
const httpListener = httpStart ? { protocol: "http", bindHost: httpBindHost, port: httpStart.port } : null;
|
|
427
|
+
const httpsListener = httpsStart ? { protocol: "https", bindHost: httpsBindHost, port: httpsStart.port } : null;
|
|
428
|
+
const remoteListener = resolvePreferredRemoteListener({ httpStart: httpListener, httpsStart: httpsListener });
|
|
417
429
|
let remoteUrl;
|
|
418
430
|
let remoteAddresses = [];
|
|
419
|
-
if (
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
remoteUrl = resolved.primaryRemoteUrl ?? `${remoteProtocol}://localhost:${remoteStart.port}`;
|
|
427
|
-
}
|
|
431
|
+
if (remoteListener) {
|
|
432
|
+
let remoteHost = remoteListener.bindHost;
|
|
433
|
+
if (isWildcardHost(remoteListener.bindHost)) {
|
|
434
|
+
const resolved = resolveRemoteAddresses({ host: remoteListener.bindHost, protocol: remoteListener.protocol, port: remoteListener.port });
|
|
435
|
+
remoteAddresses = resolved.userVisible;
|
|
436
|
+
const loopbackHost = remoteListener.bindHost === "0.0.0.0" ? "127.0.0.1" : "::1";
|
|
437
|
+
remoteUrl = resolved.primaryRemoteUrl ?? `${remoteListener.protocol}://${formatHostForUrl(loopbackHost)}:${remoteListener.port}`;
|
|
428
438
|
}
|
|
429
|
-
else {
|
|
439
|
+
else if (remoteListener.bindHost === "127.0.0.1") {
|
|
430
440
|
remoteHost = "localhost";
|
|
431
441
|
}
|
|
432
442
|
if (!remoteUrl) {
|
|
433
|
-
remoteUrl = `${
|
|
443
|
+
remoteUrl = `${remoteListener.protocol}://${formatHostForUrl(remoteHost)}:${remoteListener.port}`;
|
|
434
444
|
}
|
|
435
445
|
}
|
|
436
446
|
// Prefer an explicit IPv4 loopback address only when one of the bound listeners
|
|
437
447
|
// accepts loopback. Concrete LAN bindings do not, so plugins need the reachable
|
|
438
448
|
// bound/listener URL instead of an unreachable 127.0.0.1 URL.
|
|
439
449
|
const localUrl = resolvePluginBaseUrl({
|
|
440
|
-
httpStart:
|
|
441
|
-
httpsStart:
|
|
450
|
+
httpStart: options.http ? httpListener : null,
|
|
451
|
+
httpsStart: httpsListener,
|
|
442
452
|
remoteUrl,
|
|
443
453
|
});
|
|
444
454
|
serverMeta.localUrl = localUrl;
|
|
445
455
|
serverMeta.localPort = localStart.port;
|
|
446
456
|
serverMeta.remoteUrl = remoteUrl;
|
|
447
|
-
serverMeta.remotePort =
|
|
448
|
-
serverMeta.host = options.host;
|
|
449
|
-
serverMeta.listeningMode =
|
|
457
|
+
serverMeta.remotePort = remoteListener?.port;
|
|
458
|
+
serverMeta.host = remoteListener?.bindHost ?? options.host;
|
|
459
|
+
serverMeta.listeningMode = isWildcardHost(serverMeta.host) || !isLoopbackHost(serverMeta.host) ? "all" : "local";
|
|
450
460
|
let removeAutomationBridge;
|
|
451
461
|
if (nativeParent.available && process.env.CODENOMAD_DEVELOPER_MODE === "1") {
|
|
452
462
|
try {
|
|
@@ -465,7 +475,7 @@ async function main() {
|
|
|
465
475
|
if (serverMeta.remotePort && remoteUrl) {
|
|
466
476
|
serverMeta.addresses = remoteAddresses.length
|
|
467
477
|
? remoteAddresses
|
|
468
|
-
: resolveNetworkAddresses({ host:
|
|
478
|
+
: resolveNetworkAddresses({ host: serverMeta.host, protocol: remoteListener?.protocol ?? "http", port: serverMeta.remotePort });
|
|
469
479
|
}
|
|
470
480
|
else {
|
|
471
481
|
serverMeta.addresses = [];
|
|
@@ -500,6 +510,7 @@ async function main() {
|
|
|
500
510
|
stopRemoteProxySessions: () => remoteProxySessionManager.shutdown(),
|
|
501
511
|
stopWorkspaces: () => workspaceManager.shutdown(),
|
|
502
512
|
stopHttpServers: async () => {
|
|
513
|
+
await pruningLifecycle.stop();
|
|
503
514
|
nativeParent.close();
|
|
504
515
|
await removeAutomationBridge?.();
|
|
505
516
|
yoloManager.stop();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI entry point.\n * For now this only wires the typed modules together; actual command handling comes later.\n */\nimport { Command, InvalidArgumentError, Option } from \"commander\"\nimport path from \"path\"\nimport { fileURLToPath } from \"url\"\nimport { createRequire } from \"module\"\nimport { createHttpServer } from \"./server/http-server\"\nimport { WorkspaceManager } from \"./workspaces/manager\"\nimport { resolveConfigLocation } from \"./config/location\"\nimport { SettingsService } from \"./settings/service\"\nimport { BinaryResolver } from \"./settings/binaries\"\nimport { FileSystemBrowser } from \"./filesystem/browser\"\nimport { EventBus } from \"./events/bus\"\nimport { ServerMeta } from \"./api-types\"\nimport { InstanceStore } from \"./storage/instance-store\"\nimport { InstanceEventBridge } from \"./workspaces/instance-events\"\nimport { createLogger } from \"./logger\"\nimport { launchInBrowser } from \"./launcher\"\nimport { resolveUi } from \"./ui/remote-ui\"\nimport { AuthManager, BOOTSTRAP_TOKEN_STDOUT_PREFIX, DEFAULT_AUTH_COOKIE_NAME, DEFAULT_AUTH_USERNAME } from \"./auth/manager\"\nimport { resolveHttpsOptions } from \"./server/tls\"\nimport { RemoteProxySessionManager } from \"./server/remote-proxy\"\nimport { resolveNetworkAddresses, resolveRemoteAddresses } from \"./server/network-addresses\"\nimport { resolveAutomationBridgeUrl, resolvePluginBaseUrl } from \"./server/listener-base-url\"\nimport { startDevReleaseMonitor } from \"./releases/dev-release-monitor\"\nimport { SpeechService } from \"./speech/service\"\nimport { SideCarManager } from \"./sidecars/manager\"\nimport { PreviewManager } from \"./previews/manager\"\nimport { ClientConnectionManager } from \"./clients/connection-manager\"\nimport { runCliUpgrade } from \"./cli-upgrade\"\nimport { createServerShutdownHandler, orchestrateServerShutdown, type ServerShutdownTrigger } from \"./shutdown\"\nimport { AutoAcceptManager } from \"./permissions/auto-accept-manager\"\nimport { createOpencodePermissionReplier } from \"./permissions/opencode-replier\"\nimport { createOpencodeYoloPersistence } from \"./permissions/opencode-yolo-metadata\"\nimport { NativeParent } from \"./native-parent\"\nimport { AUTOMATION_BRIDGE_PATH, createAutomationBridgeRegistration, publishAutomationBridge, removeLegacyAutomationPlugin } from \"./opencode/automation-plugin\"\n\nconst require = createRequire(import.meta.url)\n\nconst packageJson = require(\"../package.json\") as { version: string }\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\nconst DEFAULT_UI_STATIC_DIR = path.resolve(__dirname, \"../public\")\n\ninterface CliOptions {\n host: string\n https: boolean\n http: boolean\n httpsPort: number\n httpPort: number\n tlsKeyPath?: string\n tlsCertPath?: string\n tlsCaPath?: string\n tlsSANs?: string\n rootDir: string\n configPath: string\n unrestrictedRoot: boolean\n logLevel?: string\n logDestination?: string\n uiStaticDir: string\n uiDevServer?: string\n uiAutoUpdate: boolean\n uiNoUpdate: boolean\n uiManifestUrl?: string\n launch: boolean\n authUsername: string\n authPassword?: string\n authCookieName: string\n generateToken: boolean\n dangerouslySkipAuth: boolean\n upgrade?: string | boolean\n}\n\nconst DEFAULT_HOST = \"127.0.0.1\"\nconst DEFAULT_CONFIG_PATH = \"~/.config/codenomad/config.json\"\nconst DEFAULT_HTTPS_PORT = 9898\nconst DEFAULT_HTTP_PORT = 9899\nexport const STDIN_SHUTDOWN_COMMAND = \"codenomad:shutdown\"\n\ninterface ShutdownSignalSource {\n on: (signal: \"SIGINT\" | \"SIGTERM\", listener: () => void) => unknown\n}\n\nexport function installShutdownSignalHandlers(\n source: ShutdownSignalSource,\n shutdown: (signal: ServerShutdownTrigger) => Promise<void>,\n): void {\n source.on(\"SIGINT\", () => void shutdown(\"SIGINT\"))\n source.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"))\n}\n\ninterface ShutdownStdinSource {\n on(event: \"data\", listener: (chunk: Buffer | string) => void): unknown\n off?(event: \"data\", listener: (chunk: Buffer | string) => void): unknown\n destroy?(): unknown\n}\n\nexport function installShutdownStdinHandler(\n source: ShutdownStdinSource,\n shutdown: (signal: ServerShutdownTrigger) => Promise<void>,\n handleLine?: (line: string) => boolean,\n): void {\n let buffer = \"\"\n let requested = false\n const onData = (chunk: Buffer | string) => {\n if (requested) return\n buffer += chunk.toString()\n const lines = buffer.split(/\\r?\\n/)\n buffer = lines.pop() ?? \"\"\n let shutdownRequested = false\n for (const line of lines) {\n if (line.trim() === STDIN_SHUTDOWN_COMMAND) shutdownRequested = true\n else handleLine?.(line)\n }\n if (!shutdownRequested) return\n\n requested = true\n source.off?.(\"data\", onData)\n source.destroy?.()\n void shutdown(\"stdin\")\n }\n source.on(\"data\", onData)\n}\n\nfunction parseCliOptions(argv: string[]): CliOptions {\n const program = new Command()\n .name(\"codenomad\")\n .description(\"CodeNomad CLI server\")\n .version(packageJson.version, \"-v, --version\", \"Show the CLI version\")\n .addOption(new Option(\"--host <host>\", \"Host interface to bind\").env(\"CLI_HOST\").default(DEFAULT_HOST))\n .addOption(new Option(\"--https <enabled>\", \"Enable HTTPS listener (true|false)\").env(\"CLI_HTTPS\").default(\"true\"))\n .addOption(new Option(\"--http <enabled>\", \"Enable HTTP listener (true|false)\").env(\"CLI_HTTP\").default(\"false\"))\n .addOption(new Option(\"--https-port <number>\", \"HTTPS port (0 for auto)\").env(\"CLI_HTTPS_PORT\").default(DEFAULT_HTTPS_PORT).argParser(parsePort))\n .addOption(new Option(\"--http-port <number>\", \"HTTP port (0 for auto)\").env(\"CLI_HTTP_PORT\").default(DEFAULT_HTTP_PORT).argParser(parsePort))\n .addOption(new Option(\"--tls-key <path>\", \"TLS private key (PEM)\").env(\"CLI_TLS_KEY\"))\n .addOption(new Option(\"--tls-cert <path>\", \"TLS certificate (PEM)\").env(\"CLI_TLS_CERT\"))\n .addOption(new Option(\"--tls-ca <path>\", \"TLS CA chain (PEM)\").env(\"CLI_TLS_CA\"))\n .addOption(new Option(\"--tlsSANs <list>\", \"Additional TLS SANs (comma-separated)\").env(\"CLI_TLS_SANS\"))\n .addOption(\n new Option(\"--workspace-root <path>\", \"Restricts root path where workspaces can be opened\").env(\"CLI_WORKSPACE_ROOT\").default(process.cwd()),\n )\n .addOption(new Option(\"--root <path>\").env(\"CLI_ROOT\").hideHelp(true))\n .addOption(new Option(\"--unrestricted-root\", \"Allow browsing the full filesystem\").env(\"CLI_UNRESTRICTED_ROOT\").default(false))\n .addOption(new Option(\"--config <path>\", \"Path to the config file\").env(\"CLI_CONFIG\").default(DEFAULT_CONFIG_PATH))\n .addOption(new Option(\"--log-level <level>\", \"Log level (trace|debug|info|warn|error)\").env(\"CLI_LOG_LEVEL\"))\n .addOption(new Option(\"--log-destination <path>\", \"Log destination file (defaults to stdout)\").env(\"CLI_LOG_DESTINATION\"))\n .addOption(\n new Option(\"--ui-dir <path>\", \"Directory containing the built UI bundle\").env(\"CLI_UI_DIR\").default(DEFAULT_UI_STATIC_DIR),\n )\n .addOption(new Option(\"--ui-dev-server <url>\", \"Proxy UI requests to a running dev server\").env(\"CLI_UI_DEV_SERVER\"))\n .addOption(new Option(\"--ui-no-update\", \"Disable remote UI updates\").env(\"CLI_UI_NO_UPDATE\").default(false))\n .addOption(new Option(\"--ui-auto-update <enabled>\", \"Enable remote UI updates (true|false)\").env(\"CLI_UI_AUTO_UPDATE\").default(\"true\"))\n .addOption(new Option(\"--ui-manifest-url <url>\", \"Remote UI manifest URL\").env(\"CLI_UI_MANIFEST_URL\"))\n .addOption(new Option(\"--launch\", \"Launch the UI in a browser after start\").env(\"CLI_LAUNCH\").default(false))\n .addOption(\n new Option(\"--username <username>\", \"Username for server authentication\")\n .env(\"CODENOMAD_SERVER_USERNAME\")\n .default(DEFAULT_AUTH_USERNAME),\n )\n .addOption(new Option(\"--password <password>\", \"Password for server authentication\").env(\"CODENOMAD_SERVER_PASSWORD\"))\n .addOption(\n new Option(\"--auth-cookie-name <name>\", \"Cookie name for server authentication\")\n .env(\"CODENOMAD_AUTH_COOKIE_NAME\")\n .default(DEFAULT_AUTH_COOKIE_NAME),\n )\n .addOption(\n new Option(\"--generate-token\", \"Emit a one-time bootstrap token for desktop\")\n .env(\"CODENOMAD_GENERATE_TOKEN\")\n .default(false),\n )\n .addOption(\n new Option(\n \"--dangerously-skip-auth\",\n \"Disable CodeNomad's internal auth. Use only behind a trusted perimeter (SSO/VPN/etc).\",\n )\n .env(\"CODENOMAD_SKIP_AUTH\")\n .default(false),\n )\n .addOption(new Option(\"--upgrade [version]\", \"Upgrade the global CodeNomad CLI server package and exit\"))\n\n program.parse(argv, { from: \"user\" })\n const parsed = program.opts<{\n host: string\n https?: string\n http?: string\n httpsPort: number\n httpPort: number\n tlsKey?: string\n tlsCert?: string\n tlsCa?: string\n tlsSANs?: string\n workspaceRoot?: string\n root?: string\n unrestrictedRoot?: boolean\n config: string\n logLevel?: string\n logDestination?: string\n uiDir: string\n uiDevServer?: string\n uiNoUpdate?: boolean\n uiAutoUpdate?: string\n uiManifestUrl?: string\n launch?: boolean\n username: string\n password?: string\n authCookieName: string\n generateToken?: boolean\n dangerouslySkipAuth?: boolean\n upgrade?: string | boolean\n }>()\n\n const upgrade = parsed.upgrade\n const parseBooleanEnv = (value: string | undefined): boolean => {\n const normalized = (value ?? \"\").trim().toLowerCase()\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\" || normalized === \"y\" || normalized === \"on\"\n }\n\n const resolvedRoot = parsed.workspaceRoot ?? parsed.root ?? process.cwd()\n\n const normalizedHost = resolveHost(parsed.host)\n\n const autoUpdateString = (parsed.uiAutoUpdate ?? \"true\").trim().toLowerCase()\n const uiAutoUpdate = autoUpdateString === \"1\" || autoUpdateString === \"true\" || autoUpdateString === \"yes\"\n\n const httpsEnabled = parseBooleanEnv(parsed.https)\n const httpEnabled = parseBooleanEnv(parsed.http)\n\n if (upgrade === undefined && !httpsEnabled && !httpEnabled) {\n throw new InvalidArgumentError(\"At least one listener must be enabled (--https or --http)\")\n }\n\n return {\n host: normalizedHost,\n https: httpsEnabled,\n http: httpEnabled,\n httpsPort: parsed.httpsPort,\n httpPort: parsed.httpPort,\n tlsKeyPath: parsed.tlsKey,\n tlsCertPath: parsed.tlsCert,\n tlsCaPath: parsed.tlsCa,\n tlsSANs: parsed.tlsSANs,\n rootDir: resolvedRoot,\n configPath: parsed.config,\n unrestrictedRoot: Boolean(parsed.unrestrictedRoot),\n logLevel: parsed.logLevel,\n logDestination: parsed.logDestination,\n uiStaticDir: parsed.uiDir,\n uiDevServer: parsed.uiDevServer,\n uiAutoUpdate,\n uiNoUpdate: Boolean(parsed.uiNoUpdate),\n uiManifestUrl: parsed.uiManifestUrl,\n launch: Boolean(parsed.launch),\n authUsername: parsed.username,\n authPassword: parsed.password,\n authCookieName: parsed.authCookieName,\n generateToken: Boolean(parsed.generateToken),\n dangerouslySkipAuth: Boolean(parsed.dangerouslySkipAuth),\n upgrade,\n }\n}\n\nfunction parsePort(input: string): number {\n const value = Number(input)\n if (!Number.isInteger(value) || value < 0 || value > 65535) {\n throw new InvalidArgumentError(\"Port must be an integer between 0 and 65535\")\n }\n return value\n}\n\nfunction resolveHost(input: string | undefined): string {\n const trimmed = input?.trim()\n if (!trimmed) return DEFAULT_HOST\n\n if (trimmed === \"0.0.0.0\") {\n return \"0.0.0.0\"\n }\n\n if (trimmed === \"localhost\") {\n return DEFAULT_HOST\n }\n\n return trimmed\n}\n\nexport function programHasArg(argv: string[], flag: string): boolean {\n return argv.some((argument) => argument === flag || argument.startsWith(`${flag}=`))\n}\n\nasync function main() {\n const options = parseCliOptions(process.argv.slice(2))\n if (options.upgrade !== undefined) {\n const version = typeof options.upgrade === \"string\" ? options.upgrade : undefined\n process.exitCode = await runCliUpgrade(version)\n return\n }\n\n const logger = createLogger({ level: options.logLevel, destination: options.logDestination, component: \"app\" })\n const workspaceLogger = logger.child({ component: \"workspace\" })\n const configLogger = logger.child({ component: \"config\" })\n const eventLogger = logger.child({ component: \"events\" })\n\n const logOptions = {\n ...options,\n authPassword: options.authPassword ? \"[REDACTED]\" : undefined,\n }\n\n logger.info({ options: logOptions }, \"Starting CodeNomad CLI server\")\n\n if (options.dangerouslySkipAuth) {\n logger.warn(\n \"DANGEROUS: internal authentication is disabled (--dangerously-skip-auth / CODENOMAD_SKIP_AUTH).\",\n )\n }\n\n const eventBus = new EventBus(eventLogger)\n\n const isLoopbackHost = (host: string) => host === \"127.0.0.1\" || host === \"::1\" || host.startsWith(\"127.\")\n\n const configLocation = resolveConfigLocation(options.configPath)\n const configDir = configLocation.baseDir\n\n if ((options.tlsKeyPath && !options.tlsCertPath) || (!options.tlsKeyPath && options.tlsCertPath)) {\n throw new InvalidArgumentError(\"--tls-key and --tls-cert must be provided together\")\n }\n\n const serverMeta: ServerMeta = {\n localUrl: \"http://localhost:0\",\n remoteUrl: undefined,\n eventsUrl: `/api/events`,\n host: options.host,\n listeningMode: isLoopbackHost(options.host) ? \"local\" : \"all\",\n localPort: 0,\n remotePort: undefined,\n hostLabel: options.host,\n workspaceRoot: options.rootDir,\n addresses: [],\n }\n\n const authManager = new AuthManager(\n {\n configPath: configLocation.configYamlPath,\n username: options.authUsername,\n password: options.authPassword,\n cookieName: options.authCookieName,\n generateToken: options.generateToken,\n dangerouslySkipAuth: options.dangerouslySkipAuth,\n },\n logger.child({ component: \"auth\" }),\n )\n\n if (options.generateToken && !options.dangerouslySkipAuth) {\n const token = authManager.issueBootstrapToken()\n if (token) {\n console.log(`${BOOTSTRAP_TOKEN_STDOUT_PREFIX}${token}`)\n }\n }\n\n const tlsResolution = resolveHttpsOptions({\n enabled: options.https,\n configDir,\n host: options.host,\n tlsKeyPath: options.tlsKeyPath,\n tlsCertPath: options.tlsCertPath,\n tlsCaPath: options.tlsCaPath,\n tlsSANs: options.tlsSANs,\n logger: logger.child({ component: \"tls\" }),\n })\n\n const settings = new SettingsService(configLocation, eventBus, configLogger)\n const binaryResolver = new BinaryResolver(settings)\n const workspaceManager = new WorkspaceManager({\n rootDir: options.rootDir,\n settings,\n binaryResolver,\n eventBus,\n logger: workspaceLogger,\n })\n const nativeParent = new NativeParent()\n if (nativeParent.available) {\n try {\n await removeLegacyAutomationPlugin()\n } catch (error) {\n logger.warn({ err: error }, \"Failed to remove the legacy global Developer Mode plugin\")\n }\n }\n const automationBridge = createAutomationBridgeRegistration(\"http://127.0.0.1\")\n const fileSystemBrowser = new FileSystemBrowser({\n rootDir: options.rootDir,\n unrestricted: options.unrestrictedRoot,\n })\n const instanceStore = new InstanceStore(configLocation.instancesDir)\n const speechService = new SpeechService(settings, logger.child({ component: \"speech\" }))\n const sidecarManager = new SideCarManager({\n settings,\n eventBus,\n logger: logger.child({ component: \"sidecars\" }),\n })\n const previewManager = new PreviewManager()\n const yoloLogger = logger.child({ component: \"yolo\" })\n const sessionMetadataPersistence = createOpencodeYoloPersistence(workspaceManager, settings)\n const yoloManager = new AutoAcceptManager({\n eventBus,\n logger: yoloLogger,\n replier: createOpencodePermissionReplier({ workspaceManager }),\n persistence: sessionMetadataPersistence,\n })\n yoloManager.start()\n const instanceEventBridge = new InstanceEventBridge({\n workspaceManager,\n eventBus,\n logger: logger.child({ component: \"instance-events\" }),\n })\n\n const uiDirEnvOverride = Boolean(process.env.CLI_UI_DIR)\n const uiDirCliOverride = programHasArg(process.argv.slice(2), \"--ui-dir\")\n const uiOverrideIsExplicit = uiDirEnvOverride || uiDirCliOverride\n const uiDirOverride = uiOverrideIsExplicit ? options.uiStaticDir : undefined\n\n const autoUpdateEnabled = options.uiAutoUpdate && !options.uiNoUpdate\n\n const uiResolution = await resolveUi({\n serverVersion: packageJson.version,\n bundledUiDir: DEFAULT_UI_STATIC_DIR,\n autoUpdate: autoUpdateEnabled,\n overrideUiDir: uiDirOverride,\n uiDevServerUrl: options.uiDevServer,\n manifestUrl: options.uiManifestUrl,\n logger: logger.child({ component: \"ui\" }),\n })\n\n serverMeta.serverVersion = packageJson.version\n serverMeta.ui = {\n version: uiResolution.uiVersion,\n source: uiResolution.source,\n }\n serverMeta.support = {\n supported: uiResolution.supported,\n message: uiResolution.message,\n latestServerVersion: uiResolution.latestServerVersion,\n latestServerUrl: uiResolution.latestServerUrl,\n minServerVersion: uiResolution.minServerVersion,\n }\n\n const updateChannel = (process.env.CODENOMAD_UPDATE_CHANNEL ?? \"\").trim().toLowerCase()\n const githubRepo = (process.env.CODENOMAD_GITHUB_REPO ?? \"NeuralNomadsAI/CodeNomad\").trim()\n const isDevVersion = packageJson.version.includes(\"-dev.\") || packageJson.version.includes(\"-dev-\")\n const enableDevUpdateChecks = updateChannel === \"dev\" || (updateChannel === \"\" && isDevVersion)\n const devReleaseMonitor = enableDevUpdateChecks\n ? startDevReleaseMonitor({\n currentVersion: packageJson.version,\n repo: githubRepo,\n logger: logger.child({ component: \"updates\" }),\n onUpdate: (release) => {\n serverMeta.update = release\n },\n })\n : null\n\n const remoteAccessEnabled = options.host === \"0.0.0.0\" || !isLoopbackHost(options.host)\n\n const clientConnectionManager = new ClientConnectionManager(logger.child({ component: \"client-connections\" }))\n const remoteProxySessionManager = new RemoteProxySessionManager({\n authManager,\n logger: logger.child({ component: \"remote-proxy\" }),\n httpsOptions: tlsResolution?.httpsOptions,\n })\n const httpsPortExplicit = programHasArg(process.argv.slice(2), \"--https-port\") || Boolean(process.env.CLI_HTTPS_PORT)\n const httpPortExplicit = programHasArg(process.argv.slice(2), \"--http-port\") || Boolean(process.env.CLI_HTTP_PORT)\n\n const httpsBindPort = httpsPortExplicit ? options.httpsPort : 0\n const httpBindPort = httpPortExplicit ? options.httpPort : 0\n\n // Listener binding rules:\n // - Remote access enabled: HTTP listens on loopback, HTTPS on all IPs (host=0.0.0.0 / LAN IP).\n // - Remote access disabled: both listen on loopback.\n // - HTTP-only mode: respect --host (used for dev/testing).\n const httpsBindHost = remoteAccessEnabled ? options.host : \"127.0.0.1\"\n const httpBindHost = nativeParent.available ? \"127.0.0.1\" : options.http ? (options.https ? \"127.0.0.1\" : options.host) : \"127.0.0.1\"\n\n const servers: Array<ReturnType<typeof createHttpServer>> = []\n\n const httpServer = options.http || nativeParent.available\n ? createHttpServer({\n bindHost: httpBindHost,\n bindPort: httpBindPort,\n defaultPort: options.httpPort,\n protocol: \"http\",\n workspaceManager,\n settings,\n fileSystemBrowser,\n eventBus,\n serverMeta,\n instanceStore,\n speechService,\n sidecarManager,\n previewManager,\n authManager,\n clientConnectionManager,\n remoteProxySessionManager,\n yoloManager,\n uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR,\n uiDevServerUrl: uiResolution.uiDevServerUrl,\n logger,\n nativeParent,\n automationBridgeToken: automationBridge.token,\n })\n : null\n\n const httpsServer = options.https\n ? createHttpServer({\n bindHost: httpsBindHost,\n bindPort: httpsBindPort,\n defaultPort: options.httpsPort,\n protocol: \"https\",\n httpsOptions: tlsResolution?.httpsOptions,\n workspaceManager,\n settings,\n fileSystemBrowser,\n eventBus,\n serverMeta,\n instanceStore,\n speechService,\n sidecarManager,\n previewManager,\n authManager,\n clientConnectionManager,\n remoteProxySessionManager,\n yoloManager,\n uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR,\n uiDevServerUrl: undefined,\n logger,\n nativeParent,\n automationBridgeToken: automationBridge.token,\n })\n : null\n\n if (httpServer) servers.push(httpServer)\n if (httpsServer) servers.push(httpsServer)\n\n const [httpStart, httpsStart] = await Promise.all([\n httpServer ? httpServer.start() : Promise.resolve(null),\n httpsServer ? httpsServer.start() : Promise.resolve(null),\n ])\n\n const visibleHttpStart = options.http ? httpStart : null\n const localStart = visibleHttpStart ?? httpsStart\n if (!localStart) {\n throw new Error(\"No listeners started\")\n }\n\n const remoteStart = httpsStart ?? httpStart\n const remoteProtocol: \"http\" | \"https\" = httpsStart ? \"https\" : \"http\"\n\n let remoteUrl: string | undefined\n let remoteAddresses = [] as ReturnType<typeof resolveNetworkAddresses>\n if (remoteStart) {\n const wantsAll = options.host === \"0.0.0.0\" || !isLoopbackHost(options.host)\n let remoteHost = options.host\n if (wantsAll) {\n if (options.host === \"0.0.0.0\") {\n const resolved = resolveRemoteAddresses({ host: options.host, protocol: remoteProtocol, port: remoteStart.port })\n remoteAddresses = resolved.userVisible\n remoteUrl = resolved.primaryRemoteUrl ?? `${remoteProtocol}://localhost:${remoteStart.port}`\n }\n } else {\n remoteHost = \"localhost\"\n }\n if (!remoteUrl) {\n remoteUrl = `${remoteProtocol}://${remoteHost}:${remoteStart.port}`\n }\n }\n\n // Prefer an explicit IPv4 loopback address only when one of the bound listeners\n // accepts loopback. Concrete LAN bindings do not, so plugins need the reachable\n // bound/listener URL instead of an unreachable 127.0.0.1 URL.\n const localUrl = resolvePluginBaseUrl({\n httpStart: visibleHttpStart ? { protocol: \"http\", bindHost: httpBindHost, port: visibleHttpStart.port } : null,\n httpsStart: httpsStart ? { protocol: \"https\", bindHost: httpsBindHost, port: httpsStart.port } : null,\n remoteUrl,\n })\n\n serverMeta.localUrl = localUrl\n serverMeta.localPort = localStart.port\n serverMeta.remoteUrl = remoteUrl\n serverMeta.remotePort = remoteStart?.port\n serverMeta.host = options.host\n serverMeta.listeningMode = options.host === \"0.0.0.0\" || !isLoopbackHost(options.host) ? \"all\" : \"local\"\n\n let removeAutomationBridge: (() => Promise<void>) | undefined\n if (nativeParent.available && process.env.CODENOMAD_DEVELOPER_MODE === \"1\") {\n try {\n if (!httpStart) throw new Error(\"Developer Mode HTTP listener did not start\")\n const automationUrl = resolveAutomationBridgeUrl({ protocol: \"http\", bindHost: httpBindHost, port: httpStart.port })\n removeAutomationBridge = await publishAutomationBridge({\n ...automationBridge,\n url: new URL(AUTOMATION_BRIDGE_PATH, automationUrl).href,\n })\n } catch (error) {\n logger.warn({ err: error }, \"Failed to publish the Developer Mode bridge\")\n }\n }\n\n if (serverMeta.remotePort && remoteUrl) {\n serverMeta.addresses = remoteAddresses.length\n ? remoteAddresses\n : resolveNetworkAddresses({ host: options.host, protocol: remoteProtocol, port: serverMeta.remotePort })\n } else {\n serverMeta.addresses = []\n }\n\n console.log(`Local Connection URL : ${serverMeta.localUrl}`)\n if (serverMeta.remoteUrl) {\n console.log(`Remote Connection URL : ${serverMeta.remoteUrl}`)\n const additionalRemoteUrls = serverMeta.addresses\n .map((addr) => addr.remoteUrl)\n .filter((url) => url !== serverMeta.remoteUrl)\n\n if (additionalRemoteUrls.length > 0) {\n console.log(\"Other Accessible URLs:\")\n for (const url of additionalRemoteUrls) {\n console.log(` - ${url}`)\n }\n }\n }\n\n if (options.launch) {\n await launchInBrowser(serverMeta.localUrl, logger.child({ component: \"launcher\" }))\n }\n\n const shutdown = createServerShutdownHandler({\n logger,\n holdAfterFailure: () => new Promise<void>(() => { setInterval(() => undefined, 60_000) }),\n setExitCode: (code) => {\n process.stdin.destroy()\n process.exitCode = code\n },\n shutdown: () =>\n orchestrateServerShutdown(\n {\n stopInstanceEventBridge: () => instanceEventBridge.shutdown(),\n stopSidecars: () => sidecarManager.shutdown(),\n stopClientConnections: () => clientConnectionManager.shutdown(),\n stopRemoteProxySessions: () => remoteProxySessionManager.shutdown(),\n stopWorkspaces: () => workspaceManager.shutdown(),\n stopHttpServers: async () => {\n nativeParent.close()\n await removeAutomationBridge?.()\n yoloManager.stop()\n const results = await Promise.allSettled(servers.map((srv) => srv.stop()))\n const failures = results.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []))\n if (failures.length > 0) {\n const error = new Error(\"One or more HTTP servers failed to stop\") as Error & { failures: unknown[] }\n error.failures = failures\n throw error\n }\n logger.info(\"HTTP server(s) stopped\")\n },\n stopReleaseMonitor: () => devReleaseMonitor?.stop(),\n },\n logger,\n ),\n })\n\n installShutdownSignalHandlers(process, shutdown)\n installShutdownStdinHandler(process.stdin, shutdown, (line) => nativeParent.handleLine(line))\n}\n\nif (path.resolve(process.argv[1] ?? \"\") === __filename) {\n main().catch((error) => {\n const logger = createLogger({ component: \"app\" })\n logger.error({ err: error }, \"CLI server crashed\")\n process.exit(1)\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI entry point.\n * For now this only wires the typed modules together; actual command handling comes later.\n */\nimport { Command, InvalidArgumentError, Option } from \"commander\"\nimport path from \"path\"\nimport { fileURLToPath } from \"url\"\nimport { createRequire } from \"module\"\nimport { createHttpServer } from \"./server/http-server\"\nimport { WorkspaceManager } from \"./workspaces/manager\"\nimport { resolveConfigLocation } from \"./config/location\"\nimport { SettingsService } from \"./settings/service\"\nimport { BinaryResolver } from \"./settings/binaries\"\nimport { FileSystemBrowser } from \"./filesystem/browser\"\nimport { EventBus } from \"./events/bus\"\nimport { ServerMeta } from \"./api-types\"\nimport { InstanceStore } from \"./storage/instance-store\"\nimport { InstanceEventBridge } from \"./workspaces/instance-events\"\nimport { createLogger } from \"./logger\"\nimport { launchInBrowser } from \"./launcher\"\nimport { resolveUi } from \"./ui/remote-ui\"\nimport { AuthManager, BOOTSTRAP_TOKEN_STDOUT_PREFIX, DEFAULT_AUTH_COOKIE_NAME, DEFAULT_AUTH_USERNAME } from \"./auth/manager\"\nimport { resolveHttpsOptions } from \"./server/tls\"\nimport { RemoteProxySessionManager } from \"./server/remote-proxy\"\nimport { resolveNetworkAddresses, resolveRemoteAddresses } from \"./server/network-addresses\"\nimport { resolveAutomationBridgeUrl, resolvePluginBaseUrl, resolvePreferredRemoteListener } from \"./server/listener-base-url\"\nimport { formatHostForUrl, hasIPv6Zone, isLoopbackHost, isWildcardHost, normalizeNetworkHost } from \"./server/network-host\"\nimport { startDevReleaseMonitor } from \"./releases/dev-release-monitor\"\nimport { SpeechService } from \"./speech/service\"\nimport { SideCarManager } from \"./sidecars/manager\"\nimport { PreviewManager } from \"./previews/manager\"\nimport { ClientConnectionManager } from \"./clients/connection-manager\"\nimport { runCliUpgrade } from \"./cli-upgrade\"\nimport { createServerShutdownHandler, orchestrateServerShutdown, type ServerShutdownTrigger } from \"./shutdown\"\nimport { AutoAcceptManager } from \"./permissions/auto-accept-manager\"\nimport { createOpencodePermissionReplier } from \"./permissions/opencode-replier\"\nimport { createOpencodeYoloPersistence } from \"./permissions/opencode-yolo-metadata\"\nimport { NativeParent } from \"./native-parent\"\nimport { PruningLifecycle } from \"./opencode/pruning-lifecycle\"\nimport { AUTOMATION_BRIDGE_PATH, createAutomationBridgeRegistration, publishAutomationBridge, removeLegacyAutomationPlugin } from \"./opencode/automation-plugin\"\n\nconst require = createRequire(import.meta.url)\n\nconst packageJson = require(\"../package.json\") as { version: string }\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\nconst DEFAULT_UI_STATIC_DIR = path.resolve(__dirname, \"../public\")\n\ninterface CliOptions {\n host: string\n https: boolean\n http: boolean\n httpsPort: number\n httpPort: number\n tlsKeyPath?: string\n tlsCertPath?: string\n tlsCaPath?: string\n tlsSANs?: string\n rootDir: string\n configPath: string\n unrestrictedRoot: boolean\n logLevel?: string\n logDestination?: string\n uiStaticDir: string\n uiDevServer?: string\n uiAutoUpdate: boolean\n uiNoUpdate: boolean\n uiManifestUrl?: string\n launch: boolean\n authUsername: string\n authPassword?: string\n authCookieName: string\n generateToken: boolean\n dangerouslySkipAuth: boolean\n upgrade?: string | boolean\n}\n\nconst DEFAULT_HOST = \"127.0.0.1\"\nconst DEFAULT_CONFIG_PATH = \"~/.config/codenomad/config.json\"\nconst DEFAULT_HTTPS_PORT = 9898\nconst DEFAULT_HTTP_PORT = 9899\nexport const STDIN_SHUTDOWN_COMMAND = \"codenomad:shutdown\"\n\ninterface ShutdownSignalSource {\n on: (signal: \"SIGINT\" | \"SIGTERM\", listener: () => void) => unknown\n}\n\nexport function installShutdownSignalHandlers(\n source: ShutdownSignalSource,\n shutdown: (signal: ServerShutdownTrigger) => Promise<void>,\n): void {\n source.on(\"SIGINT\", () => void shutdown(\"SIGINT\"))\n source.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"))\n}\n\ninterface ShutdownStdinSource {\n on(event: \"data\", listener: (chunk: Buffer | string) => void): unknown\n off?(event: \"data\", listener: (chunk: Buffer | string) => void): unknown\n destroy?(): unknown\n}\n\nexport function installShutdownStdinHandler(\n source: ShutdownStdinSource,\n shutdown: (signal: ServerShutdownTrigger) => Promise<void>,\n handleLine?: (line: string) => boolean,\n): void {\n let buffer = \"\"\n let requested = false\n const onData = (chunk: Buffer | string) => {\n if (requested) return\n buffer += chunk.toString()\n const lines = buffer.split(/\\r?\\n/)\n buffer = lines.pop() ?? \"\"\n let shutdownRequested = false\n for (const line of lines) {\n if (line.trim() === STDIN_SHUTDOWN_COMMAND) shutdownRequested = true\n else handleLine?.(line)\n }\n if (!shutdownRequested) return\n\n requested = true\n source.off?.(\"data\", onData)\n source.destroy?.()\n void shutdown(\"stdin\")\n }\n source.on(\"data\", onData)\n}\n\nfunction parseCliOptions(argv: string[]): CliOptions {\n const program = new Command()\n .name(\"codenomad\")\n .description(\"CodeNomad CLI server\")\n .version(packageJson.version, \"-v, --version\", \"Show the CLI version\")\n .addOption(new Option(\"--host <host>\", \"Host interface to bind\").env(\"CLI_HOST\").default(DEFAULT_HOST))\n .addOption(new Option(\"--https <enabled>\", \"Enable HTTPS listener (true|false)\").env(\"CLI_HTTPS\").default(\"true\"))\n .addOption(new Option(\"--http <enabled>\", \"Enable HTTP listener (true|false)\").env(\"CLI_HTTP\").default(\"false\"))\n .addOption(new Option(\"--https-port <number>\", \"HTTPS port (0 for auto)\").env(\"CLI_HTTPS_PORT\").default(DEFAULT_HTTPS_PORT).argParser(parsePort))\n .addOption(new Option(\"--http-port <number>\", \"HTTP port (0 for auto)\").env(\"CLI_HTTP_PORT\").default(DEFAULT_HTTP_PORT).argParser(parsePort))\n .addOption(new Option(\"--tls-key <path>\", \"TLS private key (PEM)\").env(\"CLI_TLS_KEY\"))\n .addOption(new Option(\"--tls-cert <path>\", \"TLS certificate (PEM)\").env(\"CLI_TLS_CERT\"))\n .addOption(new Option(\"--tls-ca <path>\", \"TLS CA chain (PEM)\").env(\"CLI_TLS_CA\"))\n .addOption(new Option(\"--tlsSANs <list>\", \"Additional TLS SANs (comma-separated)\").env(\"CLI_TLS_SANS\"))\n .addOption(\n new Option(\"--workspace-root <path>\", \"Restricts root path where workspaces can be opened\").env(\"CLI_WORKSPACE_ROOT\").default(process.cwd()),\n )\n .addOption(new Option(\"--root <path>\").env(\"CLI_ROOT\").hideHelp(true))\n .addOption(new Option(\"--unrestricted-root\", \"Allow browsing the full filesystem\").env(\"CLI_UNRESTRICTED_ROOT\").default(false))\n .addOption(new Option(\"--config <path>\", \"Path to the config file\").env(\"CLI_CONFIG\").default(DEFAULT_CONFIG_PATH))\n .addOption(new Option(\"--log-level <level>\", \"Log level (trace|debug|info|warn|error)\").env(\"CLI_LOG_LEVEL\"))\n .addOption(new Option(\"--log-destination <path>\", \"Log destination file (defaults to stdout)\").env(\"CLI_LOG_DESTINATION\"))\n .addOption(\n new Option(\"--ui-dir <path>\", \"Directory containing the built UI bundle\").env(\"CLI_UI_DIR\").default(DEFAULT_UI_STATIC_DIR),\n )\n .addOption(new Option(\"--ui-dev-server <url>\", \"Proxy UI requests to a running dev server\").env(\"CLI_UI_DEV_SERVER\"))\n .addOption(new Option(\"--ui-no-update\", \"Disable remote UI updates\").env(\"CLI_UI_NO_UPDATE\").default(false))\n .addOption(new Option(\"--ui-auto-update <enabled>\", \"Enable remote UI updates (true|false)\").env(\"CLI_UI_AUTO_UPDATE\").default(\"true\"))\n .addOption(new Option(\"--ui-manifest-url <url>\", \"Remote UI manifest URL\").env(\"CLI_UI_MANIFEST_URL\"))\n .addOption(new Option(\"--launch\", \"Launch the UI in a browser after start\").env(\"CLI_LAUNCH\").default(false))\n .addOption(\n new Option(\"--username <username>\", \"Username for server authentication\")\n .env(\"CODENOMAD_SERVER_USERNAME\")\n .default(DEFAULT_AUTH_USERNAME),\n )\n .addOption(new Option(\"--password <password>\", \"Password for server authentication\").env(\"CODENOMAD_SERVER_PASSWORD\"))\n .addOption(\n new Option(\"--auth-cookie-name <name>\", \"Cookie name for server authentication\")\n .env(\"CODENOMAD_AUTH_COOKIE_NAME\")\n .default(DEFAULT_AUTH_COOKIE_NAME),\n )\n .addOption(\n new Option(\"--generate-token\", \"Emit a one-time bootstrap token for desktop\")\n .env(\"CODENOMAD_GENERATE_TOKEN\")\n .default(false),\n )\n .addOption(\n new Option(\n \"--dangerously-skip-auth\",\n \"Disable CodeNomad's internal auth. Use only behind a trusted perimeter (SSO/VPN/etc).\",\n )\n .env(\"CODENOMAD_SKIP_AUTH\")\n .default(false),\n )\n .addOption(new Option(\"--upgrade [version]\", \"Upgrade the global CodeNomad CLI server package and exit\"))\n\n program.parse(argv, { from: \"user\" })\n const parsed = program.opts<{\n host: string\n https?: string\n http?: string\n httpsPort: number\n httpPort: number\n tlsKey?: string\n tlsCert?: string\n tlsCa?: string\n tlsSANs?: string\n workspaceRoot?: string\n root?: string\n unrestrictedRoot?: boolean\n config: string\n logLevel?: string\n logDestination?: string\n uiDir: string\n uiDevServer?: string\n uiNoUpdate?: boolean\n uiAutoUpdate?: string\n uiManifestUrl?: string\n launch?: boolean\n username: string\n password?: string\n authCookieName: string\n generateToken?: boolean\n dangerouslySkipAuth?: boolean\n upgrade?: string | boolean\n }>()\n\n const upgrade = parsed.upgrade\n const parseBooleanEnv = (value: string | undefined): boolean => {\n const normalized = (value ?? \"\").trim().toLowerCase()\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\" || normalized === \"y\" || normalized === \"on\"\n }\n\n const resolvedRoot = parsed.workspaceRoot ?? parsed.root ?? process.cwd()\n\n const normalizedHost = resolveHost(parsed.host)\n\n const autoUpdateString = (parsed.uiAutoUpdate ?? \"true\").trim().toLowerCase()\n const uiAutoUpdate = autoUpdateString === \"1\" || autoUpdateString === \"true\" || autoUpdateString === \"yes\"\n\n const httpsEnabled = parseBooleanEnv(parsed.https)\n const httpEnabled = parseBooleanEnv(parsed.http)\n\n if (upgrade === undefined && !httpsEnabled && !httpEnabled) {\n throw new InvalidArgumentError(\"At least one listener must be enabled (--https or --http)\")\n }\n\n return {\n host: normalizedHost,\n https: httpsEnabled,\n http: httpEnabled,\n httpsPort: parsed.httpsPort,\n httpPort: parsed.httpPort,\n tlsKeyPath: parsed.tlsKey,\n tlsCertPath: parsed.tlsCert,\n tlsCaPath: parsed.tlsCa,\n tlsSANs: parsed.tlsSANs,\n rootDir: resolvedRoot,\n configPath: parsed.config,\n unrestrictedRoot: Boolean(parsed.unrestrictedRoot),\n logLevel: parsed.logLevel,\n logDestination: parsed.logDestination,\n uiStaticDir: parsed.uiDir,\n uiDevServer: parsed.uiDevServer,\n uiAutoUpdate,\n uiNoUpdate: Boolean(parsed.uiNoUpdate),\n uiManifestUrl: parsed.uiManifestUrl,\n launch: Boolean(parsed.launch),\n authUsername: parsed.username,\n authPassword: parsed.password,\n authCookieName: parsed.authCookieName,\n generateToken: Boolean(parsed.generateToken),\n dangerouslySkipAuth: Boolean(parsed.dangerouslySkipAuth),\n upgrade,\n }\n}\n\nfunction parsePort(input: string): number {\n const value = Number(input)\n if (!Number.isInteger(value) || value < 0 || value > 65535) {\n throw new InvalidArgumentError(\"Port must be an integer between 0 and 65535\")\n }\n return value\n}\n\nexport function resolveHost(input: string | undefined): string {\n const trimmed = input?.trim()\n if (!trimmed) return DEFAULT_HOST\n\n if (hasIPv6Zone(trimmed)) {\n throw new InvalidArgumentError(\"IPv6 zone identifiers are not supported in --host\")\n }\n\n const normalized = normalizeNetworkHost(trimmed)\n if (normalized === \"localhost\") {\n return DEFAULT_HOST\n }\n\n return normalized\n}\n\nexport function programHasArg(argv: string[], flag: string): boolean {\n return argv.some((argument) => argument === flag || argument.startsWith(`${flag}=`))\n}\n\nasync function main() {\n const options = parseCliOptions(process.argv.slice(2))\n if (options.upgrade !== undefined) {\n const version = typeof options.upgrade === \"string\" ? options.upgrade : undefined\n process.exitCode = await runCliUpgrade(version)\n return\n }\n\n const logger = createLogger({ level: options.logLevel, destination: options.logDestination, component: \"app\" })\n const workspaceLogger = logger.child({ component: \"workspace\" })\n const configLogger = logger.child({ component: \"config\" })\n const eventLogger = logger.child({ component: \"events\" })\n\n const logOptions = {\n ...options,\n authPassword: options.authPassword ? \"[REDACTED]\" : undefined,\n }\n\n logger.info({ options: logOptions }, \"Starting CodeNomad CLI server\")\n\n if (options.dangerouslySkipAuth) {\n logger.warn(\n \"DANGEROUS: internal authentication is disabled (--dangerously-skip-auth / CODENOMAD_SKIP_AUTH).\",\n )\n }\n\n const eventBus = new EventBus(eventLogger)\n\n const configLocation = resolveConfigLocation(options.configPath)\n const configDir = configLocation.baseDir\n\n if ((options.tlsKeyPath && !options.tlsCertPath) || (!options.tlsKeyPath && options.tlsCertPath)) {\n throw new InvalidArgumentError(\"--tls-key and --tls-cert must be provided together\")\n }\n\n const serverMeta: ServerMeta = {\n localUrl: \"http://localhost:0\",\n remoteUrl: undefined,\n eventsUrl: `/api/events`,\n host: options.host,\n listeningMode: isLoopbackHost(options.host) ? \"local\" : \"all\",\n localPort: 0,\n remotePort: undefined,\n hostLabel: options.host,\n workspaceRoot: options.rootDir,\n addresses: [],\n }\n\n const authManager = new AuthManager(\n {\n configPath: configLocation.configYamlPath,\n username: options.authUsername,\n password: options.authPassword,\n cookieName: options.authCookieName,\n generateToken: options.generateToken,\n dangerouslySkipAuth: options.dangerouslySkipAuth,\n },\n logger.child({ component: \"auth\" }),\n )\n\n if (options.generateToken && !options.dangerouslySkipAuth) {\n const token = authManager.issueBootstrapToken()\n if (token) {\n console.log(`${BOOTSTRAP_TOKEN_STDOUT_PREFIX}${token}`)\n }\n }\n\n const tlsResolution = resolveHttpsOptions({\n enabled: options.https,\n configDir,\n host: options.host,\n tlsKeyPath: options.tlsKeyPath,\n tlsCertPath: options.tlsCertPath,\n tlsCaPath: options.tlsCaPath,\n tlsSANs: options.tlsSANs,\n logger: logger.child({ component: \"tls\" }),\n })\n\n const settings = new SettingsService(configLocation, eventBus, configLogger)\n const binaryResolver = new BinaryResolver(settings)\n const pruningLifecycle = new PruningLifecycle()\n const prepareSessionPruning: PruningLifecycle[\"start\"] = async (...args) => {\n try { await pruningLifecycle.start(...args) }\n catch (error) { logger.error({ err: error }, \"Failed to load the bundled session-pruning plugin\") }\n }\n await prepareSessionPruning()\n const workspaceManager = new WorkspaceManager({\n rootDir: options.rootDir,\n settings,\n binaryResolver,\n eventBus,\n logger: workspaceLogger,\n prepareSessionPruning,\n })\n const nativeParent = new NativeParent()\n if (nativeParent.available) {\n try {\n await removeLegacyAutomationPlugin()\n } catch (error) {\n logger.warn({ err: error }, \"Failed to remove the legacy global Developer Mode plugin\")\n }\n }\n const automationBridge = createAutomationBridgeRegistration(\"http://127.0.0.1\")\n const fileSystemBrowser = new FileSystemBrowser({\n rootDir: options.rootDir,\n unrestricted: options.unrestrictedRoot,\n })\n const instanceStore = new InstanceStore(configLocation.instancesDir)\n const speechService = new SpeechService(settings, logger.child({ component: \"speech\" }))\n const sidecarManager = new SideCarManager({\n settings,\n eventBus,\n logger: logger.child({ component: \"sidecars\" }),\n })\n const previewManager = new PreviewManager()\n const yoloLogger = logger.child({ component: \"yolo\" })\n const sessionMetadataPersistence = createOpencodeYoloPersistence(workspaceManager, settings)\n const yoloManager = new AutoAcceptManager({\n eventBus,\n logger: yoloLogger,\n replier: createOpencodePermissionReplier({ workspaceManager }),\n persistence: sessionMetadataPersistence,\n })\n yoloManager.start()\n const instanceEventBridge = new InstanceEventBridge({\n workspaceManager,\n eventBus,\n logger: logger.child({ component: \"instance-events\" }),\n })\n\n const uiDirEnvOverride = Boolean(process.env.CLI_UI_DIR)\n const uiDirCliOverride = programHasArg(process.argv.slice(2), \"--ui-dir\")\n const uiOverrideIsExplicit = uiDirEnvOverride || uiDirCliOverride\n const uiDirOverride = uiOverrideIsExplicit ? options.uiStaticDir : undefined\n\n const autoUpdateEnabled = options.uiAutoUpdate && !options.uiNoUpdate\n\n const uiResolution = await resolveUi({\n serverVersion: packageJson.version,\n bundledUiDir: DEFAULT_UI_STATIC_DIR,\n autoUpdate: autoUpdateEnabled,\n overrideUiDir: uiDirOverride,\n uiDevServerUrl: options.uiDevServer,\n manifestUrl: options.uiManifestUrl,\n logger: logger.child({ component: \"ui\" }),\n })\n\n serverMeta.serverVersion = packageJson.version\n serverMeta.ui = {\n version: uiResolution.uiVersion,\n source: uiResolution.source,\n }\n serverMeta.support = {\n supported: uiResolution.supported,\n message: uiResolution.message,\n latestServerVersion: uiResolution.latestServerVersion,\n latestServerUrl: uiResolution.latestServerUrl,\n minServerVersion: uiResolution.minServerVersion,\n }\n\n const updateChannel = (process.env.CODENOMAD_UPDATE_CHANNEL ?? \"\").trim().toLowerCase()\n const githubRepo = (process.env.CODENOMAD_GITHUB_REPO ?? \"NeuralNomadsAI/CodeNomad\").trim()\n const isDevVersion = packageJson.version.includes(\"-dev.\") || packageJson.version.includes(\"-dev-\")\n const enableDevUpdateChecks = updateChannel === \"dev\" || (updateChannel === \"\" && isDevVersion)\n const devReleaseMonitor = enableDevUpdateChecks\n ? startDevReleaseMonitor({\n currentVersion: packageJson.version,\n repo: githubRepo,\n logger: logger.child({ component: \"updates\" }),\n onUpdate: (release) => {\n serverMeta.update = release\n },\n })\n : null\n\n const clientConnectionManager = new ClientConnectionManager(logger.child({ component: \"client-connections\" }))\n const remoteProxySessionManager = new RemoteProxySessionManager({\n authManager,\n logger: logger.child({ component: \"remote-proxy\" }),\n httpsOptions: tlsResolution?.httpsOptions,\n })\n const httpsPortExplicit = programHasArg(process.argv.slice(2), \"--https-port\") || Boolean(process.env.CLI_HTTPS_PORT)\n const httpPortExplicit = programHasArg(process.argv.slice(2), \"--http-port\") || Boolean(process.env.CLI_HTTP_PORT)\n\n const httpsBindPort = httpsPortExplicit ? options.httpsPort : 0\n const httpBindPort = httpPortExplicit ? options.httpPort : 0\n\n // Listener binding rules:\n // - Native desktop HTTP and dual-listener HTTP stay on loopback.\n // - HTTPS and non-native HTTP-only modes respect --host.\n const httpsBindHost = options.host\n const httpBindHost = nativeParent.available ? \"127.0.0.1\" : options.http ? (options.https ? \"127.0.0.1\" : options.host) : \"127.0.0.1\"\n\n const servers: Array<ReturnType<typeof createHttpServer>> = []\n\n const httpServer = options.http || nativeParent.available\n ? createHttpServer({\n bindHost: httpBindHost,\n bindPort: httpBindPort,\n defaultPort: options.httpPort,\n protocol: \"http\",\n workspaceManager,\n settings,\n fileSystemBrowser,\n eventBus,\n serverMeta,\n instanceStore,\n speechService,\n sidecarManager,\n previewManager,\n authManager,\n clientConnectionManager,\n remoteProxySessionManager,\n yoloManager,\n uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR,\n uiDevServerUrl: uiResolution.uiDevServerUrl,\n logger,\n nativeParent,\n automationBridgeToken: automationBridge.token,\n })\n : null\n\n const httpsServer = options.https\n ? createHttpServer({\n bindHost: httpsBindHost,\n bindPort: httpsBindPort,\n defaultPort: options.httpsPort,\n protocol: \"https\",\n httpsOptions: tlsResolution?.httpsOptions,\n workspaceManager,\n settings,\n fileSystemBrowser,\n eventBus,\n serverMeta,\n instanceStore,\n speechService,\n sidecarManager,\n previewManager,\n authManager,\n clientConnectionManager,\n remoteProxySessionManager,\n yoloManager,\n uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR,\n uiDevServerUrl: undefined,\n logger,\n nativeParent,\n automationBridgeToken: automationBridge.token,\n })\n : null\n\n if (httpServer) servers.push(httpServer)\n if (httpsServer) servers.push(httpsServer)\n\n const [httpStart, httpsStart] = await Promise.all([\n httpServer ? httpServer.start() : Promise.resolve(null),\n httpsServer ? httpsServer.start() : Promise.resolve(null),\n ])\n\n const visibleHttpStart = options.http ? httpStart : null\n const localStart = visibleHttpStart ?? httpsStart\n if (!localStart) {\n throw new Error(\"No listeners started\")\n }\n\n const httpListener = httpStart ? { protocol: \"http\" as const, bindHost: httpBindHost, port: httpStart.port } : null\n const httpsListener = httpsStart ? { protocol: \"https\" as const, bindHost: httpsBindHost, port: httpsStart.port } : null\n const remoteListener = resolvePreferredRemoteListener({ httpStart: httpListener, httpsStart: httpsListener })\n\n let remoteUrl: string | undefined\n let remoteAddresses = [] as ReturnType<typeof resolveNetworkAddresses>\n if (remoteListener) {\n let remoteHost = remoteListener.bindHost\n if (isWildcardHost(remoteListener.bindHost)) {\n const resolved = resolveRemoteAddresses({ host: remoteListener.bindHost, protocol: remoteListener.protocol, port: remoteListener.port })\n remoteAddresses = resolved.userVisible\n const loopbackHost = remoteListener.bindHost === \"0.0.0.0\" ? \"127.0.0.1\" : \"::1\"\n remoteUrl = resolved.primaryRemoteUrl ?? `${remoteListener.protocol}://${formatHostForUrl(loopbackHost)}:${remoteListener.port}`\n } else if (remoteListener.bindHost === \"127.0.0.1\") {\n remoteHost = \"localhost\"\n }\n if (!remoteUrl) {\n remoteUrl = `${remoteListener.protocol}://${formatHostForUrl(remoteHost)}:${remoteListener.port}`\n }\n }\n\n // Prefer an explicit IPv4 loopback address only when one of the bound listeners\n // accepts loopback. Concrete LAN bindings do not, so plugins need the reachable\n // bound/listener URL instead of an unreachable 127.0.0.1 URL.\n const localUrl = resolvePluginBaseUrl({\n httpStart: options.http ? httpListener : null,\n httpsStart: httpsListener,\n remoteUrl,\n })\n\n serverMeta.localUrl = localUrl\n serverMeta.localPort = localStart.port\n serverMeta.remoteUrl = remoteUrl\n serverMeta.remotePort = remoteListener?.port\n serverMeta.host = remoteListener?.bindHost ?? options.host\n serverMeta.listeningMode = isWildcardHost(serverMeta.host) || !isLoopbackHost(serverMeta.host) ? \"all\" : \"local\"\n\n let removeAutomationBridge: (() => Promise<void>) | undefined\n if (nativeParent.available && process.env.CODENOMAD_DEVELOPER_MODE === \"1\") {\n try {\n if (!httpStart) throw new Error(\"Developer Mode HTTP listener did not start\")\n const automationUrl = resolveAutomationBridgeUrl({ protocol: \"http\", bindHost: httpBindHost, port: httpStart.port })\n removeAutomationBridge = await publishAutomationBridge({\n ...automationBridge,\n url: new URL(AUTOMATION_BRIDGE_PATH, automationUrl).href,\n })\n } catch (error) {\n logger.warn({ err: error }, \"Failed to publish the Developer Mode bridge\")\n }\n }\n\n if (serverMeta.remotePort && remoteUrl) {\n serverMeta.addresses = remoteAddresses.length\n ? remoteAddresses\n : resolveNetworkAddresses({ host: serverMeta.host, protocol: remoteListener?.protocol ?? \"http\", port: serverMeta.remotePort })\n } else {\n serverMeta.addresses = []\n }\n\n console.log(`Local Connection URL : ${serverMeta.localUrl}`)\n if (serverMeta.remoteUrl) {\n console.log(`Remote Connection URL : ${serverMeta.remoteUrl}`)\n const additionalRemoteUrls = serverMeta.addresses\n .map((addr) => addr.remoteUrl)\n .filter((url) => url !== serverMeta.remoteUrl)\n\n if (additionalRemoteUrls.length > 0) {\n console.log(\"Other Accessible URLs:\")\n for (const url of additionalRemoteUrls) {\n console.log(` - ${url}`)\n }\n }\n }\n\n if (options.launch) {\n await launchInBrowser(serverMeta.localUrl, logger.child({ component: \"launcher\" }))\n }\n\n const shutdown = createServerShutdownHandler({\n logger,\n holdAfterFailure: () => new Promise<void>(() => { setInterval(() => undefined, 60_000) }),\n setExitCode: (code) => {\n process.stdin.destroy()\n process.exitCode = code\n },\n shutdown: () =>\n orchestrateServerShutdown(\n {\n stopInstanceEventBridge: () => instanceEventBridge.shutdown(),\n stopSidecars: () => sidecarManager.shutdown(),\n stopClientConnections: () => clientConnectionManager.shutdown(),\n stopRemoteProxySessions: () => remoteProxySessionManager.shutdown(),\n stopWorkspaces: () => workspaceManager.shutdown(),\n stopHttpServers: async () => {\n await pruningLifecycle.stop()\n nativeParent.close()\n await removeAutomationBridge?.()\n yoloManager.stop()\n const results = await Promise.allSettled(servers.map((srv) => srv.stop()))\n const failures = results.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []))\n if (failures.length > 0) {\n const error = new Error(\"One or more HTTP servers failed to stop\") as Error & { failures: unknown[] }\n error.failures = failures\n throw error\n }\n logger.info(\"HTTP server(s) stopped\")\n },\n stopReleaseMonitor: () => devReleaseMonitor?.stop(),\n },\n logger,\n ),\n })\n\n installShutdownSignalHandlers(process, shutdown)\n installShutdownStdinHandler(process.stdin, shutdown, (line) => nativeParent.handleLine(line))\n}\n\nif (path.resolve(process.argv[1] ?? \"\") === __filename) {\n main().catch((error) => {\n const logger = createLogger({ component: \"app\" })\n logger.error({ err: error }, \"CLI server crashed\")\n process.exit(1)\n })\n}\n"]}
|
package/dist/index.test.js
CHANGED
|
@@ -2,7 +2,7 @@ import assert from "node:assert/strict";
|
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
3
|
import { once } from "node:events";
|
|
4
4
|
import { describe, it } from "node:test";
|
|
5
|
-
import { installShutdownSignalHandlers, installShutdownStdinHandler, STDIN_SHUTDOWN_COMMAND } from "./index";
|
|
5
|
+
import { installShutdownSignalHandlers, installShutdownStdinHandler, resolveHost, STDIN_SHUTDOWN_COMMAND } from "./index";
|
|
6
6
|
import { createServerShutdownHandler } from "./shutdown";
|
|
7
7
|
describe("CLI shutdown signal registration", () => {
|
|
8
8
|
it("routes a second process signal to forced nonzero escalation", async () => {
|
|
@@ -60,4 +60,12 @@ describe("CLI shutdown signal registration", () => {
|
|
|
60
60
|
assert.equal(code, 0);
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
|
+
describe("CLI host normalization", () => {
|
|
64
|
+
it("normalizes mapped and internationalized hosts and rejects IPv6 zones", () => {
|
|
65
|
+
assert.equal(resolveHost("::ffff:0:0"), "0.0.0.0");
|
|
66
|
+
assert.equal(resolveHost("::ffff:7f00:1"), "127.0.0.1");
|
|
67
|
+
assert.equal(resolveHost("münchen.local"), "xn--mnchen-3ya.local");
|
|
68
|
+
assert.throws(() => resolveHost("fe80::1%12"), /IPv6 zone identifiers/);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
63
71
|
//# sourceMappingURL=index.test.js.map
|
package/dist/index.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAA;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\"\nimport { spawn } from \"node:child_process\"\nimport { once } from \"node:events\"\nimport { describe, it } from \"node:test\"\n\nimport { installShutdownSignalHandlers, installShutdownStdinHandler, resolveHost, STDIN_SHUTDOWN_COMMAND } from \"./index\"\nimport { createServerShutdownHandler } from \"./shutdown\"\n\ndescribe(\"CLI shutdown signal registration\", () => {\n it(\"routes a second process signal to forced nonzero escalation\", async () => {\n const listeners = new Map<string, () => void>()\n let finishCleanup!: () => void\n const cleanup = new Promise<void>((resolve) => {\n finishCleanup = resolve\n })\n const exits: number[] = []\n let handled: Promise<void> | undefined\n const shutdown = createServerShutdownHandler({\n shutdown: () => cleanup,\n logger: { info() {}, warn() {}, error() {} },\n forceExit: (code) => exits.push(code),\n setExitCode: () => undefined,\n reportStatus: () => undefined,\n })\n installShutdownSignalHandlers(\n { on: (signal, listener) => listeners.set(signal, listener) },\n (signal) => (handled = shutdown(signal)),\n )\n\n listeners.get(\"SIGINT\")?.()\n listeners.get(\"SIGTERM\")?.()\n assert.deepEqual(exits, [1])\n\n finishCleanup()\n await handled\n })\n\n it(\"coalesces chunked and repeated stdin shutdown commands through the same handler\", async () => {\n const listeners = new Map<string, (chunk: Buffer | string) => void>()\n const triggers: string[] = []\n let destroys = 0\n const source = {\n on: (event: \"data\", listener: (chunk: Buffer | string) => void) => listeners.set(event, listener),\n off: (event: \"data\", listener: (chunk: Buffer | string) => void) => {\n if (listeners.get(event) === listener) listeners.delete(event)\n },\n destroy: () => { destroys++ },\n }\n installShutdownStdinHandler(source, async (trigger) => { triggers.push(trigger) })\n\n const listener = listeners.get(\"data\")!\n listener(STDIN_SHUTDOWN_COMMAND.slice(0, 8))\n listener(`${STDIN_SHUTDOWN_COMMAND.slice(8)}\\n${STDIN_SHUTDOWN_COMMAND}\\n`)\n listener(`${STDIN_SHUTDOWN_COMMAND}\\n`)\n await Promise.resolve()\n\n assert.deepEqual(triggers, [\"stdin\"])\n assert.equal(destroys, 1)\n assert.equal(listeners.has(\"data\"), false)\n })\n\n it(\"allows a real piped process to exit naturally after the shutdown command\", { timeout: 5_000 }, async () => {\n const moduleUrl = new URL(\"./index.ts\", import.meta.url).href\n const child = spawn(process.execPath, [\"--import\", \"tsx\", \"--input-type=module\", \"-e\", `\n import { installShutdownStdinHandler } from ${JSON.stringify(moduleUrl)}\n installShutdownStdinHandler(process.stdin, async () => { process.exitCode = 0 })\n `], { stdio: [\"pipe\", \"ignore\", \"inherit\"] })\n\n child.stdin.end(`${STDIN_SHUTDOWN_COMMAND}\\n`)\n const [code] = await once(child, \"exit\")\n assert.equal(code, 0)\n })\n})\n\ndescribe(\"CLI host normalization\", () => {\n it(\"normalizes mapped and internationalized hosts and rejects IPv6 zones\", () => {\n assert.equal(resolveHost(\"::ffff:0:0\"), \"0.0.0.0\")\n assert.equal(resolveHost(\"::ffff:7f00:1\"), \"127.0.0.1\")\n assert.equal(resolveHost(\"münchen.local\"), \"xn--mnchen-3ya.local\")\n assert.throws(() => resolveHost(\"fe80::1%12\"), /IPv6 zone identifiers/)\n })\n})\n"]}
|