nextclaw 0.13.8 → 0.13.10

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 (32) hide show
  1. package/dist/cli/index.js +574 -90
  2. package/package.json +6 -6
  3. package/ui-dist/assets/ChannelsList-DH1Ur9XW.js +0 -1
  4. package/ui-dist/assets/ChatPage-YTDcN7XS.js +0 -38
  5. package/ui-dist/assets/DocBrowser-Bi-RpLIw.js +0 -1
  6. package/ui-dist/assets/LogoBadge-BCR9CU7n.js +0 -1
  7. package/ui-dist/assets/MarketplacePage-BgCdiku7.js +0 -49
  8. package/ui-dist/assets/McpMarketplacePage-nyCbiQH6.js +0 -40
  9. package/ui-dist/assets/ModelConfig-Cf4AAYaB.js +0 -1
  10. package/ui-dist/assets/ProvidersList-CfkfKQbw.js +0 -1
  11. package/ui-dist/assets/RuntimeConfig-BI-zClCl.js +0 -1
  12. package/ui-dist/assets/SearchConfig-MBmvco1J.js +0 -1
  13. package/ui-dist/assets/SecretsConfig-CC2B6pVQ.js +0 -3
  14. package/ui-dist/assets/SessionsConfig-CTxJeVQs.js +0 -2
  15. package/ui-dist/assets/chat-message-5OiyZViy.js +0 -3
  16. package/ui-dist/assets/config-hints-CApS3K_7.js +0 -1
  17. package/ui-dist/assets/config-layout-BHnOoweL.js +0 -1
  18. package/ui-dist/assets/index-C2OKcVdN.css +0 -1
  19. package/ui-dist/assets/index-ElnZdv5o.js +0 -1
  20. package/ui-dist/assets/index-LgjZxLjc.js +0 -8
  21. package/ui-dist/assets/label-CPdcDrir.js +0 -1
  22. package/ui-dist/assets/marketplace-localization-Dk31LJJJ.js +0 -1
  23. package/ui-dist/assets/page-layout-B8V5_vM_.js +0 -1
  24. package/ui-dist/assets/popover-Bk53A74_.js +0 -1
  25. package/ui-dist/assets/provider-models-D3B_xWXx.js +0 -1
  26. package/ui-dist/assets/security-config-BNjgoyo4.js +0 -1
  27. package/ui-dist/assets/skeleton-NPxxR-L0.js +0 -1
  28. package/ui-dist/assets/switch-EowdzMK2.js +0 -1
  29. package/ui-dist/assets/tabs-custom-BjLv-uCT.js +0 -1
  30. package/ui-dist/assets/useConfirmDialog-TJcJQMfu.js +0 -5
  31. package/ui-dist/assets/vendor-425xp8cv.js +0 -407
  32. package/ui-dist/index.html +0 -18
package/dist/cli/index.js CHANGED
@@ -7,9 +7,9 @@ import { registerRemoteCommands } from "@nextclaw/remote";
7
7
 
8
8
  // src/cli/runtime.ts
