create-openclaw-bot 5.8.20 → 5.8.21

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.
@@ -609,15 +609,21 @@ async function readEnvFile(file) {
609
609
  return existsSync(file) ? readEnvText(await fsp.readFile(file, 'utf8').catch(() => '')) : {};
610
610
  }
611
611
 
612
- function openclawProjectEnv(projectDir) {
613
- return {
614
- ...process.env,
615
- OPENCLAW_HOME: join(projectDir, '.openclaw'),
616
- OPENCLAW_STATE_DIR: join(projectDir, '.openclaw'),
617
- };
618
- }
619
-
620
- async function runOpenclawJson(projectDir, args = [], timeout = 12000) {
612
+ function openclawProjectEnv(projectDir) {
613
+ return {
614
+ ...process.env,
615
+ OPENCLAW_HOME: join(projectDir, '.openclaw'),
616
+ OPENCLAW_STATE_DIR: join(projectDir, '.openclaw'),
617
+ };
618
+ }
619
+
620
+ function parseJsonText(text, fallback = undefined) {
621
+ const clean = String(text || '').replace(/^\uFEFF/, '');
622
+ if (!clean.trim() && fallback !== undefined) return fallback;
623
+ return JSON.parse(clean);
624
+ }
625
+
626
+ async function runOpenclawJson(projectDir, args = [], timeout = 12000) {
621
627
  const out = await runCapture('openclaw', args, {
622
628
  cwd: projectDir,
623
629
  env: openclawProjectEnv(projectDir),
@@ -626,8 +632,8 @@ async function runOpenclawJson(projectDir, args = [], timeout = 12000) {
626
632
  });
627
633
  if (out.code !== 0) throw new Error((out.stderr || out.stdout || `openclaw ${args.join(' ')} failed`).trim());
628
634
  const text = String(out.stdout || '').trim();
629
- return text ? JSON.parse(text) : null;
630
- }
635
+ return text ? parseJsonText(text) : null;
636
+ }
631
637
 
632
638
  async function readComposeText(projectDir) {
633
639
  const p = join(projectDir || '', 'docker', 'openclaw', 'docker-compose.yml');
@@ -672,9 +678,9 @@ function parseBaseUrlPort(baseUrl = '') {
672
678
  }
673
679
  }
674
680
 
675
- async function detectRuntime(projectDir) {
676
- const cfgPath = join(projectDir || '', '.openclaw', 'openclaw.json');
677
- const cfg = existsSync(cfgPath) ? JSON.parse(await fsp.readFile(cfgPath, 'utf8').catch(() => '{}')) : {};
681
+ async function detectRuntime(projectDir) {
682
+ const cfgPath = join(projectDir || '', '.openclaw', 'openclaw.json');
683
+ const cfg = existsSync(cfgPath) ? parseJsonText(await fsp.readFile(cfgPath, 'utf8').catch(() => '{}'), {}) : {};
678
684
  let cliGatewayStatus = null;
679
685
  let cliGatewayPort = 0;
680
686
  let cliRouterPort = 0;
@@ -1039,11 +1045,11 @@ async function resolveProject9RouterApiKey(projectDir, cfg = null) {
1039
1045
  return '';
1040
1046
  }
1041
1047
 
1042
- async function applyResolved9RouterApiKey(projectDir, cfg = null) {
1043
- if (!projectDir) return '';
1044
- const cfgPath = join(projectDir, '.openclaw', 'openclaw.json');
1045
- if (!existsSync(cfgPath)) return '';
1046
- const current = cfg || ensureConfigShape(JSON.parse(await fsp.readFile(cfgPath, 'utf8')));
1048
+ async function applyResolved9RouterApiKey(projectDir, cfg = null) {
1049
+ if (!projectDir) return '';
1050
+ const cfgPath = join(projectDir, '.openclaw', 'openclaw.json');
1051
+ if (!existsSync(cfgPath)) return '';
1052
+ const current = cfg || ensureConfigShape(parseJsonText(await fsp.readFile(cfgPath, 'utf8')));
1047
1053
  const apiKey = await resolveProject9RouterApiKey(projectDir, current);
1048
1054
  if (!apiKey) return '';
1049
1055
  current.models = current.models || { mode: 'merge', providers: {} };
@@ -1056,21 +1062,21 @@ async function applyResolved9RouterApiKey(projectDir, cfg = null) {
1056
1062
  return apiKey;
1057
1063
  }
1058
1064
 
1059
- async function readBotCredentials(projectDir) {
1060
- const found = readProjectConfig(projectDir);
1061
- if (!found) return { openclawToken: '', nineRouterApiKey: '' };
1062
- const cfg = ensureConfigShape(JSON.parse(await fsp.readFile(found.cfgPath, 'utf8')));
1065
+ async function readBotCredentials(projectDir) {
1066
+ const found = readProjectConfig(projectDir);
1067
+ if (!found) return { openclawToken: '', nineRouterApiKey: '' };
1068
+ const cfg = ensureConfigShape(parseJsonText(await fsp.readFile(found.cfgPath, 'utf8')));
1063
1069
  return {
1064
1070
  openclawToken: cfg.gateway?.auth?.token || '',
1065
1071
  nineRouterApiKey: await resolveProject9RouterApiKey(projectDir, cfg),
1066
1072
  };
1067
1073
  }
1068
1074
 
1069
- async function updateBotCredentials(projectDir, body = {}) {
1070
- const found = readProjectConfig(projectDir);
1071
- if (!found) throw httpError(400, 'Install project not found');
1072
- const raw = await fsp.readFile(found.cfgPath, 'utf8');
1073
- const cfg = ensureConfigShape(JSON.parse(raw));
1075
+ async function updateBotCredentials(projectDir, body = {}) {
1076
+ const found = readProjectConfig(projectDir);
1077
+ if (!found) throw httpError(400, 'Install project not found');
1078
+ const raw = await fsp.readFile(found.cfgPath, 'utf8');
1079
+ const cfg = ensureConfigShape(parseJsonText(raw));
1074
1080
  const nineRouterApiKey = String(body.nineRouterApiKey || '').trim();
1075
1081
  if (Object.prototype.hasOwnProperty.call(body, 'nineRouterApiKey')) {
1076
1082
  cfg.models = cfg.models || { mode: 'merge', providers: {} };
@@ -1138,11 +1144,11 @@ function mapAgentChannels(agent, cfg) {
1138
1144
  return enabled.length === 1 ? enabled : [mapAgentChannel(agent, cfg)];
1139
1145
  }
1140
1146
 
1141
- async function listConfiguredBots(projectDir) {
1142
- const cfgPath = join(projectDir || '', '.openclaw', 'openclaw.json');
1143
- if (!projectDir || !existsSync(cfgPath)) return [];
1144
- const raw = await fsp.readFile(cfgPath, 'utf8');
1145
- const cfg = ensureConfigShape(JSON.parse(raw));
1147
+ async function listConfiguredBots(projectDir) {
1148
+ const cfgPath = join(projectDir || '', '.openclaw', 'openclaw.json');
1149
+ if (!projectDir || !existsSync(cfgPath)) return [];
1150
+ const raw = await fsp.readFile(cfgPath, 'utf8');
1151
+ const cfg = ensureConfigShape(parseJsonText(raw));
1146
1152
  const normalized = JSON.stringify(cfg, null, 2) + '\n';
1147
1153
  if (normalized !== raw) await fsp.writeFile(cfgPath, normalized, 'utf8');
1148
1154
  const rows = await Promise.all(cfg.agents.list.map(async (agent) => {
@@ -1170,14 +1176,14 @@ async function rmInside(root, target) {
1170
1176
  await fsp.rm(targetFull, { recursive: true, force: true }).catch(() => {});
1171
1177
  }
1172
1178
 
1173
- async function deleteBotInProject(projectDir, agentId) {
1179
+ async function deleteBotInProject(projectDir, agentId) {
1174
1180
  if (!projectDir) throw httpError(400, 'Install project not found');
1175
1181
  const cleanId = slugify(agentId, '');
1176
1182
  if (!cleanId || cleanId !== agentId) throw httpError(400, 'Invalid bot id');
1177
1183
  const openclawHome = join(projectDir, '.openclaw');
1178
1184
  const cfgPath = join(openclawHome, 'openclaw.json');
1179
1185
  if (!existsSync(cfgPath)) throw httpError(404, 'openclaw.json not found');
1180
- const cfg = ensureConfigShape(JSON.parse(await fsp.readFile(cfgPath, 'utf8')));
1186
+ const cfg = ensureConfigShape(parseJsonText(await fsp.readFile(cfgPath, 'utf8')));
1181
1187
  const agent = cfg.agents.list.find((a) => a.id === agentId);
1182
1188
  if (!agent) throw httpError(404, 'Bot not found');
1183
1189
 
@@ -1967,12 +1973,12 @@ async function restartDockerBotContainer(projectDir = state.projectDir) {
1967
1973
  return true;
1968
1974
  }
1969
1975
 
1970
- async function readJson(req) {
1971
- const chunks = [];
1972
- for await (const chunk of req) chunks.push(chunk);
1973
- if (!chunks.length) return {};
1974
- return JSON.parse(Buffer.concat(chunks).toString('utf8'));
1975
- }
1976
+ async function readJson(req) {
1977
+ const chunks = [];
1978
+ for await (const chunk of req) chunks.push(chunk);
1979
+ if (!chunks.length) return {};
1980
+ return parseJsonText(Buffer.concat(chunks).toString('utf8'));
1981
+ }
1976
1982
 
1977
1983
  function json(res, data, status = 200) {
1978
1984
  const body = JSON.stringify(data, null, 2);
@@ -2978,16 +2984,16 @@ async function getInstalledSkillVersion(projectDir, agentId, skillFolder, cfg =
2978
2984
  return '';
2979
2985
  }
2980
2986
 
2981
- async function getFeatureFlags(projectDir, agentId = '') {
2982
- const cfgPath = join(projectDir || '', '.openclaw', 'openclaw.json');
2983
- const cfg = existsSync(cfgPath) ? ensureConfigShape(JSON.parse(await fsp.readFile(cfgPath, 'utf8').catch(() => '{}'))) : {};
2987
+ async function getFeatureFlags(projectDir, agentId = '') {
2988
+ const cfgPath = join(projectDir || '', '.openclaw', 'openclaw.json');
2989
+ const cfg = existsSync(cfgPath) ? ensureConfigShape(parseJsonText(await fsp.readFile(cfgPath, 'utf8').catch(() => '{}'), {})) : {};
2984
2990
  const aid = agentId || cfg.agents?.list?.[0]?.id || 'bot';
2985
2991
  const browserOn = !!cfg.browser?.enabled;
2986
2992
  const cronOn = !!cfg.skills?.entries?.['cronjob']?.enabled || !!cfg.skills?.entries?.['cron']?.enabled || !!(cfg.tools?.alsoAllow || []).includes('group:automation');
2987
- const fresh = cfg;
2988
- const freshSaved = {};
2989
- const installsPath = join(projectDir || '', '.openclaw', 'plugins', 'installs.json');
2990
- const installs = existsSync(installsPath) ? JSON.parse(await fsp.readFile(installsPath, 'utf8').catch(() => '{}')) : {};
2993
+ const fresh = cfg;
2994
+ const freshSaved = {};
2995
+ const installsPath = join(projectDir || '', '.openclaw', 'plugins', 'installs.json');
2996
+ const installs = existsSync(installsPath) ? parseJsonText(await fsp.readFile(installsPath, 'utf8').catch(() => '{}'), {}) : {};
2991
2997
  const installRecords = installs.installRecords || {};
2992
2998
  const installedKeys = new Set(Object.keys(installRecords).map((k) => String(k || '').toLowerCase()));
2993
2999
  const installedSpecs = new Set(Object.values(installRecords).flatMap((r) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclaw-bot",
3
- "version": "5.8.20",
3
+ "version": "5.8.21",
4
4
  "description": "Interactive CLI installer for OpenClaw Bot",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {