@wujie-shell/config
v1.1.2
Published
`@wujie-shell/config` is the product configuration loader for `wujie-shell`. It reads a UI product project's environment files and `shell.config.mjs`, then normalizes paths, ports, runtime directories, model config, and OpenClaw asset locations for shell-
Readme
@wujie-shell/config
@wujie-shell/config is the product configuration loader for wujie-shell.
It reads a UI product project's environment files and shell.config.mjs, then
normalizes paths, ports, runtime directories, model config, and OpenClaw asset
locations for shell-core.
Responsibility
- Load product env files before importing product config.
- Locate
shell.config.mjsorshell.config.jsin a product root. - Normalize relative paths into absolute paths.
- Resolve the product data directory under the current user's home directory.
- Provide canonical OpenClaw config/state paths.
- Create shell state directories before runtime or gateway startup.
This package must not contain product-specific Agent, Skill, Plugin, or UI logic. It only validates and normalizes the product contract.
Env Loading
loadShellEnv(projectRoot, options) loads env files from the product root.
Default mode is selected from:
options.modeWUJIE_SHELL_ENVNODE_ENV
Loaded files:
- Always:
.env - Local/dev mode:
.env.development,.env.development.local,.env.local - Test mode:
.env.test,.env.test.local - Prod mode:
.env.production,.env.production.local,.env.prod,.env.prod.local
Existing process.env values win over file values. Env file values are only
assigned when the key is not already present.
Shell Config Loading
loadShellConfig(projectRoot) loads env first, imports the product config, and
returns a normalized config object.
Required product fields:
appIdproductNamedescriptionandauthorare optional product package metadata.protocoldataDirName
Important rules:
appIdmust be unique and stable per product. Electron uses it to isolate the single-instance lock anduserData;productNameis display-only.rendererdefaults to./src.- Missing
ports.renderernormalizes toauto. - Missing
ports.gatewayStartnormalizes toauto. logger.logsDirNamedefaults to<dataDirName>/logsand resolves under the current user's home directory, likedataDirName.logger.logLeveldefaults toinfo. Valid values areerror,warn,info,debug.updates.enableddefaults totrue.updates.channeldefaults tolatestand only acceptslatestoralpha.updates.autoDownloaddefaults tofalse.updates.backgroundCheckIntervalMsdefaults to3600000.updates.backgroundCheckStaleMsdefaults to1800000.updates.installQuitTimeoutMsdefaults to60000.updates.nativeUpdatePrefetchTimeoutMsdefaults to45000.packaging.mac.squirrelMacEnableDirectContentsWritedefaults totrueand writesSquirrelMacEnableDirectContentsWriteinto both the main macOS appInfo.plistand the embedded Squirrel frameworkInfo.plist. The runtime updater also writes the same key to the app and.ShipItmacOS defaults domains immediately beforequitAndInstall; set the packaging option tofalseto run a signed-package A/B test against Squirrel.Mac's default bundle replacement path.openclaw.nodeVersiondefaults to22.22.1.openclaw.openclawVersiondefaults to2026.6.6.openclaw.configFileNamedefaults towujieai.jsonand must be a file name, not a path.openclaw.localAgentPathsdeclares concrete product Agent directories and resolves toresolvedLocalAgentPaths. It has no default; each path basename is the Agent ID, and.wujieaiconfig/state is kept aligned with this list.openclaw.localSkillPathsdeclares product Skill directories and resolves toresolvedLocalSkillPaths. It has no default.- Duplicate top-level Agent or Skill names across configured local paths are rejected during runtime sync.
packagingdefaults mirror the original desktop Electron Builder contract: release output,buildresources, runtime extra resource,resources/**unpacking, Linux targets, AppImage artifact name, DMG artifact name/size, andelectronUpdaterCompatibilitywhen provided by the product. Default packaged files includeshell.config.mjs,package.json, and the runtime env files.env,.env.production,.env.prod,.env.testso the packaged Shell main process can reload the same MCP/model env inprodortestmode.
Exported API
import {
ensureShellStateDirs,
getConfigPaths,
loadShellConfig,
loadShellEnv,
normalizeShellConfig,
readJsonFile,
writeJsonFile,
} from '@wujie-shell/config'loadShellEnv(projectRoot, options?)
Loads product env files and returns:
{
mode: 'local' | 'prod' | string,
files: string[]
}loadShellConfig(projectRoot)
Returns normalized shell config:
{
projectRoot,
configPath,
appId,
productName,
description,
author,
protocol,
renderer,
dataDirName,
dataDir,
logger: {
logsDirName,
logsDir,
logLevel
},
updates: {
enabled,
autoDownload,
channel,
backgroundCheckIntervalMs,
backgroundCheckStaleMs,
installQuitTimeoutMs,
nativeUpdatePrefetchTimeoutMs
},
packaging: {
iconsDir,
detectUpdateChannel,
directories,
files,
extraResources,
asarUnpack,
electronUpdaterCompatibility,
linux,
appImage,
dmg,
mac
},
ports: {
renderer,
gatewayStart
},
openclaw: {
nodeVersion,
openclawVersion,
configFileName,
pluginSpecs,
localPluginPaths,
resolvedLocalPluginPaths,
localAgentPaths,
resolvedLocalAgentPaths,
localSkillPaths,
resolvedLocalSkillPaths,
workflowsDir
},
models
}normalizeShellConfig(raw, projectRoot, configPath?)
Normalizes an already-loaded config object. Use this in tests or tooling that constructs config in memory.
getConfigPaths(shellConfig)
Returns canonical state paths:
{
stateDir,
configPath,
lastGoodConfigPath,
runtimeStateDir,
logsDir,
logLevel,
deviceIdentityPath
}For Wujie Desktop these resolve under ~/.wujieai by default.
The OpenClaw config file is ~/<dataDirName>/<openclaw.configFileName> and
defaults to wujieai.json; lastGoodConfigPath uses the same file name with
.last-good appended.
logger.logsDirName is a local machine directory name resolved as
~/<logger.logsDirName>, matching the dataDirName convention. It must not be
an absolute path or escape the user home directory.
logger.logLevel controls shell main-process file logging before message
formatting. WUJIE_SHELL_LOG_LEVEL can temporarily override it at runtime.
ensureShellStateDirs(shellConfig)
Creates the product data directory and child directories required by OpenClaw config, logs, runtime state, and device identity.
readJsonFile(path, fallback?) / writeJsonFile(path, value)
Small JSON helpers used by shell-core controllers.
Typical Usage
import { loadShellConfig } from '@wujie-shell/config'
const shellConfig = await loadShellConfig('../desktop-cn')
console.log(shellConfig.dataDir)Product Boundary
shell.config.mjs belongs to the UI product. The shell reads it but does not
own product assets. Agent, Skill, Plugin, and Workflow declarations should stay
in the UI project and be referenced by config fields such as
openclaw.localPluginPaths, openclaw.localAgentPaths, and
openclaw.localSkillPaths. Agents not listed in localAgentPaths are removed
from managed .wujieai Agent config/state during sync.
