@nextclaw/service 0.1.4 → 0.1.6

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 (33) hide show
  1. package/dist/cli/commands/diagnostics/services/diagnostics-commands.service.js +1 -1
  2. package/dist/commands/remote/index.d.ts +1 -1
  3. package/dist/commands/remote/index.js +1 -1
  4. package/dist/commands/remote/{services/remote-runtime-support.service.d.ts → utils/remote-runtime-support.utils.d.ts} +2 -2
  5. package/dist/commands/remote/{services/remote-runtime-support.service.js → utils/remote-runtime-support.utils.js} +4 -3
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.js +2 -1
  8. package/dist/launcher/npm-runtime-update-command.service.d.ts +1 -7
  9. package/dist/launcher/npm-runtime-update-command.service.js +4 -7
  10. package/dist/service-runtime.service.d.ts +2 -9
  11. package/dist/service-runtime.service.js +9 -15
  12. package/dist/shared/services/gateway/managers/gateway-remote.manager.d.ts +5 -3
  13. package/dist/shared/services/gateway/managers/gateway-remote.manager.js +3 -2
  14. package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.d.ts +4 -2
  15. package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.js +8 -9
  16. package/dist/shared/services/gateway/{service-bootstrap-status.d.ts → service-bootstrap-status.service.d.ts} +3 -4
  17. package/dist/shared/services/gateway/{service-bootstrap-status.js → service-bootstrap-status.service.js} +5 -15
  18. package/dist/shared/services/gateway/utils/gateway-runtime-lifecycle.utils.d.ts +1 -1
  19. package/dist/shared/services/runtime/nextclaw-distribution.service.d.ts +10 -0
  20. package/dist/shared/services/runtime/nextclaw-distribution.service.js +13 -0
  21. package/dist/shared/services/runtime/runtime-command.service.js +5 -3
  22. package/dist/shared/services/runtime/service-managed-startup.service.d.ts +1 -0
  23. package/dist/shared/services/runtime/service-managed-startup.service.js +4 -4
  24. package/dist/shared/services/runtime/{service-remote-runtime.service.d.ts → utils/service-remote-runtime.utils.d.ts} +5 -3
  25. package/dist/shared/services/runtime/{service-remote-runtime.service.js → utils/service-remote-runtime.utils.js} +6 -5
  26. package/dist/shared/services/ui/npm-runtime-update-host.service.js +23 -17
  27. package/dist/shared/types/distribution.types.d.ts +10 -0
  28. package/dist/shared/types/distribution.types.js +1 -0
  29. package/dist/shared/utils/cli.utils.d.ts +2 -5
  30. package/dist/shared/utils/cli.utils.js +5 -16
  31. package/dist/shared/utils/package/package-manifest.utils.d.ts +1 -5
  32. package/dist/shared/utils/package/package-manifest.utils.js +8 -18
  33. package/package.json +18 -18
@@ -1,6 +1,6 @@
1
1
  import { isProcessRunning, resolveUiApiBase, resolveUiConfig } from "../../../../shared/utils/cli.utils.js";
2
2
  import { managedServiceStateStore } from "../../../../shared/stores/managed-service-state.store.js";
3
- import { resolveNextclawRemoteStatusSnapshot } from "../../../../commands/remote/services/remote-runtime-support.service.js";
3
+ import { resolveNextclawRemoteStatusSnapshot } from "../../../../commands/remote/utils/remote-runtime-support.utils.js";
4
4
  import "../../../../commands/remote/index.js";
5
5
  import { printDoctorReport, printStatusReport } from "../utils/diagnostics-render.utils.js";
6
6
  import { APP_NAME, getConfigPath, getWorkspacePath, hasSecretRef, loadConfig, resolveAppLogPath } from "@nextclaw/core";
@@ -1,4 +1,4 @@
1
- import { buildNextclawConfiguredRemoteState, createNextclawRemoteConnector, createNextclawRemoteStatusStore, hasRunningNextclawManagedService, resolveNextclawRemoteStatusSnapshot } from "./services/remote-runtime-support.service.js";
1
+ import { buildNextclawConfiguredRemoteState, createNextclawRemoteConnector, createNextclawRemoteStatusStore, hasRunningNextclawManagedService, resolveNextclawRemoteStatusSnapshot } from "./utils/remote-runtime-support.utils.js";
2
2
  import { buildPlatformApiBaseErrorMessage, resolvePlatformApiBase } from "./utils/platform-api-base.utils.js";
3
3
  import { Config } from "@nextclaw/core";
4
4
  import { RemoteConnectCommandOptions, RemoteDoctorCommandOptions, RemoteEnableCommandOptions, RemoteStatusCommandOptions, RemoteStatusSnapshot } from "@nextclaw/remote";
@@ -1,6 +1,6 @@
1
1
  import { localUiDiscoveryService } from "../../shared/services/ui/local-ui-discovery.service.js";
2
2
  import { buildPlatformApiBaseErrorMessage, resolvePlatformApiBase } from "./utils/platform-api-base.utils.js";
3
- import { buildNextclawConfiguredRemoteState, createNextclawRemoteConnector, createNextclawRemoteStatusStore, hasRunningNextclawManagedService, resolveNextclawRemoteStatusSnapshot } from "./services/remote-runtime-support.service.js";
3
+ import { buildNextclawConfiguredRemoteState, createNextclawRemoteConnector, createNextclawRemoteStatusStore, hasRunningNextclawManagedService, resolveNextclawRemoteStatusSnapshot } from "./utils/remote-runtime-support.utils.js";
4
4
  import { getConfigPath, loadConfig, saveConfig } from "@nextclaw/core";
5
5
  import { readPlatformSessionTokenState } from "@nextclaw/remote";
6
6
  import { hostname } from "node:os";
@@ -1,13 +1,13 @@
1
1
  import { Config } from "@nextclaw/core";
2
2
  import { RemoteConnector, RemoteLogger, RemotePlatformClient, RemoteRuntimeState, RemoteStatusSnapshot, RemoteStatusStore } from "@nextclaw/remote";
3
3
 
4
- //#region src/commands/remote/services/remote-runtime-support.service.d.ts
4
+ //#region src/commands/remote/utils/remote-runtime-support.utils.d.ts
5
5
  declare function hasRunningNextclawManagedService(): boolean;
6
6
  declare function createNextclawRemotePlatformClient(): RemotePlatformClient;
7
7
  declare function createNextclawRemoteConnector(params?: {
8
8
  logger?: RemoteLogger;
9
9
  }): RemoteConnector;
10
- declare function createNextclawRemoteStatusStore(mode: RemoteRuntimeState["mode"]): RemoteStatusStore;
10
+ declare function createNextclawRemoteStatusStore(mode: RemoteRuntimeState["mode"], onChange?: (next: RemoteRuntimeState) => void): RemoteStatusStore;
11
11
  declare function buildNextclawConfiguredRemoteState(config: Config): RemoteRuntimeState;
12
12
  declare function readCurrentNextclawRemoteRuntimeState(): RemoteRuntimeState | null;
13
13
  declare function resolveNextclawRemoteStatusSnapshot(config: Config): RemoteStatusSnapshot;
@@ -2,10 +2,10 @@ import { getPackageVersion as getPackageVersion$1 } from "../../../shared/utils/
2
2
  import { isProcessRunning } from "../../../shared/utils/cli.utils.js";
3
3
  import { localUiRuntimeStore } from "../../../shared/stores/local-ui-runtime.store.js";
4
4
  import { managedServiceStateStore } from "../../../shared/stores/managed-service-state.store.js";
5
- import { resolvePlatformApiBase } from "../utils/platform-api-base.utils.js";
5
+ import { resolvePlatformApiBase } from "./platform-api-base.utils.js";
6
6
  import { getConfigPath, getDataDir, loadConfig } from "@nextclaw/core";