9
9
  import {
10
- loadConfig as loadConfig14,
10
+ loadConfig as loadConfig15,
11
11
  saveConfig as saveConfig10,
12
- getConfigPath as getConfigPath7,
12
+ getConfigPath as getConfigPath8,
13
13
  getDataDir as getDataDir9,
14
14
  ConfigSchema as ConfigSchema2,
15
15
  getWorkspacePath as getWorkspacePath10,
@@ -32,7 +32,7 @@ import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as re
32
32
  import { join as join8, resolve as resolve12 } from "path";
33
33
  import { createInterface as createInterface3 } from "readline";
34
34
  import { fileURLToPath as fileURLToPath5 } from "url";
35
- import { spawn as spawn3 } from "child_process";
35
+ import { spawn as spawn4 } from "child_process";
36
36
 
37
37
  // src/cli/restart-coordinator.ts
38
38
  var RestartCoordinator = class {
@@ -3001,8 +3001,75 @@ function readLoginPayload(raw) {
3001
3001
  }
3002
3002
  return { token, role };
3003
3003
  }
3004
+ function persistPlatformToken(params) {
3005
+ params.nextclawProvider.apiBase = params.v1Base;
3006
+ params.nextclawProvider.apiKey = params.token;
3007
+ params.providers.nextclaw = params.nextclawProvider;
3008
+ saveConfig6(params.config, params.configPath);
3009
+ }
3010
+ function parseJsonText(raw) {
3011
+ try {
3012
+ return JSON.parse(raw);
3013
+ } catch {
3014
+ return null;
3015
+ }
3016
+ }
3017
+ function readPlatformErrorMessage(raw, fallbackStatus) {
3018
+ const parsed = parseJsonText(raw);
3019
+ return typeof parsed === "object" && parsed && "error" in parsed && typeof parsed.error?.message === "string" ? parsed.error.message : raw || `Request failed (${fallbackStatus})`;
3020
+ }
3021
+ function readBrowserAuthStartPayload(raw) {
3022
+ const parsed = parseJsonText(raw);
3023
+ const data = typeof parsed === "object" && parsed && "data" in parsed ? parsed.data : null;
3024
+ const sessionId = typeof data?.sessionId === "string" ? data.sessionId.trim() : "";
3025
+ const verificationUri = typeof data?.verificationUri === "string" ? data.verificationUri.trim() : "";
3026
+ const expiresAt = typeof data?.expiresAt === "string" ? data.expiresAt.trim() : "";
3027
+ const intervalMs = typeof data?.intervalMs === "number" && Number.isFinite(data.intervalMs) ? Math.max(1e3, Math.trunc(data.intervalMs)) : 1500;
3028
+ if (!sessionId || !verificationUri || !expiresAt) {
3029
+ throw new Error("Browser authorization session payload is incomplete.");
3030
+ }
3031
+ return {
3032
+ sessionId,
3033
+ verificationUri,
3034
+ expiresAt,
3035
+ intervalMs
3036
+ };
3037
+ }
3038
+ function readBrowserAuthPollPayload(raw) {
3039
+ const parsed = parseJsonText(raw);
3040
+ const data = typeof parsed === "object" && parsed && "data" in parsed ? parsed.data : null;
3041
+ const status = typeof data?.status === "string" ? data.status.trim() : "";
3042
+ if (status === "pending") {
3043
+ return {
3044
+ status,
3045
+ nextPollMs: typeof data?.nextPollMs === "number" && Number.isFinite(data.nextPollMs) ? Math.max(1e3, Math.trunc(data.nextPollMs)) : 1500
3046
+ };
3047
+ }
3048
+ if (status === "expired") {
3049
+ return {
3050
+ status,
3051
+ message: typeof data?.message === "string" && data.message.trim() ? data.message.trim() : "Authorization session expired."
3052
+ };
3053
+ }
3054
+ if (status !== "authorized") {
3055
+ throw new Error("Unexpected browser authorization status.");
3056
+ }
3057
+ const token = typeof data?.token === "string" ? data.token.trim() : "";
3058
+ const user = typeof data?.user === "object" && data.user ? data.user : null;
3059
+ const role = typeof user?.role === "string" ? user.role.trim() : "user";
3060
+ const email = typeof user?.email === "string" ? user.email.trim() : "";
3061
+ if (!token || !email) {
3062
+ throw new Error("Authorized browser login payload is incomplete.");
3063
+ }
3064
+ return {
3065
+ status,
3066
+ token,
3067
+ role,
3068
+ email
3069
+ };
3070
+ }
3004
3071
  var PlatformAuthCommands = class {
3005
- async login(opts = {}) {
3072
+ async loginResult(opts = {}) {
3006
3073
  const { configPath, config: config2, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
3007
3074
  const { email, password } = await resolveCredentials(opts);
3008
3075
  const endpoint = opts.register ? `${platformBase}/platform/auth/register` : `${platformBase}/platform/auth/login`;
@@ -3015,23 +3082,105 @@ var PlatformAuthCommands = class {
3015
3082
  });
3016
3083
  const raw = await response.text();
3017
3084
  if (!response.ok) {
3018
- let parsed = null;
3019
- try {
3020
- parsed = JSON.parse(raw);
3021
- } catch {
3022
- parsed = null;
3023
- }
3024
- const maybeMessage = typeof parsed === "object" && parsed && "error" in parsed && typeof parsed.error?.message === "string" ? parsed.error.message : raw || `Request failed (${response.status})`;
3025
- throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, maybeMessage));
3085
+ throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
3026
3086
  }
3027
3087
  const { token, role } = readLoginPayload(raw);
3028
- nextclawProvider.apiBase = v1Base;
3029
- nextclawProvider.apiKey = token;
3088
+ persistPlatformToken({
3089
+ configPath,
3090
+ config: config2,
3091
+ providers,
3092
+ nextclawProvider,
3093
+ v1Base,
3094
+ token
3095
+ });
3096
+ return {
3097
+ token,
3098
+ role,
3099
+ email,
3100
+ platformBase,
3101
+ v1Base
3102
+ };
3103
+ }
3104
+ async startBrowserAuth(opts = {}) {
3105
+ const { platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
3106
+ const response = await fetch(`${platformBase}/platform/auth/browser/start`, {
3107
+ method: "POST",
3108
+ headers: {
3109
+ "Content-Type": "application/json"
3110
+ },
3111
+ body: JSON.stringify({})
3112
+ });
3113
+ const raw = await response.text();
3114
+ if (!response.ok) {
3115
+ throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
3116
+ }
3117
+ const result = readBrowserAuthStartPayload(raw);
3118
+ return {
3119
+ ...result,
3120
+ platformBase,
3121
+ v1Base
3122
+ };
3123
+ }
3124
+ async pollBrowserAuth(params) {
3125
+ const { configPath, config: config2, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig({
3126
+ apiBase: params.apiBase
3127
+ });
3128
+ const response = await fetch(`${platformBase}/platform/auth/browser/poll`, {
3129
+ method: "POST",
3130
+ headers: {
3131
+ "Content-Type": "application/json"
3132
+ },
3133
+ body: JSON.stringify({
3134
+ sessionId: params.sessionId
3135
+ })
3136
+ });
3137
+ const raw = await response.text();
3138
+ if (!response.ok) {
3139
+ throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
3140
+ }
3141
+ const result = readBrowserAuthPollPayload(raw);
3142
+ if (result.status === "pending") {
3143
+ return {
3144
+ status: "pending",
3145
+ nextPollMs: result.nextPollMs ?? 1500
3146
+ };
3147
+ }
3148
+ if (result.status === "expired") {
3149
+ return {
3150
+ status: "expired",
3151
+ message: result.message ?? "Authorization session expired."
3152
+ };
3153
+ }
3154
+ persistPlatformToken({
3155
+ configPath,
3156
+ config: config2,
3157
+ providers,
3158
+ nextclawProvider,
3159
+ v1Base,
3160
+ token: result.token ?? ""
3161
+ });
3162
+ return {
3163
+ status: "authorized",
3164
+ token: result.token ?? "",
3165
+ role: result.role ?? "user",
3166
+ email: result.email ?? "",
3167
+ platformBase,
3168
+ v1Base
3169
+ };
3170
+ }
3171
+ async login(opts = {}) {
3172
+ const result = await this.loginResult(opts);
3173
+ console.log(`\u2713 Logged in to NextClaw platform (${result.platformBase})`);
3174
+ console.log(`\u2713 Account: ${result.email} (${result.role})`);
3175
+ console.log(`\u2713 Token saved into providers.nextclaw.apiKey`);
3176
+ }
3177
+ logout() {
3178
+ const { configPath, config: config2, providers, nextclawProvider } = resolveProviderConfig({});
3179
+ const cleared = Boolean(nextclawProvider.apiKey?.trim());
3180
+ nextclawProvider.apiKey = "";
3030
3181
  providers.nextclaw = nextclawProvider;
3031
3182
  saveConfig6(config2, configPath);
3032
- console.log(`\u2713 Logged in to NextClaw platform (${platformBase})`);
3033
- console.log(`\u2713 Account: ${email} (${role})`);
3034
- console.log(`\u2713 Token saved into providers.nextclaw.apiKey`);
3183
+ return { cleared };
3035
3184
  }
3036
3185
  };
3037
3186
 
@@ -3112,6 +3261,9 @@ function normalizeOptionalString3(value) {
3112
3261
  const trimmed = value.trim();
3113
3262
  return trimmed.length > 0 ? trimmed : void 0;
3114
3263
  }
3264
+ function isPlatformSessionToken(value) {
3265
+ return typeof value === "string" && value.startsWith("nca.");
3266
+ }
3115
3267
  function resolveConfiguredLocalOrigin(config2) {
3116
3268
  const state = readServiceState();
3117
3269
  if (state && isProcessRunning(state.pid) && Number.isFinite(state.uiPort)) {
@@ -3135,15 +3287,18 @@ async function probeLocalUi(localOrigin) {
3135
3287
  }
3136
3288
  }
3137
3289
  var RemoteCommands = class {
3138
- enableConfig(opts = {}) {
3290
+ updateConfig(params = {}) {
3139
3291
  const config2 = loadConfig9(getConfigPath4());
3292
+ const nextEnabled = typeof params.enabled === "boolean" ? params.enabled : config2.remote.enabled;
3293
+ const nextPlatformApiBase = typeof params.apiBase === "string" ? params.apiBase.trim() : config2.remote.platformApiBase;
3294
+ const nextDeviceName = typeof params.name === "string" ? params.name.trim() : config2.remote.deviceName;
3140
3295
  const next = {
3141
3296
  ...config2,
3142
3297
  remote: {
3143
3298
  ...config2.remote,
3144
- enabled: true,
3145
- ...normalizeOptionalString3(opts.apiBase) ? { platformApiBase: normalizeOptionalString3(opts.apiBase) ?? "" } : {},
3146
- ...normalizeOptionalString3(opts.name) ? { deviceName: normalizeOptionalString3(opts.name) ?? "" } : {}
3299
+ enabled: nextEnabled,
3300
+ platformApiBase: nextPlatformApiBase,
3301
+ deviceName: nextDeviceName
3147
3302
  }
3148
3303
  };
3149
3304
  saveConfig7(next);
@@ -3152,20 +3307,15 @@ var RemoteCommands = class {
3152
3307
  config: next
3153
3308
  };
3154
3309
  }
3310
+ enableConfig(opts = {}) {
3311
+ return this.updateConfig({
3312
+ enabled: true,
3313
+ apiBase: typeof opts.apiBase === "string" ? opts.apiBase : void 0,
3314
+ name: typeof opts.name === "string" ? opts.name : void 0
3315
+ });
3316
+ }
3155
3317
  disableConfig() {
3156
- const config2 = loadConfig9(getConfigPath4());
3157
- const next = {
3158
- ...config2,
3159
- remote: {
3160
- ...config2.remote,
3161
- enabled: false
3162
- }
3163
- };
3164
- saveConfig7(next);
3165
- return {
3166
- changed: config2.remote.enabled !== next.remote.enabled,
3167
- config: next
3168
- };
3318
+ return this.updateConfig({ enabled: false });
3169
3319
  }
3170
3320
  async connect(opts = {}) {
3171
3321
  const connector = createNextclawRemoteConnector();
@@ -3174,23 +3324,31 @@ var RemoteCommands = class {
3174
3324
  mode: "foreground"
3175
3325
  });
3176
3326
  }
3177
- async status(opts = {}) {
3327
+ getStatusView() {
3178
3328
  const config2 = loadConfig9(getConfigPath4());
3179
3329
  const snapshot = resolveNextclawRemoteStatusSnapshot(config2);
3330
+ return {
3331
+ configuredEnabled: snapshot.configuredEnabled,
3332
+ runtime: snapshot.runtime,
3333
+ localOrigin: resolveConfiguredLocalOrigin(config2),
3334
+ deviceName: snapshot.runtime?.deviceName ?? normalizeOptionalString3(config2.remote.deviceName) ?? hostname(),
3335
+ platformBase: snapshot.runtime?.platformBase ?? normalizeOptionalString3(config2.remote.platformApiBase) ?? normalizeOptionalString3(config2.providers.nextclaw?.apiBase) ?? null
3336
+ };
3337
+ }
3338
+ async status(opts = {}) {
3339
+ const view = this.getStatusView();
3180
3340
  if (opts.json) {
3181
- console.log(JSON.stringify(snapshot, null, 2));
3341
+ console.log(JSON.stringify(view, null, 2));
3182
3342
  return;
3183
3343
  }
3184
- const runtime2 = snapshot.runtime;
3344
+ const runtime2 = view.runtime;
3185
3345
  console.log("NextClaw Remote Status");
3186
- console.log(`Enabled: ${snapshot.configuredEnabled ? "yes" : "no"}`);
3346
+ console.log(`Enabled: ${view.configuredEnabled ? "yes" : "no"}`);
3187
3347
  console.log(`Mode: ${runtime2?.mode ?? "service"}`);
3188
3348
  console.log(`State: ${runtime2?.state ?? "disabled"}`);
3189
- console.log(`Device: ${runtime2?.deviceName ?? normalizeOptionalString3(config2.remote.deviceName) ?? hostname()}`);
3190
- console.log(
3191
- `Platform: ${runtime2?.platformBase ?? normalizeOptionalString3(config2.remote.platformApiBase) ?? normalizeOptionalString3(config2.providers.nextclaw?.apiBase) ?? "not set"}`
3192
- );
3193
- console.log(`Local origin: ${runtime2?.localOrigin ?? resolveConfiguredLocalOrigin(config2)}`);
3349
+ console.log(`Device: ${view.deviceName}`);
3350
+ console.log(`Platform: ${view.platformBase ?? "not set"}`);
3351
+ console.log(`Local origin: ${runtime2?.localOrigin ?? view.localOrigin}`);
3194
3352
  if (runtime2?.deviceId) {
3195
3353
  console.log(`Device ID: ${runtime2.deviceId}`);
3196
3354
  }
@@ -3201,7 +3359,7 @@ var RemoteCommands = class {
3201
3359
  console.log(`Last error: ${runtime2.lastError}`);
3202
3360
  }
3203
3361
  }
3204
- async doctor(opts = {}) {
3362
+ async getDoctorView() {
3205
3363
  const config2 = loadConfig9(getConfigPath4());
3206
3364
  const snapshot = resolveNextclawRemoteStatusSnapshot(config2);
3207
3365
  const localOrigin = resolveConfiguredLocalOrigin(config2);
@@ -3216,8 +3374,8 @@ var RemoteCommands = class {
3216
3374
  },
3217
3375
  {
3218
3376
  name: "platform-token",
3219
- ok: Boolean(token),
3220
- detail: token ? "token configured" : 'run "nextclaw login" first'
3377
+ ok: isPlatformSessionToken(token),
3378
+ detail: isPlatformSessionToken(token) ? "platform session token configured" : 'run remote browser login or "nextclaw login" first'
3221
3379
  },
3222
3380
  {
3223
3381
  name: "platform-api-base",
@@ -3235,12 +3393,20 @@ var RemoteCommands = class {
3235
3393
  detail: snapshot.runtime ? snapshot.runtime.state : "no managed remote runtime detected"
3236
3394
  }
3237
3395
  ];
3396
+ return {
3397
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3398
+ checks,
3399
+ snapshot
3400
+ };
3401
+ }
3402
+ async doctor(opts = {}) {
3403
+ const report = await this.getDoctorView();
3238
3404
  if (opts.json) {
3239
- console.log(JSON.stringify({ generatedAt: (/* @__PURE__ */ new Date()).toISOString(), checks, snapshot }, null, 2));
3405
+ console.log(JSON.stringify(report, null, 2));
3240
3406
  return;
3241
3407
  }
3242
3408
  console.log("NextClaw Remote Doctor");
3243
- for (const check of checks) {
3409
+ for (const check of report.checks) {
3244
3410
  console.log(`${check.ok ? "\u2713" : "\u2717"} ${check.name}: ${check.detail}`);
3245
3411
  }
3246
3412
  }
@@ -3642,7 +3808,7 @@ import {
3642
3808
  import { startUiServer } from "@nextclaw/server";
3643
3809
  import { appendFileSync, closeSync, cpSync as cpSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, openSync } from "fs";
3644
3810
  import { dirname as dirname2, join as join6, resolve as resolve10 } from "path";
3645
- import { spawn as spawn2 } from "child_process";
3811
+ import { spawn as spawn3 } from "child_process";
3646
3812
  import { request as httpRequest } from "http";
3647
3813
  import { request as httpsRequest } from "https";
3648
3814
  import { createServer as createNetServer2 } from "net";
@@ -3658,8 +3824,8 @@ import {
3658
3824
  redactConfigObject
3659
3825
  } from "@nextclaw/core";
3660
3826
  var hashRaw = (raw) => createHash("sha256").update(raw).digest("hex");
3661
- var readConfigSnapshot = (getConfigPath8) => {
3662
- const path2 = getConfigPath8();
3827
+ var readConfigSnapshot = (getConfigPath9) => {
3828
+ const path2 = getConfigPath9();
3663
3829
  let raw = "";
3664
3830
  let parsed = {};
3665
3831
  if (existsSync7(path2)) {
@@ -6368,6 +6534,325 @@ function writeReadyManagedServiceState(params) {
6368
6534
  return state;
6369
6535
  }
6370
6536
 
6537
+ // src/cli/commands/remote-access-host.ts
6538
+ import { getConfigPath as getConfigPath6, loadConfig as loadConfig13 } from "@nextclaw/core";
6539
+ import { spawn as spawn2 } from "child_process";
6540
+ var FORCED_PUBLIC_UI_HOST = "0.0.0.0";
6541
+ function normalizeOptionalString5(value) {
6542
+ if (typeof value !== "string") {
6543
+ return null;
6544
+ }
6545
+ const trimmed = value.trim();
6546
+ return trimmed.length > 0 ? trimmed : null;
6547
+ }
6548
+ function decodeJwtPayload(token) {
6549
+ const segments = token.split(".");
6550
+ if (segments.length < 2) {
6551
+ return null;
6552
+ }
6553
+ try {
6554
+ const raw = Buffer.from(segments[1], "base64url").toString("utf-8");
6555
+ const parsed = JSON.parse(raw);
6556
+ return typeof parsed === "object" && parsed !== null ? parsed : null;
6557
+ } catch {
6558
+ return null;
6559
+ }
6560
+ }
6561
+ function isPlatformSessionToken2(token) {
6562
+ return typeof token === "string" && token.startsWith("nca.");
6563
+ }
6564
+ function toRemoteRuntimeView(runtime2) {
6565
+ if (!runtime2) {
6566
+ return null;
6567
+ }
6568
+ return {
6569
+ enabled: runtime2.enabled,
6570
+ mode: runtime2.mode,
6571
+ state: runtime2.state,
6572
+ deviceId: runtime2.deviceId,
6573
+ deviceName: runtime2.deviceName,
6574
+ platformBase: runtime2.platformBase,
6575
+ localOrigin: runtime2.localOrigin,
6576
+ lastConnectedAt: runtime2.lastConnectedAt,
6577
+ lastError: runtime2.lastError,
6578
+ updatedAt: runtime2.updatedAt
6579
+ };
6580
+ }
6581
+ var RemoteAccessHost = class {
6582
+ constructor(deps) {
6583
+ this.deps = deps;
6584
+ }
6585
+ getStatus() {
6586
+ const config2 = loadConfig13(getConfigPath6());
6587
+ const status = this.deps.remoteCommands.getStatusView();
6588
+ const serviceState = readServiceState();
6589
+ const serviceRunning = Boolean(serviceState && isProcessRunning(serviceState.pid));
6590
+ const account = this.readAccountView({
6591
+ token: normalizeOptionalString5(config2.providers.nextclaw?.apiKey),
6592
+ apiBase: normalizeOptionalString5(config2.providers.nextclaw?.apiBase),
6593
+ platformBase: status.platformBase
6594
+ });
6595
+ const service = {
6596
+ running: serviceRunning,
6597
+ currentProcess: Boolean(serviceRunning && serviceState?.pid === process.pid),
6598
+ ...serviceState?.pid ? { pid: serviceState.pid } : {},
6599
+ ...serviceState?.uiUrl ? { uiUrl: serviceState.uiUrl } : {},
6600
+ ...typeof serviceState?.uiPort === "number" ? { uiPort: serviceState.uiPort } : {}
6601
+ };
6602
+ return {
6603
+ account,
6604
+ settings: {
6605
+ enabled: config2.remote.enabled,
6606
+ deviceName: config2.remote.deviceName,
6607
+ platformApiBase: config2.remote.platformApiBase
6608
+ },
6609
+ service,
6610
+ localOrigin: status.localOrigin,
6611
+ configuredEnabled: status.configuredEnabled,
6612
+ platformBase: status.platformBase,
6613
+ runtime: toRemoteRuntimeView(status.runtime)
6614
+ };
6615
+ }
6616
+ async login(input) {
6617
+ await this.deps.platformAuthCommands.loginResult(input);
6618
+ return this.getStatus();
6619
+ }
6620
+ async startBrowserAuth(input) {
6621
+ const result = await this.deps.platformAuthCommands.startBrowserAuth({
6622
+ apiBase: input.apiBase
6623
+ });
6624
+ return {
6625
+ sessionId: result.sessionId,
6626
+ verificationUri: result.verificationUri,
6627
+ expiresAt: result.expiresAt,
6628
+ intervalMs: result.intervalMs
6629
+ };
6630
+ }
6631
+ async pollBrowserAuth(input) {
6632
+ const config2 = loadConfig13(getConfigPath6());
6633
+ const result = await this.deps.platformAuthCommands.pollBrowserAuth({
6634
+ apiBase: normalizeOptionalString5(input.apiBase) ?? normalizeOptionalString5(config2.remote.platformApiBase) ?? normalizeOptionalString5(config2.providers.nextclaw?.apiBase) ?? void 0,
6635
+ sessionId: input.sessionId
6636
+ });
6637
+ if (result.status !== "authorized") {
6638
+ return result;
6639
+ }
6640
+ return {
6641
+ status: "authorized",
6642
+ email: result.email,
6643
+ role: result.role
6644
+ };
6645
+ }
6646
+ logout() {
6647
+ this.deps.platformAuthCommands.logout();
6648
+ return this.getStatus();
6649
+ }
6650
+ updateSettings(input) {
6651
+ this.deps.remoteCommands.updateConfig({
6652
+ enabled: input.enabled,
6653
+ apiBase: input.platformApiBase,
6654
+ name: input.deviceName
6655
+ });
6656
+ return this.getStatus();
6657
+ }
6658
+ async runDoctor() {
6659
+ const report = await this.deps.remoteCommands.getDoctorView();
6660
+ return {
6661
+ generatedAt: report.generatedAt,
6662
+ checks: report.checks,
6663
+ snapshot: {
6664
+ configuredEnabled: report.snapshot.configuredEnabled,
6665
+ runtime: toRemoteRuntimeView(report.snapshot.runtime)
6666
+ }
6667
+ };
6668
+ }
6669
+ async controlService(action) {
6670
+ const state = readServiceState();
6671
+ const running = Boolean(state && isProcessRunning(state.pid));
6672
+ const currentProcess = Boolean(running && state?.pid === process.pid);
6673
+ const uiOverrides = this.resolveManagedUiOverrides();
6674
+ if (action === "start") {
6675
+ if (running) {
6676
+ return {
6677
+ accepted: true,
6678
+ action,
6679
+ message: currentProcess ? "Managed service is already running for this UI." : "Managed service is already running."
6680
+ };
6681
+ }
6682
+ await this.deps.serviceCommands.startService({
6683
+ uiOverrides,
6684
+ open: false
6685
+ });
6686
+ return {
6687
+ accepted: true,
6688
+ action,
6689
+ message: "Managed service started."
6690
+ };
6691
+ }
6692
+ if (!running) {
6693
+ if (action === "restart") {
6694
+ await this.deps.serviceCommands.startService({
6695
+ uiOverrides,
6696
+ open: false
6697
+ });
6698
+ return {
6699
+ accepted: true,
6700
+ action,
6701
+ message: "Managed service was not running and has been started."
6702
+ };
6703
+ }
6704
+ return {
6705
+ accepted: true,
6706
+ action,
6707
+ message: "No managed service is currently running."
6708
+ };
6709
+ }
6710
+ if (currentProcess) {
6711
+ if (action === "restart") {
6712
+ await this.deps.requestManagedServiceRestart({
6713
+ uiPort: uiOverrides.port ?? 18791
6714
+ });
6715
+ } else {
6716
+ this.scheduleSelfStop();
6717
+ }
6718
+ return {
6719
+ accepted: true,
6720
+ action,
6721
+ message: action === "restart" ? "Restart scheduled. This page may disconnect for a few seconds." : "Stop scheduled. This page will disconnect shortly."
6722
+ };
6723
+ }
6724
+ if (action === "stop") {
6725
+ await this.deps.serviceCommands.stopService();
6726
+ return {
6727
+ accepted: true,
6728
+ action,
6729
+ message: "Managed service stopped."
6730
+ };
6731
+ }
6732
+ await this.deps.serviceCommands.stopService();
6733
+ await this.deps.serviceCommands.startService({
6734
+ uiOverrides,
6735
+ open: false
6736
+ });
6737
+ return {
6738
+ accepted: true,
6739
+ action,
6740
+ message: "Managed service restarted."
6741
+ };
6742
+ }
6743
+ resolveManagedUiOverrides() {
6744
+ const config2 = loadConfig13(getConfigPath6());
6745
+ const resolved = resolveUiConfig(config2, {
6746
+ enabled: true,
6747
+ host: FORCED_PUBLIC_UI_HOST,
6748
+ open: false
6749
+ });
6750
+ return {
6751
+ enabled: true,
6752
+ host: FORCED_PUBLIC_UI_HOST,
6753
+ open: false,
6754
+ port: resolved.port
6755
+ };
6756
+ }
6757
+ readAccountView(params) {
6758
+ if (!isPlatformSessionToken2(params.token)) {
6759
+ return {
6760
+ loggedIn: false,
6761
+ apiBase: params.apiBase,
6762
+ platformBase: params.platformBase
6763
+ };
6764
+ }
6765
+ const payload = decodeJwtPayload(params.token);
6766
+ const email = typeof payload?.email === "string" ? payload.email : void 0;
6767
+ const role = typeof payload?.role === "string" ? payload.role : void 0;
6768
+ return {
6769
+ loggedIn: true,
6770
+ email,
6771
+ role,
6772
+ apiBase: params.apiBase,
6773
+ platformBase: params.platformBase
6774
+ };
6775
+ }
6776
+ scheduleSelfStop() {
6777
+ this.launchManagedSelfControl();
6778
+ }
6779
+ launchManagedSelfControl(params = {}) {
6780
+ const script = [
6781
+ 'const { spawn } = require("node:child_process");',
6782
+ 'const { rmSync } = require("node:fs");',
6783
+ `const parentPid = ${process.pid};`,
6784
+ `const serviceStatePath = ${JSON.stringify(resolveServiceStatePath())};`,
6785
+ `const command = ${JSON.stringify(params.command ?? null)};`,
6786
+ `const args = ${JSON.stringify(params.args ?? [])};`,
6787
+ `const cwd = ${JSON.stringify(process.cwd())};`,
6788
+ "const env = process.env;",
6789
+ "function isRunning(pid) {",
6790
+ " try {",
6791
+ " process.kill(pid, 0);",
6792
+ " return true;",
6793
+ " } catch {",
6794
+ " return false;",
6795
+ " }",
6796
+ "}",
6797
+ "setTimeout(() => {",
6798
+ " try {",
6799
+ " process.kill(parentPid, 'SIGTERM');",
6800
+ " } catch {}",
6801
+ "}, 150);",
6802
+ "const startedAt = Date.now();",
6803
+ "const maxWaitMs = 30000;",
6804
+ "const timer = setInterval(() => {",
6805
+ " if (isRunning(parentPid)) {",
6806
+ " if (Date.now() - startedAt > maxWaitMs) {",
6807
+ " try {",
6808
+ " process.kill(parentPid, 'SIGKILL');",
6809
+ " } catch {}",
6810
+ " }",
6811
+ " return;",
6812
+ " }",
6813
+ " clearInterval(timer);",
6814
+ " try {",
6815
+ " rmSync(serviceStatePath, { force: true });",
6816
+ " } catch {}",
6817
+ " if (command) {",
6818
+ " const child = spawn(command, args, { detached: true, stdio: 'ignore', cwd, env });",
6819
+ " child.unref();",
6820
+ " }",
6821
+ " process.exit(0);",
6822
+ "}, 250);"
6823
+ ].join("");
6824
+ const helper = spawn2(process.execPath, ["-e", script], {
6825
+ detached: true,
6826
+ stdio: "ignore",
6827
+ env: process.env,
6828
+ cwd: process.cwd()
6829
+ });
6830
+ helper.unref();
6831
+ }
6832
+ };
6833
+
6834
+ // src/cli/commands/service-remote-access.ts
6835
+ function requestManagedServiceRestart(requestRestart, options = {}) {
6836
+ const uiPort = typeof options.uiPort === "number" && Number.isFinite(options.uiPort) ? Math.floor(options.uiPort) : void 0;
6837
+ const reason = options.reason?.trim() || "remote access service restart";
6838
+ const manualMessage = uiPort ? `Restart the managed service to restore the UI on port ${uiPort}.` : "Restart the managed service to restore the UI.";
6839
+ return requestRestart({
6840
+ reason,
6841
+ manualMessage,
6842
+ strategy: "background-service-or-exit",
6843
+ delayMs: 500,
6844
+ silentOnServiceRestart: true
6845
+ });
6846
+ }
6847
+ function createRemoteAccessHost(params) {
6848
+ return new RemoteAccessHost({
6849
+ serviceCommands: params.serviceCommands,
6850
+ requestManagedServiceRestart: (options) => requestManagedServiceRestart(params.requestRestart, options),
6851
+ remoteCommands: new RemoteCommands(),
6852
+ platformAuthCommands: new PlatformAuthCommands()
6853
+ });
6854
+ }
6855
+
6371
6856
  // src/cli/commands/ui-chat-run-coordinator.ts
6372
6857
  import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
6373
6858
  import { join as join5 } from "path";
@@ -6992,14 +7477,14 @@ var {
6992
7477
  ChannelManager: ChannelManager2,
6993
7478
  CronService: CronService2,
6994
7479
  getApiBase,
6995
- getConfigPath: getConfigPath6,
7480
+ getConfigPath: getConfigPath7,
6996
7481
  getDataDir: getDataDir7,
6997
7482
  getProvider,
6998
7483
  getProviderName,
6999
7484
  getWorkspacePath: getWorkspacePath9,
7000
7485
  HeartbeatService,
7001
7486
  LiteLLMProvider,
7002
- loadConfig: loadConfig13,
7487
+ loadConfig: loadConfig14,
7003
7488
  MessageBus,
7004
7489
  ProviderManager,
7005
7490
  resolveConfigSecrets: resolveConfigSecrets2,
@@ -7023,8 +7508,8 @@ var ServiceCommands = class {
7023
7508
  async startGateway(options = {}) {
7024
7509
  this.applyLiveConfigReload = null;
7025
7510
  this.liveUiNcpAgent = null;
7026
- const runtimeConfigPath = getConfigPath6();
7027
- const config2 = resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath });
7511
+ const runtimeConfigPath = getConfigPath7();
7512
+ const config2 = resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath });
7028
7513
  const workspace = getWorkspacePath9(config2.agents.defaults.workspace);
7029
7514
  let pluginRegistry = loadPluginRegistry(config2, workspace);
7030
7515
  let extensionRegistry = toExtensionRegistry(pluginRegistry);
@@ -7053,7 +7538,7 @@ var ServiceCommands = class {
7053
7538
  sessionManager,
7054
7539
  providerManager,
7055
7540
  makeProvider: (nextConfig) => this.makeProvider(nextConfig, { allowMissing: true }) ?? this.makeMissingProvider(nextConfig),
7056
- loadConfig: () => resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }),
7541
+ loadConfig: () => resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7057
7542
  getExtensionChannels: () => extensionRegistry.channels,
7058
7543
  onRestartRequired: (paths) => {
7059
7544
  void this.deps.requestRestart({
@@ -7064,13 +7549,13 @@ var ServiceCommands = class {
7064
7549
  }
7065
7550
  });
7066
7551
  this.applyLiveConfigReload = async () => {
7067
- await reloader.applyReloadPlan(resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }));
7552
+ await reloader.applyReloadPlan(resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }));
7068
7553
  };
7069
7554
  const gatewayController = new GatewayControllerImpl({
7070
7555
  reloader,
7071
7556
  cron: cron2,
7072
7557
  sessionManager,
7073
- getConfigPath: getConfigPath6,
7558
+ getConfigPath: getConfigPath7,
7074
7559
  saveConfig: saveConfig9,
7075
7560
  requestRestart: async (options2) => {
7076
7561
  await this.deps.requestRestart({
@@ -7097,7 +7582,7 @@ var ServiceCommands = class {
7097
7582
  resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
7098
7583
  registry: pluginRegistry,
7099
7584
  channel,
7100
- cfg: resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }),
7585
+ cfg: resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7101
7586
  accountId
7102
7587
  })
7103
7588
  });
@@ -7130,12 +7615,12 @@ var ServiceCommands = class {
7130
7615
  });
7131
7616
  let pluginChannelBindings = getPluginChannelBindings3(pluginRegistry);
7132
7617
  setPluginRuntimeBridge({
7133
- loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }), pluginChannelBindings),
7618
+ loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }), pluginChannelBindings),
7134
7619
  writeConfigFile: async (nextConfigView) => {
7135
7620
  if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
7136
7621
  throw new Error("plugin runtime writeConfigFile expects an object config");
7137
7622
  }
7138
- const current = loadConfig13();
7623
+ const current = loadConfig14();
7139
7624
  const next = mergePluginConfigView(current, nextConfigView, pluginChannelBindings);
7140
7625
  saveConfig9(next);
7141
7626
  },
