@neuralnomads/codenomad-dev 0.20.0-dev-20260910-abaf6eba → 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.
Files changed (143) hide show
  1. package/dist/api-types.js.map +1 -1
  2. package/dist/index.js +13 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/opencode/pruning-installation.js +65 -0
  5. package/dist/opencode/pruning-installation.js.map +1 -0
  6. package/dist/opencode/pruning-installation.test.js +101 -0
  7. package/dist/opencode/pruning-installation.test.js.map +1 -0
  8. package/dist/opencode/pruning-lifecycle.js +66 -0
  9. package/dist/opencode/pruning-lifecycle.js.map +1 -0
  10. package/dist/opencode/session-pruning/claim-fence.js +33 -0
  11. package/dist/opencode/session-pruning/claim-fence.js.map +1 -0
  12. package/dist/opencode/session-pruning/claim-fence.test.js +104 -0
  13. package/dist/opencode/session-pruning/claim-fence.test.js.map +1 -0
  14. package/dist/opencode/session-pruning/contract.js +40 -0
  15. package/dist/opencode/session-pruning/contract.js.map +1 -0
  16. package/dist/opencode/session-pruning/database-path.js +17 -0
  17. package/dist/opencode/session-pruning/database-path.js.map +1 -0
  18. package/dist/opencode/session-pruning/database-path.test.js +22 -0
  19. package/dist/opencode/session-pruning/database-path.test.js.map +1 -0
  20. package/dist/opencode/session-pruning/desktop-plugin.js +14 -0
  21. package/dist/opencode/session-pruning/desktop-plugin.js.map +1 -0
  22. package/dist/opencode/session-pruning/index.js +2 -0
  23. package/dist/opencode/session-pruning/index.js.map +1 -0
  24. package/dist/opencode/session-pruning/isolated-store.js +18 -0
  25. package/dist/opencode/session-pruning/isolated-store.js.map +1 -0
  26. package/dist/opencode/session-pruning/planner.js +36 -0
  27. package/dist/opencode/session-pruning/planner.js.map +1 -0
  28. package/dist/opencode/session-pruning/plugin.js +45 -0
  29. package/dist/opencode/session-pruning/plugin.js.map +1 -0
  30. package/dist/opencode/session-pruning/presence.js +42 -0
  31. package/dist/opencode/session-pruning/presence.js.map +1 -0
  32. package/dist/opencode/session-pruning/preview-store.js +21 -0
  33. package/dist/opencode/session-pruning/preview-store.js.map +1 -0
  34. package/dist/opencode/session-pruning/pruning.test.js +172 -0
  35. package/dist/opencode/session-pruning/pruning.test.js.map +1 -0
  36. package/dist/opencode/session-pruning/revision.js +18 -0
  37. package/dist/opencode/session-pruning/revision.js.map +1 -0
  38. package/dist/opencode/session-pruning/service.js +56 -0
  39. package/dist/opencode/session-pruning/service.js.map +1 -0
  40. package/dist/opencode/session-pruning/service.test.js +74 -0
  41. package/dist/opencode/session-pruning/service.test.js.map +1 -0
  42. package/dist/opencode/session-pruning/storage-path.js +6 -0
  43. package/dist/opencode/session-pruning/storage-path.js.map +1 -0
  44. package/dist/opencode/session-pruning/transaction.js +53 -0
  45. package/dist/opencode/session-pruning/transaction.js.map +1 -0
  46. package/dist/opencode/session-pruning/tui-reload.js +84 -0
  47. package/dist/opencode/session-pruning/tui-reload.js.map +1 -0
  48. package/dist/opencode/session-pruning/tui-reload.native.js +269 -0
  49. package/dist/opencode/session-pruning/tui-reload.native.js.map +1 -0
  50. package/dist/opencode/session-pruning/tui-reload.test.js +71 -0
  51. package/dist/opencode/session-pruning/tui-reload.test.js.map +1 -0
  52. package/dist/opencode/session-pruning/tui.js +12 -0
  53. package/dist/opencode/session-pruning/tui.js.map +1 -0
  54. package/dist/plugins/session-pruning/plugin.mjs +26559 -0
  55. package/dist/server/__tests__/instance-proxy.test.js +10 -5
  56. package/dist/server/__tests__/instance-proxy.test.js.map +1 -1
  57. package/dist/server/http-server.js +2 -1
  58. package/dist/server/http-server.js.map +1 -1
  59. package/dist/server/routes/session-pruning.js +45 -0
  60. package/dist/server/routes/session-pruning.js.map +1 -0
  61. package/dist/server/routes/session-pruning.test.js +98 -0
  62. package/dist/server/routes/session-pruning.test.js.map +1 -0
  63. package/dist/workspaces/manager.js +1 -0
  64. package/dist/workspaces/manager.js.map +1 -1
  65. package/package.json +6 -3
  66. package/public/assets/App-0-FcHzPS.js +44 -0
  67. package/public/assets/App-0-FcHzPS.js.map +1 -0
  68. package/public/assets/{FilesTab-BVJawmU7.js → FilesTab-CRpGDs1B.js} +3 -3
  69. package/public/assets/{FilesTab-BVJawmU7.js.map → FilesTab-CRpGDs1B.js.map} +1 -1
  70. package/public/assets/{GitChangesTab-BVdfbJ_l.js → GitChangesTab-DxFebTiq.js} +3 -3
  71. package/public/assets/{GitChangesTab-BVdfbJ_l.js.map → GitChangesTab-DxFebTiq.js.map} +1 -1
  72. package/public/assets/{SplitFilePanel-CSR5-RHY.js → SplitFilePanel-DgTMrrO-.js} +2 -2
  73. package/public/assets/{SplitFilePanel-CSR5-RHY.js.map → SplitFilePanel-DgTMrrO-.js.map} +1 -1
  74. package/public/assets/{StatusTab-DIodfPQd.js → StatusTab-LKUA9cbH.js} +2 -2
  75. package/public/assets/{StatusTab-DIodfPQd.js.map → StatusTab-LKUA9cbH.js.map} +1 -1
  76. package/public/assets/{align-justify-kDFhSvpm.js → align-justify-v_yPXSys.js} +2 -2
  77. package/public/assets/{align-justify-kDFhSvpm.js.map → align-justify-v_yPXSys.js.map} +1 -1
  78. package/public/assets/{bundle-full-B4eYITdG.js → bundle-full-HzL_Jtqk.js} +2 -2
  79. package/public/assets/{bundle-full-B4eYITdG.js.map → bundle-full-HzL_Jtqk.js.map} +1 -1
  80. package/public/assets/{client-state-D3g-WH8W.js → client-state-CF-PJ0GG.js} +2 -2
  81. package/public/assets/{client-state-D3g-WH8W.js.map → client-state-CF-PJ0GG.js.map} +1 -1
  82. package/public/assets/{diff-viewer-BLL0OcUK.js → diff-viewer-BFDQBDVy.js} +2 -2
  83. package/public/assets/{diff-viewer-BLL0OcUK.js.map → diff-viewer-BFDQBDVy.js.map} +1 -1
  84. package/public/assets/{index-D21P0GMO.js → index-8iPlm2r0.js} +2 -2
  85. package/public/assets/index-8iPlm2r0.js.map +1 -0
  86. package/public/assets/{index-DnqYBc2b.js → index-B185mC7m.js} +2 -2
  87. package/public/assets/index-B185mC7m.js.map +1 -0
  88. package/public/assets/{index-DLtH2OSD.js → index-Bbj1xF8i.js} +2 -2
  89. package/public/assets/index-Bbj1xF8i.js.map +1 -0
  90. package/public/assets/{index-BtuH3zKP.js → index-BsmFN3k1.js} +2 -2
  91. package/public/assets/index-BsmFN3k1.js.map +1 -0
  92. package/public/assets/{index-CrOPzgHN.js → index-C52CfqK3.js} +2 -2
  93. package/public/assets/index-C52CfqK3.js.map +1 -0
  94. package/public/assets/{index-DWnsOFes.js → index-CHYmKl10.js} +2 -2
  95. package/public/assets/index-CHYmKl10.js.map +1 -0
  96. package/public/assets/{index-DbfYo3i-.js → index-CTKYD_VJ.js} +2 -2
  97. package/public/assets/index-CTKYD_VJ.js.map +1 -0
  98. package/public/assets/index-D2UHSOG5.js +2 -0
  99. package/public/assets/{index-BIqxsbaj.js.map → index-D2UHSOG5.js.map} +1 -1
  100. package/public/assets/{index-DLRrUgI7.js → index-DDoB_Z36.js} +2 -2
  101. package/public/assets/index-DDoB_Z36.js.map +1 -0
  102. package/public/assets/{index-e5yyN2yK.js → index-DcwAtZw-.js} +3 -3
  103. package/public/assets/{index-e5yyN2yK.js.map → index-DcwAtZw-.js.map} +1 -1
  104. package/public/assets/{index-ZnQhzm1X.js → index-DxUD3RYr.js} +2 -2
  105. package/public/assets/{index-ZnQhzm1X.js.map → index-DxUD3RYr.js.map} +1 -1
  106. package/public/assets/{index-CeF-jpOV.js → index-RK9gf0uk.js} +2 -2
  107. package/public/assets/{index-CeF-jpOV.js.map → index-RK9gf0uk.js.map} +1 -1
  108. package/public/assets/{loading-CaoeVfIV.js → loading-BSB82snY.js} +2 -2
  109. package/public/assets/{loading-CaoeVfIV.js.map → loading-BSB82snY.js.map} +1 -1
  110. package/public/assets/main-CZztwrfv.js +48 -0
  111. package/public/assets/main-CZztwrfv.js.map +1 -0
  112. package/public/assets/{markdown-BeJ9YIFU.js → markdown-DtidoL2Z.js} +4 -4
  113. package/public/assets/{markdown-BeJ9YIFU.js.map → markdown-DtidoL2Z.js.map} +1 -1
  114. package/public/assets/{monaco-viewer-Cc9bWg7I.js → monaco-viewer-CpxDfB-6.js} +2 -2
  115. package/public/assets/monaco-viewer-CpxDfB-6.js.map +1 -0
  116. package/public/assets/{startup-state-settings-card-BvpJJ6ei.js → startup-state-settings-card-BY741Rt0.js} +2 -2
  117. package/public/assets/{startup-state-settings-card-BvpJJ6ei.js.map → startup-state-settings-card-BY741Rt0.js.map} +1 -1
  118. package/public/assets/{terminal-square-DBCSEAmh.js → terminal-square-BdC_jwm3.js} +2 -2
  119. package/public/assets/{terminal-square-DBCSEAmh.js.map → terminal-square-BdC_jwm3.js.map} +1 -1
  120. package/public/assets/{tool-call-BJiSHSx7.js → tool-call-DbtCsJ4x.js} +4 -4
  121. package/public/assets/{tool-call-BJiSHSx7.js.map → tool-call-DbtCsJ4x.js.map} +1 -1
  122. package/public/assets/{unified-picker-CAEyj3a0.js → unified-picker-C0eo1chJ.js} +2 -2
  123. package/public/assets/{unified-picker-CAEyj3a0.js.map → unified-picker-C0eo1chJ.js.map} +1 -1
  124. package/public/assets/{wrap-text-DJNV0ypl.js → wrap-text-BuMtdvMx.js} +2 -2
  125. package/public/assets/{wrap-text-DJNV0ypl.js.map → wrap-text-BuMtdvMx.js.map} +1 -1
  126. package/public/index.html +3 -3
  127. package/public/loading.html +3 -3
  128. package/public/sw.js +1 -1
  129. package/public/sw.js.map +1 -1
  130. package/public/assets/App-0ECD8eRb.js +0 -43
  131. package/public/assets/App-0ECD8eRb.js.map +0 -1
  132. package/public/assets/index-BIqxsbaj.js +0 -2
  133. package/public/assets/index-BtuH3zKP.js.map +0 -1
  134. package/public/assets/index-CrOPzgHN.js.map +0 -1
  135. package/public/assets/index-D21P0GMO.js.map +0 -1
  136. package/public/assets/index-DLRrUgI7.js.map +0 -1
  137. package/public/assets/index-DLtH2OSD.js.map +0 -1
  138. package/public/assets/index-DWnsOFes.js.map +0 -1
  139. package/public/assets/index-DbfYo3i-.js.map +0 -1
  140. package/public/assets/index-DnqYBc2b.js.map +0 -1
  141. package/public/assets/main-CeMcnDRn.js +0 -48
  142. package/public/assets/main-CeMcnDRn.js.map +0 -1
  143. package/public/assets/monaco-viewer-Cc9bWg7I.js.map +0 -1
