nextclaw 0.13.21 → 0.13.23

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 (30) hide show
  1. package/README.md +2 -2
  2. package/dist/cli/index.js +206 -192
  3. package/package.json +9 -9
  4. package/templates/USAGE.md +19 -19
  5. package/ui-dist/assets/{ChannelsList-CIMYaIji.js → ChannelsList-a063_8pv.js} +1 -1
  6. package/ui-dist/assets/{ChatPage-B5UpeEIp.js → ChatPage-CMthudUt.js} +1 -1
  7. package/ui-dist/assets/{DocBrowser-BJ610SPa.js → DocBrowser-BOvBC_5q.js} +1 -1
  8. package/ui-dist/assets/{LogoBadge-BKq1GKWP.js → LogoBadge-BUvLZbji.js} +1 -1
  9. package/ui-dist/assets/{MarketplacePage-Bs3sLsgx.js → MarketplacePage-CcbfvtGX.js} +1 -1
  10. package/ui-dist/assets/{McpMarketplacePage-BWTguHCs.js → McpMarketplacePage-D56yvyWI.js} +1 -1
  11. package/ui-dist/assets/{ModelConfig-B-oTP-Bc.js → ModelConfig-D5AuTffd.js} +1 -1
  12. package/ui-dist/assets/{ProvidersList-r7bD0-R0.js → ProvidersList-Bd4n7muZ.js} +1 -1
  13. package/ui-dist/assets/{RemoteAccessPage-D7On6waK.js → RemoteAccessPage-Be8jduPM.js} +1 -1
  14. package/ui-dist/assets/{RuntimeConfig-C11xVxH9.js → RuntimeConfig-D8DYogZ1.js} +1 -1
  15. package/ui-dist/assets/{SearchConfig-BVZdCxiM.js → SearchConfig-BtiGCmXR.js} +1 -1
  16. package/ui-dist/assets/{SecretsConfig-DuEDdC3X.js → SecretsConfig-fwAjbwlq.js} +1 -1
  17. package/ui-dist/assets/{SessionsConfig-Y-Blf_-K.js → SessionsConfig-Y7_TDSk2.js} +1 -1
  18. package/ui-dist/assets/{chat-message-B6VCCEXF.js → chat-message-Cwq8nW0e.js} +1 -1
  19. package/ui-dist/assets/index-C6dwNe7e.js +8 -0
  20. package/ui-dist/assets/{label-DzwitL78.js → label-C0dJBNgU.js} +1 -1
  21. package/ui-dist/assets/{page-layout-DEq5N_8L.js → page-layout-4_789zOC.js} +1 -1
  22. package/ui-dist/assets/{popover-CY54V8F6.js → popover-CWmq2f6H.js} +1 -1
  23. package/ui-dist/assets/{security-config-CgbYP57d.js → security-config-CZeVwEwq.js} +1 -1
  24. package/ui-dist/assets/{skeleton-zjQZMWu9.js → skeleton-kjkadEki.js} +1 -1
  25. package/ui-dist/assets/{status-dot-CU_P0tvO.js → status-dot-C7cVa53V.js} +1 -1
  26. package/ui-dist/assets/{switch-PvjTvlcs.js → switch-C6zdGbY0.js} +1 -1
  27. package/ui-dist/assets/{tabs-custom-Bke5J9ny.js → tabs-custom-BQj0Z-ZC.js} +1 -1
  28. package/ui-dist/assets/{useConfirmDialog-8tzzp_oW.js → useConfirmDialog-yX-ZMNf9.js} +1 -1
  29. package/ui-dist/index.html +1 -1
  30. package/ui-dist/assets/index-DvA7S11O.js +0 -8
package/dist/cli/index.js CHANGED
@@ -7,11 +7,10 @@ import { registerRemoteCommands } from "@nextclaw/remote";
7
7
 
8
8
  // src/cli/runtime.ts
9
9
  import {
10
- loadConfig as loadConfig17,
10
+ loadConfig as loadConfig18,
11
11
  saveConfig as saveConfig11,
12
- getConfigPath as getConfigPath9,
12
+ getConfigPath as getConfigPath10,
13
13
  getDataDir as getDataDir9,
14
- ConfigSchema as ConfigSchema2,
15
14
  getWorkspacePath as getWorkspacePath10,
16
15
  expandHome as expandHome2,
17
16
  MessageBus as MessageBus2,
@@ -28,7 +27,7 @@ import {
28
27
  resolvePluginChannelMessageToolHints as resolvePluginChannelMessageToolHints2,
29
28
  setPluginRuntimeBridge as setPluginRuntimeBridge3
30
29
  } from "@nextclaw/openclaw-compat";
31
- import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
30
+ import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
32
31
  import { join as join8, resolve as resolve12 } from "path";
33
32
  import { createInterface as createInterface3 } from "readline";
34
33
  import { fileURLToPath as fileURLToPath5 } from "url";
@@ -91,8 +90,19 @@ var RestartCoordinator = class {
91
90
  }
92
91
  };
93
92
 
93
+ // src/cli/runtime-config-init.ts
94
+ import { existsSync } from "fs";
95
+ import { getConfigPath, loadConfig } from "@nextclaw/core";
96
+ function initializeConfigIfMissing(configPath = getConfigPath()) {
97
+ if (existsSync(configPath)) {
98
+ return false;
99
+ }
100
+ loadConfig(configPath);
101
+ return true;
102
+ }
103
+
94
104
  // src/cli/restart-sentinel.ts
