@nextclaw/service 0.1.8 → 0.1.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 (28) hide show
  1. package/dist/commands/channel/channel-list-view.service.d.ts +39 -0
  2. package/dist/commands/channel/channel-list-view.service.js +85 -0
  3. package/dist/commands/channel/index.d.ts +4 -1
  4. package/dist/commands/channel/index.js +29 -0
  5. package/dist/commands/service/services/autostart/windows-task-autostart.service.js +2 -1
  6. package/dist/index.d.ts +2 -2
  7. package/dist/launcher/npm-runtime-bundle.types.d.ts +1 -1
  8. package/dist/launcher/npm-runtime-launcher.service.js +3 -2
  9. package/dist/launcher/npm-runtime-update-command.service.js +2 -1
  10. package/dist/launcher/npm-runtime-update.manager.d.ts +2 -2
  11. package/dist/launcher/npm-runtime-update.manager.js +7 -3
  12. package/dist/launcher/npm-runtime-update.service.d.ts +1 -1
  13. package/dist/launcher/npm-runtime-update.service.js +1 -1
  14. package/dist/service-runtime.service.js +19 -18
  15. package/dist/shared/controllers/gateway.controller.js +6 -8
  16. package/dist/shared/services/extensions/extension-lifecycle.service.d.ts +7 -0
  17. package/dist/shared/services/extensions/extension-lifecycle.service.js +34 -3
  18. package/dist/shared/services/extensions/service-extension-runtime.service.d.ts +1 -0
  19. package/dist/shared/services/extensions/service-extension-runtime.service.js +25 -39
  20. package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.js +1 -1
  21. package/dist/shared/services/runtime/runtime-command.service.js +3 -2
  22. package/dist/shared/services/runtime/service-managed-startup.service.js +3 -2
  23. package/dist/shared/services/session/service-deferred-ncp-agent.service.js +1 -1
  24. package/dist/shared/services/ui/companion-runtime.service.js +1 -0
  25. package/dist/shared/services/workspace/workspace-manager.service.js +1 -1
  26. package/dist/shared/types/cli.types.d.ts +5 -1
  27. package/dist/shared/utils/cli.utils.js +2 -1
  28. package/package.json +19 -19
@@ -0,0 +1,39 @@
1
+ import { Config } from "@nextclaw/core";
2
+ import { PluginChannelBinding } from "@nextclaw/openclaw-compat";
3
+
4
+ //#region src/commands/channel/channel-list-view.service.d.ts
5
+ type ChannelListEntry = {
6
+ id: string;
7
+ label: string;
8
+ pluginId: string;
9
+ enabled: boolean;
10
+ outbound: {
11
+ text: boolean;
12
+ };
13
+ auth: {
14
+ login: boolean;
15
+ };
16
+ defaultAccountId?: string;
17
+ };
18
+ type ChannelListOutput = {
19
+ channels: ChannelListEntry[];
20
+ };
21
+ declare class ChannelListViewService {
22
+ private readonly params;
23
+ constructor(params: {
24
+ channelLabels: Record<string, string>;
25
+ });
26
+ build: (params: {
27
+ config: Config;
28
+ workspaceDir: string;
29
+ pluginBindings: PluginChannelBinding[];
30
+ }) => ChannelListOutput;
31
+ private toManifestChannelSources;
32
+ private toPluginChannelSource;
33
+ private toChannelListEntry;
34
+ private mergeChannelSources;
35
+ private discoverExtensionManifests;
36
+ private resolveDefaultAccountId;
37
+ }
38
+ //#endregion
39
+ export { ChannelListEntry, ChannelListOutput, ChannelListViewService };
@@ -0,0 +1,85 @@
1
+ import { resolveChannelConfigView } from "./channel-config-view.js";
2
+ import { ExtensionManifestDiscoveryService } from "../../shared/services/extensions/extension-lifecycle.service.js";
3
+ import { resolveExtensionManifestRoots } from "../../shared/services/extensions/service-extension-runtime.service.js";
4
+ //#region src/commands/channel/channel-list-view.service.ts
5
+ function readRecord(value) {
6
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
7
+ return value;
8
+ }
9
+ function readString(value) {
10
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
11
+ }
12
+ var ChannelListViewService = class {
13
+ constructor(params) {
14
+ this.params = params;
15
+ }
16
+ build = (params) => {
17
+ const { config, pluginBindings, workspaceDir } = params;
18
+ const sources = this.mergeChannelSources(pluginBindings.map(this.toPluginChannelSource), this.toManifestChannelSources(this.discoverExtensionManifests(config, workspaceDir)));
19
+ const channelConfigs = readRecord(resolveChannelConfigView(config, pluginBindings).channels) ?? {};
20
+ return { channels: sources.map((source) => this.toChannelListEntry(source, channelConfigs[source.id])).sort((left, right) => left.id.localeCompare(right.id)) };
21
+ };
22
+ toManifestChannelSources = (manifests) => {
23
+ const sources = [];
24
+ for (const manifest of manifests) {
25
+ const channels = manifest.contributes?.channels ?? [];
26
+ for (const channel of channels) {
27
+ const channelId = readString(channel.id);
28
+ if (!channelId) continue;
29
+ sources.push({
30
+ pluginId: manifest.id,
31
+ id: channelId,
32
+ label: readString(channel.name) ?? this.params.channelLabels[channelId] ?? channelId,
33
+ outboundText: channel.outbound?.text === true,
34
+ login: Boolean(channel.auth)
35
+ });
36
+ }
37
+ }
38
+ return sources;
39
+ };
40
+ toPluginChannelSource = (binding) => ({
41
+ id: binding.channelId,
42
+ label: readString(binding.channel.meta?.label) ?? this.params.channelLabels[binding.channelId] ?? binding.channelId,
43
+ pluginId: binding.pluginId,
44
+ outboundText: typeof binding.channel.outbound?.sendText === "function",
45
+ login: typeof binding.channel.auth?.login === "function",
46
+ resolveDefaultAccountId: (channelConfig) => this.resolveDefaultAccountId(binding, channelConfig)
47
+ });
48
+ toChannelListEntry = (source, rawChannelConfig) => {
49
+ const channelConfig = readRecord(rawChannelConfig);
50
+ const defaultAccountId = readString(channelConfig?.defaultAccountId) ?? source.resolveDefaultAccountId?.(channelConfig);
51
+ return {
52
+ id: source.id,
53
+ label: source.label,
54
+ pluginId: source.pluginId,
55
+ enabled: channelConfig?.enabled === true,
56
+ outbound: { text: source.outboundText },
57
+ auth: { login: source.login },
58
+ ...defaultAccountId ? { defaultAccountId } : {}
59
+ };
60
+ };
61
+ mergeChannelSources = (pluginSources, extensionSources) => {
62
+ const sourcesByChannelId = /* @__PURE__ */ new Map();
63
+ for (const source of [...pluginSources, ...extensionSources]) sourcesByChannelId.set(source.id, source);
64
+ return [...sourcesByChannelId.values()];
65
+ };
66
+ discoverExtensionManifests = (config, workspaceDir) => {
67
+ const discovery = new ExtensionManifestDiscoveryService();
68
+ const roots = resolveExtensionManifestRoots({
69
+ config,
70
+ workspace: workspaceDir
71
+ });
72
+ return discovery.discoverSync(roots);
73
+ };
74
+ resolveDefaultAccountId = (binding, channelConfig) => {
75
+ const configAdapter = binding.channel.config?.defaultAccountId;
76
+ if (!configAdapter) return;
77
+ try {
78
+ return readString(configAdapter({ channels: { [binding.channelId]: channelConfig ?? {} } }));
79
+ } catch {
80
+ return;
81
+ }
82
+ };
83
+ };
84
+ //#endregion
85
+ export { ChannelListViewService };
@@ -1,18 +1,21 @@
1
- import { ChannelsAddOptions, ChannelsLoginOptions, RequestRestartParams } from "../../shared/types/cli.types.js";
1
+ import { ChannelsAddOptions, ChannelsListOptions, ChannelsLoginOptions, RequestRestartParams } from "../../shared/types/cli.types.js";
2
2
  import { resolveChannelConfigView } from "./channel-config-view.js";