@@ -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
@@ -35,6 +35,7 @@ import { AutoAcceptManager } from "./permissions/auto-accept-manager";
35
35
  import { createOpencodePermissionReplier } from "./permissions/opencode-replier";
36
36
  import { createOpencodeYoloPersistence } from "./permissions/opencode-yolo-metadata";
37
37
  import { NativeParent } from "./native-parent";
38
+ import { PruningLifecycle } from "./opencode/pruning-lifecycle";
38
39
  import { AUTOMATION_BRIDGE_PATH, createAutomationBridgeRegistration, publishAutomationBridge, removeLegacyAutomationPlugin } from "./opencode/automation-plugin";
39
40
  const require = createRequire(import.meta.url);
40
41
  const packageJson = require("../package.json");
@@ -246,12 +247,23 @@ async function main() {
246
247
  });
247
248
  const settings = new SettingsService(configLocation, eventBus, configLogger);
248
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();
249
260
  const workspaceManager = new WorkspaceManager({
250
261
  rootDir: options.rootDir,
251
262
  settings,
252
263
  binaryResolver,
253
264
  eventBus,
254
265
  logger: workspaceLogger,
266
+ prepareSessionPruning,
255
267
  });
256
268
  const nativeParent = new NativeParent();
257
269
  if (nativeParent.available) {
@@ -498,6 +510,7 @@ async function main() {
498
510
  stopRemoteProxySessions: () => remoteProxySessionManager.shutdown(),
499
511
  stopWorkspaces: () => workspaceManager.shutdown(),
500
512
  stopHttpServers: async () => {
513
+ await pruningLifecycle.stop();
501
514
  nativeParent.close();
502
515
  await removeAutomationBridge?.();
503
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, 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 { 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 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 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 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"]}
@@ -0,0 +1,65 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { mkdir, readFile, rename, rm, writeFile, utimes } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import { PRESENCE_INTERVAL_MS } from "./session-pruning/presence";
6
+ const marker = "// Managed by CodeNomad: session pruning lifecycle v1\n";
7
+ export async function installPruningPresence(bundle, paths) {
8
+ const hash = createHash("sha256").update(bundle).digest("hex");
9
+ const directory = path.join(paths.data, "session-pruning");
10
+ const nativeDirectory = paths.nativeData ? path.posix.join(paths.nativeData, "session-pruning") : directory;
11
+ const leases = path.join(directory, "presence");
12
+ const nativeLeases = paths.nativeData ? path.posix.join(nativeDirectory, "presence") : leases;
13
+ const plugin = path.join(directory, `${hash}.mjs`);
14
+ const nativeUrl = new URL("file:///");
15
+ nativeUrl.pathname = `${nativeDirectory}/${hash}.mjs`;
16
+ const pluginUrl = paths.nativeData ? nativeUrl.href : pathToFileURL(plugin).href;
17
+ const entry = path.join(paths.config, "plugins", "codenomad-session-pruning.ts");
18
+ const source = `${marker}import { desktopPlugin } from ${JSON.stringify(pluginUrl)}\nexport default desktopPlugin(${JSON.stringify(nativeLeases)})\n`;
19
+ await mkdir(leases, { recursive: true });
20
+ await mkdir(path.dirname(entry), { recursive: true });
21
+ const existing = await readFile(entry, "utf8").catch((error) => {
22
+ if (error.code !== "ENOENT")
23
+ throw error;
24
+ return undefined;
25
+ });
26
+ if (existing && !existing.startsWith(marker))
27
+ throw new Error(`Existing plugin entry is not managed by CodeNomad: ${entry}`);
28
+ // Immutable, content-addressed payloads keep running instances independent of upgrades.
29
+ await writeFile(plugin, bundle, { flag: "wx" }).catch((error) => {
30
+ if (error.code !== "EEXIST")
31
+ throw error;
32
+ });
33
+ const lease = path.join(leases, `${randomUUID()}.lease`);
34
+ await writeFile(lease, "");
35
+ try {
36
+ if (existing !== source) {
37
+ const temporary = `${entry}.${randomUUID()}.tmp`;
38
+ try {
39
+ await writeFile(temporary, source);
40
+ await rename(temporary, entry);
41
+ }
42
+ finally {
43
+ await rm(temporary, { force: true });
44
+ }
45
+ }
46
+ }
47
+ catch (error) {
48
+ await rm(lease, { force: true });
49
+ throw error;
50
+ }
51
+ let pending = Promise.resolve();
52
+ const timer = setInterval(() => {
53
+ pending = pending.then(async () => {
54
+ const now = new Date();
55
+ await utimes(lease, now, now);
56
+ }).catch(() => { });
57
+ }, PRESENCE_INTERVAL_MS);
58
+ timer.unref();
59
+ return async () => {
60
+ clearInterval(timer);
61
+ await pending;
62
+ await rm(lease, { force: true });
63
+ };
64
+ }
65
+ //# sourceMappingURL=pruning-installation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pruning-installation.js","sourceRoot":"","sources":["../../src/opencode/pruning-installation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACjF,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAQjE,MAAM,MAAM,GAAG,yDAAyD,CAAA;AAExE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAkB,EAAE,KAAmB;IAClF,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IAC1D,MAAM,eAAe,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3G,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IAC7F,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,MAAM,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAA;IACrC,SAAS,CAAC,QAAQ,GAAG,GAAG,eAAe,IAAI,IAAI,MAAM,CAAA;IACrD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAA;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,8BAA8B,CAAC,CAAA;IAChF,MAAM,MAAM,GAAG,GAAG,MAAM,iCAAiC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,kCAAkC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAA;IACrJ,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAA4B,EAAE,EAAE;QACpF,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAA;QACxC,OAAO,SAAS,CAAA;IAClB,CAAC,CAAC,CAAA;IACF,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,KAAK,EAAE,CAAC,CAAA;IAC5H,wFAAwF;IACxF,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAA4B,EAAE,EAAE;QACrF,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAA;IAC1C,CAAC,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,EAAE,QAAQ,CAAC,CAAA;IACxD,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC1B,IAAI,CAAC;QACH,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,MAAM,SAAS,GAAG,GAAG,KAAK,IAAI,UAAU,EAAE,MAAM,CAAA;YAChD,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;gBAClC,MAAM,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YAChC,CAAC;oBAAS,CAAC;gBAAC,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;YAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAChC,MAAM,KAAK,CAAA;IACb,CAAC;IACD,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;IAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;YACtB,MAAM,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACpB,CAAC,EAAE,oBAAoB,CAAC,CAAA;IACxB,KAAK,CAAC,KAAK,EAAE,CAAA;IACb,OAAO,KAAK,IAAI,EAAE;QAChB,aAAa,CAAC,KAAK,CAAC,CAAA;QACpB,MAAM,OAAO,CAAA;QACb,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAClC,CAAC,CAAA;AACH,CAAC","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\"\nimport { mkdir, readFile, rename, rm, writeFile, utimes } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport { PRESENCE_INTERVAL_MS } from \"./session-pruning/presence\"\n\nexport interface PruningPaths {\n config: string\n data: string\n // WSL uses Linux paths in the entry, UNC paths only for host filesystem I/O.\n nativeData?: string\n}\nconst marker = \"// Managed by CodeNomad: session pruning lifecycle v1\\n\"\n\nexport async function installPruningPresence(bundle: Uint8Array, paths: PruningPaths) {\n const hash = createHash(\"sha256\").update(bundle).digest(\"hex\")\n const directory = path.join(paths.data, \"session-pruning\")\n const nativeDirectory = paths.nativeData ? path.posix.join(paths.nativeData, \"session-pruning\") : directory\n const leases = path.join(directory, \"presence\")\n const nativeLeases = paths.nativeData ? path.posix.join(nativeDirectory, \"presence\") : leases\n const plugin = path.join(directory, `${hash}.mjs`)\n const nativeUrl = new URL(\"file:///\")\n nativeUrl.pathname = `${nativeDirectory}/${hash}.mjs`\n const pluginUrl = paths.nativeData ? nativeUrl.href : pathToFileURL(plugin).href\n const entry = path.join(paths.config, \"plugins\", \"codenomad-session-pruning.ts\")\n const source = `${marker}import { desktopPlugin } from ${JSON.stringify(pluginUrl)}\\nexport default desktopPlugin(${JSON.stringify(nativeLeases)})\\n`\n await mkdir(leases, { recursive: true })\n await mkdir(path.dirname(entry), { recursive: true })\n const existing = await readFile(entry, \"utf8\").catch((error: NodeJS.ErrnoException) => {\n if (error.code !== \"ENOENT\") throw error\n return undefined\n })\n if (existing && !existing.startsWith(marker)) throw new Error(`Existing plugin entry is not managed by CodeNomad: ${entry}`)\n // Immutable, content-addressed payloads keep running instances independent of upgrades.\n await writeFile(plugin, bundle, { flag: \"wx\" }).catch((error: NodeJS.ErrnoException) => {\n if (error.code !== \"EEXIST\") throw error\n })\n const lease = path.join(leases, `${randomUUID()}.lease`)\n await writeFile(lease, \"\")\n try {\n if (existing !== source) {\n const temporary = `${entry}.${randomUUID()}.tmp`\n try {\n await writeFile(temporary, source)\n await rename(temporary, entry)\n } finally { await rm(temporary, { force: true }) }\n }\n } catch (error) {\n await rm(lease, { force: true })\n throw error\n }\n let pending = Promise.resolve()\n const timer = setInterval(() => {\n pending = pending.then(async () => {\n const now = new Date()\n await utimes(lease, now, now)\n }).catch(() => {})\n }, PRESENCE_INTERVAL_MS)\n timer.unref()\n return async () => {\n clearInterval(timer)\n await pending\n await rm(lease, { force: true })\n }\n}\n"]}
@@ -0,0 +1,101 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { mkdtemp, mkdir, readFile, readdir, rm, utimes, writeFile } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { installPruningPresence } from "./pruning-installation";
7
+ import { followPresence, hasPresence, PRESENCE_EXPIRY_MS, PRESENCE_INTERVAL_MS } from "./session-pruning/presence";
8
+ import { setTimeout as delay } from "node:timers/promises";
9
+ test("bundled installation supports two backends, clean close, crash expiry and reopening", async () => {
10
+ const root = await mkdtemp(path.join(os.tmpdir(), "codenomad-pruning-presence-"));
11
+ const paths = { config: path.join(root, "config"), data: path.join(root, "data") };
12
+ const leases = path.join(paths.data, "session-pruning", "presence");
13
+ let first;
14
+ let second;
15
+ let stop;
16
+ let registrations = 0;
17
+ let disposals = 0;
18
+ const check = async (predicate) => {
19
+ for (let i = 0; i < 100 && !predicate(); i++)
20
+ await delay(100);
21
+ assert(predicate());
22
+ };
23
+ try {
24
+ stop = await followPresence(leases, async () => { registrations++; return () => { disposals++; }; });
25
+ assert.equal(registrations, 0);
26
+ const bundle = Buffer.from("export const desktopPlugin = () => ({id: 'fixture'})");
27
+ first = await installPruningPresence(bundle, paths);
28
+ await check(() => registrations === 1);
29
+ const entry = path.join(paths.config, "plugins", "codenomad-session-pruning.ts");
30
+ const source = await readFile(entry, "utf8");
31
+ assert(!source.includes("node_modules"));
32
+ second = await installPruningPresence(bundle, paths);
33
+ assert.equal(await readFile(entry, "utf8"), source);
34
+ await first();
35
+ first = undefined;
36
+ await delay(PRESENCE_INTERVAL_MS + 100);
37
+ assert.equal(disposals, 0);
38
+ await second();
39
+ second = undefined;
40
+ await check(() => disposals === 1);
41
+ const stale = path.join(leases, "dead.lease");
42
+ await writeFile(stale, "");
43
+ const beforeCrash = new Date(Date.now() - PRESENCE_EXPIRY_MS - 100);
44
+ await utimes(stale, beforeCrash, beforeCrash);
45
+ assert.equal(await hasPresence(leases), false);
46
+ first = await installPruningPresence(bundle, paths);
47
+ await check(() => registrations === 2);
48
+ await stop();
49
+ stop = undefined;
50
+ assert.equal(disposals, 2);
51
+ assert.equal((await readdir(path.join(paths.data, "session-pruning"))).filter(name => name.endsWith(".mjs")).length, 1);
52
+ }
53
+ finally {
54
+ await stop?.();
55
+ await first?.();
56
+ await second?.();
57
+ await rm(root, { recursive: true, force: true });
58
+ }
59
+ });
60
+ test("unloading while RPC registration is pending disposes it exactly once", async () => {
61
+ const root = await mkdtemp(path.join(os.tmpdir(), "codenomad-pruning-unload-"));
62
+ let finish;
63
+ let stopped = 0;
64
+ let started = false;
65
+ const pending = new Promise(resolve => { finish = resolve; });
66
+ const cleanup = await followPresence(root, async () => {
67
+ started = true;
68
+ await pending;
69
+ return () => { stopped++; };
70
+ });
71
+ try {
72
+ await writeFile(path.join(root, "abcd.lease"), "");
73
+ for (let i = 0; i < 100 && !started; i++)
74
+ await delay(50);
75
+ assert(started);
76
+ const closing = cleanup();
77
+ finish();
78
+ await closing;
79
+ assert.equal(stopped, 1);
80
+ }
81
+ finally {
82
+ finish();
83
+ await cleanup();
84
+ await rm(root, { recursive: true, force: true });
85
+ }
86
+ });
87
+ test("installation preserves a user-authored plugin entry", async () => {
88
+ const root = await mkdtemp(path.join(os.tmpdir(), "codenomad-pruning-existing-"));
89
+ const plugins = path.join(root, "plugins");
90
+ try {
91
+ await mkdir(plugins);
92
+ const entry = path.join(plugins, "codenomad-session-pruning.ts");
93
+ await writeFile(entry, "// user work");
94
+ await assert.rejects(installPruningPresence(Buffer.from("fixture"), { config: root, data: path.join(root, "data") }), /not managed/);
95
+ assert.equal(await readFile(entry, "utf8"), "// user work");
96
+ }
97
+ finally {
98
+ await rm(root, { recursive: true, force: true });
99
+ }
100
+ });
101
+ //# sourceMappingURL=pruning-installation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pruning-installation.test.js","sourceRoot":"","sources":["../../src/opencode/pruning-installation.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\"\nimport { test } from \"node:test\"\nimport { mkdtemp, mkdir, readFile, readdir, rm, utimes, writeFile } from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\nimport { installPruningPresence } from \"./pruning-installation\"\nimport { followPresence, hasPresence, PRESENCE_EXPIRY_MS, PRESENCE_INTERVAL_MS } from \"./session-pruning/presence\"\nimport { setTimeout as delay } from \"node:timers/promises\"\n\ntest(\"bundled installation supports two backends, clean close, crash expiry and reopening\", async () => {\n const root = await mkdtemp(path.join(os.tmpdir(), \"codenomad-pruning-presence-\"))\n const paths = { config: path.join(root, \"config\"), data: path.join(root, \"data\") }\n const leases = path.join(paths.data, \"session-pruning\", \"presence\")\n let first: (() => Promise<void>) | undefined\n let second: (() => Promise<void>) | undefined\n let stop: (() => Promise<void>) | undefined\n let registrations = 0\n let disposals = 0\n const check = async (predicate: () => boolean) => {\n for (let i = 0; i < 100 && !predicate(); i++) await delay(100)\n assert(predicate())\n }\n try {\n stop = await followPresence(leases, async () => { registrations++; return () => { disposals++ } })\n assert.equal(registrations, 0)\n const bundle = Buffer.from(\"export const desktopPlugin = () => ({id: 'fixture'})\")\n first = await installPruningPresence(bundle, paths)\n await check(() => registrations === 1)\n const entry = path.join(paths.config, \"plugins\", \"codenomad-session-pruning.ts\")\n const source = await readFile(entry, \"utf8\")\n assert(!source.includes(\"node_modules\"))\n second = await installPruningPresence(bundle, paths)\n assert.equal(await readFile(entry, \"utf8\"), source)\n await first(); first = undefined\n await delay(PRESENCE_INTERVAL_MS + 100)\n assert.equal(disposals, 0)\n await second(); second = undefined\n await check(() => disposals === 1)\n const stale = path.join(leases, \"dead.lease\")\n await writeFile(stale, \"\")\n const beforeCrash = new Date(Date.now() - PRESENCE_EXPIRY_MS - 100)\n await utimes(stale, beforeCrash, beforeCrash)\n assert.equal(await hasPresence(leases), false)\n first = await installPruningPresence(bundle, paths)\n await check(() => registrations === 2)\n await stop(); stop = undefined\n assert.equal(disposals, 2)\n assert.equal((await readdir(path.join(paths.data, \"session-pruning\"))).filter(name => name.endsWith(\".mjs\")).length, 1)\n } finally {\n await stop?.(); await first?.(); await second?.()\n await rm(root, { recursive: true, force: true })\n }\n})\n\ntest(\"unloading while RPC registration is pending disposes it exactly once\", async () => {\n const root = await mkdtemp(path.join(os.tmpdir(), \"codenomad-pruning-unload-\"))\n let finish!: () => void\n let stopped = 0\n let started = false\n const pending = new Promise<void>(resolve => { finish = resolve })\n const cleanup = await followPresence(root, async () => {\n started = true\n await pending\n return () => { stopped++ }\n })\n try {\n await writeFile(path.join(root, \"abcd.lease\"), \"\")\n for (let i = 0; i < 100 && !started; i++) await delay(50)\n assert(started)\n const closing = cleanup()\n finish()\n await closing\n assert.equal(stopped, 1)\n } finally { finish(); await cleanup(); await rm(root, { recursive: true, force: true }) }\n})\n\ntest(\"installation preserves a user-authored plugin entry\", async () => {\n const root = await mkdtemp(path.join(os.tmpdir(), \"codenomad-pruning-existing-\"))\n const plugins = path.join(root, \"plugins\")\n try {\n await mkdir(plugins)\n const entry = path.join(plugins, \"codenomad-session-pruning.ts\")\n await writeFile(entry, \"// user work\")\n await assert.rejects(installPruningPresence(Buffer.from(\"fixture\"), { config: root, data: path.join(root, \"data\") }), /not managed/)\n assert.equal(await readFile(entry, \"utf8\"), \"// user work\")\n } finally { await rm(root, { recursive: true, force: true }) }\n})\n"]}