@@ -7211,12 +7696,12 @@ var ServiceCommands = class {
7211
7696
  providerManager,
7212
7697
  bus,
7213
7698
  gatewayController,
7214
- () => resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }),
7699
+ () => resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7215
7700
  () => extensionRegistry,
7216
7701
  ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
7217
7702
  registry: pluginRegistry,
7218
7703
  channel,
7219
- cfg: resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }),
7704
+ cfg: resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7220
7705
  accountId
7221
7706
  })
7222
7707
  );
@@ -7254,7 +7739,7 @@ var ServiceCommands = class {
7254
7739
  return trimmed || void 0;
7255
7740
  }
7256
7741
  watchConfigFile(reloader) {
7257
- const configPath = resolve10(getConfigPath6());
7742
+ const configPath = resolve10(getConfigPath7());
7258
7743
  const watcher = chokidar.watch(configPath, {
7259
7744
  ignoreInitial: true,
7260
7745
  awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
@@ -7375,7 +7860,7 @@ var ServiceCommands = class {
7375
7860
  });
7376
7861
  }
7377
7862
  async runForeground(options) {
7378
- const config2 = loadConfig13();
7863
+ const config2 = loadConfig14();
7379
7864
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7380
7865
  const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
7381
7866
  if (options.open) {
@@ -7388,7 +7873,7 @@ var ServiceCommands = class {
7388
7873
  });
7389
7874
  }
7390
7875
  async startService(options) {
7391
- const config2 = loadConfig13();
7876
+ const config2 = loadConfig14();
7392
7877
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7393
7878
  const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
7394
7879
  const apiUrl = `${uiUrl}/api`;
@@ -7461,7 +7946,7 @@ var ServiceCommands = class {
7461
7946
  console.log(`Starting ${APP_NAME3} background service (readiness timeout ${Math.ceil(readinessTimeoutMs / 1e3)}s)...`);
7462
7947
  const serveArgs = buildServeArgs({ uiPort: uiConfig.port });
7463
7948
  this.appendStartupStage(logPath, `spawning background process: ${process.execPath} ${[...process.execArgv, ...serveArgs].join(" ")}`);
7464
- const child = spawn2(process.execPath, [...process.execArgv, ...serveArgs], {
7949
+ const child = spawn3(process.execPath, [...process.execArgv, ...serveArgs], {
7465
7950
  env: process.env,
7466
7951
  stdio: ["ignore", logFd, logFd],
7467
7952
  detached: true
@@ -7796,7 +8281,7 @@ var ServiceCommands = class {
7796
8281
  return null;
7797
8282
  }
7798
8283
  console.error("Error: No API key configured.");
7799
- console.error(`Set one in ${getConfigPath6()} under providers section`);
8284
+ console.error(`Set one in ${getConfigPath7()} under providers section`);
7800
8285
  process.exit(1);
7801
8286
  }
7802
8287
  return new LiteLLMProvider({
@@ -7909,10 +8394,7 @@ var ServiceCommands = class {
7909
8394
  gatewayController,
7910
8395
  getConfig,
7911
8396
  getExtensionRegistry,
7912
- resolveMessageToolHints: ({ channel, accountId }) => resolveMessageToolHints({
7913
- channel,
7914
- accountId
7915
- })
8397
+ resolveMessageToolHints: ({ channel, accountId }) => resolveMessageToolHints({ channel, accountId })
7916
8398
  });
7917
8399
  this.liveUiNcpAgent = ncpAgent;
7918
8400
  const marketplaceInstaller = new ServiceMarketplaceInstaller({
@@ -7920,10 +8402,11 @@ var ServiceCommands = class {
7920
8402
  runCliSubcommand: (args) => this.runCliSubcommand(args),
7921
8403
  installBuiltinSkill: (slug, force) => this.installBuiltinMarketplaceSkill(slug, force)
7922
8404
  }).createInstaller();
8405
+ const remoteAccess = createRemoteAccessHost({ serviceCommands: this, requestRestart: this.deps.requestRestart });
7923
8406
  const uiServer = startUiServer({
7924
8407
  host: uiConfig.host,
7925
8408
  port: uiConfig.port,
7926
- configPath: getConfigPath6(),
8409
+ configPath: getConfigPath7(),
7927
8410
  productVersion: getPackageVersion(),
7928
8411
  staticDir: uiStaticDir ?? void 0,
7929
8412
  cronService,
@@ -7931,6 +8414,7 @@ var ServiceCommands = class {
7931
8414
  apiBaseUrl: process.env.NEXTCLAW_MARKETPLACE_API_BASE,
7932
8415
  installer: marketplaceInstaller
7933
8416
  },
8417
+ remoteAccess,
7934
8418
  ncpAgent,
7935
8419
  chatRuntime: {
7936
8420
  listSessionTypes: async () => {
@@ -8011,7 +8495,7 @@ var ServiceCommands = class {
8011
8495
  }
8012
8496
  }
8013
8497
  installBuiltinMarketplaceSkill(slug, force) {
8014
- const workspace = getWorkspacePath9(loadConfig13().agents.defaults.workspace);
8498
+ const workspace = getWorkspacePath9(loadConfig14().agents.defaults.workspace);
8015
8499
  const destination = join6(workspace, "skills", slug);
8016
8500
  const destinationSkillFile = join6(destination, "SKILL.md");
8017
8501
  if (existsSync10(destinationSkillFile) && !force) {
@@ -8052,7 +8536,7 @@ ${stderr}`.trim();
8052
8536
  runCommand(command, args, options = {}) {
8053
8537
  const timeoutMs = options.timeoutMs ?? 18e4;
8054
8538
  return new Promise((resolvePromise, rejectPromise) => {
8055
- const child = spawn2(command, args, {
8539
+ const child = spawn3(command, args, {
8056
8540
  cwd: options.cwd ?? process.cwd(),
8057
8541
  env: process.env,
8058
8542
  stdio: ["ignore", "pipe", "pipe"]
@@ -8270,7 +8754,7 @@ var WorkspaceManager = class {
8270
8754
  // src/cli/runtime.ts
8271
8755
  var LOGO = "\u{1F916}";
8272
8756
  var EXIT_COMMANDS = /* @__PURE__ */ new Set(["exit", "quit", "/exit", "/quit", ":q"]);
8273
- var FORCED_PUBLIC_UI_HOST = "0.0.0.0";
8757
+ var FORCED_PUBLIC_UI_HOST2 = "0.0.0.0";
8274
8758
  function resolveSkillsInstallWorkdir(params) {
8275
8759
  if (params.explicitWorkdir) {
8276
8760
  return expandHome2(params.explicitWorkdir);
@@ -8350,7 +8834,7 @@ var CliRuntime = class {
8350
8834
  if (!state || !isProcessRunning(state.pid) || state.pid === process.pid) {
8351
8835
  return false;
8352
8836
  }
8353
- const uiHost = FORCED_PUBLIC_UI_HOST;
8837
+ const uiHost = FORCED_PUBLIC_UI_HOST2;
8354
8838
  const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
8355
8839
  console.log(
8356
8840
  `Applying changes (${reason}): restarting ${APP_NAME5} background service...`
@@ -8447,7 +8931,7 @@ var CliRuntime = class {
8447
8931
  "}, delayMs);"
8448
8932
  ].join("\n");
8449
8933
  try {
8450
- const helper = spawn3(process.execPath, ["-e", helperScript], {
8934
+ const helper = spawn4(process.execPath, ["-e", helperScript], {
8451
8935
  detached: true,
8452
8936
  stdio: "ignore",
8453
8937
  env: process.env
@@ -8516,14 +9000,14 @@ var CliRuntime = class {
8516
9000
  const source = options.source ?? "init";
8517
9001
  const prefix = options.auto ? "Auto init" : "Init";
8518
9002
  const force = Boolean(options.force);
8519
- const configPath = getConfigPath7();
9003
+ const configPath = getConfigPath8();
8520
9004
  let createdConfig = false;
8521
9005
  if (!existsSync12(configPath)) {
8522
9006
  const config3 = ConfigSchema2.parse({});
8523
9007
  saveConfig10(config3);
8524
9008
  createdConfig = true;
8525
9009
  }
8526
- const config2 = loadConfig14();
9010
+ const config2 = loadConfig15();
8527
9011
  const workspaceSetting = config2.agents.defaults.workspace;
8528
9012
  const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir9(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
8529
9013
  const workspaceExisted = existsSync12(workspacePath);
@@ -8562,7 +9046,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8562
9046
  }
8563
9047
  async gateway(opts) {
8564
9048
  const uiOverrides = {
8565
- host: FORCED_PUBLIC_UI_HOST
9049
+ host: FORCED_PUBLIC_UI_HOST2
8566
9050
  };
8567
9051
  if (opts.ui) {
8568
9052
  uiOverrides.enabled = true;
@@ -8578,7 +9062,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8578
9062
  async ui(opts) {
8579
9063
  const uiOverrides = {
8580
9064
  enabled: true,
8581
- host: FORCED_PUBLIC_UI_HOST,
9065
+ host: FORCED_PUBLIC_UI_HOST2,
8582
9066
  open: Boolean(opts.open)
8583
9067
  };
8584
9068
  if (opts.port) {
@@ -8594,7 +9078,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8594
9078
  await this.init({ source: "start", auto: true });
8595
9079
  const uiOverrides = {
8596
9080
  enabled: true,
8597
- host: FORCED_PUBLIC_UI_HOST,
9081
+ host: FORCED_PUBLIC_UI_HOST2,
8598
9082
  open: false
8599
9083
  };
8600
9084
  if (opts.uiPort) {
@@ -8623,7 +9107,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8623
9107
  async serve(opts) {
8624
9108
  const uiOverrides = {
8625
9109
  enabled: true,
8626
- host: FORCED_PUBLIC_UI_HOST,
9110
+ host: FORCED_PUBLIC_UI_HOST2,
8627
9111
  open: false
8628
9112
  };
8629
9113
  if (opts.uiPort) {
@@ -8649,8 +9133,8 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8649
9133
  await this.serviceCommands.stopService();
8650
9134
  }
8651
9135
  async agent(opts) {
8652
- const configPath = getConfigPath7();
8653
- const config2 = resolveConfigSecrets3(loadConfig14(), { configPath });
9136
+ const configPath = getConfigPath8();
9137
+ const config2 = resolveConfigSecrets3(loadConfig15(), { configPath });
8654
9138
  const workspace = getWorkspacePath10(config2.agents.defaults.workspace);
8655
9139
  const pluginRegistry = loadPluginRegistry(config2, workspace);
8656
9140
  const extensionRegistry = toExtensionRegistry(pluginRegistry);
@@ -8658,7 +9142,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8658
9142
  const pluginChannelBindings = getPluginChannelBindings4(pluginRegistry);
8659
9143
  setPluginRuntimeBridge2({
8660
9144
  loadConfig: () => toPluginConfigView(
8661
- resolveConfigSecrets3(loadConfig14(), { configPath }),
9145
+ resolveConfigSecrets3(loadConfig15(), { configPath }),
8662
9146
  pluginChannelBindings
8663
9147
  ),
8664
9148
  writeConfigFile: async (nextConfigView) => {
@@ -8667,7 +9151,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8667
9151
  "plugin runtime writeConfigFile expects an object config"
8668
9152
  );
8669
9153
  }
8670
- const current = loadConfig14();
9154
+ const current = loadConfig15();
8671
9155
  const next = mergePluginConfigView(
8672
9156
  current,
8673
9157
  nextConfigView,
@@ -8699,7 +9183,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8699
9183
  resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
8700
9184
  registry: pluginRegistry,
8701
9185
  channel,
8702
- cfg: resolveConfigSecrets3(loadConfig14(), { configPath }),
9186
+ cfg: resolveConfigSecrets3(loadConfig15(), { configPath }),
8703
9187
  accountId
8704
9188
  })
8705
9189
  });
@@ -8894,7 +9378,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
8894
9378
  await this.diagnosticsCommands.doctor(opts);
8895
9379
  }
8896
9380
  async skillsInstall(options) {
8897
- const config2 = loadConfig14();
9381
+ const config2 = loadConfig15();
8898
9382
  const workdir = resolveSkillsInstallWorkdir({
8899
9383
  explicitWorkdir: options.workdir,
8900
9384
  configuredWorkspace: config2.agents.defaults.workspace