@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.
- package/dist/commands/channel/channel-list-view.service.d.ts +39 -0
- package/dist/commands/channel/channel-list-view.service.js +85 -0
- package/dist/commands/channel/index.d.ts +4 -1
- package/dist/commands/channel/index.js +29 -0
- package/dist/commands/service/services/autostart/windows-task-autostart.service.js +2 -1
- package/dist/index.d.ts +2 -2
- package/dist/launcher/npm-runtime-bundle.types.d.ts +1 -1
- package/dist/launcher/npm-runtime-launcher.service.js +3 -2
- package/dist/launcher/npm-runtime-update-command.service.js +2 -1
- package/dist/launcher/npm-runtime-update.manager.d.ts +2 -2
- package/dist/launcher/npm-runtime-update.manager.js +7 -3
- package/dist/launcher/npm-runtime-update.service.d.ts +1 -1
- package/dist/launcher/npm-runtime-update.service.js +1 -1
- package/dist/service-runtime.service.js +19 -18
- package/dist/shared/controllers/gateway.controller.js +6 -8
- package/dist/shared/services/extensions/extension-lifecycle.service.d.ts +7 -0
- package/dist/shared/services/extensions/extension-lifecycle.service.js +34 -3
- package/dist/shared/services/extensions/service-extension-runtime.service.d.ts +1 -0
- package/dist/shared/services/extensions/service-extension-runtime.service.js +25 -39
- package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.js +1 -1
- package/dist/shared/services/runtime/runtime-command.service.js +3 -2
- package/dist/shared/services/runtime/service-managed-startup.service.js +3 -2
- package/dist/shared/services/session/service-deferred-ncp-agent.service.js +1 -1
- package/dist/shared/services/ui/companion-runtime.service.js +1 -0
- package/dist/shared/services/workspace/workspace-manager.service.js +1 -1
- package/dist/shared/types/cli.types.d.ts +5 -1
- package/dist/shared/utils/cli.utils.js +2 -1
- 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;
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
21
|
-
if (
|
|
22
|
-
|
|
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
|
|
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
|
|
208
|
-
process.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
222
|
-
`const
|
|
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(
|
|
247
|
+
" spawnSync(command, args, {",
|
|
245
248
|
" stdio: \"ignore\",",
|
|
246
249
|
" env: process.env,",
|
|
247
|
-
" timeout:
|
|
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
|
-
|
|
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 =
|
|
284
|
+
const delayMs = restartDelayMs ?? 0;
|
|
287
285
|
const sentinelPath = await this.writeRestartSentinelPayload({
|
|
288
286
|
kind: "update.run",
|
|
289
287
|
status: "ok",
|
|
290
|
-
sessionKey
|
|
291
|
-
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:
|
|
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)
|
|
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
|
|
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
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
|
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();
|
|
@@ -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.
|
|
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/
|
|
39
|
-
"@nextclaw/
|
|
40
|
-
"@nextclaw/
|
|
41
|
-
"@nextclaw/
|
|
42
|
-
"@nextclaw/
|
|
43
|
-
"@nextclaw/ncp
|
|
44
|
-
"@nextclaw/
|
|
45
|
-
"@nextclaw/
|
|
46
|
-
"@nextclaw/
|
|
47
|
-
"@nextclaw/
|
|
48
|
-
"@nextclaw/
|
|
49
|
-
"@nextclaw/ncp-
|
|
50
|
-
"@nextclaw/
|
|
51
|
-
"@nextclaw/
|
|
52
|
-
"@nextclaw/ncp-
|
|
53
|
-
"@nextclaw/
|
|
54
|
-
"@nextclaw/
|
|
55
|
-
"@nextclaw/server": "0.12.
|
|
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",
|