* feat(auth): add passkey login for protected UI * fix: polish passkey setup and correct WebAuthn user IDs * feat: improve passkey login management * build: align passkey deps with upstream main * refactor: move ui auth out of opencode module --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
20 KiB
20 KiB
OpenCode Module Documentation
Purpose
This module provides OpenCode server integration utilities for the web server runtime, including configuration management and provider authentication.
Entrypoints and structure
packages/web/server/lib/opencode/index.js: public entrypoint (currently baseline placeholder).packages/web/server/lib/opencode/auth.js: provider authentication file operations.packages/web/server/lib/opencode/auth-state-runtime.js: managed OpenCode server auth password/header runtime.packages/web/server/lib/opencode/cli-options.js: CLI/environment option parsing for server startup arguments.packages/web/server/lib/opencode/cli-entry-runtime.js: CLI entrypoint runtime that detects direct execution, parses CLI options, and starts server bootstrap.packages/web/server/lib/opencode/routes.js: OpenCode/provider settings and auth-related route registration.packages/web/server/lib/opencode/lifecycle.js: OpenCode process lifecycle runtime (startup, restart, readiness, health monitoring).packages/web/server/lib/opencode/env-runtime.js: OpenCode CLI/binary resolution and shell environment runtime.packages/web/server/lib/opencode/env-config.js: OpenCode-related environment variable parsing and validation (host/port/hostname).packages/web/server/lib/opencode/hmr-state-runtime.js: HMR-persistent runtime state initialization, auth-state bootstrap, and HMR sync helpers.packages/web/server/lib/opencode/bootstrap-runtime.js: base app bootstrap runtime for status/auth/tts/notification/OpenChamber route wiring.packages/web/server/lib/opencode/network-runtime.js: OpenCode URL construction, health-probe readiness checks, and API prefix runtime.packages/web/server/lib/opencode/project-directory-runtime.js: request-scoped and settings-backed project directory resolution/validation runtime.packages/web/server/lib/opencode/config-entity-routes.js: route registration for agent/command/MCP config orchestration and reload semantics.packages/web/server/lib/opencode/cli-options.js: CLI/environment option parsing for server startup arguments.packages/web/server/lib/opencode/core-routes.js: server status/system routes, auth/access guard routes, and settings utility route registration.packages/web/server/lib/opencode/shutdown-runtime.js: graceful shutdown orchestration runtime for watcher/session/terminal/process/server teardown.packages/web/server/lib/opencode/server-startup-runtime.js: server listen/startup tunnel flow and process/signal handler orchestration runtime.packages/web/server/lib/opencode/static-routes-runtime.js: static asset/SPA fallback route registration and manifest route wiring.packages/web/server/lib/opencode/feature-routes-runtime.js: feature route composition runtime for dynamic import-backed config/skill/provider route registration.packages/web/server/lib/opencode/opencode-resolution-runtime.js: OpenCode binary resolution snapshot runtime for settings routes and diagnostics.packages/web/server/lib/opencode/tunnel-wiring-runtime.js: tunnel service/routes composition runtime and active-port wiring for main server startup.packages/web/server/lib/opencode/startup-pipeline-runtime.js: server startup tail orchestration runtime for terminal/proxy/static/start-listen flow.packages/web/server/lib/opencode/server-utils-runtime.js: shared server runtime utilities for OpenCode proxy wiring, OpenCode port/readiness helpers, and snapshot fetchers.packages/web/server/lib/opencode/openchamber-routes.js: OpenChamber update and models metadata route registration.packages/web/server/lib/opencode/pwa-manifest-routes.js: PWA manifest route registration with recent-session shortcut resolution and short-lived caching.packages/web/server/lib/opencode/project-icon-routes.js: project icon upload/read/discovery route registration and icon storage orchestration.packages/web/server/lib/opencode/skill-routes.js: route registration for skill config CRUD, supporting files, and skills catalog scan/install flows.packages/web/server/lib/opencode/settings-runtime.js: Settings persistence runtime (disk IO, migrations, normalization, project validation, and persisted update serialization).packages/web/server/lib/opencode/settings-helpers.js: Settings payload sanitization/format helpers runtime for response shaping and persisted merge prep.packages/web/server/lib/opencode/settings-normalization-runtime.js: path/settings/tunnel normalization and sanitization helpers runtime used by settings/routes/config wiring.packages/web/server/lib/opencode/theme-runtime.js: custom theme JSON validation and theme directory loading runtime for settings utility routes.packages/web/server/lib/opencode/proxy.js: OpenCode API/SSE forwarding and readiness-gate route registration.packages/web/server/lib/opencode/session-runtime.js: session status/attention/activity runtime for OpenCode SSE events.packages/web/server/lib/opencode/watcher.js: global SSE watcher runtime for push/session event fanout.packages/web/server/lib/opencode/shared.js: shared utilities for config, markdown, skills, and git helpers.packages/web/server/lib/ui-auth/ui-auth.js: UI session authentication runtime (outside OpenCode module).packages/web/server/lib/ui-auth/ui-passkeys.js: UI passkey storage and WebAuthn registration/authentication helpers (outside OpenCode module).
Public exports (auth.js)
readAuthFile(): Reads and parses~/.local/share/opencode/auth.json.writeAuthFile(auth): Writes auth file with automatic backup.removeProviderAuth(providerId): Removes a provider's auth entry.getProviderAuth(providerId): Returns auth for a specific provider or null.listProviderAuths(): Returns list of provider IDs with configured auth.AUTH_FILE: Auth file path constant.OPENCODE_DATA_DIR: OpenCode data directory path constant.
Public exports (shared.js)
OPENCODE_CONFIG_DIR,AGENT_DIR,COMMAND_DIR,SKILL_DIR,CONFIG_FILE,CUSTOM_CONFIG_FILE: Path constants.AGENT_SCOPE,COMMAND_SCOPE,SKILL_SCOPE: Scope constants with USER and PROJECT values.ensureDirs(): Creates required OpenCode directories.parseMdFile(filePath),writeMdFile(filePath, frontmatter, body): Markdown file operations with YAML frontmatter.getConfigPaths(workingDirectory),readConfigLayers(workingDirectory),readConfig(workingDirectory): Config file operations with layer merging (user, project, custom).writeConfig(config, filePath): Writes config with automatic backup.getJsonEntrySource(layers, sectionKey, entryName): Resolves which config layer provides an entry.getJsonWriteTarget(layers, preferredScope): Determines write target for config updates.getAncestors(startDir, stopDir),findWorktreeRoot(startDir): Git worktree helpers.isPromptFileReference(value),resolvePromptFilePath(reference),writePromptFile(filePath, content): Prompt file reference handling.walkSkillMdFiles(rootDir): Recursively finds all SKILL.md files.addSkillFromMdFile(skillsMap, skillMdPath, scope, source): Parses and indexes a skill file.resolveSkillSearchDirectories(workingDirectory): Returns skill search path order (config, project, home, custom).listSkillSupportingFiles(skillDir),readSkillSupportingFile(skillDir, relativePath),writeSkillSupportingFile(skillDir, relativePath, content),deleteSkillSupportingFile(skillDir, relativePath): Skill supporting file management.
Public exports (routes.js)
registerOpenCodeRoutes(app, dependencies): Registers OpenCode-owned HTTP routes and internal module runtime:GET /api/config/settingsPUT /api/config/settingsGET /api/config/opencode-resolutionPOST /api/opencode/directoryGET /api/provider/:providerId/sourceDELETE /api/provider/:providerId/auth
- Owns lazy auth library loading for provider auth checks/removal.
- Keeps route behavior independent from composition root;
index.jsnow supplies dependencies only.
Public exports (session-runtime.js)
createSessionRuntime({ writeSseEvent, getNotificationClients }): creates runtime-owned state machine and APIs for session status.- Returned API:
processOpenCodeSsePayload(payload)getSessionActivitySnapshot()getSessionStateSnapshot()getSessionAttentionSnapshot()getSessionState(sessionId)getSessionAttentionState(sessionId)markSessionViewed(sessionId, clientId)markSessionUnviewed(sessionId, clientId)markUserMessageSent(sessionId)resetAllSessionActivityToIdle()dispose()
Public exports (lifecycle.js)
createOpenCodeLifecycleRuntime(dependencies): creates lifecycle runtime for managed/external OpenCode process orchestration.- Returned API:
startOpenCode()restartOpenCode()waitForOpenCodeReady(timeoutMs?, intervalMs?)waitForAgentPresence(agentName, timeoutMs?, intervalMs?)refreshOpenCodeAfterConfigChange(reason, options?)bootstrapOpenCodeAtStartup()startHealthMonitoring(healthCheckIntervalMs)waitForPortRelease(port, timeoutMs, hostname?)killProcessOnPort(port)
Public exports (env-runtime.js)
createOpenCodeEnvRuntime(dependencies): creates runtime that owns OpenCode CLI environment and binary discovery state.- Returned API:
applyLoginShellEnvSnapshot()getLoginShellEnvSnapshot()ensureOpencodeCliEnv()applyOpencodeBinaryFromSettings()resolveOpencodeCliPath()resolveManagedOpenCodeLaunchSpec(opencodePath): resolves the effective managed OpenCode launch target, unwrapping Windows package-manager shims to a direct native binary or explicit runtime+script when possible.resolveGitBinaryForSpawn()resolveWslExecutablePath()buildWslExecArgs(execArgs, distroOverride?)isExecutable(filePath)searchPathFor(binaryName)clearResolvedOpenCodeBinary()
Public exports (env-config.js)
resolveOpenCodeEnvConfig(options?): resolves and validates OpenCode host/port/hostname environment configuration.- Returned object fields:
configuredOpenCodePortconfiguredOpenCodeHosteffectivePortconfiguredOpenCodeHostname
Public exports (hmr-state-runtime.js)
createHmrStateRuntime(dependencies): creates runtime for HMR state container initialization and runtime<->HMR state synchronization.- Returned API:
getOrCreateHmrState()ensureUserProvidedOpenCodePassword(hmrState)getUserProvidedOpenCodePassword(hmrState)resolveOpenCodeAuthFromState({ hmrState, userProvidedOpenCodePassword })syncStateFromRuntime(hmrState, runtime)restoreRuntimeFromState({ hmrState, userProvidedOpenCodePassword })
Public exports (bootstrap-runtime.js)
createBootstrapRuntime(dependencies): creates runtime for base app route bootstrap and UI auth controller initialization.- Returned API:
setupBaseRoutes(app, options)
Public exports (network-runtime.js)
createOpenCodeNetworkRuntime(dependencies): creates runtime for OpenCode network and URL concerns.- Returned API:
waitForReady(url, timeoutMs?)normalizeApiPrefix(prefix)setDetectedOpenCodeApiPrefix()buildOpenCodeUrl(path, prefixOverride?)ensureOpenCodeApiPrefix()scheduleOpenCodeApiDetection()
Public exports (settings-runtime.js)
createSettingsRuntime(dependencies): creates settings lifecycle runtime for read/migrate/persist concerns.- Returned API:
readSettingsFromDisk()readSettingsFromDiskMigrated()writeSettingsToDisk(settings)persistSettings(changes)
Public exports (settings-helpers.js)
createSettingsHelpers(dependencies): creates settings helper runtime for settings request/response shaping.- Returned API:
normalizePwaAppName(value, fallback?)sanitizeSettingsUpdate(payload)mergePersistedSettings(current, changes)formatSettingsResponse(settings)
Public exports (settings-normalization-runtime.js)
createSettingsNormalizationRuntime(dependencies): creates normalization/sanitization runtime for shared settings and tunnel helper logic.- Returned API:
normalizeDirectoryPath(value)normalizePathForPersistence(value)normalizeSettingsPaths(input)normalizeTunnelBootstrapTtlMs(value)normalizeTunnelSessionTtlMs(value)normalizeManagedRemoteTunnelHostname(value)normalizeManagedRemoteTunnelPresets(value)normalizeManagedRemoteTunnelPresetTokens(value)isUnsafeSkillRelativePath(value)sanitizeTypographySizesPartial(input)normalizeStringArray(input)sanitizeModelRefs(input, limit)sanitizeSkillCatalogs(input)sanitizeProjects(input)
Public exports (theme-runtime.js)
createThemeRuntime(dependencies): creates custom theme runtime for on-disk theme discovery and JSON normalization/validation.- Returned API:
normalizeThemeJson(raw)readCustomThemesFromDisk()
Public exports (project-directory-runtime.js)
createProjectDirectoryRuntime(dependencies): creates runtime for request/project directory candidate normalization and validation.- Returned API:
resolveDirectoryCandidate(value)validateDirectoryPath(candidate)resolveProjectDirectory(req)resolveOptionalProjectDirectory(req)
Public exports (config-entity-routes.js)
registerConfigEntityRoutes(app, dependencies): registers configuration entity routes:- Agents:
/api/config/agents/:nameand/api/config/agents/:name/config - Commands:
/api/config/commands/:name - MCP servers:
/api/config/mcpand/api/config/mcp/:name
- Agents:
Public exports (auth-state-runtime.js)
createOpenCodeAuthStateRuntime(dependencies): creates runtime for managed OpenCode auth password state and request headers.- Returned API:
getOpenCodeAuthHeaders()isOpenCodeConnectionSecure()ensureLocalOpenCodeServerPassword(options?)
Public exports (core-routes.js)
registerServerStatusRoutes(app, dependencies): registers status/system endpoints:GET /healthPOST /api/system/shutdownGET /api/system/info
registerAuthAndAccessRoutes(app, dependencies): registers browser auth/session exchange and API access middleware:GET /auth/sessionPOST /auth/sessionGET /auth/passkey/statusPOST /auth/passkey/authenticate/optionsPOST /auth/passkey/authenticate/verifyPOST /auth/passkey/register/optionsPOST /auth/passkey/register/verifyGET /api/passkeysDELETE /api/passkeys/:idPOST /api/auth/resetGET /connectapp.use('/api', ...)auth/tunnel guard
registerSettingsUtilityRoutes(app, dependencies): registers small settings utility endpoints:GET /api/config/themesPOST /api/config/reload
registerCommonRequestMiddleware(app, dependencies): registers shared request middleware stack:- conditional JSON body parser behavior for
/api/*vs non-API requests - URL-encoded parser setup
- request logging middleware
- conditional JSON body parser behavior for
Public exports (cli-options.js)
parseServeCliOptions(options): parses serve CLI flags and environment-derived defaults:- Port/host/ui-password
- Tunnel provider/mode/config/token/hostname
- Legacy
--tunnelshorthand normalization
Public exports (cli-entry-runtime.js)
runCliEntryIfMain(dependencies): detects direct CLI execution and runs server startup with parsed CLI options.
Public exports (server-utils-runtime.js)
createServerUtilsRuntime(dependencies): creates server utility runtime for OpenCode orchestration helpers.- Returned API:
setOpenCodePort(port)waitForOpenCodePort(timeoutMs?)buildAugmentedPath()parseSseDataPayload(block)fetchAgentsSnapshot()fetchProvidersSnapshot()fetchModelsSnapshot()setupProxy(app)
Public exports (shutdown-runtime.js)
createGracefulShutdownRuntime(dependencies): creates graceful shutdown runtime for managed OpenCode and web server teardown sequencing.- Returned API:
gracefulShutdown(options?)
Public exports (server-startup-runtime.js)
createServerStartupRuntime(dependencies): creates runtime for server bind/startup tunnel and process handler wiring.- Returned API:
resolveBindHost(host)startListeningAndMaybeTunnel(options)attachProcessHandlers(options)
Public exports (static-routes-runtime.js)
createStaticRoutesRuntime(dependencies): creates runtime for static dist resolution and static route registration.- Returned API:
registerStaticRoutes(app)
Public exports (feature-routes-runtime.js)
createFeatureRoutesRuntime(dependencies): creates runtime for main feature route registration orchestration.- Returned API:
registerRoutes(app, routeDependencies)
Public exports (opencode-resolution-runtime.js)
createOpenCodeResolutionRuntime(dependencies): creates runtime for OpenCode binary/source snapshot resolution.- Returned API:
getOpenCodeResolutionSnapshot(settings): returns configured/resolved OpenCode binary details plus effective managed-launch fields (launchBinary,launchArgs,launchWrapperType) when applicable.
Public exports (tunnel-wiring-runtime.js)
createTunnelWiringRuntime(dependencies): creates runtime for tunnel service construction and tunnel route registration.- Returned API:
initialize(app, initialPort)
Public exports (startup-pipeline-runtime.js)
createStartupPipelineRuntime(dependencies): creates runtime for terminal wiring, proxy/bootstrap scheduling, static route registration, and server startup/listen flow.- Returned API:
run(options)
Public exports (openchamber-routes.js)
registerOpenChamberRoutes(app, dependencies): registers OpenChamber endpoints:GET /api/openchamber/update-checkPOST /api/openchamber/update-installGET /api/openchamber/models-metadataGET /api/zen/models
Public exports (pwa-manifest-routes.js)
registerPwaManifestRoute(app, dependencies): registers PWA manifest endpoint with dynamic app-name resolution and recent-session shortcuts:GET /manifest.webmanifest
Public exports (project-icon-routes.js)
registerProjectIconRoutes(app, dependencies): registers project icon routes and owns icon storage/discovery flow:GET /api/projects/:projectId/iconPUT /api/projects/:projectId/iconDELETE /api/projects/:projectId/iconPOST /api/projects/:projectId/icon/discover
Public exports (skill-routes.js)
registerSkillRoutes(app, dependencies): registers skills-related routes:- Skills config CRUD and metadata under
/api/config/skills* - Skills catalog listing/source pagination, scan, and install routes
- Supporting skill file read/write/delete routes
- Skills config CRUD and metadata under
Public exports (proxy.js)
registerOpenCodeProxy(app, dependencies): registers OpenCode proxy routes and middleware.- Owns:
- SSE forwarders:
GET /api/global/event,GET /api/event - Session message forwarder:
POST /api/session/:sessionId/message - Generic
/api/*forwarding with hop-by-hop header filtering - Windows
/sessionmerge fallback path behavior - OpenCode readiness gate for proxied
/apirequests
- SSE forwarders:
Public exports (watcher.js)
createOpenCodeWatcherRuntime(dependencies): creates global event watcher runtime.- Returned API:
start()stop()
Storage and configuration
- Provider auth:
~/.local/share/opencode/auth.json. - User config:
~/.config/opencode/opencode.json. - Project config:
<workingDirectory>/.opencode/opencode.jsonoropencode.json. - Custom config:
OPENCODE_CONFIGenv var path. - Rate limit config:
OPENCHAMBER_RATE_LIMIT_MAX_ATTEMPTS,OPENCHAMBER_RATE_LIMIT_NO_IP_MAX_ATTEMPTSenv vars.
Notes for contributors
- This module serves as foundation for OpenCode-related server utilities.
- Route ownership moved to module-level
routes.js;index.jswires dependencies only. - All file writes include automatic backup before modification.
- Config merging follows priority: custom > project > user.
- UI auth uses scrypt for password hashing with constant-time comparison.
- Tunnel auth treats
host.docker.internalas local-only when the socket remote IP is private/loopback.