3
3
 
4
4
  //#region src/commands/channel/index.d.ts
5
5
  declare class ChannelCommands {
6
6
  private deps;
7
+ private readonly channelListView;
7
8
  constructor(deps: {
8
9
  logo: string;
9
10
  getBridgeDir: () => string;
10
11
  requestRestart: (params: RequestRestartParams) => Promise<void>;
11
12
  });
12
13
  status: () => void;
14
+ list: (opts?: ChannelsListOptions) => void;
13
15
  login: (opts?: ChannelsLoginOptions) => Promise<void>;
14
16
  private runLegacyBridgeLogin;
15
17
  private resolvePluginChannelContext;
18
+ private buildChannelListOutput;
16
19
  private loginPluginChannel;
17
20
  private clonePluginConfig;
18
21
  private assertValidPluginLoginResult;
@@ -1,5 +1,6 @@
1
1
  import { loadPluginRegistry, mergePluginConfigView, toPluginConfigView as toPluginConfigView$1 } from "../plugin/index.js";
2
2
  import { resolveChannelConfigView } from "./channel-config-view.js";
3
+ import { ChannelListViewService } from "./channel-list-view.service.js";
3
4
  import { getWorkspacePath, loadConfig, saveConfig } from "@nextclaw/core";
4
5
  import { buildPluginStatusReport, enablePluginInConfig, getPluginChannelBindings } from "@nextclaw/openclaw-compat";
5
6
  import { spawnSync } from "node:child_process";
@@ -23,6 +24,7 @@ function resolveChannelBindings(pluginRegistry) {
23
24
  return getPluginChannelBindings(pluginRegistry);
24
25
  }
25
26
  var ChannelCommands = class {
27
+ channelListView = new ChannelListViewService({ channelLabels: CHANNEL_LABELS });
26
28
  constructor(deps) {
27
29
  this.deps = deps;
28
30
  }
@@ -51,6 +53,23 @@ var ChannelCommands = class {
51
53
  }
52
54
  }
53
55
  };
56
+ list = (opts = {}) => {
57
+ const output = this.buildChannelListOutput();
58
+ if (opts.json) {
59
+ console.log(JSON.stringify(output, null, 2));
60
+ return;
61
+ }
62
+ console.log("Channels");
63
+ for (const channel of output.channels) {
64
+ const flags = [
65
+ channel.enabled ? "enabled" : "disabled",
66
+ channel.outbound.text ? "outbound:text" : void 0,
67
+ channel.auth.login ? "login" : void 0,
68
+ channel.defaultAccountId ? `defaultAccountId=${channel.defaultAccountId}` : void 0
69
+ ].filter(Boolean);
70
+ console.log(`- ${channel.id} (${channel.label}) [${flags.join(", ")}] plugin=${channel.pluginId}`);
71
+ }
72
+ };
54
73
  login = async (opts = {}) => {
55
74
  const channelId = opts.channel?.trim();
56
75
  if (!channelId) {
@@ -92,6 +111,16 @@ var ChannelCommands = class {
92
111
  bindings
93
112
  };
94
113
  };
114
+ buildChannelListOutput = () => {
115
+ const config = loadConfig();
116
+ const workspaceDir = getWorkspacePath(config.agents.defaults.workspace);
117
+ const pluginRegistry = loadPluginRegistry(config, workspaceDir);
118
+ return this.channelListView.build({
119
+ config,
120
+ workspaceDir,
121
+ pluginBindings: resolveChannelBindings(pluginRegistry)
122
+ });
123
+ };
95
124
  loginPluginChannel = async (config, channelContext, opts) => {
96
125
  const { binding, bindings } = channelContext;
97
126
  const login = binding.channel.auth?.login;
@@ -375,7 +375,8 @@ const defaultRunCommand = async (command, args) => {
375
375
  "ignore",
376
376
  "pipe",
377
377
  "pipe"
378
- ]
378
+ ],
379
+ windowsHide: true
379
380
  });
380
381
  let stdout = "";