7
7
  import { RemoteConnector, RemotePlatformClient, RemoteStatusStore, buildConfiguredRemoteState, resolveRemoteStatusSnapshot } from "@nextclaw/remote";
8
- //#region src/commands/remote/services/remote-runtime-support.service.ts
8
+ //#region src/commands/remote/utils/remote-runtime-support.utils.ts
9
9
  let currentProcessRemoteRuntimeState = null;
10
10
  function hasRunningNextclawManagedService() {
11
11
  const state = managedServiceStateStore.read();
@@ -37,9 +37,10 @@ function createNextclawRemoteConnector(params = {}) {
37
37
  logger: params.logger
38
38
  });
39
39
  }
40
- function createNextclawRemoteStatusStore(mode) {
40
+ function createNextclawRemoteStatusStore(mode, onChange) {
41
41
  return new RemoteStatusStore(mode, { writeRemoteState: (next) => {
42
42
  currentProcessRemoteRuntimeState = next;
43
+ onChange?.(next);
43
44
  if (localUiRuntimeStore.read()?.pid === process.pid) localUiRuntimeStore.update((state) => ({
44
45
  ...state,
45
46
  remote: next
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsLoginOptions, CompanionDisableCommandOptions, CompanionEnableCommandOptions, CompanionStartCommandOptions, CompanionStatusCommandOptions, CompanionStopCommandOptions, ConfigGetOptions, ConfigSetOptions, CronAddOptions, DoctorCommandOptions, GatewayCommandOptions, HealthProbe, LoginCommandOptions, LogsTailCommandOptions, MarketplaceSkillsRecommendCommandOptions, MarketplaceSkillsSearchCommandOptions, McpAddCommandOptions, McpDoctorOptions, McpListOptions, PluginsInfoOptions, PluginsInstallOptions, PluginsListOptions, PluginsUninstallOptions, RemoteConnectCommandOptions, RemoteDoctorCommandOptions, RemoteEnableCommandOptions, RemoteStatusCommandOptions, RequestRestartParams, RuntimeStatusReport, SecretsApplyOptions, SecretsAuditOptions, SecretsConfigureOptions, SecretsReloadOptions, ServiceAutostartCommandOptions, SkillsInfoCommandOptions, SkillsInstalledCommandOptions, StartCommandOptions, StatusCommandOptions, UiCommandOptions, UpdateCommandOptions, UsageCommandOptions } from "./shared/types/cli.types.js";
2
2
  import { NextclawServiceRuntime, NextclawServiceRuntimeOptions, runNextclawNpmRuntimeLauncher } from "./service-runtime.service.js";
3
+ import { NextclawDistribution } from "./shared/types/distribution.types.js";
4
+ import { NextclawDistributionService } from "./shared/services/runtime/nextclaw-distribution.service.js";
3
5
  import { readLearningLoopRuntimeConfig } from "@nextclaw/kernel";
4
- export { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsLoginOptions, CompanionDisableCommandOptions, CompanionEnableCommandOptions, CompanionStartCommandOptions, CompanionStatusCommandOptions, CompanionStopCommandOptions, ConfigGetOptions, ConfigSetOptions, CronAddOptions, DoctorCommandOptions, GatewayCommandOptions, HealthProbe, LoginCommandOptions, LogsTailCommandOptions, MarketplaceSkillsRecommendCommandOptions, MarketplaceSkillsSearchCommandOptions, McpAddCommandOptions, McpDoctorOptions, McpListOptions, NextclawServiceRuntime, type NextclawServiceRuntimeOptions, PluginsInfoOptions, PluginsInstallOptions, PluginsListOptions, PluginsUninstallOptions, RemoteConnectCommandOptions, RemoteDoctorCommandOptions, RemoteEnableCommandOptions, RemoteStatusCommandOptions, RequestRestartParams, RuntimeStatusReport, SecretsApplyOptions, SecretsAuditOptions, SecretsConfigureOptions, SecretsReloadOptions, ServiceAutostartCommandOptions, SkillsInfoCommandOptions, SkillsInstalledCommandOptions, StartCommandOptions, StatusCommandOptions, UiCommandOptions, UpdateCommandOptions, UsageCommandOptions, readLearningLoopRuntimeConfig, runNextclawNpmRuntimeLauncher };
6
+ export { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsLoginOptions, CompanionDisableCommandOptions, CompanionEnableCommandOptions, CompanionStartCommandOptions, CompanionStatusCommandOptions, CompanionStopCommandOptions, ConfigGetOptions, ConfigSetOptions, CronAddOptions, DoctorCommandOptions, GatewayCommandOptions, HealthProbe, LoginCommandOptions, LogsTailCommandOptions, MarketplaceSkillsRecommendCommandOptions, MarketplaceSkillsSearchCommandOptions, McpAddCommandOptions, McpDoctorOptions, McpListOptions, type NextclawDistribution, NextclawDistributionService, NextclawServiceRuntime, type NextclawServiceRuntimeOptions, PluginsInfoOptions, PluginsInstallOptions, PluginsListOptions, PluginsUninstallOptions, RemoteConnectCommandOptions, RemoteDoctorCommandOptions, RemoteEnableCommandOptions, RemoteStatusCommandOptions, RequestRestartParams, RuntimeStatusReport, SecretsApplyOptions, SecretsAuditOptions, SecretsConfigureOptions, SecretsReloadOptions, ServiceAutostartCommandOptions, SkillsInfoCommandOptions, SkillsInstalledCommandOptions, StartCommandOptions, StatusCommandOptions, UiCommandOptions, UpdateCommandOptions, UsageCommandOptions, readLearningLoopRuntimeConfig, runNextclawNpmRuntimeLauncher };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { NextclawDistributionService } from "./shared/services/runtime/nextclaw-distribution.service.js";
1
2
  import { NextclawServiceRuntime, runNextclawNpmRuntimeLauncher } from "./service-runtime.service.js";
2
3
  import { readLearningLoopRuntimeConfig } from "@nextclaw/kernel";
3
- export { NextclawServiceRuntime, readLearningLoopRuntimeConfig, runNextclawNpmRuntimeLauncher };
4
+ export { NextclawDistributionService, NextclawServiceRuntime, readLearningLoopRuntimeConfig, runNextclawNpmRuntimeLauncher };
@@ -1,14 +1,8 @@
1
1
  import { UpdateCommandOptions } from "../shared/types/cli.types.js";
2
- import { UpdateSnapshot } from "@nextclaw/kernel/update-contract";
2
+ import { UpdateSnapshot } from "@nextclaw/kernel";
3
3
 
4
4
  //#region src/launcher/npm-runtime-update-command.service.d.ts
5
- type NpmRuntimeUpdateCommandServiceOptions = {
6
- launcherVersion?: string;
7
- packagedPublicKeyPath?: string;
8
- };
9
5
  declare class NpmRuntimeUpdateCommandService {
10
- private readonly options;
11
- constructor(options?: NpmRuntimeUpdateCommandServiceOptions);
12
6
  run: (opts: UpdateCommandOptions) => Promise<UpdateSnapshot>;
13
7
  runManaged: (opts: UpdateCommandOptions) => Promise<UpdateSnapshot>;
14
8
  private printProgress;
@@ -2,15 +2,11 @@ import { NpmRuntimeBundleLayoutStore } from "./npm-runtime-bundle-layout.store.j
2
2
  import { NpmRuntimeBundleService } from "./npm-runtime-bundle.service.js";
3
3
  import { NpmRuntimeUpdateSourceService } from "./npm-runtime-update-source.service.js";
4
4
  import { NpmRuntimeUpdateStateStore } from "./npm-runtime-update-state.store.js";
5
- import { getPackageVersion } from "../shared/utils/package/package-manifest.utils.js";
6
- import "../shared/utils/cli.utils.js";
7
5
  import { NpmRuntimeUpdateManager } from "./npm-runtime-update.manager.js";
8
6
  import { NpmRuntimeUpdateService } from "./npm-runtime-update.service.js";
7
+ import { NextclawDistributionService } from "../shared/services/runtime/nextclaw-distribution.service.js";
9
8
  //#region src/launcher/npm-runtime-update-command.service.ts
10
9
  var NpmRuntimeUpdateCommandService = class {
11
- constructor(options = {}) {
12
- this.options = options;
13
- }
14
10
  run = async (opts) => {
15
11
  const snapshot = await this.runManaged(opts);
16
12
  if (opts.json) console.log(JSON.stringify(snapshot, null, 2));
@@ -18,8 +14,9 @@ var NpmRuntimeUpdateCommandService = class {
18
14
  return snapshot;
19
15
  };
20
16
  runManaged = async (opts) => {
21
- const source = new NpmRuntimeUpdateSourceService({ packagedPublicKeyPath: this.options.packagedPublicKeyPath });
22
- const launcherVersion = this.options.launcherVersion ?? getPackageVersion();
17
+ const distribution = NextclawDistributionService.get();
18
+ const source = new NpmRuntimeUpdateSourceService({ packagedPublicKeyPath: distribution.runtimeUpdatePublicKeyPath });
19
+ const launcherVersion = distribution.version;
23
20
  const channel = source.resolveChannel(opts.channel, launcherVersion);
24
21
  const manifestUrl = source.resolveManifestUrl(channel, opts.manifestUrl);
25
22
  const layout = new NpmRuntimeBundleLayoutStore();
@@ -23,8 +23,6 @@ import { RemoteRuntimeActions } from "@nextclaw/remote";
23
23
  //#region src/service-runtime.service.d.ts
24
24
  type NextclawServiceRuntimeOptions = {
25
25
  logo?: string;
26
- version?: string;
27
- packagedPublicKeyPath?: string;
28
26
  };
29
27
  type NextclawServiceRuntimeAccount = {
30
28
  status: (opts?: {
@@ -60,8 +58,6 @@ type NextclawServiceCommands = {
60
58
  };
61
59
  declare class NextclawServiceRuntime {
62
60
  private logo;
63
- private productVersion;
64
- private packagedPublicKeyPath?;
65
61
  private restartCoordinator;
66
62
  private serviceRestartTask;
67
63
  private selfRelaunchArmed;
@@ -72,7 +68,7 @@ declare class NextclawServiceRuntime {
72
68
  private remoteCommands;
73
69
  account: NextclawServiceRuntimeAccount;
74
70
  commands: NextclawServiceCommands;
75
- constructor(options?: NextclawServiceRuntimeOptions);
71
+ constructor(options: NextclawServiceRuntimeOptions);
76
72
  private createCommands;
77
73
  get version(): string;
78
74
  private scheduleProcessExit;
@@ -90,9 +86,6 @@ declare class NextclawServiceRuntime {
90
86
  agent: (opts: AgentCommandOptions) => Promise<void>;
91
87
  update: (opts: UpdateCommandOptions) => Promise<void>;
92
88
  }
93
- declare const runNextclawNpmRuntimeLauncher: (argv?: string[], options?: {
94
- launcherVersion?: string;
95
- packagedAppEntrypoint?: string;
96
- }) => void;
89
+ declare const runNextclawNpmRuntimeLauncher: (argv?: string[]) => void;
97
90
  //#endregion
98
91
  export { NextclawServiceCommands, NextclawServiceRuntime, NextclawServiceRuntimeAccount, NextclawServiceRuntimeOptions, runNextclawNpmRuntimeLauncher };
@@ -1,12 +1,12 @@
1
- import { getPackageVersion as getPackageVersion$1 } from "./shared/utils/package/package-manifest.utils.js";
2
1
  import { isProcessRunning } from "./shared/utils/cli.utils.js";
3
2
  import { NpmRuntimeLauncher } from "./launcher/npm-runtime-launcher.service.js";
3
+ import { NextclawDistributionService } from "./shared/services/runtime/nextclaw-distribution.service.js";
4
4
  import { NpmRuntimeUpdateCommandService } from "./launcher/npm-runtime-update-command.service.js";
5
5
  import { managedServiceStateStore } from "./shared/stores/managed-service-state.store.js";
6
6
  import { logStartupTrace, measureStartupSync } from "./shared/utils/startup-trace.js";
7
7
  import { createTopLevelNextclawCommandEnv } from "./shared/utils/top-level-nextclaw-command-env.utils.js";
8
8
  import { writeRestartSentinel } from "./shared/services/restart/restart-sentinel.service.js";
9
- import { hasRunningNextclawManagedService } from "./commands/remote/services/remote-runtime-support.service.js";
9
+ import { hasRunningNextclawManagedService } from "./commands/remote/utils/remote-runtime-support.utils.js";
10
10
  import { RemoteCommands } from "./commands/remote/index.js";
11
11
  import { PlatformAuthCommands } from "./commands/platform-auth/services/platform-auth-commands.service.js";
12
12
  import "./commands/platform-auth/index.js";
@@ -53,8 +53,6 @@ import { NextclawKernel } from "@nextclaw/kernel";
53
53
  const FORCED_PUBLIC_UI_HOST = "0.0.0.0";
54
54
  var NextclawServiceRuntime = class {
55
55
  logo;
56
- productVersion;
57
- packagedPublicKeyPath;
58
56
  restartCoordinator;
59
57
  serviceRestartTask = null;
60
58
  selfRelaunchArmed = false;
@@ -65,11 +63,9 @@ var NextclawServiceRuntime = class {
65
63
  remoteCommands;
66
64
  account;
67
65
  commands;
68
- constructor(options = {}) {
66
+ constructor(options) {
69
67
  logStartupTrace("cli.runtime.constructor.begin");
70
68
  this.logo = options.logo ?? "🤖";
71
- this.productVersion = options.version ?? getPackageVersion$1();
72
- this.packagedPublicKeyPath = options.packagedPublicKeyPath;
73
69
  this.workspaceManager = measureStartupSync("cli.runtime.workspace_manager", () => new WorkspaceManager(this.logo));
74
70
  this.runtimeCommandService = measureStartupSync("cli.runtime.runtime_command_service", () => new RuntimeCommandService({
75
71
  requestRestart: (params) => this.requestRestart(params),
@@ -168,7 +164,7 @@ var NextclawServiceRuntime = class {
168
164
  };
169
165
  };
170
166
  get version() {
171
- return this.productVersion;
167
+ return NextclawDistributionService.get().version;
172
168
  }
173
169
  scheduleProcessExit = (delayMs, reason) => {
174
170
  console.warn(`Gateway restart requested (${reason}).`);
@@ -383,20 +379,18 @@ var NextclawServiceRuntime = class {
383
379
  update = async (opts) => {
384
380
  const versionBefore = this.version;
385
381
  if (!opts.json) console.log(`Current npm launcher version: ${versionBefore}`);
386
- const snapshot = await new NpmRuntimeUpdateCommandService({
387
- launcherVersion: versionBefore,
388
- packagedPublicKeyPath: this.packagedPublicKeyPath
389
- }).run(opts);
382
+ const snapshot = await new NpmRuntimeUpdateCommandService().run(opts);
390
383
  if (snapshot.status === "blocked" || snapshot.status === "failed") process.exit(1);
391
384
  const state = managedServiceStateStore.read();
392
385
  if (snapshot.requiresRestart && state && isProcessRunning(state.pid)) console.log(`Tip: restart ${APP_NAME} to apply the update.`);
393
386
  };
394
387
  };
395
- const runNextclawNpmRuntimeLauncher = (argv = process.argv, options = {}) => {
388
+ const runNextclawNpmRuntimeLauncher = (argv = process.argv) => {
389
+ const distribution = NextclawDistributionService.get();
396
390
  new NpmRuntimeLauncher({
397
391
  argv,
398
- launcherVersion: options.launcherVersion,
399
- packagedAppEntrypoint: options.packagedAppEntrypoint
392
+ launcherVersion: distribution.version,
393
+ packagedAppEntrypoint: distribution.appEntrypoint
400
394
  }).run();
401
395
  };
402
396
  //#endregion
@@ -1,18 +1,20 @@
1
- import { createManagedRemoteModuleForUi } from "../../runtime/service-remote-runtime.service.js";
1
+ import { createManagedRemoteModuleForUi } from "../../runtime/utils/service-remote-runtime.utils.js";
2
2
  import { GatewayRuntimeDeps } from "../nextclaw-gateway-runtime.service.js";
3
3
  import { Config } from "@nextclaw/core";
4
4
  import { UiRemoteAccessHost } from "@nextclaw/server";
5
+ import { RemoteRuntimeState } from "@nextclaw/remote";
5
6
  import { ConfigManager } from "@nextclaw/kernel";
6
7
 
7
8
  //#region src/shared/services/gateway/managers/gateway-remote.manager.d.ts
8
- type RemoteServiceModule = ReturnType<typeof createManagedRemoteModuleForUi>;
9
+ type RemoteServiceModule$1 = ReturnType<typeof createManagedRemoteModuleForUi>;
9
10
  declare class GatewayRemoteManager {
10
- readonly remoteModule: RemoteServiceModule;
11
+ readonly remoteModule: RemoteServiceModule$1;
11
12
  readonly remoteAccess: UiRemoteAccessHost;
12
13
  constructor(params: {
13
14
  deps: GatewayRuntimeDeps;
14
15
  configManager: ConfigManager;
15
16
  uiConfig: Config["ui"];
17
+ onRemoteStateChange?: (state: RemoteRuntimeState) => void;
16
18
  });
17
19
  stop: () => Promise<void>;
18
20
  }
@@ -1,5 +1,5 @@
1
1
  import { createRemoteAccessHost } from "../../ui/service-remote-access.service.js";
2
- import { createManagedRemoteModuleForUi } from "../../runtime/service-remote-runtime.service.js";
2
+ import { createManagedRemoteModuleForUi } from "../../runtime/utils/service-remote-runtime.utils.js";
3
3
  //#region src/shared/services/gateway/managers/gateway-remote.manager.ts
4
4
  var GatewayRemoteManager = class {
5
5
  remoteModule;
@@ -8,7 +8,8 @@ var GatewayRemoteManager = class {
8
8
  const { configManager, deps, uiConfig } = params;
9
9
  this.remoteModule = createManagedRemoteModuleForUi({
10
10
  loadConfig: configManager.loadConfig,
11
- uiConfig
11
+ uiConfig,
12
+ onRemoteStateChange: params.onRemoteStateChange
12
13
  });
13
14
  this.remoteAccess = createRemoteAccessHost({
14
15
  serviceCommands: deps,
@@ -1,10 +1,11 @@
1
1
  import { RequestRestartParams } from "../../types/cli.types.js";
2
+ import { NextclawDistribution } from "../../types/distribution.types.js";
2
3
  import { GatewayControllerImpl } from "../../controllers/gateway.controller.js";
3
4
  import { GatewayPluginManager } from "./managers/gateway-plugin.manager.js";
4
5
  import { GatewayRemoteManager } from "./managers/gateway-remote.manager.js";
5
6
  import { GatewayRestartWakeService } from "./gateway-restart-wake.service.js";
6
7
  import { UiStartupHandle } from "./nextclaw-app.service.js";
7
- import { ServiceBootstrapStatusStore } from "./service-bootstrap-status.js";
8
+ import { ServiceBootstrapStatusStore } from "./service-bootstrap-status.service.js";
8
9
  import { ServiceFileWatcherRegistry } from "./service-startup-support.service.js";
9
10
  import { ServiceExtensionRuntime } from "../extensions/service-extension-runtime.service.js";
10
11
  import * as NextclawCore from "@nextclaw/core";
@@ -45,6 +46,7 @@ declare class NextclawGatewayRuntime {
45
46
  readonly runtimeControl: UiRuntimeControlHost;
46
47
  readonly runtimeUpdate: UiRuntimeUpdateHost | null;
47
48
  readonly ingress: Ingress;
49
+ readonly distribution: NextclawDistribution;
48
50
  readonly productVersion: string;
49
51
  readonly providerManager: LlmProviderManager;
50
52
  readonly gatewayController: GatewayControllerImpl;
@@ -62,7 +64,7 @@ declare class NextclawGatewayRuntime {
62
64
  liveAgentRuntime: AgentRuntimeHandle | null;
63
65
  readonly fileWatchers: ServiceFileWatcherRegistry;
64
66
  private deferredChannelStarter;
65
- constructor(deps: GatewayRuntimeDeps, options?: GatewayRuntimeOptions);
67
+ constructor(deps: GatewayRuntimeDeps, options: GatewayRuntimeOptions);
66
68
  start: () => Promise<void>;
67
69
  private reset;
68
70
  get ncpAgent(): UiNcpAgent;
@@ -1,5 +1,5 @@
1
- import { getPackageVersion as getPackageVersion$1 } from "../../utils/package/package-manifest.utils.js";
2
1
  import { openBrowser, resolveUiConfig, resolveUiStaticDir } from "../../utils/cli.utils.js";
2
+ import { NextclawDistributionService } from "../runtime/nextclaw-distribution.service.js";
3
3
  import { localUiRuntimeStore } from "../../stores/local-ui-runtime.store.js";
4
4
  import { managedServiceStateStore } from "../../stores/managed-service-state.store.js";
5
5
  import { logStartupTrace, measureStartupAsync, measureStartupSync } from "../../utils/startup-trace.js";
@@ -17,7 +17,7 @@ import { GatewayRestartWakeService } from "./gateway-restart-wake.service.js";
17
17
  import { createCronJobHandler } from "./cron-job-handler.service.js";
18
18
  import { handleGatewayDeferredStartupError } from "./utils/gateway-runtime-lifecycle.utils.js";
19
19
  import { NextclawApp } from "./nextclaw-app.service.js";
20
- import { ServiceBootstrapStatusStore } from "./service-bootstrap-status.js";
20
+ import { ServiceBootstrapStatusStore } from "./service-bootstrap-status.service.js";
21
21
  import { createDeferredUiNcpAgent } from "../session/service-deferred-ncp-agent.service.js";
22
22
  import { installPluginRuntimeBridge } from "../plugin/utils/plugin-runtime-bridge.utils.js";
23
23
  import { wrapStartChannelsWithDevPluginHotReload } from "../plugin/utils/plugin-dev-hot-reload.utils.js";
@@ -45,6 +45,7 @@ var NextclawGatewayRuntime = class {
45
45
  runtimeControl;
46
46
  runtimeUpdate;
47
47
  ingress;
48
+ distribution = NextclawDistributionService.get();
48
49
  productVersion;
49
50
  providerManager;
50
51
  gatewayController;
@@ -62,7 +63,7 @@ var NextclawGatewayRuntime = class {
62
63
  liveAgentRuntime = null;
63
64
  fileWatchers = new ServiceFileWatcherRegistry();
64
65
  deferredChannelStarter;
65
- constructor(deps, options = {}) {
66
+ constructor(deps, options) {
66
67
  this.deps = deps;
67
68
  this.options = options;
68
69
  const configPath = getConfigPath$1();
@@ -73,14 +74,14 @@ var NextclawGatewayRuntime = class {
73
74
  this.configManager = this.kernel.configManager;
74
75
  const config = this.configManager.config;
75
76
  this.uiConfig = resolveUiConfig(config, options.uiOverrides);
76
- this.uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
77
+ this.uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir(this.distribution.uiDistDir) : options.uiStaticDir;
77
78
  this.workspace = getWorkspacePath$1(config.agents.defaults.workspace);
78
79
  this.appEventBus = this.kernel.eventBus;
79
80
  this.ingress = this.kernel.ingress;
80
81
  this.messageBus = this.kernel.messageBus;
81
82
  this.sessionManager = this.kernel.sessions;
82
83
  this.automation = this.kernel.automation;
83
- this.productVersion = getPackageVersion$1();
84
+ this.productVersion = this.distribution.version;
84
85
  this.plugins = new GatewayPluginManager(this);
85
86
  this.providerManager = this.kernel.llmProviders;
86
87
  this.installConfigRuntimeHooks();
@@ -91,7 +92,8 @@ var NextclawGatewayRuntime = class {
91
92
  this.remoteManager = new GatewayRemoteManager({
92
93
  deps: this.deps,
93
94
  configManager: this.configManager,
94
- uiConfig: this.uiConfig
95
+ uiConfig: this.uiConfig,
96
+ onRemoteStateChange: (state) => this.bootstrapStatus.syncRemoteRuntimeState(state)
95
97
  });
96
98
  this.marketplace = this.createMarketplace();
97
99
  this.runtimeControl = createRuntimeControlHost({
@@ -143,8 +145,6 @@ var NextclawGatewayRuntime = class {
143
145
  };
144
146
  createBootstrapStatus = () => {
145
147
  const bootstrapStatus = new ServiceBootstrapStatusStore();
146
- bootstrapStatus.markNcpAgentPending();
147
- bootstrapStatus.markPluginHydrationPending();
148
148
  bootstrapStatus.markChannelsPending();
149
149
  bootstrapStatus.setRemoteState(this.configManager.config.remote.enabled ? "pending" : "disabled");
150
150
  return bootstrapStatus;
@@ -240,7 +240,6 @@ var NextclawGatewayRuntime = class {
240
240
  if (enabledChannels.length > 0) console.log(`✓ Channels enabled: ${enabledChannels.join(", ")}`);
241
241
  else console.log("Warning: No channels enabled");
242
242
  this.bootstrapStatus.markChannelsReady(enabledChannels);
243
- this.bootstrapStatus.markReady();
244
243
  };
245
244
  createMarketplace = () => ({
246
245
  apiBaseUrl: process.env.NEXTCLAW_MARKETPLACE_API_BASE,
@@ -1,15 +1,14 @@
1
1
  import { BootstrapRemoteState, BootstrapStatusView } from "@nextclaw/server";
2
+ import { RemoteRuntimeState } from "@nextclaw/remote";
2
3
 
3
- //#region src/shared/services/gateway/service-bootstrap-status.d.ts
4
+ //#region src/shared/services/gateway/service-bootstrap-status.service.d.ts
4
5
  declare class ServiceBootstrapStatusStore {
5
6
  private state;
6
7
  getStatus(): BootstrapStatusView;
7
8
  markShellReady(): void;
8
- markNcpAgentPending(): void;
9
9
  markNcpAgentRunning(): void;
10
10
  markNcpAgentReady(): void;
11
11
  markNcpAgentError(error: string): void;
12
- markPluginHydrationPending(): void;
13
12
  markPluginHydrationRunning(params: {
14
13
  totalPluginCount: number;
15
14
  }): void;
@@ -26,7 +25,7 @@ declare class ServiceBootstrapStatusStore {
26
25
  markChannelsReady(enabled: string[]): void;
27
26
  markChannelsError(error: string): void;
28
27
  setRemoteState(state: BootstrapRemoteState, message?: string): void;
29
- markReady(): void;
28
+ syncRemoteRuntimeState(runtime: RemoteRuntimeState): void;
30
29
  markError(error: string): void;
31
30
  }
32
31
  //#endregion
@@ -1,4 +1,4 @@
1
- //#region src/shared/services/gateway/service-bootstrap-status.ts
1
+ //#region src/shared/services/gateway/service-bootstrap-status.service.ts
2
2
  function now() {
3
3
  return (/* @__PURE__ */ new Date()).toISOString();
4
4
  }
@@ -33,9 +33,6 @@ var ServiceBootstrapStatusStore = class {
33
33
  this.state.phase = "shell-ready";
34
34
  this.state.shellReadyAt = this.state.shellReadyAt ?? now();
35
35
  }
36
- markNcpAgentPending() {
37
- this.state.ncpAgent = { state: "pending" };
38
- }
39
36
  markNcpAgentRunning() {
40
37
  this.state.ncpAgent = {
41
38
  state: "running",
@@ -60,14 +57,6 @@ var ServiceBootstrapStatusStore = class {
60
57
  error
61
58
  };
62
59
  }
63
- markPluginHydrationPending() {
64
- this.state.pluginHydration = {
65
- ...this.state.pluginHydration,
66
- state: "pending",
67
- loadedPluginCount: 0,
68
- totalPluginCount: 0
69
- };
70
- }
71
60
  markPluginHydrationRunning(params) {
72
61
  this.state.phase = "hydrating-capabilities";
73
62
  this.state.pluginHydration = {
@@ -139,9 +128,10 @@ var ServiceBootstrapStatusStore = class {
139
128
  ...message ? { message } : {}
140
129
  };
141
130
  }
142
- markReady() {
143
- this.state.phase = "ready";
144
- this.state.lastError = void 0;
131
+ syncRemoteRuntimeState(runtime) {
132
+ const message = runtime.lastError?.trim() || void 0;
133
+ const state = runtime.state === "connected" ? "ready" : runtime.state === "disabled" ? "disabled" : runtime.state === "error" && message?.includes("already owned") ? "conflict" : runtime.state === "error" ? "error" : "pending";
134
+ this.setRemoteState(state, message);
145
135
  }
146
136
  markError(error) {
147
137
  this.state.phase = "error";
@@ -1,4 +1,4 @@
1
- import { ServiceBootstrapStatusStore } from "../service-bootstrap-status.js";
1
+ import { ServiceBootstrapStatusStore } from "../service-bootstrap-status.service.js";
2
2
 
3
3
  //#region src/shared/services/gateway/utils/gateway-runtime-lifecycle.utils.d.ts
4
4
  declare function handleGatewayDeferredStartupError(params: {
@@ -0,0 +1,10 @@
1
+ import { NextclawDistribution } from "../../types/distribution.types.js";
2
+
3
+ //#region src/shared/services/runtime/nextclaw-distribution.service.d.ts
4
+ declare class NextclawDistributionService {
5
+ private static currentDistribution;
6
+ static configure(distribution: NextclawDistribution): void;
7
+ static get(): NextclawDistribution;
8
+ }
9
+ //#endregion
10
+ export { NextclawDistributionService };
@@ -0,0 +1,13 @@
1
+ //#region src/shared/services/runtime/nextclaw-distribution.service.ts
2
+ var NextclawDistributionService = class NextclawDistributionService {
3
+ static currentDistribution = null;
4
+ static configure(distribution) {
5
+ NextclawDistributionService.currentDistribution = distribution;
6
+ }
7
+ static get() {
8
+ if (!NextclawDistributionService.currentDistribution) throw new Error("NextClaw distribution is not configured.");
9
+ return NextclawDistributionService.currentDistribution;
10
+ }
11
+ };
12
+ //#endregion
13
+ export { NextclawDistributionService };
@@ -1,4 +1,5 @@
1
- import { isLoopbackHost, resolvePublicIp } from "../../utils/cli.utils.js";
1
+ import { isLoopbackHost, resolvePublicIp, resolveUiStaticDir } from "../../utils/cli.utils.js";
2
+ import { NextclawDistributionService } from "./nextclaw-distribution.service.js";
2
3
  import { describeUnmanagedHealthyTargetMessage, inspectUiTarget } from "../../utils/service-port-probe.utils.js";
3
4
  import { buildMarketplaceSkillInstallArgs, pickUserFacingCommandSummary } from "../../utils/marketplace/service-marketplace-helpers.utils.js";
4
5
  import { resolveCliSubcommandEntry } from "../../utils/marketplace/cli-subcommand-launch.utils.js";
@@ -15,7 +16,8 @@ var RuntimeCommandService = class {
15
16
  startGateway: async (options) => await this.startGateway(options),
16
17
  printPublicUiUrls: async (host, port) => await this.printPublicUiUrls(host, port),
17
18
  printServiceControlHints: () => this.printServiceControlHints(),
18
- checkUiPortPreflight: async (params) => await this.checkUiPortPreflight(params)
19
+ checkUiPortPreflight: async (params) => await this.checkUiPortPreflight(params),
20
+ resolveUiStaticDir: () => resolveUiStaticDir(NextclawDistributionService.get().uiDistDir)
19
21
  });
20
22
  constructor(deps) {
21
23
  this.deps = deps;
@@ -29,7 +31,7 @@ var RuntimeCommandService = class {
29
31
  stopService: this.stopService,
30
32
  runCliSubcommand: this.runCliSubcommand,
31
33
  installBuiltinMarketplaceSkill: this.installBuiltinMarketplaceSkill
32
- }, options).start();
34
+ }, { ...options }).start();
33
35
  };
34
36
  startService = async (options) => {
35
37
  await this.managedServiceCommandService.startService(options);
@@ -127,6 +127,7 @@ declare class ManagedServiceCommandService {
127
127
  ok: false;
128
128
  message: string;
129
129
  }>;
130
+ resolveUiStaticDir: () => string | null;
130
131
  });
131
132
  runForeground: (options: {
132
133
  uiOverrides: Partial<Config$1["ui"]>;
@@ -1,10 +1,10 @@
1
- import { isProcessRunning, openBrowser, resolveServiceLogPath, resolveUiApiBase, resolveUiConfig, resolveUiStaticDir, waitForExit } from "../../utils/cli.utils.js";
1
+ import { isProcessRunning, openBrowser, resolveServiceLogPath, resolveUiApiBase, resolveUiConfig, waitForExit } from "../../utils/cli.utils.js";
2
2
  import { localUiRuntimeStore } from "../../stores/local-ui-runtime.store.js";
3
3
  import { managedServiceStateStore } from "../../stores/managed-service-state.store.js";
4
4
  import { probeHealthEndpoint } from "../../utils/service-port-probe.utils.js";
5
5
  import { resolveCliSubcommandLaunch } from "../../utils/marketplace/cli-subcommand-launch.utils.js";
6
6
  import { createTopLevelNextclawCommandEnv } from "../../utils/top-level-nextclaw-command-env.utils.js";
7
- import { writeInitialManagedServiceState, writeReadyManagedServiceState } from "./service-remote-runtime.service.js";
7
+ import { writeInitialManagedServiceState, writeReadyManagedServiceState } from "./utils/service-remote-runtime.utils.js";
8
8
  import { spawn } from "node:child_process";
9
9
  import { dirname } from "node:path";
10
10
  import * as NextclawCore from "@nextclaw/core";
@@ -171,7 +171,7 @@ var ManagedServiceCommandService = class {
171
171
  if (options.open) openBrowser(uiUrl);
172
172
  await this.deps.startGateway({
173
173
  uiOverrides: options.uiOverrides,
174
- uiStaticDir: resolveUiStaticDir()
174
+ uiStaticDir: this.deps.resolveUiStaticDir()
175
175
  });
176
176
  };
177
177
  startService = async (options) => {
@@ -181,7 +181,7 @@ var ManagedServiceCommandService = class {
181
181
  const uiConfig = resolveUiConfig(config, uiOverrides);
182
182
  const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
183
183
  const apiUrl = `${uiUrl}/api`;
184
- const staticDir = resolveUiStaticDir();
184
+ const staticDir = this.deps.resolveUiStaticDir();
185
185
  const existing = managedServiceStateStore.read();
186
186
  if (existing && isProcessRunning(existing.pid)) {
187
187
  await this.handleExistingManagedService({
@@ -1,8 +1,8 @@
1
- import { ManagedServiceState } from "../../stores/managed-service-state.store.js";
1
+ import { ManagedServiceState } from "../../../stores/managed-service-state.store.js";
2
2
  import { Config } from "@nextclaw/core";
3
- import { RemoteServiceModule } from "@nextclaw/remote";
3
+ import { RemoteRuntimeState, RemoteServiceModule } from "@nextclaw/remote";
4
4
 
5
- //#region src/shared/services/runtime/service-remote-runtime.service.d.ts
5
+ //#region src/shared/services/runtime/utils/service-remote-runtime.utils.d.ts
6
6
  type ManagedServiceSnapshot = {
7
7
  pid: number;
8
8
  uiUrl: string;
@@ -30,11 +30,13 @@ declare function createManagedRemoteModule(params: {
30
30
  loadConfig: () => Config;
31
31
  uiEnabled: boolean;
32
32
  localOrigin: string;
33
+ onRemoteStateChange?: (state: RemoteRuntimeState) => void;
33
34
  }): RemoteServiceModule | null;
34
35
  declare function createManagedRemoteModuleForUi(params: {
35
36
  loadConfig: () => Config;
36
37
  uiConfig: Pick<Config["ui"], "enabled" | "host" | "port">;
37
38
  localOriginOverride?: string;
39
+ onRemoteStateChange?: (state: RemoteRuntimeState) => void;
38
40
  }): RemoteServiceModule | null;
39
41
  declare function writeInitialManagedServiceState(params: {
40
42
  config: Config;
@@ -1,11 +1,11 @@
1
- import { isProcessRunning, resolveUiApiBase } from "../../utils/cli.utils.js";
2
- import { managedServiceStateStore } from "../../stores/managed-service-state.store.js";
3
- import { buildNextclawConfiguredRemoteState, createNextclawRemoteConnector, createNextclawRemoteStatusStore } from "../../../commands/remote/services/remote-runtime-support.service.js";
1
+ import { isProcessRunning, resolveUiApiBase } from "../../../utils/cli.utils.js";
2
+ import { managedServiceStateStore } from "../../../stores/managed-service-state.store.js";
3
+ import { buildNextclawConfiguredRemoteState, createNextclawRemoteConnector, createNextclawRemoteStatusStore } from "../../../../commands/remote/utils/remote-runtime-support.utils.js";
4
4
  import { dirname, resolve } from "node:path";
5
5
  import { getDataDir } from "@nextclaw/core";
6
6
  import { closeSync, existsSync, mkdirSync, openSync, readFileSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
7
7
  import { RemoteServiceModule } from "@nextclaw/remote";
8
- //#region src/shared/services/runtime/service-remote-runtime.service.ts
8
+ //#region src/shared/services/runtime/utils/service-remote-runtime.utils.ts
9
9
  function resolveRemoteOwnershipLockPath() {
10
10
  return resolve(getDataDir(), "run", "remote-owner.lock.json");
11
11
  }
@@ -117,7 +117,7 @@ function createManagedRemoteModule(params) {
117
117
  loadConfig: params.loadConfig,
118
118
  uiEnabled: params.uiEnabled,
119
119
  localOrigin: params.localOrigin,
120
- statusStore: createNextclawRemoteStatusStore("service"),
120
+ statusStore: createNextclawRemoteStatusStore("service", params.onRemoteStateChange),
121
121
  createConnector: (logger) => createNextclawRemoteConnector({ logger }),
122
122
  claimOwnership: () => claimManagedRemoteRuntimeOwnership({ localOrigin: params.localOrigin }),
123
123
  logger: {
@@ -132,6 +132,7 @@ function createManagedRemoteModuleForUi(params) {
132
132
  return createManagedRemoteModule({
133
133
  loadConfig: params.loadConfig,
134
134
  uiEnabled: params.uiConfig.enabled,
135
+ onRemoteStateChange: params.onRemoteStateChange,
135
136
  localOrigin: explicitLocalOrigin && explicitLocalOrigin.length > 0 ? explicitLocalOrigin.replace(/\/+$/, "") : resolveUiApiBase(params.uiConfig.host, params.uiConfig.port)
136
137
  });
137
138
  }
@@ -2,10 +2,9 @@ import { NpmRuntimeBundleLayoutStore } from "../../../launcher/npm-runtime-bundl
2
2
  import { NpmRuntimeBundleService } from "../../../launcher/npm-runtime-bundle.service.js";
3
3
  import { NpmRuntimeUpdateSourceService } from "../../../launcher/npm-runtime-update-source.service.js";
4
4
  import { NpmRuntimeUpdateStateStore } from "../../../launcher/npm-runtime-update-state.store.js";
5
- import { getPackageVersion } from "../../utils/package/package-manifest.utils.js";
6
- import "../../utils/cli.utils.js";
7
5
  import { NpmRuntimeUpdateManager } from "../../../launcher/npm-runtime-update.manager.js";
8
6
  import { NpmRuntimeUpdateService } from "../../../launcher/npm-runtime-update.service.js";
7
+ import { NextclawDistributionService } from "../runtime/nextclaw-distribution.service.js";
9
8
  import { requestManagedServiceRestart } from "./service-remote-access.service.js";
10
9
  import { eventKeys } from "@nextclaw/shared";
11
10
  //#region src/shared/services/ui/npm-runtime-update-host.service.ts
@@ -15,26 +14,33 @@ const INITIAL_DOWNLOAD_PROGRESS = {
15
14
  percent: null
16
15
  };
17
16
  var NpmRuntimeUpdateHost = class {
18
- source = new NpmRuntimeUpdateSourceService();
19
- layout = new NpmRuntimeBundleLayoutStore();
20
- launcherVersion = getPackageVersion();
21
- stateStore = new NpmRuntimeUpdateStateStore(this.layout.getStatePath(), { defaultChannel: this.source.resolveChannel(void 0, this.launcherVersion) });
22
- bundleService = new NpmRuntimeBundleService({
23
- layout: this.layout,
24
- stateStore: this.stateStore,
25
- launcherVersion: this.launcherVersion
26
- });
27
- updateService = new NpmRuntimeUpdateService({
28
- layout: this.layout,
29
- bundleService: this.bundleService,
30
- launcherVersion: this.launcherVersion,
31
- bundlePublicKey: this.source.resolveBundlePublicKey() ?? void 0
32
- });
17
+ source;
18
+ layout;
19
+ launcherVersion;
20
+ stateStore;
21
+ bundleService;
22
+ updateService;
33
23
  snapshot;
34
24
  activeTask = null;
35
25
  automaticSyncStarted = false;
36
26
  constructor(deps) {
37
27
  this.deps = deps;
28
+ const distribution = NextclawDistributionService.get();
29
+ this.source = new NpmRuntimeUpdateSourceService({ packagedPublicKeyPath: distribution.runtimeUpdatePublicKeyPath });
30
+ this.layout = new NpmRuntimeBundleLayoutStore();
31
+ this.launcherVersion = distribution.version;
32
+ this.stateStore = new NpmRuntimeUpdateStateStore(this.layout.getStatePath(), { defaultChannel: this.source.resolveChannel(void 0, this.launcherVersion) });
33
+ this.bundleService = new NpmRuntimeBundleService({
34
+ layout: this.layout,
35
+ stateStore: this.stateStore,
36
+ launcherVersion: this.launcherVersion
37
+ });
38
+ this.updateService = new NpmRuntimeUpdateService({
39
+ layout: this.layout,
40
+ bundleService: this.bundleService,
41
+ launcherVersion: this.launcherVersion,
42
+ bundlePublicKey: this.source.resolveBundlePublicKey() ?? void 0
43
+ });
38
44
  this.snapshot = this.createManager().getSnapshot();
39
45
  this.startAutomaticSync();
40
46
  }
@@ -0,0 +1,10 @@
1
+ //#region src/shared/types/distribution.types.d.ts
2
+ type NextclawDistribution = {
3
+ version: string;
4
+ packageRoot: string;
5
+ appEntrypoint: string;
6
+ uiDistDir: string;
7
+ runtimeUpdatePublicKeyPath: string;
8
+ };
9
+ //#endregion
10
+ export { NextclawDistribution };
@@ -0,0 +1 @@
1
+ export {};
@@ -7,9 +7,6 @@ declare function resolveUiConfig(config: Config, overrides?: Partial<Config["ui"
7
7
  declare function resolveUiApiBase(host: string, port: number): string;
8
8
  declare function isLoopbackHost(host: string): boolean;
9
9
  declare function resolvePublicIp(timeoutMs?: number): Promise<string | null>;
10
- declare function buildServeArgs(options: {
11
- uiPort: number;
12
- }): string[];
13
10
  declare function resolveServiceLogPath(): string;
14
11
  declare function isProcessRunning(pid: number): boolean;
15
12
  declare function waitForExit(pid: number, timeoutMs: number): Promise<boolean>;
@@ -18,7 +15,7 @@ type ListeningProcessInfo = {
18
15
  command: string | null;
19
16
  };
20
17
  declare function findListeningProcessByPort(port: number): ListeningProcessInfo | null;
21
- declare function resolveUiStaticDir(importMetaUrl?: string): string | null;
18
+ declare function resolveUiStaticDir(packagedUiDistDir?: string | null): string | null;
22
19
  declare function openBrowser(url: string): boolean;
23
20
  type ExecutableLookupEnv = {
24
21
  [key: string]: string | undefined;
@@ -31,4 +28,4 @@ declare function findExecutableOnPath(binary: string, env?: ExecutableLookupEnv,
31
28
  declare function printAgentResponse(response: string): void;
32
29
  declare function prompt(rl: Interface, question: string): Promise<string>;
33
30
  //#endregion
34
- export { ExecutableLookupEnv, ListeningProcessInfo, buildServeArgs, findExecutableOnPath, findListeningProcessByPort, getPackageVersion, isLoopbackHost, isProcessRunning, openBrowser, printAgentResponse, prompt, resolvePublicIp, resolveServiceLogPath, resolveUiApiBase, resolveUiConfig, resolveUiStaticDir, waitForExit };
31
+ export { ExecutableLookupEnv, ListeningProcessInfo, findExecutableOnPath, findListeningProcessByPort, getPackageVersion, isLoopbackHost, isProcessRunning, openBrowser, printAgentResponse, prompt, resolvePublicIp, resolveServiceLogPath, resolveUiApiBase, resolveUiConfig, resolveUiStaticDir, waitForExit };
@@ -1,6 +1,5 @@
1
- import { findNearestPackageManifest, getPackageVersion } from "./package/package-manifest.utils.js";
1
+ import { getPackageVersion } from "./package/package-manifest.utils.js";
2
2
  import { spawn, spawnSync } from "node:child_process";
3
- import { fileURLToPath } from "node:url";
4
3
  import { join, resolve } from "node:path";
5
4
  import { createExternalCommandEnv, getLogsPath, resolveLocalUiBaseUrl } from "@nextclaw/core";
6
5
  import { existsSync } from "node:fs";
@@ -52,14 +51,6 @@ async function resolvePublicIp(timeoutMs = 1500) {
52
51
  }
53
52
  return null;
54
53
  }
55
- function buildServeArgs(options) {
56
- return [
57
- fileURLToPath(new URL("../../app/index.js", import.meta.url)),
58
- "serve",
59
- "--ui-port",
60
- String(options.uiPort)
61
- ];
62
- }
63
54
  function resolveServiceLogPath() {
64
55
  return resolve(getLogsPath(), "service.log");
65
56
  }
@@ -171,14 +162,12 @@ function findListeningProcessByPort(port) {
171
162
  command: lookupProcessCommandByPid(pid)
172
163
  };
173
164
  }
174
- function resolveUiStaticDir(importMetaUrl = import.meta.url) {
165
+ function resolveUiStaticDir(packagedUiDistDir) {
175
166
  if (process.env.NEXTCLAW_DISABLE_STATIC_UI === "1") return null;
176
167
  const envDir = process.env.NEXTCLAW_UI_STATIC_DIR;
177
168
  if (envDir) return existsSync(join(envDir, "index.html")) ? envDir : null;
178
- const pkgRoot = findNearestPackageManifest(resolve(fileURLToPath(new URL(".", importMetaUrl))), "nextclaw")?.rootDir;
179
- if (!pkgRoot) return null;
180
- const bundledDir = join(pkgRoot, "ui-dist");
181
- return existsSync(join(bundledDir, "index.html")) ? bundledDir : null;
169
+ if (!packagedUiDistDir) return null;
170
+ return existsSync(join(packagedUiDistDir, "index.html")) ? packagedUiDistDir : null;
182
171
  }
183
172
  function openBrowser(url) {
184
173
  const platform = process.platform;
@@ -259,4 +248,4 @@ async function prompt(rl, question) {
259
248
  });
260
249
  }
261
250
  //#endregion
262
- export { buildServeArgs, findExecutableOnPath, findListeningProcessByPort, getPackageVersion, isLoopbackHost, isProcessRunning, openBrowser, printAgentResponse, prompt, resolvePublicIp, resolveServiceLogPath, resolveUiApiBase, resolveUiConfig, resolveUiStaticDir, waitForExit };
251
+ export { findExecutableOnPath, findListeningProcessByPort, getPackageVersion, isLoopbackHost, isProcessRunning, openBrowser, printAgentResponse, prompt, resolvePublicIp, resolveServiceLogPath, resolveUiApiBase, resolveUiConfig, resolveUiStaticDir, waitForExit };
@@ -1,8 +1,4 @@
1
1
  //#region src/shared/utils/package/package-manifest.utils.d.ts
2
- declare function findNearestPackageManifest(startDir: string, expectedName?: string): {
3
- rootDir: string;
4
- version?: string;
5
- } | null;
6
2
  declare function getPackageVersion(importMetaUrl?: string): string;
7
3
  //#endregion
8
- export { findNearestPackageManifest, getPackageVersion };
4
+ export { getPackageVersion };
@@ -5,44 +5,34 @@ import { readFileSync } from "node:fs";
5
5
  //#region src/shared/utils/package/package-manifest.utils.ts
6
6
  function readPackageManifest(pkgPath) {
7
7
  try {
8
- const raw = readFileSync(pkgPath, "utf-8");
9
- return JSON.parse(raw);
8
+ return JSON.parse(readFileSync(pkgPath, "utf-8"));
10
9
  } catch {
11
10
  return null;
12
11
  }
13
12
  }
14
- function findNearestPackageManifest(startDir, expectedName) {
13
+ function findNearestPackageVersion(startDir, expectedName) {
15
14
  let current = resolve(startDir);
16
15
  while (current.length > 0) {
17
16
  const parsed = readPackageManifest(join(current, "package.json"));
18
- if (parsed && (!expectedName || parsed.name === expectedName)) return {
19
- rootDir: current,
20
- version: typeof parsed.version === "string" ? parsed.version : void 0
21
- };
17
+ if (parsed && (!expectedName || parsed.name === expectedName)) return typeof parsed.version === "string" ? parsed.version : void 0;
22
18
  const parent = resolve(current, "..");
23
19
  if (parent === current) break;
24
20
  current = parent;
25
21
  }
26
- return null;
27
22
  }
28
- function findWorkspacePackageManifest(startDir, packageName) {
23
+ function findWorkspacePackageVersion(startDir, packageName) {
29
24
  let current = resolve(startDir);
30
25
  while (current.length > 0) {
31
- const rootDir = join(current, "packages", packageName);
32
- const parsed = readPackageManifest(join(rootDir, "package.json"));
33
- if (parsed?.name === packageName) return {
34
- rootDir,
35
- version: typeof parsed.version === "string" ? parsed.version : void 0
36
- };
26
+ const parsed = readPackageManifest(join(join(current, "packages", packageName), "package.json"));
27
+ if (parsed?.name === packageName) return typeof parsed.version === "string" ? parsed.version : void 0;
37
28
  const parent = resolve(current, "..");
38
29
  if (parent === current) break;
39
30
  current = parent;
40
31
  }
41
- return null;
42
32
  }
43
33
  function getPackageVersion(importMetaUrl = import.meta.url) {
44
34
  const cliDir = resolve(fileURLToPath(new URL(".", importMetaUrl)));
45
- return findNearestPackageManifest(cliDir, "nextclaw")?.version ?? findWorkspacePackageManifest(cliDir, "nextclaw")?.version ?? findNearestPackageManifest(cliDir)?.version ?? getPackageVersion$1();
35
+ return findNearestPackageVersion(cliDir, "nextclaw") ?? findWorkspacePackageVersion(cliDir, "nextclaw") ?? findNearestPackageVersion(cliDir) ?? getPackageVersion$1();
46
36
  }
47
37
  //#endregion
48
- export { findNearestPackageManifest, getPackageVersion };
38
+ export { getPackageVersion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/service",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "private": false,
5
5
  "description": "NextClaw long-running service host and runtime lifecycle.",
6
6
  "type": "module",
@@ -34,23 +34,23 @@
34
34
  "commander": "^12.1.0",
35
35
  "jszip": "^3.10.1",
36
36
  "yaml": "^2.8.1",
37
- "@nextclaw/channel-extension-weixin": "0.1.1",
38
- "@nextclaw/core": "0.12.14",
39
- "@nextclaw/kernel": "0.1.3",
40
- "@nextclaw/mcp": "0.1.79",
41
- "@nextclaw/ncp": "0.5.7",
42
- "@nextclaw/ncp-agent-runtime": "0.3.17",
43
- "@nextclaw/ncp-http-agent-server": "0.3.19",
44
- "@nextclaw/ncp-mcp": "0.1.81",
45
- "@nextclaw/ncp-toolkit": "0.5.12",
46
- "@nextclaw/nextclaw-hermes-acp-bridge": "0.1.6",
47
- "@nextclaw/nextclaw-ncp-runtime-http-client": "0.1.6",
48
- "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.1.7",
49
- "@nextclaw/openclaw-compat": "1.0.14",
50
- "@nextclaw/remote": "0.1.91",
51
- "@nextclaw/runtime": "0.2.46",
52
- "@nextclaw/shared": "0.1.1",
53
- "@nextclaw/server": "0.12.14"
37
+ "@nextclaw/channel-extension-weixin": "0.1.2",
38
+ "@nextclaw/core": "0.12.15",
39
+ "@nextclaw/ncp-agent-runtime": "0.3.18",
40
+ "@nextclaw/kernel": "0.1.4",
41
+ "@nextclaw/ncp-http-agent-server": "0.3.20",
42
+ "@nextclaw/ncp": "0.5.8",
43
+ "@nextclaw/ncp-mcp": "0.1.82",
44
+ "@nextclaw/nextclaw-ncp-runtime-http-client": "0.1.7",
45
+ "@nextclaw/ncp-toolkit": "0.5.13",
46
+ "@nextclaw/mcp": "0.1.80",
47
+ "@nextclaw/openclaw-compat": "1.0.15",
48
+ "@nextclaw/remote": "0.1.92",
49
+ "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.1.8",
50
+ "@nextclaw/shared": "0.1.2",
51
+ "@nextclaw/server": "0.12.15",
52
+ "@nextclaw/runtime": "0.2.47",
53
+ "@nextclaw/nextclaw-hermes-acp-bridge": "0.1.7"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^20.17.6",