95
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
105
+ import { existsSync as existsSync2, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
96
106
  import { resolve } from "path";
97
107
  import { getDataDir } from "@nextclaw/core";
98
108
  var RESTART_SENTINEL_FILENAME = "restart-sentinel.json";
@@ -129,7 +139,7 @@ async function writeRestartSentinel(payload) {
129
139
  }
130
140
  async function consumeRestartSentinel() {
131
141
  const path2 = resolveRestartSentinelPath();
132
- if (!existsSync(path2)) {
142
+ if (!existsSync2(path2)) {
133
143
  return null;
134
144
  }
135
145
  try {
@@ -188,12 +198,12 @@ function parseSessionKey(sessionKey) {
188
198
  }
189
199
 
190
200
  // src/cli/skills/marketplace.ts
191
- import { cpSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
201
+ import { cpSync, existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
192
202
  import { basename, dirname, isAbsolute, join, relative, resolve as resolve3 } from "path";
193
203
  import { SkillsLoader } from "@nextclaw/core";
194
204
 
195
205
  // src/cli/skills/marketplace.metadata.ts
196
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
206
+ import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
197
207
  import { resolve as resolve2 } from "path";
198
208
  import { parse as parseYaml } from "yaml";
199
209
  var DEFAULT_MARKETPLACE_META_FILENAME = "marketplace.json";
@@ -266,7 +276,7 @@ function readMarketplaceMetadataFile(skillDir, explicitMetaFile) {
266
276
  }
267
277
  function resolveMarketplaceMetadataPath(skillDir, explicitMetaFile) {
268
278
  const resolved = explicitMetaFile?.trim() ? resolve2(explicitMetaFile) : resolve2(skillDir, DEFAULT_MARKETPLACE_META_FILENAME);
269
- return existsSync2(resolved) ? resolved : void 0;
279
+ return existsSync3(resolved) ? resolved : void 0;
270
280
  }
271
281
  function mergeLocalizedTextMap(...maps) {
272
282
  const localized = {};
@@ -407,7 +417,7 @@ var DEFAULT_MARKETPLACE_API_BASE = "https://marketplace-api.nextclaw.io";
407
417
  async function installMarketplaceSkill(options) {
408
418
  const slug = validateSkillSlug(options.slug.trim(), "slug");
409
419
  const workdir = resolve3(options.workdir);
410
- if (!existsSync3(workdir)) {
420
+ if (!existsSync4(workdir)) {
411
421
  throw new Error(`Workdir does not exist: ${workdir}`);
412
422
  }
413
423
  const dirName = options.dir?.trim() || "skills";
@@ -416,8 +426,8 @@ async function installMarketplaceSkill(options) {
416
426
  const apiBase = resolveMarketplaceApiBase(options.apiBaseUrl);
417
427
  const item = await fetchMarketplaceSkillItem(apiBase, slug);
418
428
  if (item.install.kind === "builtin") {
419
- if (!options.force && existsSync3(destinationDir)) {
420
- if (existsSync3(skillFile)) {
429
+ if (!options.force && existsSync4(destinationDir)) {
430
+ if (existsSync4(skillFile)) {
421
431
  return {
422
432
  slug,
423
433
  destinationDir,
@@ -427,7 +437,7 @@ async function installMarketplaceSkill(options) {
427
437
  }
428
438
  throw new Error(`Skill directory already exists: ${destinationDir} (use --force)`);
429
439
  }
430
- if (existsSync3(destinationDir) && options.force) {
440
+ if (existsSync4(destinationDir) && options.force) {
431
441
  rmSync2(destinationDir, { recursive: true, force: true });
432
442
  }
433
443
  installBuiltinSkill(workdir, destinationDir, slug);
@@ -438,7 +448,7 @@ async function installMarketplaceSkill(options) {
438
448
  };
439
449
  }
440
450
  const filesPayload = await fetchMarketplaceSkillFiles(apiBase, slug);
441
- if (!options.force && existsSync3(destinationDir)) {
451
+ if (!options.force && existsSync4(destinationDir)) {
442
452
  const existingDirState = inspectMarketplaceSkillDirectory(destinationDir, filesPayload.files);
443
453
  if (existingDirState === "installed") {
444
454
  return {
@@ -454,7 +464,7 @@ async function installMarketplaceSkill(options) {
454
464
  throw new Error(`Skill directory already exists: ${destinationDir} (use --force)`);
455
465
  }
456
466
  }
457
- if (existsSync3(destinationDir) && options.force) {
467
+ if (existsSync4(destinationDir) && options.force) {
458
468
  rmSync2(destinationDir, { recursive: true, force: true });
459
469
  }
460
470
  mkdirSync2(destinationDir, { recursive: true });
@@ -468,7 +478,7 @@ async function installMarketplaceSkill(options) {
468
478
  const bytes = file.contentBase64 ? decodeMarketplaceFileContent(file.path, file.contentBase64) : await fetchMarketplaceSkillFileBlob(apiBase, slug, file);
469
479
  writeFileSync2(targetPath, bytes);
470
480
  }
471
- if (!existsSync3(join(destinationDir, "SKILL.md"))) {
481
+ if (!existsSync4(join(destinationDir, "SKILL.md"))) {
472
482
  throw new Error(`Marketplace skill ${slug} does not include SKILL.md`);
473
483
  }
474
484
  return {
@@ -478,7 +488,7 @@ async function installMarketplaceSkill(options) {
478
488
  };
479
489
  }
480
490
  function inspectMarketplaceSkillDirectory(destinationDir, files) {
481
- if (existsSync3(join(destinationDir, "SKILL.md"))) {
491
+ if (existsSync4(join(destinationDir, "SKILL.md"))) {
482
492
  return "installed";
483
493
  }
484
494
  const discoveredFiles = collectRelativeFiles(destinationDir);
@@ -522,7 +532,7 @@ function isIgnorableMarketplaceResidue(path2) {
522
532
  }
523
533
  async function publishMarketplaceSkill(options) {
524
534
  const skillDir = resolve3(options.skillDir);
525
- if (!existsSync3(skillDir)) {
535
+ if (!existsSync4(skillDir)) {
526
536
  throw new Error(`Skill directory not found: ${skillDir}`);
527
537
  }
528
538
  const files = collectFiles(skillDir);
@@ -754,14 +764,14 @@ import { spawnSync } from "child_process";
754
764
  import { resolve as resolve5 } from "path";
755
765
 
756
766
  // src/cli/utils.ts
757
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync as rmSync3 } from "fs";
767
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync as rmSync3 } from "fs";
758
768
  import { join as join2, resolve as resolve4 } from "path";
759
769
  import { spawn } from "child_process";
760
770
  import { isIP } from "net";
761
771
  import { fileURLToPath } from "url";
762
772
  import { getDataDir as getDataDir2, getPackageVersion as getCorePackageVersion } from "@nextclaw/core";
763
773
  function resolveUiConfig(config2, overrides) {
764
- const base = config2.ui ?? { enabled: false, host: "127.0.0.1", port: 18791, open: false };
774
+ const base = config2.ui ?? { enabled: false, host: "127.0.0.1", port: 55667, open: false };
765
775
  return { ...base, ...overrides ?? {} };
766
776
  }
767
777
  function resolveUiApiBase(host, port) {
@@ -809,7 +819,7 @@ function buildServeArgs(options) {
809
819
  }
810
820
  function readServiceState() {
811
821
  const path2 = resolveServiceStatePath();
812
- if (!existsSync4(path2)) {
822
+ if (!existsSync5(path2)) {
813
823
  return null;
814
824
  }
815
825
  try {
@@ -835,7 +845,7 @@ function updateServiceState(updater) {
835
845
  }
836
846
  function clearServiceState() {
837
847
  const path2 = resolveServiceStatePath();
838
- if (existsSync4(path2)) {
848
+ if (existsSync5(path2)) {
839
849
  rmSync3(path2, { force: true });
840
850
  }
841
851
  }
@@ -866,12 +876,12 @@ async function waitForExit(pid, timeoutMs) {
866
876
  function resolveUiStaticDir() {
867
877
  const envDir = process.env.NEXTCLAW_UI_STATIC_DIR;
868
878
  if (envDir) {
869
- return existsSync4(join2(envDir, "index.html")) ? envDir : null;
879
+ return existsSync5(join2(envDir, "index.html")) ? envDir : null;
870
880
  }
871
881
  const cliDir = resolve4(fileURLToPath(new URL(".", import.meta.url)));
872
882
  const pkgRoot = resolve4(cliDir, "..", "..");
873
883
  const bundledDir = join2(pkgRoot, "ui-dist");
874
- return existsSync4(join2(bundledDir, "index.html")) ? bundledDir : null;
884
+ return existsSync5(join2(bundledDir, "index.html")) ? bundledDir : null;
875
885
  }
876
886
  function openBrowser(url) {
877
887
  const platform = process.platform;
@@ -918,7 +928,7 @@ function findExecutableOnPath(binary, env = process.env, platform = process.plat
918
928
  return null;
919
929
  }
920
930
  if (target.includes("/") || target.includes("\\")) {
921
- return existsSync4(target) ? target : null;
931
+ return existsSync5(target) ? target : null;
922
932
  }
923
933
  const rawPath = env.PATH ?? env.Path ?? env.path ?? "";
924
934
  if (!rawPath.trim()) {
@@ -928,7 +938,7 @@ function findExecutableOnPath(binary, env = process.env, platform = process.plat
928
938
  if (entries.length === 0) {
929
939
  return null;
930
940
  }
931
- const checkCandidates = (candidate) => existsSync4(candidate) ? candidate : null;
941
+ const checkCandidates = (candidate) => existsSync5(candidate) ? candidate : null;
932
942
  for (const dir of entries) {
933
943
  const direct = checkCandidates(join2(dir, target));
934
944
  if (direct) {
@@ -953,7 +963,7 @@ function resolveVersionFromPackageTree(startDir, expectedName) {
953
963
  let current = resolve4(startDir);
954
964
  while (current.length > 0) {
955
965
  const pkgPath = join2(current, "package.json");
956
- if (existsSync4(pkgPath)) {
966
+ if (existsSync5(pkgPath)) {
957
967
  try {
958
968
  const raw = readFileSync4(pkgPath, "utf-8");
959
969
  const parsed = JSON.parse(raw);
@@ -1247,7 +1257,7 @@ var applyDevFirstPartyPluginLoadPaths = (config2, workspaceExtensionsDir) => {
1247
1257
 
1248
1258
  // src/cli/commands/plugins.ts
1249
1259
  import {
1250
- loadConfig as loadConfig2,
1260
+ loadConfig as loadConfig3,
1251
1261
  getWorkspacePath as getWorkspacePath2
1252
1262
  } from "@nextclaw/core";
1253
1263
  import { createInterface } from "readline";
@@ -1264,9 +1274,9 @@ import {
1264
1274
  recordPluginInstall,
1265
1275
  uninstallPlugin
1266
1276
  } from "@nextclaw/openclaw-compat";
1267
- import { existsSync as existsSync5 } from "fs";
1277
+ import { existsSync as existsSync6 } from "fs";
1268
1278
  import { resolve as resolve6 } from "path";
1269
- import { expandHome, getWorkspacePath, loadConfig, saveConfig } from "@nextclaw/core";
1279
+ import { expandHome, getWorkspacePath, loadConfig as loadConfig2, saveConfig } from "@nextclaw/core";
1270
1280
  function resolveFileNpmSpecToLocalPath(raw) {
1271
1281
  const trimmed = raw.trim();
1272
1282
  if (!trimmed.toLowerCase().startsWith("file:")) {
@@ -1298,7 +1308,7 @@ function isArchivePath(filePath) {
1298
1308
  return lower.endsWith(".zip") || lower.endsWith(".tgz") || lower.endsWith(".tar.gz") || lower.endsWith(".tar");
1299
1309
  }
1300
1310
  async function enablePluginMutation(id) {
1301
- const config2 = loadConfig();
1311
+ const config2 = loadConfig2();
1302
1312
  const next = enablePluginInConfig(config2, id);
1303
1313
  saveConfig(next);
1304
1314
  return {
@@ -1306,7 +1316,7 @@ async function enablePluginMutation(id) {
1306
1316
  };
1307
1317
  }
1308
1318
  async function disablePluginMutation(id) {
1309
- const config2 = loadConfig();
1319
+ const config2 = loadConfig2();
1310
1320
  const next = disablePluginInConfig(config2, id);
1311
1321
  saveConfig(next);
1312
1322
  return {
@@ -1314,7 +1324,7 @@ async function disablePluginMutation(id) {
1314
1324
  };
1315
1325
  }
1316
1326
  async function uninstallPluginMutation(id, opts = {}) {
1317
- const config2 = loadConfig();
1327
+ const config2 = loadConfig2();
1318
1328
  const workspaceDir = getWorkspacePath(config2.agents.defaults.workspace);
1319
1329
  const report = buildPluginStatusReport({
1320
1330
  config: config2,
@@ -1371,8 +1381,8 @@ async function installPluginMutation(pathOrSpec, opts = {}) {
1371
1381
  }
1372
1382
  const normalized = fileSpec && fileSpec.ok ? fileSpec.path : pathOrSpec;
1373
1383
  const resolved = resolve6(expandHome(normalized));
1374
- const config2 = loadConfig();
1375
- if (existsSync5(resolved)) {
1384
+ const config2 = loadConfig2();
1385
+ if (existsSync6(resolved)) {
1376
1386
  if (opts.link) {
1377
1387
  const probe = await installPluginFromPath({ path: resolved, dryRun: true });
1378
1388
  if (!probe.ok) {
@@ -1567,7 +1577,7 @@ var PluginCommands = class {
1567
1577
  return await installPluginMutation(pathOrSpec, opts);
1568
1578
  }
1569
1579
  pluginsList(opts = {}) {
1570
- const config2 = loadConfig2();
1580
+ const config2 = loadConfig3();
1571
1581
  const workspaceDir = getWorkspacePath2(config2.agents.defaults.workspace);
1572
1582
  const report = buildPluginStatusReport2({
1573
1583
  config: config2,
@@ -1619,7 +1629,7 @@ var PluginCommands = class {
1619
1629
  }
1620
1630
  }
1621
1631
  pluginsInfo(id, opts = {}) {
1622
- const config2 = loadConfig2();
1632
+ const config2 = loadConfig3();
1623
1633
  const workspaceDir = getWorkspacePath2(config2.agents.defaults.workspace);
1624
1634
  const report = buildPluginStatusReport2({
1625
1635
  config: config2,
@@ -1700,7 +1710,7 @@ var PluginCommands = class {
1700
1710
  if (opts.keepConfig) {
1701
1711
  console.log("`--keep-config` is deprecated, use `--keep-files`.");
1702
1712
  }
1703
- const config2 = loadConfig2();
1713
+ const config2 = loadConfig3();
1704
1714
  const workspaceDir = getWorkspacePath2(config2.agents.defaults.workspace);
1705
1715
  const report = buildPluginStatusReport2({
1706
1716
  config: config2,
@@ -1784,7 +1794,7 @@ var PluginCommands = class {
1784
1794
  console.log("If gateway is running, plugin changes are hot-applied automatically.");
1785
1795
  }
1786
1796
  pluginsDoctor() {
1787
- const config2 = loadConfig2();
1797
+ const config2 = loadConfig3();
1788
1798
  const workspaceDir = getWorkspacePath2(config2.agents.defaults.workspace);
1789
1799
  const report = buildPluginStatusReport2({
1790
1800
  config: config2,
@@ -1829,7 +1839,7 @@ var PluginCommands = class {
1829
1839
  };
1830
1840
 
1831
1841
  // src/cli/commands/config.ts
1832
- import { buildReloadPlan, diffConfigPaths, loadConfig as loadConfig3, saveConfig as saveConfig2 } from "@nextclaw/core";
1842
+ import { buildReloadPlan, diffConfigPaths, loadConfig as loadConfig4, saveConfig as saveConfig2 } from "@nextclaw/core";
1833
1843
 
1834
1844
  // src/cli/config-path.ts
1835
1845
  function isIndexSegment(raw) {
@@ -2024,7 +2034,7 @@ var ConfigCommands = class {
2024
2034
  this.deps = deps;
2025
2035
  }
2026
2036
  configGet(pathExpr, opts = {}) {
2027
- const config2 = loadConfig3();
2037
+ const config2 = loadConfig4();
2028
2038
  let parsedPath;
2029
2039
  try {
2030
2040
  parsedPath = parseRequiredConfigPath(pathExpr);
@@ -2066,7 +2076,7 @@ var ConfigCommands = class {
2066
2076
  process.exit(1);
2067
2077
  return;
2068
2078
  }
2069
- const prevConfig = loadConfig3();
2079
+ const prevConfig = loadConfig4();
2070
2080
  const nextConfig = structuredClone(prevConfig);
2071
2081
  try {
2072
2082
  setAtConfigPath(nextConfig, parsedPath, parsedValue);
@@ -2092,7 +2102,7 @@ var ConfigCommands = class {
2092
2102
  process.exit(1);
2093
2103
  return;
2094
2104
  }
2095
- const prevConfig = loadConfig3();
2105
+ const prevConfig = loadConfig4();
2096
2106
  const nextConfig = structuredClone(prevConfig);
2097
2107
  const removed = unsetAtConfigPath(nextConfig, parsedPath);
2098
2108
  if (!removed) {
@@ -2125,7 +2135,7 @@ var ConfigCommands = class {
2125
2135
  };
2126
2136
 
2127
2137
  // src/cli/commands/mcp.ts
2128
- import { loadConfig as loadConfig4, saveConfig as saveConfig3 } from "@nextclaw/core";
2138
+ import { loadConfig as loadConfig5, saveConfig as saveConfig3 } from "@nextclaw/core";
2129
2139
  import {
2130
2140
  McpDoctorFacade,
2131
2141
  McpMutationService,
@@ -2255,7 +2265,7 @@ function buildMcpServerDefinition(command, opts) {
2255
2265
  var McpCommands = class {
2256
2266
  mcpList(opts = {}) {
2257
2267
  const registry = new McpRegistryService({
2258
- getConfig: () => loadConfig4()
2268
+ getConfig: () => loadConfig5()
2259
2269
  });
2260
2270
  const servers = registry.listServers().map((server) => ({
2261
2271
  name: server.name,
@@ -2278,7 +2288,7 @@ var McpCommands = class {
2278
2288
  }
2279
2289
  async mcpAdd(name, command, opts) {
2280
2290
  const mutation = new McpMutationService({
2281
- getConfig: () => loadConfig4(),
2291
+ getConfig: () => loadConfig5(),
2282
2292
  saveConfig: (config2) => saveConfig3(config2)
2283
2293
  });
2284
2294
  const result = mutation.addServer(name, buildMcpServerDefinition(command, opts));
@@ -2290,7 +2300,7 @@ var McpCommands = class {
2290
2300
  }
2291
2301
  async mcpRemove(name) {
2292
2302
  const mutation = new McpMutationService({
2293
- getConfig: () => loadConfig4(),
2303
+ getConfig: () => loadConfig5(),
2294
2304
  saveConfig: (config2) => saveConfig3(config2)
2295
2305
  });
2296
2306
  const result = mutation.removeServer(name);
@@ -2308,10 +2318,10 @@ var McpCommands = class {
2308
2318
  }
2309
2319
  async mcpDoctor(name, opts = {}) {
2310
2320
  const registry = new McpRegistryService({
2311
- getConfig: () => loadConfig4()
2321
+ getConfig: () => loadConfig5()
2312
2322
  });
2313
2323
  const doctor = new McpDoctorFacade({
2314
- getConfig: () => loadConfig4(),
2324
+ getConfig: () => loadConfig5(),
2315
2325
  registryService: registry
2316
2326
  });
2317
2327
  try {
@@ -2337,7 +2347,7 @@ var McpCommands = class {
2337
2347
  }
2338
2348
  async toggleEnabled(name, enabled) {
2339
2349
  const mutation = new McpMutationService({
2340
- getConfig: () => loadConfig4(),
2350
+ getConfig: () => loadConfig5(),
2341
2351
  saveConfig: (config2) => saveConfig3(config2)
2342
2352
  });
2343
2353
  const result = mutation.toggleEnabled(name, enabled);
@@ -2358,8 +2368,8 @@ import { readFileSync as readFileSync5 } from "fs";
2358
2368
  import {
2359
2369
  buildReloadPlan as buildReloadPlan2,
2360
2370
  diffConfigPaths as diffConfigPaths2,
2361
- getConfigPath,
2362
- loadConfig as loadConfig5,
2371
+ getConfigPath as getConfigPath2,
2372
+ loadConfig as loadConfig6,
2363
2373
  resolveConfigSecrets,
2364
2374
  saveConfig as saveConfig4
2365
2375
  } from "@nextclaw/core";
@@ -2455,8 +2465,8 @@ var SecretsCommands = class {
2455
2465
  this.deps = deps;
2456
2466
  }
2457
2467
  secretsAudit(opts = {}) {
2458
- const config2 = loadConfig5();
2459
- const configPath = getConfigPath();
2468
+ const config2 = loadConfig6();
2469
+ const configPath = getConfigPath2();
2460
2470
  const refs = config2.secrets.refs;
2461
2471
  const items = [];
2462
2472
  for (const [path2, ref] of Object.entries(refs)) {
@@ -2523,7 +2533,7 @@ var SecretsCommands = class {
2523
2533
  if (!alias) {
2524
2534
  throw new Error("provider alias is required");
2525
2535
  }
2526
- const prevConfig = loadConfig5();
2536
+ const prevConfig = loadConfig6();
2527
2537
  const nextConfig = structuredClone(prevConfig);
2528
2538
  const remove = Boolean(opts.remove);
2529
2539
  if (remove) {
@@ -2570,7 +2580,7 @@ var SecretsCommands = class {
2570
2580
  nextConfig.secrets.defaults[source] = alias;
2571
2581
  }
2572
2582
  }
2573
- resolveConfigSecrets(nextConfig, { configPath: getConfigPath() });
2583
+ resolveConfigSecrets(nextConfig, { configPath: getConfigPath2() });
2574
2584
  saveConfig4(nextConfig);
2575
2585
  await this.requestRestartForConfigDiff({
2576
2586
  prevConfig,
@@ -2585,7 +2595,7 @@ var SecretsCommands = class {
2585
2595
  console.log(`Secrets provider ${remove ? "removed" : "configured"}: ${alias}`);
2586
2596
  }
2587
2597
  async secretsApply(opts) {
2588
- const prevConfig = loadConfig5();
2598
+ const prevConfig = loadConfig6();
2589
2599
  const nextConfig = structuredClone(prevConfig);
2590
2600
  if (opts.enable && opts.disable) {
2591
2601
  throw new Error("cannot set --enable and --disable at the same time");
@@ -2635,7 +2645,7 @@ var SecretsCommands = class {
2635
2645
  } else if (opts.remove && !opts.file) {
2636
2646
  throw new Error("--remove requires --path");
2637
2647
  }
2638
- resolveConfigSecrets(nextConfig, { configPath: getConfigPath() });
2648
+ resolveConfigSecrets(nextConfig, { configPath: getConfigPath2() });
2639
2649
  saveConfig4(nextConfig);
2640
2650
  await this.requestRestartForConfigDiff({
2641
2651
  prevConfig,
@@ -2650,8 +2660,8 @@ var SecretsCommands = class {
2650
2660
  console.log("Secrets applied.");
2651
2661
  }
2652
2662
  async secretsReload(opts = {}) {
2653
- const config2 = loadConfig5();
2654
- const configPath = getConfigPath();
2663
+ const config2 = loadConfig6();
2664
+ const configPath = getConfigPath2();
2655
2665
  resolveConfigSecrets(config2, { configPath });
2656
2666
  saveConfig4(config2);
2657
2667
  if (opts.json) {
@@ -2678,7 +2688,7 @@ var SecretsCommands = class {
2678
2688
 
2679
2689
  // src/cli/commands/channels.ts
2680
2690
  import { spawnSync as spawnSync2 } from "child_process";
2681
- import { getWorkspacePath as getWorkspacePath3, loadConfig as loadConfig6, saveConfig as saveConfig5 } from "@nextclaw/core";
2691
+ import { getWorkspacePath as getWorkspacePath3, loadConfig as loadConfig7, saveConfig as saveConfig5 } from "@nextclaw/core";
2682
2692
  import { BUILTIN_CHANNEL_PLUGIN_IDS, builtinProviderIds as builtinProviderIds2 } from "@nextclaw/runtime";
2683
2693
  import { buildPluginStatusReport as buildPluginStatusReport3, enablePluginInConfig as enablePluginInConfig2, getPluginChannelBindings } from "@nextclaw/openclaw-compat";
2684
2694
  var CHANNEL_LABELS = {
@@ -2699,7 +2709,7 @@ var ChannelCommands = class {
2699
2709
  this.deps = deps;
2700
2710
  }
2701
2711
  channelsStatus() {
2702
- const config2 = loadConfig6();
2712
+ const config2 = loadConfig7();
2703
2713
  console.log("Channel Status");
2704
2714
  const channelConfig = config2.channels;
2705
2715
  for (const channelId of BUILTIN_CHANNEL_PLUGIN_IDS) {
@@ -2738,7 +2748,7 @@ var ChannelCommands = class {
2738
2748
  console.error("--channel is required");
2739
2749
  process.exit(1);
2740
2750
  }
2741
- const config2 = loadConfig6();
2751
+ const config2 = loadConfig7();
2742
2752
  const workspaceDir = getWorkspacePath3(config2.agents.defaults.workspace);
2743
2753
  const pluginRegistry = loadPluginRegistry(config2, workspaceDir);
2744
2754
  const bindings = getPluginChannelBindings(pluginRegistry);
@@ -2867,7 +2877,7 @@ var CronCommands = class {
2867
2877
  };
2868
2878
 
2869
2879
  // src/cli/commands/platform-auth.ts
2870
- import { getConfigPath as getConfigPath2, loadConfig as loadConfig7, saveConfig as saveConfig6 } from "@nextclaw/core";
2880
+ import { getConfigPath as getConfigPath3, loadConfig as loadConfig8, saveConfig as saveConfig6 } from "@nextclaw/core";
2871
2881
  import { createInterface as createInterface2 } from "readline";
2872
2882
 
2873
2883
  // src/cli/commands/platform-api-base.ts
@@ -2920,8 +2930,8 @@ function buildPlatformApiBaseErrorMessage(inputApiBase, rawMessage) {
2920
2930
 
2921
2931
  // src/cli/commands/platform-auth.ts
2922
2932
  function resolveProviderConfig(opts) {
2923
- const configPath = getConfigPath2();
2924
- const config2 = loadConfig7(configPath);
2933
+ const configPath = getConfigPath3();
2934
+ const config2 = loadConfig8(configPath);
2925
2935
  const providers = config2.providers;
2926
2936
  const nextclawProvider = providers.nextclaw ?? {
2927
2937
  displayName: "",
@@ -3057,8 +3067,7 @@ var PlatformAuthCommands = class {
3057
3067
  async loginResult(opts = {}) {
3058
3068
  const { configPath, config: config2, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
3059
3069
  const { email, password } = await resolveCredentials(opts);
3060
- const endpoint = opts.register ? `${platformBase}/platform/auth/register` : `${platformBase}/platform/auth/login`;
3061
- const response = await fetch(endpoint, {
3070
+ const response = await fetch(`${platformBase}/platform/auth/login`, {
3062
3071
  method: "POST",
3063
3072
  headers: {
3064
3073
  "Content-Type": "application/json"
@@ -3170,12 +3179,14 @@ var PlatformAuthCommands = class {
3170
3179
  };
3171
3180
 
3172
3181
  // src/cli/commands/remote.ts
3173
- import { getConfigPath as getConfigPath4, loadConfig as loadConfig9, saveConfig as saveConfig7 } from "@nextclaw/core";
3174
- import "@nextclaw/remote";
3182
+ import { getConfigPath as getConfigPath5, loadConfig as loadConfig10, saveConfig as saveConfig7 } from "@nextclaw/core";
3183
+ import {
3184
+ readPlatformSessionTokenState
3185
+ } from "@nextclaw/remote";
3175
3186
  import { hostname } from "os";
3176
3187
 
3177
3188
  // src/cli/commands/remote-runtime-support.ts
3178
- import { getConfigPath as getConfigPath3, getDataDir as getDataDir4, loadConfig as loadConfig8 } from "@nextclaw/core";
3189
+ import { getConfigPath as getConfigPath4, getDataDir as getDataDir4, loadConfig as loadConfig9 } from "@nextclaw/core";
3179
3190
  import {
3180
3191
  RemoteConnector,
3181
3192
  RemotePlatformClient,
@@ -3190,7 +3201,7 @@ function hasRunningNextclawManagedService() {
3190
3201
  }
3191
3202
  function createNextclawRemotePlatformClient() {
3192
3203
  return new RemotePlatformClient({
3193
- loadConfig: () => loadConfig8(getConfigPath3()),
3204
+ loadConfig: () => loadConfig9(getConfigPath4()),
3194
3205
  getDataDir: getDataDir4,
3195
3206
  getPackageVersion,
3196
3207
  resolvePlatformBase: (rawApiBase) => resolvePlatformApiBase({
@@ -3252,15 +3263,12 @@ function normalizeOptionalString3(value) {
3252
3263
  const trimmed = value.trim();
3253
3264
  return trimmed.length > 0 ? trimmed : void 0;
3254
3265
  }
3255
- function isPlatformSessionToken(value) {
3256
- return typeof value === "string" && value.startsWith("nca.");
3257
- }
3258
3266
  function resolveConfiguredLocalOrigin(config2) {
3259
3267
  const state = readServiceState();
3260
3268
  if (state && isProcessRunning(state.pid) && Number.isFinite(state.uiPort)) {
3261
3269
  return `http://127.0.0.1:${state.uiPort}`;
3262
3270
  }
3263
- const port = typeof config2.ui.port === "number" && Number.isFinite(config2.ui.port) ? config2.ui.port : 18791;
3271
+ const port = typeof config2.ui.port === "number" && Number.isFinite(config2.ui.port) ? config2.ui.port : 55667;
3264
3272
  return `http://127.0.0.1:${port}`;
3265
3273
  }
3266
3274
  async function probeLocalUi(localOrigin) {
@@ -3277,12 +3285,41 @@ async function probeLocalUi(localOrigin) {
3277
3285
  };
3278
3286
  }
3279
3287
  }
3288
+ function describePlatformTokenCheck(token) {
3289
+ const tokenState = readPlatformSessionTokenState(token);
3290
+ if (tokenState.valid) {
3291
+ return {
3292
+ name: "platform-token",
3293
+ ok: true,
3294
+ detail: "platform session token configured"
3295
+ };
3296
+ }
3297
+ if (tokenState.reason === "expired") {
3298
+ return {
3299
+ name: "platform-token",
3300
+ ok: false,
3301
+ detail: 'platform session token expired; run remote browser login or "nextclaw login" again'
3302
+ };
3303
+ }
3304
+ if (tokenState.reason === "malformed") {
3305
+ return {
3306
+ name: "platform-token",
3307
+ ok: false,
3308
+ detail: 'platform session token invalid; run remote browser login or "nextclaw login" again'
3309
+ };
3310
+ }
3311
+ return {
3312
+ name: "platform-token",
3313
+ ok: false,
3314
+ detail: 'run remote browser login or "nextclaw login" first'
3315
+ };
3316
+ }
3280
3317
  var RemoteCommands = class {
3281
3318
  constructor(deps = {}) {
3282
3319
  this.deps = deps;
3283
3320
  }
3284
3321
  updateConfig(params = {}) {
3285
- const config2 = loadConfig9(getConfigPath4());
3322
+ const config2 = loadConfig10(getConfigPath5());
3286
3323
  const nextEnabled = typeof params.enabled === "boolean" ? params.enabled : config2.remote.enabled;
3287
3324
  const nextPlatformApiBase = typeof params.apiBase === "string" ? params.apiBase.trim() : config2.remote.platformApiBase;
3288
3325
  const nextDeviceName = typeof params.name === "string" ? params.name.trim() : config2.remote.deviceName;
@@ -3319,7 +3356,7 @@ var RemoteCommands = class {
3319
3356
  });
3320
3357
  }
3321
3358
  getStatusView() {
3322
- const config2 = loadConfig9(getConfigPath4());
3359
+ const config2 = loadConfig10(getConfigPath5());
3323
3360
  const snapshot = resolveNextclawRemoteStatusSnapshot(config2);
3324
3361
  const resolvedLocalOrigin = snapshot.runtime?.localOrigin ?? this.deps.currentLocalOrigin ?? resolveConfiguredLocalOrigin(config2);
3325
3362
  return {
@@ -3355,7 +3392,7 @@ var RemoteCommands = class {
3355
3392
  }
3356
3393
  }
3357
3394
  async getDoctorView() {
3358
- const config2 = loadConfig9(getConfigPath4());
3395
+ const config2 = loadConfig10(getConfigPath5());
3359
3396
  const snapshot = resolveNextclawRemoteStatusSnapshot(config2);
3360
3397
  const localOrigin = snapshot.runtime?.localOrigin ?? this.deps.currentLocalOrigin ?? resolveConfiguredLocalOrigin(config2);
3361
3398
  const localUi = await probeLocalUi(localOrigin);
@@ -3367,11 +3404,7 @@ var RemoteCommands = class {
3367
3404
  ok: snapshot.configuredEnabled,
3368
3405
  detail: snapshot.configuredEnabled ? "enabled in config" : "disabled in config"
3369
3406
  },
3370
- {
3371
- name: "platform-token",
3372
- ok: isPlatformSessionToken(token),
3373
- detail: isPlatformSessionToken(token) ? "platform session token configured" : 'run remote browser login or "nextclaw login" first'
3374
- },
3407
+ describePlatformTokenCheck(token),
3375
3408
  {
3376
3409
  name: "platform-api-base",
3377
3410
  ok: Boolean(platformApiBase),
@@ -3409,15 +3442,15 @@ var RemoteCommands = class {
3409
3442
 
3410
3443
  // src/cli/commands/diagnostics.ts
3411
3444
  import { createServer as createNetServer } from "net";
3412
- import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
3445
+ import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
3413
3446
  import { resolve as resolve8 } from "path";
3414
3447
  import {
3415
3448
  APP_NAME as APP_NAME2,
3416
- getConfigPath as getConfigPath5,
3449
+ getConfigPath as getConfigPath6,
3417
3450
  getDataDir as getDataDir5,
3418
3451
  getWorkspacePath as getWorkspacePath4,
3419
3452
  hasSecretRef,
3420
- loadConfig as loadConfig10
3453
+ loadConfig as loadConfig11
3421
3454
  } from "@nextclaw/core";
3422
3455
  import { listBuiltinProviders } from "@nextclaw/runtime";
3423
3456
 
@@ -3535,7 +3568,7 @@ var DiagnosticsCommands = class {
3535
3568
  const base = report.process.running && report.endpoints.uiUrl ? report.endpoints.uiUrl : report.endpoints.configuredUiUrl;
3536
3569
  return Number(new URL(base).port || 80);
3537
3570
  } catch {
3538
- return 18791;
3571
+ return 55667;
3539
3572
  }
3540
3573
  })()
3541
3574
  });
@@ -3602,8 +3635,8 @@ var DiagnosticsCommands = class {
3602
3635
  process.exitCode = exitCode;
3603
3636
  }
3604
3637
  async collectRuntimeStatus(params) {
3605
- const configPath = getConfigPath5();
3606
- const config2 = loadConfig10();
3638
+ const configPath = getConfigPath6();
3639
+ const config2 = loadConfig11();
3607
3640
  const workspacePath = getWorkspacePath4(config2.agents.defaults.workspace);
3608
3641
  const serviceStatePath = resolve8(getDataDir5(), "run", "service.json");
3609
3642
  const fixActions = [];
@@ -3646,13 +3679,13 @@ var DiagnosticsCommands = class {
3646
3679
  return {
3647
3680
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3648
3681
  configPath,
3649
- configExists: existsSync6(configPath),
3682
+ configExists: existsSync7(configPath),
3650
3683
  workspacePath,
3651
- workspaceExists: existsSync6(workspacePath),
3684
+ workspaceExists: existsSync7(workspacePath),
3652
3685
  model: config2.agents.defaults.model,
3653
3686
  providers,
3654
3687
  serviceStatePath,
3655
- serviceStateExists: existsSync6(serviceStatePath),
3688
+ serviceStateExists: existsSync7(serviceStatePath),
3656
3689
  fixActions,
3657
3690
  process: {
3658
3691
  managedByState,
@@ -3727,11 +3760,11 @@ var DiagnosticsCommands = class {
3727
3760
  });
3728
3761
  }
3729
3762
  collectRuntimeIssues(params) {
3730
- if (!existsSync6(params.configPath)) {
3763
+ if (!existsSync7(params.configPath)) {
3731
3764
  params.issues.push("Config file is missing.");
3732
3765
  params.recommendations.push(`Run ${APP_NAME2} init to create config files.`);
3733
3766
  }
3734
- if (!existsSync6(params.workspacePath)) {
3767
+ if (!existsSync7(params.workspacePath)) {
3735
3768
  params.issues.push("Workspace directory does not exist.");
3736
3769
  params.recommendations.push(`Run ${APP_NAME2} init to create workspace templates.`);
3737
3770
  }
@@ -3760,7 +3793,7 @@ var DiagnosticsCommands = class {
3760
3793
  }
3761
3794
  }
3762
3795
  readLogTail(path2, maxLines = 25) {
3763
- if (!existsSync6(path2)) {
3796
+ if (!existsSync7(path2)) {
3764
3797
  return [];
3765
3798
  }
3766
3799
  try {
@@ -3804,7 +3837,7 @@ import {
3804
3837
  stopPluginChannelGateways as stopPluginChannelGateways2
3805
3838
  } from "@nextclaw/openclaw-compat";
3806
3839
  import { startUiServer } from "@nextclaw/server";
3807
- import { appendFileSync, closeSync, cpSync as cpSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, openSync } from "fs";
3840
+ import { appendFileSync, closeSync, cpSync as cpSync2, existsSync as existsSync11, mkdirSync as mkdirSync5, openSync } from "fs";
3808
3841
  import { dirname as dirname2, join as join6, resolve as resolve10 } from "path";
3809
3842
  import { spawn as spawn3 } from "child_process";
3810
3843
  import { request as httpRequest } from "http";
@@ -3814,7 +3847,7 @@ import chokidar from "chokidar";
3814
3847
 
3815
3848
  // src/cli/gateway/controller.ts
3816
3849
  import { createHash } from "crypto";
3817
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
3850
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
3818
3851
  import {
3819
3852
  buildConfigSchema,
3820
3853
  ConfigSchema,
@@ -3822,11 +3855,11 @@ import {
3822
3855
  redactConfigObject
3823
3856
  } from "@nextclaw/core";
3824
3857
  var hashRaw = (raw) => createHash("sha256").update(raw).digest("hex");
3825
- var readConfigSnapshot = (getConfigPath10) => {
3826
- const path2 = getConfigPath10();
3858
+ var readConfigSnapshot = (getConfigPath11) => {
3859
+ const path2 = getConfigPath11();
3827
3860
  let raw = "";
3828
3861
  let parsed = {};
3829
- if (existsSync7(path2)) {
3862
+ if (existsSync8(path2)) {
3830
3863
  raw = readFileSync7(path2, "utf-8");
3831
3864
  try {
3832
3865
  parsed = JSON.parse(raw);
@@ -4284,8 +4317,8 @@ var MissingProvider = class extends LLMProvider {
4284
4317
  };
4285
4318
 
4286
4319
  // src/cli/commands/service-marketplace-installer.ts
4287
- import { getWorkspacePath as getWorkspacePath5, loadConfig as loadConfig12 } from "@nextclaw/core";
4288
- import { existsSync as existsSync8, rmSync as rmSync4 } from "fs";
4320
+ import { getWorkspacePath as getWorkspacePath5, loadConfig as loadConfig13 } from "@nextclaw/core";
4321
+ import { existsSync as existsSync9, rmSync as rmSync4 } from "fs";
4289
4322
  import { join as join4 } from "path";
4290
4323
 
4291
4324
  // src/cli/commands/service-marketplace-helpers.ts
@@ -4334,7 +4367,7 @@ var buildMarketplaceSkillInstallArgs = (params) => {
4334
4367
  };
4335
4368
 
4336
4369
  // src/cli/commands/service-mcp-marketplace-ops.ts
4337
- import { loadConfig as loadConfig11, saveConfig as saveConfig8 } from "@nextclaw/core";
4370
+ import { loadConfig as loadConfig12, saveConfig as saveConfig8 } from "@nextclaw/core";
4338
4371
  import { McpDoctorFacade as McpDoctorFacade2, McpMutationService as McpMutationService2 } from "@nextclaw/mcp";
4339
4372
  var ServiceMcpMarketplaceOps = class {
4340
4373
  constructor(options) {
@@ -4402,13 +4435,13 @@ var ServiceMcpMarketplaceOps = class {
4402
4435
  }
4403
4436
  createMutationService() {
4404
4437
  return new McpMutationService2({
4405
- getConfig: () => loadConfig11(),
4438
+ getConfig: () => loadConfig12(),
4406
4439
  saveConfig: (config2) => saveConfig8(config2)
4407
4440
  });
4408
4441
  }
4409
4442
  createDoctorFacade() {
4410
4443
  return new McpDoctorFacade2({
4411
- getConfig: () => loadConfig11()
4444
+ getConfig: () => loadConfig12()
4412
4445
  });
4413
4446
  }
4414
4447
  };
@@ -4449,7 +4482,7 @@ var ServiceMarketplaceInstaller = class {
4449
4482
  if (params.kind && params.kind !== "marketplace") {
4450
4483
  throw new Error(`Unsupported marketplace skill kind: ${params.kind}`);
4451
4484
  }
4452
- const workspace = getWorkspacePath5(loadConfig12().agents.defaults.workspace);
4485
+ const workspace = getWorkspacePath5(loadConfig13().agents.defaults.workspace);
4453
4486
  const args = buildMarketplaceSkillInstallArgs({
4454
4487
  slug: params.slug,
4455
4488
  workspace,
@@ -4488,9 +4521,9 @@ var ServiceMarketplaceInstaller = class {
4488
4521
  return { message: result.message };
4489
4522
  }
4490
4523
  async uninstallSkill(slug) {
4491
- const workspace = getWorkspacePath5(loadConfig12().agents.defaults.workspace);
4524
+ const workspace = getWorkspacePath5(loadConfig13().agents.defaults.workspace);
4492
4525
  const targetDir = join4(workspace, "skills", slug);
4493
- if (!existsSync8(targetDir)) {
4526
+ if (!existsSync9(targetDir)) {
4494
4527
  throw new Error(`Skill not installed in workspace: ${slug}`);
4495
4528
  }
4496
4529
  rmSync4(targetDir, { recursive: true, force: true });
@@ -4518,17 +4551,17 @@ var ServiceMarketplaceInstaller = class {
4518
4551
  };
4519
4552
 
4520
4553
  // src/cli/commands/service-plugin-runtime-bridge.ts
4521
- import { loadConfig as loadConfig13, resolveConfigSecrets as resolveConfigSecrets2, saveConfig as saveConfig9 } from "@nextclaw/core";
4554
+ import { loadConfig as loadConfig14, resolveConfigSecrets as resolveConfigSecrets2, saveConfig as saveConfig9 } from "@nextclaw/core";
4522
4555
  import { setPluginRuntimeBridge } from "@nextclaw/openclaw-compat";
4523
4556
  function installPluginRuntimeBridge(params) {
4524
4557
  const { runtimePool, runtimeConfigPath, pluginChannelBindings } = params;
4525
4558
  setPluginRuntimeBridge({
4526
- loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }), pluginChannelBindings),
4559
+ loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }), pluginChannelBindings),
4527
4560
  writeConfigFile: async (nextConfigView) => {
4528
4561
  if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
4529
4562
  throw new Error("plugin runtime writeConfigFile expects an object config");
4530
4563
  }
4531
- const current = loadConfig13();
4564
+ const current = loadConfig14();
4532
4565
  const next = mergePluginConfigView(current, nextConfigView, pluginChannelBindings);
4533
4566
  saveConfig9(next);
4534
4567
  },
@@ -6609,10 +6642,11 @@ function writeReadyManagedServiceState(params) {
6609
6642
  }
6610
6643
 
6611
6644
  // src/cli/commands/remote-access-host.ts
6612
- import { getConfigPath as getConfigPath7, loadConfig as loadConfig15 } from "@nextclaw/core";
6645
+ import { getConfigPath as getConfigPath8, loadConfig as loadConfig16 } from "@nextclaw/core";
6646
+ import { readPlatformSessionTokenState as readPlatformSessionTokenState2 } from "@nextclaw/remote";
6613
6647
 
6614
6648
  // src/cli/commands/remote-access-service-control.ts
6615
- import { getConfigPath as getConfigPath6, loadConfig as loadConfig14 } from "@nextclaw/core";
6649
+ import { getConfigPath as getConfigPath7, loadConfig as loadConfig15 } from "@nextclaw/core";
6616
6650
  import { spawn as spawn2 } from "child_process";
6617
6651
  var FORCED_PUBLIC_UI_HOST = "0.0.0.0";
6618
6652
  function resolveRemoteServiceView(currentUi) {
@@ -6682,7 +6716,7 @@ async function controlManagedService(action, deps) {
6682
6716
  }
6683
6717
  if (currentProcess) {
6684
6718
  if (action === "restart") {
6685
- await deps.requestManagedServiceRestart({ uiPort: uiOverrides.port ?? 18791 });
6719
+ await deps.requestManagedServiceRestart({ uiPort: uiOverrides.port ?? 55667 });
6686
6720
  } else {
6687
6721
  scheduleManagedSelfStop();
6688
6722
  }
@@ -6701,7 +6735,7 @@ async function controlManagedService(action, deps) {
6701
6735
  return { accepted: true, action, message: "Managed service restarted." };
6702
6736
  }
6703
6737
  function resolveManagedUiOverrides() {
6704
- const config2 = loadConfig14(getConfigPath6());
6738
+ const config2 = loadConfig15(getConfigPath7());
6705
6739
  const resolved = resolveUiConfig(config2, {
6706
6740
  enabled: true,
6707
6741
  host: FORCED_PUBLIC_UI_HOST,
@@ -6779,22 +6813,6 @@ function normalizeOptionalString5(value) {
6779
6813
  const trimmed = value.trim();
6780
6814
  return trimmed.length > 0 ? trimmed : null;
6781
6815
  }
6782
- function decodeJwtPayload(token) {
6783
- const segments = token.split(".");
6784
- if (segments.length < 2) {
6785
- return null;
6786
- }
6787
- try {
6788
- const raw = Buffer.from(segments[1], "base64url").toString("utf-8");
6789
- const parsed = JSON.parse(raw);
6790
- return typeof parsed === "object" && parsed !== null ? parsed : null;
6791
- } catch {
6792
- return null;
6793
- }
6794
- }
6795
- function isPlatformSessionToken2(token) {
6796
- return typeof token === "string" && token.startsWith("nca.");
6797
- }
6798
6816
  function toRemoteRuntimeView(runtime2) {
6799
6817
  if (!runtime2) {
6800
6818
  return null;
@@ -6817,7 +6835,7 @@ var RemoteAccessHost = class {
6817
6835
  this.deps = deps;
6818
6836
  }
6819
6837
  getStatus() {
6820
- const config2 = loadConfig15(getConfigPath7());
6838
+ const config2 = loadConfig16(getConfigPath8());
6821
6839
  const status = this.deps.remoteCommands.getStatusView();
6822
6840
  const account = this.readAccountView({
6823
6841
  token: normalizeOptionalString5(config2.providers.nextclaw?.apiKey),
@@ -6854,7 +6872,7 @@ var RemoteAccessHost = class {
6854
6872
  };
6855
6873
  }
6856
6874
  async pollBrowserAuth(input) {
6857
- const config2 = loadConfig15(getConfigPath7());
6875
+ const config2 = loadConfig16(getConfigPath8());
6858
6876
  const result = await this.deps.platformAuthCommands.pollBrowserAuth({
6859
6877
  apiBase: normalizeOptionalString5(input.apiBase) ?? normalizeOptionalString5(config2.remote.platformApiBase) ?? normalizeOptionalString5(config2.providers.nextclaw?.apiBase) ?? void 0,
6860
6878
  sessionId: input.sessionId
@@ -6895,14 +6913,15 @@ var RemoteAccessHost = class {
6895
6913
  return controlRemoteService(action, this.deps);
6896
6914
  }
6897
6915
  readAccountView(params) {
6898
- if (!isPlatformSessionToken2(params.token)) {
6916
+ const tokenState = readPlatformSessionTokenState2(params.token);
6917
+ if (!tokenState.valid) {
6899
6918
  return {
6900
6919
  loggedIn: false,
6901
6920
  apiBase: params.apiBase,
6902
6921
  platformBase: params.platformBase
6903
6922
  };
6904
6923
  }
6905
- const payload = decodeJwtPayload(params.token);
6924
+ const payload = tokenState.payload;
6906
6925
  const email = typeof payload?.email === "string" ? payload.email : void 0;
6907
6926
  const role = typeof payload?.role === "string" ? payload.role : void 0;
6908
6927
  return {
@@ -6951,7 +6970,7 @@ function createRemoteAccessHost(params) {
6951
6970
  }
6952
6971
 
6953
6972
  // src/cli/commands/ui-chat-run-coordinator.ts
6954
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
6973
+ import { existsSync as existsSync10, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
6955
6974
  import { join as join5 } from "path";
6956
6975
  import {
6957
6976
  getDataDir as getDataDir6,
@@ -7506,7 +7525,7 @@ var UiChatRunCoordinator = class {
7506
7525
  `);
7507
7526
  }
7508
7527
  loadPersistedRuns() {
7509
- if (!existsSync9(RUNS_DIR)) {
7528
+ if (!existsSync10(RUNS_DIR)) {
7510
7529
  return;
7511
7530
  }
7512
7531
  for (const entry of readdirSync2(RUNS_DIR, { withFileTypes: true })) {
@@ -7574,14 +7593,14 @@ var {
7574
7593
  ChannelManager: ChannelManager2,
7575
7594
  CronService: CronService2,
7576
7595
  getApiBase,
7577
- getConfigPath: getConfigPath8,
7596
+ getConfigPath: getConfigPath9,
7578
7597
  getDataDir: getDataDir7,
7579
7598
  getProvider,
7580
7599
  getProviderName,
7581
7600
  getWorkspacePath: getWorkspacePath9,
7582
7601
  HeartbeatService,
7583
7602
  LiteLLMProvider,
7584
- loadConfig: loadConfig16,
7603
+ loadConfig: loadConfig17,
7585
7604
  MessageBus,
7586
7605
  ProviderManager,
7587
7606
  resolveConfigSecrets: resolveConfigSecrets3,
@@ -7605,8 +7624,8 @@ var ServiceCommands = class {
7605
7624
  async startGateway(options = {}) {
7606
7625
  this.applyLiveConfigReload = null;
7607
7626
  this.liveUiNcpAgent = null;
7608
- const runtimeConfigPath = getConfigPath8();
7609
- const config2 = resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath });
7627
+ const runtimeConfigPath = getConfigPath9();
7628
+ const config2 = resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath });
7610
7629
  const workspace = getWorkspacePath9(config2.agents.defaults.workspace);
7611
7630
  let pluginRegistry = loadPluginRegistry(config2, workspace);
7612
7631
  let extensionRegistry = toExtensionRegistry(pluginRegistry);
@@ -7624,7 +7643,7 @@ var ServiceCommands = class {
7624
7643
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7625
7644
  const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
7626
7645
  const remoteModule = createManagedRemoteModuleForUi({
7627
- loadConfig: () => resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7646
+ loadConfig: () => resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath }),
7628
7647
  uiConfig
7629
7648
  });
7630
7649
  if (!provider) {
@@ -7638,7 +7657,7 @@ var ServiceCommands = class {
7638
7657
  sessionManager,
7639
7658
  providerManager,
7640
7659
  makeProvider: (nextConfig) => this.makeProvider(nextConfig, { allowMissing: true }) ?? this.makeMissingProvider(nextConfig),
7641
- loadConfig: () => resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7660
+ loadConfig: () => resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath }),
7642
7661
  getExtensionChannels: () => extensionRegistry.channels,
7643
7662
  onRestartRequired: (paths) => {
7644
7663
  void this.deps.requestRestart({
@@ -7649,13 +7668,13 @@ var ServiceCommands = class {
7649
7668
  }
7650
7669
  });
7651
7670
  this.applyLiveConfigReload = async () => {
7652
- await reloader.applyReloadPlan(resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }));
7671
+ await reloader.applyReloadPlan(resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath }));
7653
7672
  };
7654
7673
  const gatewayController = new GatewayControllerImpl({
7655
7674
  reloader,
7656
7675
  cron: cron2,
7657
7676
  sessionManager,
7658
- getConfigPath: getConfigPath8,
7677
+ getConfigPath: getConfigPath9,
7659
7678
  saveConfig: saveConfig10,
7660
7679
  requestRestart: async (options2) => {
7661
7680
  await this.deps.requestRestart({
@@ -7682,7 +7701,7 @@ var ServiceCommands = class {
7682
7701
  resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
7683
7702
  registry: pluginRegistry,
7684
7703
  channel,
7685
- cfg: resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7704
+ cfg: resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath }),
7686
7705
  accountId
7687
7706
  })
7688
7707
  });
@@ -7758,12 +7777,12 @@ var ServiceCommands = class {
7758
7777
  providerManager,
7759
7778
  bus,
7760
7779
  gatewayController,
7761
- () => resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7780
+ () => resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath }),
7762
7781
  () => extensionRegistry,
7763
7782
  ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
7764
7783
  registry: pluginRegistry,
7765
7784
  channel,
7766
- cfg: resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7785
+ cfg: resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath }),
7767
7786
  accountId
7768
7787
  }),
7769
7788
  remoteModule
@@ -7801,7 +7820,7 @@ var ServiceCommands = class {
7801
7820
  return trimmed || void 0;
7802
7821
  }
7803
7822
  watchConfigFile(reloader) {
7804
- const configPath = resolve10(getConfigPath8());
7823
+ const configPath = resolve10(getConfigPath9());
7805
7824
  const watcher = chokidar.watch(configPath, {
7806
7825
  ignoreInitial: true,
7807
7826
  awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
@@ -7922,7 +7941,7 @@ var ServiceCommands = class {
7922
7941
  });
7923
7942
  }
7924
7943
  async runForeground(options) {
7925
- const config2 = loadConfig16();
7944
+ const config2 = loadConfig17();
7926
7945
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7927
7946
  const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
7928
7947
  if (options.open) {
@@ -7935,7 +7954,7 @@ var ServiceCommands = class {
7935
7954
  });
7936
7955
  }
7937
7956
  async startService(options) {
7938
- const config2 = loadConfig16();
7957
+ const config2 = loadConfig17();
7939
7958
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7940
7959
  const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
7941
7960
  const apiUrl = `${uiUrl}/api`;
@@ -7951,12 +7970,12 @@ var ServiceCommands = class {
7951
7970
  const port = Number(parsed.port || 80);
7952
7971
  return {
7953
7972
  host: existing.uiHost ?? parsed.hostname,
7954
- port: Number.isFinite(port) ? port : existing.uiPort ?? 18791
7973
+ port: Number.isFinite(port) ? port : existing.uiPort ?? 55667
7955
7974
  };
7956
7975
  } catch {
7957
7976
  return {
7958
7977
  host: existing.uiHost ?? "127.0.0.1",
7959
- port: existing.uiPort ?? 18791
7978
+ port: existing.uiPort ?? 55667
7960
7979
  };
7961
7980
  }
7962
7981
  })();
@@ -8343,7 +8362,7 @@ var ServiceCommands = class {
8343
8362
  return null;
8344
8363
  }
8345
8364
  console.error("Error: No API key configured.");
8346
- console.error(`Set one in ${getConfigPath8()} under providers section`);
8365
+ console.error(`Set one in ${getConfigPath9()} under providers section`);
8347
8366
  process.exit(1);
8348
8367
  }
8349
8368
  return new LiteLLMProvider({
@@ -8473,7 +8492,7 @@ var ServiceCommands = class {
8473
8492
  const uiServer = startUiServer({
8474
8493
  host: uiConfig.host,
8475
8494
  port: uiConfig.port,
8476
- configPath: getConfigPath8(),
8495
+ configPath: getConfigPath9(),
8477
8496
  productVersion: getPackageVersion(),
8478
8497
  staticDir: uiStaticDir ?? void 0,
8479
8498
  cronService,
@@ -8562,10 +8581,10 @@ var ServiceCommands = class {
8562
8581
  }
8563
8582
  }
8564
8583
  installBuiltinMarketplaceSkill(slug, force) {
8565
- const workspace = getWorkspacePath9(loadConfig16().agents.defaults.workspace);
8584
+ const workspace = getWorkspacePath9(loadConfig17().agents.defaults.workspace);
8566
8585
  const destination = join6(workspace, "skills", slug);
8567
8586
  const destinationSkillFile = join6(destination, "SKILL.md");
8568
- if (existsSync10(destinationSkillFile) && !force) {
8587
+ if (existsSync11(destinationSkillFile) && !force) {
8569
8588
  return {
8570
8589
  message: `${slug} is already installed`
8571
8590
  };
@@ -8573,7 +8592,7 @@ var ServiceCommands = class {
8573
8592
  const loader = createSkillsLoader(workspace);
8574
8593
  const builtin = (loader?.listSkills(false) ?? []).find((skill) => skill.name === slug && skill.source === "builtin");
8575
8594
  if (!builtin) {
8576
- if (existsSync10(destinationSkillFile)) {
8595
+ if (existsSync11(destinationSkillFile)) {
8577
8596
  return {
8578
8597
  message: `${slug} is already installed`
8579
8598
  };
@@ -8640,7 +8659,7 @@ ${stderr}`.trim();
8640
8659
  };
8641
8660
 
8642
8661
  // src/cli/workspace.ts
8643
- import { cpSync as cpSync3, existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9, readdirSync as readdirSync3, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
8662
+ import { cpSync as cpSync3, existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync9, readdirSync as readdirSync3, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
8644
8663
  import { createRequire as createRequire2 } from "module";
8645
8664
  import { dirname as dirname3, join as join7, resolve as resolve11 } from "path";
8646
8665
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -8673,11 +8692,11 @@ var WorkspaceManager = class {
8673
8692
  ];
8674
8693
  for (const entry of templateFiles) {
8675
8694
  const filePath = join7(workspace, entry.target);
8676
- if (!force && existsSync11(filePath)) {
8695
+ if (!force && existsSync12(filePath)) {
8677
8696
  continue;
8678
8697
  }
8679
8698
  const templatePath = join7(templateDir, entry.source);
8680
- if (!existsSync11(templatePath)) {
8699
+ if (!existsSync12(templatePath)) {
8681
8700
  console.warn(`Warning: Template file missing: ${templatePath}`);
8682
8701
  continue;
8683
8702
  }
@@ -8688,12 +8707,12 @@ var WorkspaceManager = class {
8688
8707
  created.push(entry.target);
8689
8708
  }
8690
8709
  const memoryDir = join7(workspace, "memory");
8691
- if (!existsSync11(memoryDir)) {
8710
+ if (!existsSync12(memoryDir)) {
8692
8711
  mkdirSync6(memoryDir, { recursive: true });
8693
8712
  created.push(join7("memory", ""));
8694
8713
  }
8695
8714
  const skillsDir = join7(workspace, "skills");
8696
- if (!existsSync11(skillsDir)) {
8715
+ if (!existsSync12(skillsDir)) {
8697
8716
  mkdirSync6(skillsDir, { recursive: true });
8698
8717
  created.push(join7("skills", ""));
8699
8718
  }
@@ -8715,11 +8734,11 @@ var WorkspaceManager = class {
8715
8734
  continue;
8716
8735
  }
8717
8736
  const src = join7(sourceDir, entry.name);
8718
- if (!existsSync11(join7(src, "SKILL.md"))) {
8737
+ if (!existsSync12(join7(src, "SKILL.md"))) {
8719
8738
  continue;
8720
8739
  }
8721
8740
  const dest = join7(targetDir, entry.name);
8722
- if (!force && existsSync11(dest)) {
8741
+ if (!force && existsSync12(dest)) {
8723
8742
  continue;
8724
8743
  }
8725
8744
  try {
@@ -8738,11 +8757,11 @@ var WorkspaceManager = class {
8738
8757
  const entry = require3.resolve("@nextclaw/core");
8739
8758
  const pkgRoot = resolve11(dirname3(entry), "..");
8740
8759
  const distSkills = join7(pkgRoot, "dist", "skills");
8741
- if (existsSync11(distSkills)) {
8760
+ if (existsSync12(distSkills)) {
8742
8761
  return distSkills;
8743
8762
  }
8744
8763
  const srcSkills = join7(pkgRoot, "src", "agent", "skills");
8745
- if (existsSync11(srcSkills)) {
8764
+ if (existsSync12(srcSkills)) {
8746
8765
  return srcSkills;
8747
8766
  }
8748
8767
  return null;
@@ -8759,7 +8778,7 @@ var WorkspaceManager = class {
8759
8778
  const pkgRoot = resolve11(cliDir, "..", "..");
8760
8779
  const candidates = [join7(pkgRoot, "templates")];
8761
8780
  for (const candidate of candidates) {
8762
- if (existsSync11(candidate)) {
8781
+ if (existsSync12(candidate)) {
8763
8782
  return candidate;
8764
8783
  }
8765
8784
  }
@@ -8767,7 +8786,7 @@ var WorkspaceManager = class {
8767
8786
  }
8768
8787
  getBridgeDir() {
8769
8788
  const userBridge = join7(getDataDir8(), "bridge");
8770
- if (existsSync11(join7(userBridge, "dist", "index.js"))) {
8789
+ if (existsSync12(join7(userBridge, "dist", "index.js"))) {
8771
8790
  return userBridge;
8772
8791
  }
8773
8792
  if (!which("npm")) {
@@ -8779,9 +8798,9 @@ var WorkspaceManager = class {
8779
8798
  const pkgBridge = join7(pkgRoot, "bridge");
8780
8799
  const srcBridge = join7(pkgRoot, "..", "..", "bridge");
8781
8800
  let source = null;
8782
- if (existsSync11(join7(pkgBridge, "package.json"))) {
8801
+ if (existsSync12(join7(pkgBridge, "package.json"))) {
8783
8802
  source = pkgBridge;
8784
- } else if (existsSync11(join7(srcBridge, "package.json"))) {
8803
+ } else if (existsSync12(join7(srcBridge, "package.json"))) {
8785
8804
  source = srcBridge;
8786
8805
  }
8787
8806
  if (!source) {
@@ -8790,7 +8809,7 @@ var WorkspaceManager = class {
8790
8809
  }
8791
8810
  console.log(`${this.logo} Setting up bridge...`);
8792
8811
  mkdirSync6(resolve11(userBridge, ".."), { recursive: true });
8793
- if (existsSync11(userBridge)) {
8812
+ if (existsSync12(userBridge)) {
8794
8813
  rmSync5(userBridge, { recursive: true, force: true });
8795
8814
  }
8796
8815
  cpSync3(source, userBridge, {
@@ -8902,7 +8921,7 @@ var CliRuntime = class {
8902
8921
  return false;
8903
8922
  }
8904
8923
  const uiHost = FORCED_PUBLIC_UI_HOST2;
8905
- const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
8924
+ const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 55667;
8906
8925
  console.log(
8907
8926
  `Applying changes (${reason}): restarting ${APP_NAME5} background service...`
8908
8927
  );
@@ -8935,7 +8954,7 @@ var CliRuntime = class {
8935
8954
  if (!state || state.pid !== process.pid) {
8936
8955
  return;
8937
8956
  }
8938
- const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
8957
+ const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 55667;
8939
8958
  const delayMs = typeof params.delayMs === "number" && Number.isFinite(params.delayMs) ? Math.max(0, Math.floor(params.delayMs)) : 100;
8940
8959
  const cliPath = process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() || fileURLToPath5(new URL("./index.js", import.meta.url));
8941
8960
  const startArgs = [cliPath, "start", "--ui-port", String(uiPort)];
@@ -9067,17 +9086,12 @@ var CliRuntime = class {
9067
9086
  const source = options.source ?? "init";
9068
9087
  const prefix = options.auto ? "Auto init" : "Init";
9069
9088
  const force = Boolean(options.force);
9070
- const configPath = getConfigPath9();
9071
- let createdConfig = false;
9072
- if (!existsSync12(configPath)) {
9073
- const config3 = ConfigSchema2.parse({});
9074
- saveConfig11(config3);
9075
- createdConfig = true;
9076
- }
9077
- const config2 = loadConfig17();
9089
+ const configPath = getConfigPath10();
9090
+ const createdConfig = initializeConfigIfMissing(configPath);
9091
+ const config2 = loadConfig18();
9078
9092
  const workspaceSetting = config2.agents.defaults.workspace;
9079
9093
  const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir9(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
9080
- const workspaceExisted = existsSync12(workspacePath);
9094
+ const workspaceExisted = existsSync13(workspacePath);
9081
9095
  mkdirSync7(workspacePath, { recursive: true });
9082
9096
  const templateResult = this.workspaceManager.createWorkspaceTemplates(
9083
9097
  workspacePath,
@@ -9200,8 +9214,8 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9200
9214
  await this.serviceCommands.stopService();
9201
9215
  }
9202
9216
  async agent(opts) {
9203
- const configPath = getConfigPath9();
9204
- const config2 = resolveConfigSecrets4(loadConfig17(), { configPath });
9217
+ const configPath = getConfigPath10();
9218
+ const config2 = resolveConfigSecrets4(loadConfig18(), { configPath });
9205
9219
  const workspace = getWorkspacePath10(config2.agents.defaults.workspace);
9206
9220
  const pluginRegistry = loadPluginRegistry(config2, workspace);
9207
9221
  const extensionRegistry = toExtensionRegistry(pluginRegistry);
@@ -9209,7 +9223,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9209
9223
  const pluginChannelBindings = getPluginChannelBindings4(pluginRegistry);
9210
9224
  setPluginRuntimeBridge3({
9211
9225
  loadConfig: () => toPluginConfigView(
9212
- resolveConfigSecrets4(loadConfig17(), { configPath }),
9226
+ resolveConfigSecrets4(loadConfig18(), { configPath }),
9213
9227
  pluginChannelBindings
9214
9228
  ),
9215
9229
  writeConfigFile: async (nextConfigView) => {
@@ -9218,7 +9232,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9218
9232
  "plugin runtime writeConfigFile expects an object config"
9219
9233
  );
9220
9234
  }
9221
- const current = loadConfig17();
9235
+ const current = loadConfig18();
9222
9236
  const next = mergePluginConfigView(
9223
9237
  current,
9224
9238
  nextConfigView,
@@ -9250,7 +9264,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9250
9264
  resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
9251
9265
  registry: pluginRegistry,
9252
9266
  channel,
9253
- cfg: resolveConfigSecrets4(loadConfig17(), { configPath }),
9267
+ cfg: resolveConfigSecrets4(loadConfig18(), { configPath }),
9254
9268
  accountId
9255
9269
  })
9256
9270
  });
@@ -9272,7 +9286,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9272
9286
  const historyFile = join8(getDataDir9(), "history", "cli_history");
9273
9287
  const historyDir = resolve12(historyFile, "..");
9274
9288
  mkdirSync7(historyDir, { recursive: true });
9275
- const history = existsSync12(historyFile) ? readFileSync10(historyFile, "utf-8").split("\n").filter(Boolean) : [];
9289
+ const history = existsSync13(historyFile) ? readFileSync10(historyFile, "utf-8").split("\n").filter(Boolean) : [];
9276
9290
  const rl = createInterface3({
9277
9291
  input: process.stdin,
9278
9292
  output: process.stdout
@@ -9445,7 +9459,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9445
9459
  await this.diagnosticsCommands.doctor(opts);
9446
9460
  }
9447
9461
  async skillsInstall(options) {
9448
- const config2 = loadConfig17();
9462
+ const config2 = loadConfig18();
9449
9463
  const workdir = resolveSkillsInstallWorkdir({
9450
9464
  explicitWorkdir: options.workdir,
9451
9465
  configuredWorkspace: config2.agents.defaults.workspace
@@ -9512,7 +9526,7 @@ var runtime = new CliRuntime({ logo: LOGO });
9512
9526
  program.name(APP_NAME6).description(`${LOGO} ${APP_NAME6} - ${APP_TAGLINE}`).version(getPackageVersion(), "-v, --version", "show version");
9513
9527
  program.command("onboard").description(`Initialize ${APP_NAME6} configuration and workspace`).action(async () => runtime.onboard());
9514
9528
  program.command("init").description(`Initialize ${APP_NAME6} configuration and workspace`).option("-f, --force", "Overwrite existing template files").action(async (opts) => runtime.init({ force: Boolean(opts.force) }));
9515
- program.command("login").description("Login to NextClaw platform and save token into providers.nextclaw.apiKey").option("--api-base <url>", "Platform API base (supports /v1 suffix)").option("--email <email>", "Login email").option("--password <password>", "Login password").option("--register", "Register first, then login", false).action(async (opts) => runtime.login(opts));
9529
+ program.command("login").description("Login to NextClaw platform and save token into providers.nextclaw.apiKey").option("--api-base <url>", "Platform API base (supports /v1 suffix)").option("--email <email>", "Login email").option("--password <password>", "Login password").action(async (opts) => runtime.login(opts));
9516
9530
  registerRemoteCommands(program, runtime.remote);
9517
9531
  program.command("gateway").description(`Start the ${APP_NAME6} gateway`).option("-p, --port <port>", "Gateway port", "18790").option("-v, --verbose", "Verbose output", false).option("--ui", "Enable UI server", false).option("--ui-port <port>", "UI port").option("--ui-open", "Open browser when UI starts", false).action(async (opts) => runtime.gateway(opts));
9518
9532
  program.command("ui").description(`Start the ${APP_NAME6} UI with gateway`).option("--port <port>", "UI port").option("--no-open", "Disable opening browser").action(async (opts) => runtime.ui(opts));