381
382
  let stderr = "";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsLoginOptions, 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";
1
+ import { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsListOptions, ChannelsLoginOptions, 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
3
  import { NextclawDistribution } from "./shared/types/distribution.types.js";
4
4
  import { NextclawDistributionService } from "./shared/services/runtime/nextclaw-distribution.service.js";
5
5
  import { readLearningLoopRuntimeConfig } from "@nextclaw/kernel";
6
- export { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsLoginOptions, 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 };
6
+ export { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsListOptions, ChannelsLoginOptions, 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 };
@@ -1,4 +1,4 @@
1
- import { UpdateManifest, UpdateProgress, UpdateSnapshot } from "@nextclaw/kernel/update-contract";
1
+ import { UpdateManifest, UpdateProgress, UpdateSnapshot } from "@nextclaw/kernel";
2
2
 
3
3
  //#region src/launcher/npm-runtime-bundle.types.d.ts
4
4
  type NpmRuntimeBundleManifest = {
@@ -6,8 +6,8 @@ import { inferDefaultNpmRuntimeReleaseChannel } from "./npm-runtime-update-sourc
6
6
  import { NpmRuntimeUpdateStateStore } from "./npm-runtime-update-state.store.js";
7
7
  import { createExternalCommandEnv } from "@nextclaw/core";
8
8
  import { dirname, resolve } from "node:path";
9
- import { fileURLToPath } from "node:url";
10
9
  import { spawnSync } from "node:child_process";
10
+ import { fileURLToPath } from "node:url";
11
11
  //#region src/launcher/npm-runtime-launcher.service.ts
12
12
  var NpmRuntimeLauncher = class {
13
13
  env;
@@ -24,7 +24,8 @@ var NpmRuntimeLauncher = class {
24
24
  env: {
25
25
  ...createExternalCommandEnv(this.env),
26
26
  NEXTCLAW_RUNTIME_BUNDLE_CHILD: "1"
27
- }
27
+ },
28
+ windowsHide: true
28
29
  });
29
30
  process.exit(typeof result.status === "number" ? result.status : 1);
30
31
  };
@@ -14,6 +14,7 @@ var NpmRuntimeUpdateCommandService = class {
14
14
  return snapshot;
15
15
  };
16
16
  runManaged = async (opts) => {
17
+ const downloadOnly = Boolean(opts.downloadOnly || opts.download);
17
18
  const distribution = NextclawDistributionService.get();
18
19
  const source = new NpmRuntimeUpdateSourceService({ packagedPublicKeyPath: distribution.runtimeUpdatePublicKeyPath });
19
20
  const launcherVersion = distribution.version;
@@ -42,7 +43,7 @@ var NpmRuntimeUpdateCommandService = class {
42
43
  }).run({
43
44
  apply: Boolean(opts.apply),
44
45
  checkOnly: Boolean(opts.check),
45
- download: opts.download === void 0 ? true : Boolean(opts.download),
46
+ applyAfterDownload: !downloadOnly,
46
47
  onProgress: opts.json ? void 0 : this.printProgress
47
48
  });
48
49
  };
@@ -3,7 +3,7 @@ import { NpmRuntimeReleaseChannel } from "./npm-runtime-update-source.service.js
3
3
  import { NpmRuntimeUpdateStateStore } from "./npm-runtime-update-state.store.js";
4
4
  import { NpmRuntimeBundleService } from "./npm-runtime-bundle.service.js";
5
5
  import { NpmRuntimeUpdateService } from "./npm-runtime-update.service.js";
6
- import { UpdateProgress, UpdateSnapshot } from "@nextclaw/kernel/update-contract";
6
+ import { UpdateProgress, UpdateSnapshot } from "@nextclaw/kernel";
7
7
 
8
8
  //#region src/launcher/npm-runtime-update.manager.d.ts
9
9
  type NpmRuntimeUpdateManagerOptions = {
@@ -17,8 +17,8 @@ type NpmRuntimeUpdateManagerOptions = {
17
17
  now?: () => Date;
18
18
  };
19
19
  type NpmRuntimeUpdateActionOptions = {
20
- download?: boolean;
21
20
  apply?: boolean;
21
+ applyAfterDownload?: boolean;
22
22
  checkOnly?: boolean;
23
23
  onProgress?: (progress: UpdateProgress) => void;
24
24
  };
@@ -16,10 +16,14 @@ var NpmRuntimeUpdateManager = class {
16
16
  getSnapshot = () => this.toSnapshotFromState(this.options.stateStore.read(), { status: this.options.stateStore.read().downloadedVersion ? "downloaded" : "idle" });
17
17
  run = async (options = {}) => {
18
18
  if (options.apply) return this.applyDownloadedUpdate();
19
+ const applyAfterDownload = options.applyAfterDownload ?? true;
19
20
  const checkedSnapshot = await this.checkForUpdate();
20
- if (options.checkOnly || checkedSnapshot.status !== "update-available") return checkedSnapshot;
21
- if (options.download === false) return checkedSnapshot;
22
- return await this.downloadUpdate(options.onProgress);
21
+ if (options.checkOnly) return checkedSnapshot;
22
+ if (applyAfterDownload && checkedSnapshot.status === "downloaded") return this.applyDownloadedUpdate();
23
+ if (checkedSnapshot.status !== "update-available") return checkedSnapshot;
24
+ const downloadedSnapshot = await this.downloadUpdate(options.onProgress);
25
+ if (!applyAfterDownload || downloadedSnapshot.status !== "downloaded") return downloadedSnapshot;
26
+ return this.applyDownloadedUpdate();
23
27
  };
24
28
  checkForUpdate = async () => {
25
29
  const manifestUrl = this.options.resolveManifestUrl(this.options.channel);
@@ -1,7 +1,7 @@
1
1
  import { NpmRuntimeDownloadedUpdate, NpmRuntimeUpdateProgressReporter } from "./npm-runtime-bundle.types.js";
2
2
  import { NpmRuntimeBundleLayoutStore } from "./npm-runtime-bundle-layout.store.js";
3
3
  import { NpmRuntimeBundleService } from "./npm-runtime-bundle.service.js";
4
- import { UpdateManifest, UpdateManifestReader } from "@nextclaw/kernel/update-contract";
4
+ import { UpdateManifest, UpdateManifestReader } from "@nextclaw/kernel";
5
5
 
6
6
  //#region src/launcher/npm-runtime-update.service.d.ts
7
7
  type FetchLike = typeof fetch;
@@ -1,11 +1,11 @@
1
1
  import { compareNpmRuntimeVersions } from "./npm-runtime-bundle.service.js";
2
+ import { UpdateManifestReader, serializeUnsignedUpdateManifest } from "@nextclaw/kernel";
2
3
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
3
4
  import { dirname, join, resolve, sep } from "node:path";
4
5
  import { fileURLToPath } from "node:url";
5
6
  import { rm } from "node:fs/promises";
6
7
  import { createHash, createPublicKey, verify } from "node:crypto";
7
8
  import JSZip from "jszip";
8
- import { UpdateManifestReader, serializeUnsignedUpdateManifest } from "@nextclaw/kernel/update-contract";
9
9
  //#region src/launcher/npm-runtime-update.service.ts
10
10
  var NpmRuntimeUpdateService = class {
11
11
  platform;
@@ -2,6 +2,7 @@ import { RestartCoordinator } from "./shared/services/restart/restart-coordinato
2
2
  import { initializeConfigIfMissing } from "./shared/services/runtime/runtime-config-init.service.js";
3
3
  import { writeRestartSentinel } from "./shared/services/restart/restart-sentinel.service.js";
4
4
  import { createTopLevelNextclawCommandEnv } from "./shared/utils/top-level-nextclaw-command-env.utils.js";
5
+ import { resolveCliSubcommandLaunch } from "./shared/utils/marketplace/cli-subcommand-launch.utils.js";
5
6
  import { logStartupTrace, measureStartupSync } from "./shared/utils/startup-trace.js";
6
7
  import { isProcessRunning } from "./shared/utils/cli.utils.js";
7
8
  import { NextclawDistributionService } from "./shared/services/runtime/nextclaw-distribution.service.js";
@@ -46,7 +47,6 @@ import { RemoteRuntimeActions } from "@nextclaw/remote";
46
47
  import { getPluginChannelBindings, resolvePluginChannelMessageToolHints, setPluginRuntimeBridge } from "@nextclaw/openclaw-compat";
47
48
  import { existsSync, mkdirSync } from "node:fs";
48
49
  import { join } from "node:path";
49
- import { fileURLToPath } from "node:url";
50
50
  import { spawn } from "node:child_process";
51
51
  //#region src/service-runtime.service.ts
52
52
  const FORCED_PUBLIC_UI_HOST = "0.0.0.0";
@@ -204,12 +204,16 @@ var NextclawServiceRuntime = class {
204
204
  if (!state || state.pid !== process.pid) return;
205
205
  const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 55667;
206
206
  const delayMs = typeof requestedDelayMs === "number" && Number.isFinite(requestedDelayMs) ? Math.max(0, Math.floor(requestedDelayMs)) : 100;
207
- const startArgs = [
208
- process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() || fileURLToPath(new URL("./index.js", import.meta.url)),
209
- "start",
210
- "--ui-port",
211
- String(uiPort)
212
- ];
207
+ const launch = resolveCliSubcommandLaunch({
208
+ argvEntry: process.argv[1],
209
+ importMetaUrl: import.meta.url,
210
+ cliArgs: [
211
+ "start",
212
+ "--ui-port",
213
+ String(uiPort)
214
+ ],
215
+ nodePath: process.execPath
216
+ });
213
217
  const serviceStatePath = managedServiceStateStore.path;
214
218
  const helperScript = [
215
219
  "const { spawnSync } = require(\"node:child_process\");",
@@ -218,9 +222,8 @@ var NextclawServiceRuntime = class {
218
222
  `const delayMs = ${delayMs};`,
219
223
  "const maxWaitMs = 120000;",
220
224
  "const retryIntervalMs = 1000;",
221
- "const startTimeoutMs = 60000;",
222
- `const nodePath = ${JSON.stringify(process.execPath)};`,
223
- `const startArgs = ${JSON.stringify(startArgs)};`,
225
+ `const command = ${JSON.stringify(launch.command)};`,
226
+ `const args = ${JSON.stringify(launch.args)};`,
224
227
  `const serviceStatePath = ${JSON.stringify(serviceStatePath)};`,
225
228
  "function isRunning(pid) {",
226
229
  " try {",
@@ -241,20 +244,17 @@ var NextclawServiceRuntime = class {
241
244
  " }",
242
245
  "}",
243
246
  "function tryStart() {",
244
- " spawnSync(nodePath, startArgs, {",
247
+ " spawnSync(command, args, {",
245
248
  " stdio: \"ignore\",",
246
249
  " env: process.env,",
247
- " timeout: startTimeoutMs",
250
+ " timeout: 60000,",
251
+ " windowsHide: true",
248
252
  " });",
249
253
  "}",
250
254
  "setTimeout(() => {",
251
255
  " const startedAt = Date.now();",
252
256
  " const tick = () => {",
253
- " if (hasReplacementService()) {",
254
- " process.exit(0);",
255
- " return;",
256
- " }",
257
- " if (Date.now() - startedAt >= maxWaitMs) {",
257
+ " if (hasReplacementService() || Date.now() - startedAt >= maxWaitMs) {",
258
258
  " process.exit(0);",
259
259
  " return;",
260
260
  " }",
@@ -272,7 +272,8 @@ var NextclawServiceRuntime = class {
272
272
  spawn(process.execPath, ["-e", helperScript], {
273
273
  detached: true,
274
274
  stdio: "ignore",
275
- env: createTopLevelNextclawCommandEnv(process.env)
275
+ env: createTopLevelNextclawCommandEnv(process.env),
276
+ windowsHide: true
276
277
  }).unref();
277
278
  this.selfRelaunchArmed = true;
278
279
  console.warn(`Gateway self-restart armed (${reason}).`);
@@ -267,11 +267,9 @@ var GatewayControllerImpl = class {
267
267
  });
268
268
  };
269
269
  updateRun = async (params) => {
270
+ const { note, restartDelayMs, sessionKey, timeoutMs } = params;
270
271
  const versionBefore = getPackageVersion$1();
271
- params.timeoutMs;
272
- const updateCommand = new NpmRuntimeUpdateCommandService();
273
- const downloadedSnapshot = await updateCommand.runManaged({ download: true });
274
- const snapshot = downloadedSnapshot.status === "downloaded" ? await updateCommand.runManaged({ apply: true }) : downloadedSnapshot;
272
+ const snapshot = await new NpmRuntimeUpdateCommandService().runManaged({});
275
273
  if (snapshot.status === "blocked" || snapshot.status === "failed") return {
276
274
  ok: false,
277
275
  error: snapshot.errorMessage ?? snapshot.blockReason ?? "update failed",
@@ -283,12 +281,12 @@ var GatewayControllerImpl = class {
283
281
  }
284
282
  };
285
283
  const versionAfter = getPackageVersion$1();
286
- const delayMs = params.restartDelayMs ?? 0;
284
+ const delayMs = restartDelayMs ?? 0;
287
285
  const sentinelPath = await this.writeRestartSentinelPayload({
288
286
  kind: "update.run",
289
287
  status: "ok",
290
- sessionKey: params.sessionKey,
291
- note: params.note,
288
+ sessionKey,
289
+ note,
292
290
  reason: "update.run",
293
291
  strategy: "runtime-bundle"
294
292
  });
@@ -298,7 +296,7 @@ var GatewayControllerImpl = class {
298
296
  });
299
297
  return {
300
298
  ok: true,
301
- note: params.note ?? null,
299
+ note: note ?? null,
302
300
  restart: {
303
301
  scheduled: true,
304
302
  delayMs
@@ -22,6 +22,9 @@ type ExtensionManifest = {
22
22
  configSchema?: Record<string, unknown>;
23
23
  configUiHints?: Record<string, Record<string, unknown>>;
24
24
  auth?: boolean | Record<string, unknown>;
25
+ outbound?: {
26
+ text?: boolean;
27
+ };
25
28
  }>;
26
29
  };
27
30
  };
@@ -37,8 +40,12 @@ type ExtensionLifecycleServiceOptions = {
37
40
  };
38
41
  declare class ExtensionManifestDiscoveryService {
39
42
  readonly discover: (roots: string[]) => Promise<ExtensionManifest[]>;
43
+ readonly discoverSync: (roots: string[]) => ExtensionManifest[];
40
44
  private readonly discoverRoot;
45
+ private readonly discoverRootSync;
41
46
  private readonly readManifestIfExists;
47
+ private readonly readManifestIfExistsSync;
48
+ private readonly readDirectoriesSync;
42
49
  }
43
50
  declare class ExtensionLifecycleService {
44
51
  private readonly options;
@@ -1,3 +1,4 @@
1
+ import { readFileSync, readdirSync } from "node:fs";
1
2
  import { dirname, join } from "node:path";
2
3
  import { spawn } from "node:child_process";
3
4
  import { readFile, readdir } from "node:fs/promises";
@@ -62,12 +63,22 @@ var ExtensionManifestDiscoveryService = class {
62
63
  for (const root of roots) manifests.push(...await this.discoverRoot(root));
63
64
  return manifests;
64
65
  };
66
+ discoverSync = (roots) => {
67
+ const manifests = [];
68
+ for (const root of roots) manifests.push(...this.discoverRootSync(root));
69
+ return manifests;
70
+ };
65
71
  discoverRoot = async (root) => {
66
72
  const directManifest = await this.readManifestIfExists(join(root, EXTENSION_MANIFEST_FILE));
67
73
  if (directManifest) return [directManifest];
68
74
  const entries = await readdir(root, { withFileTypes: true }).catch(() => []);
69
75
  return (await Promise.all(entries.filter((entry) => entry.isDirectory()).map((entry) => this.readManifestIfExists(join(root, entry.name, EXTENSION_MANIFEST_FILE))))).filter((manifest) => Boolean(manifest));
70
76
  };
77
+ discoverRootSync = (root) => {
78
+ const directManifest = this.readManifestIfExistsSync(join(root, EXTENSION_MANIFEST_FILE));
79
+ if (directManifest) return [directManifest];
80
+ return this.readDirectoriesSync(root).map((entry) => this.readManifestIfExistsSync(join(root, entry, EXTENSION_MANIFEST_FILE))).filter((manifest) => Boolean(manifest));
81
+ };
71
82
  readManifestIfExists = async (path) => {
72
83
  try {
73
84
  return toManifest(JSON.parse(await readFile(path, "utf-8")), dirname(path));
@@ -76,6 +87,21 @@ var ExtensionManifestDiscoveryService = class {
76
87
  throw error;
77
88
  }
78
89
  };
90
+ readManifestIfExistsSync = (path) => {
91
+ try {
92
+ return toManifest(JSON.parse(readFileSync(path, "utf-8")), dirname(path));
93
+ } catch (error) {
94
+ if (error.code === "ENOENT") return null;
95
+ throw error;
96
+ }
97
+ };
98
+ readDirectoriesSync = (root) => {
99
+ try {
100
+ return readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
101
+ } catch {
102
+ return [];
103
+ }
104
+ };
79
105
  };
80
106
  var ExtensionLifecycleService = class {
81
107
  processes = /* @__PURE__ */ new Map();
@@ -88,13 +114,17 @@ var ExtensionLifecycleService = class {
88
114
  }
89
115
  startAll = async (manifests) => {
90
116
  const started = [];
91
- for (const manifest of manifests) started.push(this.start(manifest));
117
+ for (const manifest of manifests) try {
118
+ started.push(this.start(manifest));
119
+ } catch (error) {
120
+ this.logger.warn(`Extension ${manifest.id} failed to start: ${error instanceof Error ? error.message : String(error)}`);
121
+ }
92
122
  return started;
93
123
  };
94
124
  start = (manifest) => {
95
125
  const existing = this.processes.get(manifest.id);
96
126
  if (existing) return existing;
97
- const child = this.spawnProcess(manifest.server.command, manifest.server.args ?? [], {
127
+ const child = this.spawnProcess(manifest.server.command === "node" || manifest.server.command === "node.exe" ? process.execPath : manifest.server.command, manifest.server.args ?? [], {
98
128
  cwd: manifest.rootDir,
99
129
  env: {
100
130
  ...process.env,
@@ -108,7 +138,8 @@ var ExtensionLifecycleService = class {
108
138
  "ignore",
109
139
  "ignore",
110
140
  "inherit"
111
- ]
141
+ ],
142
+ windowsHide: true
112
143
  });
113
144
  const running = {
114
145
  manifest,
@@ -44,6 +44,7 @@ declare class ServiceExtensionRuntime {
44
44
  private readonly toContributions;
45
45
  private readonly readConfigUiHints;
46
46
  private readonly createChannelAuth;
47
+ private readonly createChannelOutbound;
47
48
  private readonly requestExtension;
48
49
  private readonly assertAuthorized;
49
50
  }
@@ -2,7 +2,7 @@ import { resolveDevFirstPartyPluginDir } from "../../../commands/plugin/developm
2
2
  import { ExtensionLifecycleService, ExtensionManifestDiscoveryService } from "./extension-lifecycle.service.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { getDataPath } from "@nextclaw/core";
5
- import { existsSync, readFileSync, readdirSync } from "node:fs";
5
+ import { existsSync, readFileSync } from "node:fs";
6
6
  import { dirname, join, resolve } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { randomUUID } from "node:crypto";
@@ -13,7 +13,7 @@ const EXTENSION_REQUEST_EVENT_TYPE = "extension.request";
13
13
  const EXTENSION_RESPONSE_INGRESS_TYPE = "extension.response";
14
14
  const serviceRequire = createRequire(import.meta.url);
15
15
  const EXTENSION_REQUEST_TIMEOUT_MS = 6e4;
16
- var ExtensionChannelAuthClient = class {
16
+ var ExtensionChannelClient = class {
17
17
  constructor(params) {
18
18
  this.params = params;
19
19
  }
@@ -45,6 +45,16 @@ var ExtensionChannelAuthClient = class {
45
45
  sessionId
46
46
  }
47
47
  });
48
+ sendText = async ({ to, text, accountId }) => await this.params.request({
49
+ extensionId: this.params.extensionId,
50
+ kind: "channel.outbound.sendText",
51
+ payload: {
52
+ channelId: this.params.channelId,
53
+ to,
54
+ text,
55
+ accountId
56
+ }
57
+ });
48
58
  };
49
59
  function uniquePaths(paths) {
50
60
  const seen = /* @__PURE__ */ new Set();
@@ -67,6 +77,7 @@ function findExtensionManifestRoot(startPath) {
67
77
  }
68
78
  }
69
79
  function readBuiltinExtensionPackages() {
80
+ if (process.env.NEXTCLAW_DISABLE_BUILTIN_EXTENSIONS === "1") return [];
70
81
  const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), "../../../..", "package.json");
71
82
  try {
72
83
  const packages = JSON.parse(readFileSync(packageJsonPath, "utf-8")).nextclaw?.builtinExtensions;
@@ -75,43 +86,12 @@ function readBuiltinExtensionPackages() {
75
86
  return [];
76
87
  }
77
88
  }
78
- function readPackageName(packageJsonPath) {
79
- try {
80
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
81
- return typeof packageJson.name === "string" ? packageJson.name : void 0;
82
- } catch {
83
- return;
84
- }
85
- }
86
- function readDirectoryNames(root) {
87
- try {
88
- return readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => String(entry.name));
89
- } catch {
90
- return [];
91
- }
92
- }
93
- function findWorkspacePackageRoot(packageName) {
94
- const roots = [
95
- resolve(process.cwd(), "packages", "extensions"),
96
- resolve(process.cwd(), "packages"),
97
- resolve(process.cwd(), "apps"),
98
- resolve(process.cwd(), "workers")
99
- ];
100
- for (const root of roots) for (const name of readDirectoryNames(root)) {
101
- const candidateRoot = join(root, name);
102
- if (readPackageName(join(candidateRoot, "package.json")) === packageName && existsSync(join(candidateRoot, "nextclaw.extension.json"))) return candidateRoot;
103
- }
104
- }
105
89
  function resolveBuiltinExtensionManifestRoots() {
106
90
  const roots = [];
107
- for (const packageName of readBuiltinExtensionPackages()) {
108
- try {
109
- const root = findExtensionManifestRoot(dirname(serviceRequire.resolve(packageName)));
110
- if (root) roots.push(root);
111
- } catch {}
112
- const workspaceRoot = findWorkspacePackageRoot(packageName);
113
- if (workspaceRoot) roots.push(workspaceRoot);
114
- }
91
+ for (const packageName of readBuiltinExtensionPackages()) try {
92
+ const root = findExtensionManifestRoot(dirname(serviceRequire.resolve(packageName)));
93
+ if (root) roots.push(root);
94
+ } catch {}
115
95
  return uniquePaths(roots);
116
96
  }
117
97
  function readRecord(value) {
@@ -281,7 +261,8 @@ var ServiceExtensionRuntime = class {
281
261
  schema: channel.configSchema,
282
262
  ...configUiHints ? { uiHints: configUiHints } : {}
283
263
  } } : {},
284
- ...channel.auth ? { auth: this.createChannelAuth(manifest.id, channelId) } : {}
264
+ ...channel.auth ? { auth: this.createChannelAuth(manifest.id, channelId) } : {},
265
+ ...channel.outbound?.text ? { outbound: this.createChannelOutbound(manifest.id, channelId) } : {}
285
266
  }
286
267
  });
287
268
  uiMetadata.push({
@@ -300,7 +281,12 @@ var ServiceExtensionRuntime = class {
300
281
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
301
282
  return value;
302
283
  };
303
- createChannelAuth = (extensionId, channelId) => new ExtensionChannelAuthClient({
284
+ createChannelAuth = (extensionId, channelId) => new ExtensionChannelClient({
285
+ extensionId,
286
+ channelId,
287
+ request: this.requestExtension
288
+ });
289
+ createChannelOutbound = (extensionId, channelId) => new ExtensionChannelClient({
304
290
  extensionId,
305
291
  channelId,
306
292
  request: this.requestExtension
@@ -3,9 +3,9 @@ import { openBrowser, resolveUiConfig, resolveUiStaticDir } from "../../utils/cl
3
3
  import { NextclawDistributionService } from "../runtime/nextclaw-distribution.service.js";
4
4
  import { managedServiceStateStore } from "../../stores/managed-service-state.store.js";
5
5
  import { resolveChannelConfigView } from "../../../commands/channel/channel-config-view.js";
6
+ import { ServiceExtensionRuntime } from "../extensions/service-extension-runtime.service.js";
6
7
  import { localUiRuntimeStore } from "../../stores/local-ui-runtime.store.js";
7
8
  import { GatewayControllerImpl } from "../../controllers/gateway.controller.js";
8
- import { ServiceExtensionRuntime } from "../extensions/service-extension-runtime.service.js";
9
9
  import { ServiceFileWatcherRegistry, markLocalUiRuntimeIfStarted, startGatewayRuntimeSupport, watchServiceConfigFile } from "./service-startup-support.service.js";
10
10
  import { GatewayPluginManager } from "./managers/gateway-plugin.manager.js";
11
11
  import { GatewayRemoteManager } from "./managers/gateway-remote.manager.js";
@@ -1,6 +1,6 @@
1
+ import { resolveCliSubcommandEntry } from "../../utils/marketplace/cli-subcommand-launch.utils.js";
1
2
  import { isLoopbackHost, resolvePublicIp, resolveUiStaticDir } from "../../utils/cli.utils.js";
2
3
  import { NextclawDistributionService } from "./nextclaw-distribution.service.js";
3
- import { resolveCliSubcommandEntry } from "../../utils/marketplace/cli-subcommand-launch.utils.js";
4
4
  import { describeUnmanagedHealthyTargetMessage, inspectUiTarget } from "../../utils/service-port-probe.utils.js";
5
5
  import { ManagedServiceCommandService } from "./service-managed-startup.service.js";
6
6
  import { buildMarketplaceSkillInstallArgs, pickUserFacingCommandSummary } from "../../utils/marketplace/service-marketplace-helpers.utils.js";
@@ -86,7 +86,8 @@ var RuntimeCommandService = class {
86
86
  "ignore",
87
87
  "pipe",
88
88
  "pipe"
89
- ]
89
+ ],
90
+ windowsHide: true
90
91
  });
91
92
  let stdout = "";
92
93
  let stderr = "";
@@ -1,8 +1,8 @@
1
1
  import { createTopLevelNextclawCommandEnv } from "../../utils/top-level-nextclaw-command-env.utils.js";
2
+ import { resolveCliSubcommandLaunch } from "../../utils/marketplace/cli-subcommand-launch.utils.js";
2
3
  import { isProcessRunning, openBrowser, resolveServiceLogPath, resolveUiApiBase, resolveUiConfig, waitForExit } from "../../utils/cli.utils.js";
3
4
  import { managedServiceStateStore } from "../../stores/managed-service-state.store.js";
4
5
  import { localUiRuntimeStore } from "../../stores/local-ui-runtime.store.js";
5
- import { resolveCliSubcommandLaunch } from "../../utils/marketplace/cli-subcommand-launch.utils.js";
6
6
  import { writeInitialManagedServiceState, writeReadyManagedServiceState } from "./utils/service-remote-runtime.utils.js";
7
7
  import { resolveManagedServiceReadySnapshot, resolveManagedServiceUiBinding, resolveSessionRouteCandidate } from "./utils/managed-service-routing.utils.js";
8
8
  import { probeHealthEndpoint } from "../../utils/service-port-probe.utils.js";
@@ -39,7 +39,8 @@ function spawnManagedService(params) {
39
39
  const child = spawn(cliLaunch.command, childArgs, {
40
40
  env: createTopLevelNextclawCommandEnv(process.env),
41
41
  stdio: "ignore",
42
- detached: true
42
+ detached: true,
43
+ windowsHide: true
43
44
  });
44
45
  appendStartupStage(logPath, `spawned background process pid=${child.pid ?? "unknown"}`);
45
46
  if (!child.pid) {
@@ -36,7 +36,7 @@ var DeferredUiNcpAgentControllerOwner = class {
36
36
  },
37
37
  send: async (envelope) => {
38
38
  if (!this.activeAgent) throw createUnavailableError();
39
- await this.activeAgent.agentClientEndpoint.send(envelope);
39
+ return await this.activeAgent.agentClientEndpoint.send(envelope);
40
40
  },
41
41
  stream: async (payload) => {
42
42
  if (!this.activeAgent) throw createUnavailableError();
@@ -89,6 +89,7 @@ var CompanionRuntimeService = class {
89
89
  ], {
90
90
  detached: true,
91
91
  stdio: "ignore",
92
+ windowsHide: true,
92
93
  env: {
93
94
  ...process.env,
94
95
  NEXTCLAW_COMPANION_RUNTIME_STATE_PATH: this.runtimeStore.path
@@ -2,8 +2,8 @@ import { findExecutableOnPath } from "../../utils/cli.utils.js";
2
2
  import { APP_NAME, getDataDir } from "@nextclaw/core";
3
3
  import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join, resolve } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
5
  import { spawnSync } from "node:child_process";
6
+ import { fileURLToPath } from "node:url";
7
7
  //#region src/shared/services/workspace/workspace-manager.service.ts
8
8
  var WorkspaceManager = class {
9
9
  constructor(logo) {
@@ -56,6 +56,7 @@ type MarketplaceSkillsRecommendCommandOptions = {
56
56
  type UpdateCommandOptions = {
57
57
  check?: boolean;
58
58
  download?: boolean;
59
+ downloadOnly?: boolean;
59
60
  apply?: boolean;
60
61
  channel?: string;
61
62
  manifestUrl?: string;
@@ -125,6 +126,9 @@ type ChannelsAddOptions = {
125
126
  url?: string;
126
127
  httpUrl?: string;
127
128
  };
129
+ type ChannelsListOptions = {
130
+ json?: boolean;
131
+ };
128
132
  type ChannelsLoginOptions = {
129
133
  channel?: string;
130
134
  account?: string;
@@ -279,4 +283,4 @@ type RequestRestartParams = {
279
283
  mode?: "execute" | "notify";
280
284
  };
281
285
  //#endregion
282
- export { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsLoginOptions, ConfigGetOptions, ConfigSetOptions, CronAddOptions, DoctorCommandOptions, GatewayCommandOptions, HealthProbe, LoginCommandOptions, LogsTailCommandOptions, MarketplaceSkillsRecommendCommandOptions, MarketplaceSkillsSearchCommandOptions, McpAddCommandOptions, McpDoctorOptions, McpListOptions, PluginsInfoOptions, PluginsInstallOptions, PluginsListOptions, PluginsUninstallOptions, type RemoteConnectCommandOptions, type RemoteDoctorCommandOptions, type RemoteEnableCommandOptions, type RemoteStatusCommandOptions, RequestRestartParams, RuntimeStatusReport, SecretsApplyOptions, SecretsAuditOptions, SecretsConfigureOptions, SecretsReloadOptions, ServiceAutostartCommandOptions, SkillsInfoCommandOptions, SkillsInstalledCommandOptions, StartCommandOptions, StatusCommandOptions, UiCommandOptions, UpdateCommandOptions, UsageCommandOptions };
286
+ export { AccountCommandOptions, AccountSetUsernameCommandOptions, AgentCommandOptions, AgentsListCommandOptions, AgentsNewCommandOptions, AgentsRemoveCommandOptions, AgentsRuntimesCommandOptions, AgentsUpdateCommandOptions, ChannelsAddOptions, ChannelsListOptions, ChannelsLoginOptions, ConfigGetOptions, ConfigSetOptions, CronAddOptions, DoctorCommandOptions, GatewayCommandOptions, HealthProbe, LoginCommandOptions, LogsTailCommandOptions, MarketplaceSkillsRecommendCommandOptions, MarketplaceSkillsSearchCommandOptions, McpAddCommandOptions, McpDoctorOptions, McpListOptions, PluginsInfoOptions, PluginsInstallOptions, PluginsListOptions, PluginsUninstallOptions, type RemoteConnectCommandOptions, type RemoteDoctorCommandOptions, type RemoteEnableCommandOptions, type RemoteStatusCommandOptions, RequestRestartParams, RuntimeStatusReport, SecretsApplyOptions, SecretsAuditOptions, SecretsConfigureOptions, SecretsReloadOptions, ServiceAutostartCommandOptions, SkillsInfoCommandOptions, SkillsInstalledCommandOptions, StartCommandOptions, StatusCommandOptions, UiCommandOptions, UpdateCommandOptions, UsageCommandOptions };
@@ -193,7 +193,8 @@ function openBrowser(url) {
193
193
  spawn(command, args, {
194
194
  stdio: "ignore",
195
195
  detached: true,
196
- env: createExternalCommandEnv(process.env)
196
+ env: createExternalCommandEnv(process.env),
197
+ windowsHide: true
197
198
  }).unref();
198
199
  return true;
199
200
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/service",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "private": false,
5
5
  "description": "NextClaw long-running service host and runtime lifecycle.",
6
6
  "type": "module",
@@ -35,24 +35,24 @@
35
35
  "commander": "^12.1.0",
36
36
  "jszip": "^3.10.1",
37
37
  "yaml": "^2.8.1",
38
- "@nextclaw/channel-extension-feishu": "0.1.1",
39
- "@nextclaw/core": "0.12.17",
40
- "@nextclaw/kernel": "0.1.6",
41
- "@nextclaw/mcp": "0.1.82",
42
- "@nextclaw/channel-extension-weixin": "0.1.4",
43
- "@nextclaw/ncp-http-agent-server": "0.3.22",
44
- "@nextclaw/ncp": "0.5.10",
45
- "@nextclaw/ncp-toolkit": "0.5.15",
46
- "@nextclaw/openclaw-compat": "1.0.17",
47
- "@nextclaw/nextclaw-hermes-acp-bridge": "0.1.9",
48
- "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.1.10",
49
- "@nextclaw/ncp-agent-runtime": "0.3.20",
50
- "@nextclaw/nextclaw-ncp-runtime-http-client": "0.1.9",
51
- "@nextclaw/remote": "0.1.94",
52
- "@nextclaw/ncp-mcp": "0.1.84",
53
- "@nextclaw/runtime": "0.2.49",
54
- "@nextclaw/shared": "0.1.4",
55
- "@nextclaw/server": "0.12.17"
38
+ "@nextclaw/core": "0.12.18",
39
+ "@nextclaw/channel-extension-feishu": "0.1.2",
40
+ "@nextclaw/channel-extension-weixin": "0.1.5",
41
+ "@nextclaw/kernel": "0.1.7",
42
+ "@nextclaw/ncp-agent-runtime": "0.3.21",
43
+ "@nextclaw/ncp": "0.5.11",
44
+ "@nextclaw/mcp": "0.1.83",
45
+ "@nextclaw/nextclaw-hermes-acp-bridge": "0.1.10",
46
+ "@nextclaw/ncp-http-agent-server": "0.3.23",
47
+ "@nextclaw/ncp-toolkit": "0.5.16",
48
+ "@nextclaw/ncp-mcp": "0.1.85",
49
+ "@nextclaw/nextclaw-ncp-runtime-http-client": "0.1.10",
50
+ "@nextclaw/openclaw-compat": "1.0.18",
51
+ "@nextclaw/runtime": "0.2.50",
52
+ "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.1.11",
53
+ "@nextclaw/shared": "0.1.5",
54
+ "@nextclaw/remote": "0.1.95",
55
+ "@nextclaw/server": "0.12.18"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/node": "^20.17.6",