@nextclaw/service 0.1.10 → 0.1.12

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 (71) hide show
  1. package/dist/cli/commands/agent/agent-runtime.utils.d.ts +1 -2
  2. package/dist/cli/commands/agent/agent-runtime.utils.js +6 -50
  3. package/dist/cli/commands/agent/cli-agent-runner.utils.d.ts +0 -7
  4. package/dist/cli/commands/agent/cli-agent-runner.utils.js +7 -9
  5. package/dist/cli/commands/agent/services/agent-commands.service.js +0 -1
  6. package/dist/cli/commands/skills/index.js +1 -1
  7. package/dist/cli/commands/skills/marketplace-client.d.ts +11 -1
  8. package/dist/cli/commands/skills/marketplace-client.js +39 -1
  9. package/dist/cli/commands/skills/marketplace-command-options.utils.d.ts +1 -1
  10. package/dist/cli/commands/skills/marketplace.metadata.d.ts +3 -12
  11. package/dist/cli/commands/skills/marketplace.metadata.js +1 -87
  12. package/dist/cli/commands/skills/{marketplace.service.d.ts → marketplace.utils.d.ts} +1 -1
  13. package/dist/cli/commands/skills/{marketplace.service.js → marketplace.utils.js} +11 -47
  14. package/dist/cli/commands/skills/skills-query.service.d.ts +5 -37
  15. package/dist/cli/commands/skills/skills-query.service.js +16 -98
  16. package/dist/cli/commands/usage/services/llm-usage-command.service.d.ts +3 -5
  17. package/dist/cli/commands/usage/services/llm-usage-command.service.js +16 -26
  18. package/dist/commands/channel/channel-list-view.service.d.ts +7 -14
  19. package/dist/commands/channel/channel-list-view.service.js +20 -41
  20. package/dist/commands/channel/index.js +3 -9
  21. package/dist/commands/plugin/index.d.ts +2 -4
  22. package/dist/commands/plugin/index.js +8 -20
  23. package/dist/commands/plugin/{plugin-command-utils.d.ts → plugin-command.utils.d.ts} +1 -2
  24. package/dist/commands/plugin/{plugin-command-utils.js → plugin-command.utils.js} +2 -4
  25. package/dist/commands/plugin/{plugin-mutation-actions.d.ts → plugin-mutation-actions.utils.d.ts} +1 -1
  26. package/dist/commands/plugin/{plugin-mutation-actions.js → plugin-mutation-actions.utils.js} +2 -2
  27. package/dist/commands/service/services/autostart/linux-systemd-autostart.service.js +1 -1
  28. package/dist/commands/service/services/autostart/macos-launch-agent-autostart.service.js +1 -1
  29. package/dist/commands/service/services/autostart/windows-task-autostart.service.js +1 -1
  30. package/dist/launcher/npm-runtime-launcher.service.js +1 -1
  31. package/dist/service-runtime.service.d.ts +1 -1
  32. package/dist/service-runtime.service.js +7 -22
  33. package/dist/shared/controllers/gateway.controller.d.ts +3 -11
  34. package/dist/shared/controllers/gateway.controller.js +24 -180
  35. package/dist/shared/services/gateway/managers/gateway-plugin.manager.d.ts +3 -9
  36. package/dist/shared/services/gateway/managers/gateway-plugin.manager.js +30 -88
  37. package/dist/shared/services/gateway/nextclaw-app.service.d.ts +2 -7
  38. package/dist/shared/services/gateway/nextclaw-app.service.js +6 -16
  39. package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.d.ts +4 -9
  40. package/dist/shared/services/gateway/nextclaw-gateway-runtime.service.js +12 -46
  41. package/dist/shared/services/gateway/{cron-job-handler.service.d.ts → utils/cron-job-handler.utils.d.ts} +3 -6
  42. package/dist/shared/services/gateway/utils/cron-job-handler.utils.js +57 -0
  43. package/dist/shared/services/marketplace/service-marketplace-installer.service.js +3 -3
  44. package/dist/shared/services/plugin/utils/plugin-runtime-bridge.utils.js +1 -1
  45. package/dist/shared/services/runtime/runtime-command.service.js +2 -2
  46. package/dist/shared/services/runtime/service-managed-startup.service.js +1 -1
  47. package/dist/shared/services/ui/companion-runtime.service.js +1 -1
  48. package/dist/shared/services/workspace/workspace-manager.service.js +8 -10
  49. package/dist/shared/utils/cli.utils.js +1 -1
  50. package/package.json +20 -20
  51. package/dist/cli/commands/usage/services/llm-usage-query.service.d.ts +0 -43
  52. package/dist/cli/commands/usage/services/llm-usage-query.service.js +0 -85
  53. package/dist/commands/plugin/development-source/dev-plugin-overrides.utils.d.ts +0 -18
  54. package/dist/commands/plugin/development-source/dev-plugin-overrides.utils.js +0 -111
  55. package/dist/commands/plugin/development-source/first-party-plugin-load-paths.utils.d.ts +0 -9
  56. package/dist/commands/plugin/development-source/first-party-plugin-load-paths.utils.js +0 -183
  57. package/dist/commands/plugin/plugin-extension-registry.d.ts +0 -10
  58. package/dist/commands/plugin/plugin-extension-registry.js +0 -35
  59. package/dist/commands/plugin/plugin-registry-loader.utils.d.ts +0 -15
  60. package/dist/commands/plugin/plugin-registry-loader.utils.js +0 -43
  61. package/dist/commands/plugin/plugin-reload.d.ts +0 -13
  62. package/dist/commands/plugin/plugin-reload.js +0 -42
  63. package/dist/shared/services/extensions/extension-lifecycle.service.d.ts +0 -63
  64. package/dist/shared/services/extensions/extension-lifecycle.service.js +0 -174
  65. package/dist/shared/services/extensions/service-extension-runtime.service.d.ts +0 -52
  66. package/dist/shared/services/extensions/service-extension-runtime.service.js +0 -325
  67. package/dist/shared/services/gateway/cron-job-handler.service.js +0 -100
  68. package/dist/shared/services/runtime/utils/skills-loader.utils.d.ts +0 -12
  69. package/dist/shared/services/runtime/utils/skills-loader.utils.js +0 -9
  70. package/dist/shared/services/session/service-deferred-ncp-agent.service.d.ts +0 -14
  71. package/dist/shared/services/session/service-deferred-ncp-agent.service.js +0 -85
@@ -1,41 +1,32 @@
1
- import { parseSkillFrontmatter } from "./marketplace.metadata.js";
2
1
  import { runWithMarketplaceNetworkRetry } from "./marketplace-network-retry.js";
3
2
  import { readMarketplaceEnvelope, resolveMarketplaceApiBase } from "./marketplace-client.js";
4
- import { SkillsLoader } from "@nextclaw/core";
5
- import { readFileSync } from "node:fs";
6
- import { relative, resolve } from "node:path";
3
+ import { SkillManager } from "@nextclaw/kernel";
4
+ import { resolve } from "node:path";
7
5
  //#region src/cli/commands/skills/skills-query.service.ts
8
6
  var SkillsQueryService = class {
9
7
  listInstalled = (params) => {
10
- const workspace = resolve(params.workdir);
11
- const loader = new SkillsLoader(workspace);
12
- const scope = this.normalizeInstalledScope(params.scope);
13
- const normalizedQuery = this.normalizeOptionalString(params.query)?.toLowerCase() ?? null;
14
- const skills = loader.listSkills(false).map((skill) => this.buildInstalledSkillSummary(skill, loader, workspace)).filter((skill) => scope === "all" || skill.scope === scope).filter((skill) => this.matchesInstalledSkillQuery(skill, normalizedQuery));
15
- return {
16
- workspace,
17
- total: skills.length,
18
- skills
19
- };
8
+ return new SkillManager({ workspace: resolve(params.workdir) }).listInstalledSkills({
9
+ scope: params.scope,
10
+ query: params.query
11
+ });
20
12
  };
21
13
  getInstalledInfo = (params) => {
22
- const workspace = resolve(params.workdir);
23
- const loader = new SkillsLoader(workspace);
24
- const skill = loader.getSkillInfo(params.selector);
25
- if (!skill) throw new Error(`Installed skill not found: ${params.selector}`);
26
- return this.buildInstalledSkillDetail(skill, loader, workspace);
14
+ const detail = new SkillManager({ workspace: resolve(params.workdir) }).getInstalledSkillDetail(params.selector);
15
+ if (!detail) throw new Error(`Installed skill not found: ${params.selector}`);
16
+ return detail;
27
17
  };
28
18
  searchMarketplaceSkills = async (params) => {
29
- const apiBaseUrl = resolveMarketplaceApiBase(params.apiBaseUrl);
19
+ const { apiBaseUrl: rawApiBaseUrl, page, pageSize, query, sort, tag } = params;
20
+ const apiBaseUrl = resolveMarketplaceApiBase(rawApiBaseUrl);
30
21
  const result = await this.fetchMarketplaceView({
31
22
  apiBaseUrl,
32
23
  path: "/api/v1/skills/items",
33
24
  query: {
34
- q: this.normalizeOptionalString(params.query) ?? void 0,
35
- tag: this.normalizeOptionalString(params.tag) ?? void 0,
36
- sort: this.normalizeMarketplaceSort(params.sort),
37
- page: this.normalizePositiveInteger(params.page),
38
- pageSize: this.normalizePositiveInteger(params.pageSize)
25
+ q: this.normalizeOptionalString(query) ?? void 0,
26
+ tag: this.normalizeOptionalString(tag) ?? void 0,
27
+ sort: this.normalizeMarketplaceSort(sort),
28
+ page: this.normalizePositiveInteger(page),
29
+ pageSize: this.normalizePositiveInteger(pageSize)
39
30
  }
40
31
  });
41
32
  return {
@@ -85,73 +76,6 @@ var SkillsQueryService = class {
85
76
  items: result.items.map((item) => this.normalizeMarketplaceSummary(item))
86
77
  };
87
78
  };
88
- buildInstalledSkillSummary = (skill, loader, workspace) => {
89
- const raw = readFileSync(skill.path, "utf8");
90
- const metadata = loader.getSkillMetadata(skill);
91
- const frontmatter = parseSkillFrontmatter(raw);
92
- return {
93
- ref: skill.ref,
94
- name: skill.name,
95
- path: skill.path,
96
- relativePath: this.buildRelativePath(workspace, skill.path),
97
- scope: skill.scope,
98
- source: skill.source,
99
- summary: frontmatter.summary ?? null,
100
- summaryI18n: frontmatter.summaryI18n ?? null,
101
- description: frontmatter.description ?? metadata?.description ?? null,
102
- descriptionI18n: frontmatter.descriptionI18n ?? null,
103
- author: frontmatter.author ?? null,
104
- tags: frontmatter.tags ?? [],
105
- always: this.readAlwaysFlag(metadata)
106
- };
107
- };
108
- buildInstalledSkillDetail = (skill, loader, workspace) => {
109
- const summary = this.buildInstalledSkillSummary(skill, loader, workspace);
110
- const raw = readFileSync(skill.path, "utf8");
111
- return {
112
- ...summary,
113
- metadata: loader.getSkillMetadata(skill),
114
- raw,
115
- bodyRaw: this.stripFrontmatter(raw)
116
- };
117
- };
118
- matchesInstalledSkillQuery = (skill, query) => {
119
- if (!query) return true;
120
- return [
121
- skill.ref,
122
- skill.name,
123
- skill.path,
124
- skill.relativePath ?? "",
125
- skill.scope,
126
- skill.source,
127
- skill.summary ?? "",
128
- skill.description ?? "",
129
- skill.author ?? "",
130
- ...skill.tags,
131
- ...Object.values(skill.summaryI18n ?? {}),
132
- ...Object.values(skill.descriptionI18n ?? {})
133
- ].some((value) => value.toLowerCase().includes(query));
134
- };
135
- stripFrontmatter = (raw) => {
136
- const normalized = raw.replace(/\r\n/g, "\n");
137
- const match = normalized.match(/^---\n[\s\S]*?\n---\n?/);
138
- if (!match) return normalized.trim();
139
- return normalized.slice(match[0].length).trim();
140
- };
141
- readAlwaysFlag = (metadata) => {
142
- if (metadata?.always === "true") return true;
143
- const raw = metadata?.metadata;
144
- if (!raw) return false;
145
- try {
146
- return JSON.parse(raw).nextclaw?.always === true;
147
- } catch {
148
- return false;
149
- }
150
- };
151
- buildRelativePath = (workspace, absolutePath) => {
152
- const relativePath = relative(workspace, absolutePath).replace(/\\/g, "/");
153
- return relativePath.startsWith("..") ? null : relativePath;
154
- };
155
79
  normalizeMarketplaceSummary = (item) => ({
156
80
  ...item,
157
81
  install: this.normalizeMarketplaceInstallSpec(item.install, item.slug)
@@ -168,12 +92,6 @@ var SkillsQueryService = class {
168
92
  ...install,
169
93
  command: `nextclaw marketplace skills install ${slug}`
170
94
  });
171
- normalizeInstalledScope = (value) => {
172
- const normalized = this.normalizeOptionalString(value);
173
- if (!normalized || normalized === "all") return "all";
174
- if (normalized === "builtin" || normalized === "project" || normalized === "workspace") return normalized;
175
- throw new Error(`Invalid skill scope: ${value}. Expected all, builtin, project, or workspace.`);
176
- };
177
95
  normalizeMarketplaceSort = (value) => {
178
96
  const normalized = this.normalizeOptionalString(value);
179
97
  if (!normalized) return;
@@ -1,21 +1,19 @@
1
1
  import { UsageCommandOptions } from "../../../../shared/types/cli.types.js";
2
- import { LlmUsageQueryService } from "./llm-usage-query.service.js";
2
+ import { LlmUsageManager } from "@nextclaw/kernel";
3
3
 
4
4
  //#region src/cli/commands/usage/services/llm-usage-command.service.d.ts
5
5
  declare class LlmUsageCommandService {
6
- private readonly deps;
6
+ private readonly usageManager;
7
7
  constructor(deps?: {
8
- queryService?: LlmUsageQueryService;
8
+ usageManager?: LlmUsageManager;
9
9
  });
10
10
  readonly show: (opts?: UsageCommandOptions) => Promise<void>;
11
- private get queryService();
12
11
  private readonly showSnapshot;
13
12
  private readonly showHistory;
14
13
  private readonly showStats;
15
14
  private readonly renderSnapshot;
16
15
  private readonly renderHistory;
17
16
  private readonly renderStats;
18
- private readonly resolveLimit;
19
17
  private readonly toPercent;
20
18
  }
21
19
  //#endregion
@@ -1,8 +1,9 @@
1
- import { llmUsageQueryService } from "./llm-usage-query.service.js";
1
+ import { LlmUsageManager } from "@nextclaw/kernel";
2
2
  //#region src/cli/commands/usage/services/llm-usage-command.service.ts
3
3
  var LlmUsageCommandService = class {
4
+ usageManager;
4
5
  constructor(deps = {}) {
5
- this.deps = deps;
6
+ this.usageManager = deps.usageManager ?? new LlmUsageManager();
6
7
  }
7
8
  show = async (opts = {}) => {
8
9
  if (opts.history && opts.stats) {
@@ -20,16 +21,13 @@ var LlmUsageCommandService = class {
20
21
  }
21
22
  this.showSnapshot(opts);
22
23
  };
23
- get queryService() {
24
- return this.deps.queryService ?? llmUsageQueryService;
25
- }
26
24
  showSnapshot = (opts) => {
27
- const snapshot = this.queryService.getSnapshot();
25
+ const snapshot = this.usageManager.getSnapshot();
28
26
  if (opts.json) {
29
27
  console.log(JSON.stringify({
30
28
  ok: Boolean(snapshot),
31
29
  mode: "snapshot",
32
- path: this.queryService.snapshotPath,
30
+ path: this.usageManager.snapshotPath,
33
31
  snapshot
34
32
  }, null, 2));
35
33
  process.exitCode = 0;
@@ -38,7 +36,7 @@ var LlmUsageCommandService = class {
38
36
  if (!snapshot) {
39
37
  console.log([
40
38
  "No LLM usage snapshot recorded yet.",
41
- `Snapshot path: ${this.queryService.snapshotPath}`,
39
+ `Snapshot path: ${this.usageManager.snapshotPath}`,
42
40
  "Run `nextclaw agent -m \"ping\"` or use the local UI once, then retry `nextclaw usage`."
43
41
  ].join("\n"));
44
42
  process.exitCode = 0;
@@ -48,13 +46,13 @@ var LlmUsageCommandService = class {
48
46
  process.exitCode = 0;
49
47
  };
50
48
  showHistory = (opts) => {
51
- const records = this.queryService.getHistory(opts.limit);
49
+ const records = this.usageManager.getHistory(opts.limit);
52
50
  if (opts.json) {
53
51
  console.log(JSON.stringify({
54
52
  ok: records.length > 0,
55
53
  mode: "history",
56
- path: this.queryService.historyPath,
57
- limit: this.resolveLimit(opts.limit),
54
+ path: this.usageManager.historyPath,
55
+ limit: this.usageManager.resolveHistoryLimit(opts.limit),
58
56
  records
59
57
  }, null, 2));
60
58
  process.exitCode = 0;
@@ -63,7 +61,7 @@ var LlmUsageCommandService = class {
63
61
  if (records.length === 0) {
64
62
  console.log([
65
63
  "No LLM usage history recorded yet.",
66
- `History path: ${this.queryService.historyPath}`,
64
+ `History path: ${this.usageManager.historyPath}`,
67
65
  "Run `nextclaw agent -m \"ping\"` or use the local UI once, then retry `nextclaw usage --history`."
68
66
  ].join("\n"));
69
67
  process.exitCode = 0;
@@ -73,12 +71,12 @@ var LlmUsageCommandService = class {
73
71
  process.exitCode = 0;
74
72
  };
75
73
  showStats = (opts) => {
76
- const stats = this.queryService.getStats();
74
+ const stats = this.usageManager.getStats();
77
75
  if (opts.json) {
78
76
  console.log(JSON.stringify({
79
77
  ok: stats.totalRecords > 0,
80
78
  mode: "stats",
81
- path: this.queryService.historyPath,
79
+ path: this.usageManager.historyPath,
82
80
  stats
83
81
  }, null, 2));
84
82
  process.exitCode = 0;
@@ -87,7 +85,7 @@ var LlmUsageCommandService = class {
87
85
  if (stats.totalRecords === 0) {
88
86
  console.log([
89
87
  "No LLM usage history recorded yet.",
90
- `History path: ${this.queryService.historyPath}`,
88
+ `History path: ${this.usageManager.historyPath}`,
91
89
  "Run `nextclaw agent -m \"ping\"` or use the local UI once, then retry `nextclaw usage --stats`."
92
90
  ].join("\n"));
93
91
  process.exitCode = 0;
@@ -107,7 +105,7 @@ var LlmUsageCommandService = class {
107
105
  `Total tokens: ${snapshot.summary.totalTokens}`,
108
106
  `Cached tokens: ${snapshot.summary.cachedTokens}`,
109
107
  `Cache hit: ${snapshot.summary.cacheHit ? "yes" : "no"}`,
110
- `Snapshot path: ${this.queryService.snapshotPath}`
108
+ `Snapshot path: ${this.usageManager.snapshotPath}`
111
109
  ];
112
110
  if (snapshot.summary.cacheMetricKeys.length > 0) lines.push(`Cache metric keys: ${snapshot.summary.cacheMetricKeys.join(", ")}`);
113
111
  if (Object.keys(snapshot.usage).length > 0) lines.push("", "Raw usage:", JSON.stringify(snapshot.usage, null, 2));
@@ -116,7 +114,7 @@ var LlmUsageCommandService = class {
116
114
  renderHistory = (records) => {
117
115
  const lines = [
118
116
  "Recent LLM usage history",
119
- `History path: ${this.queryService.historyPath}`,
117
+ `History path: ${this.usageManager.historyPath}`,
120
118
  `Showing: ${records.length} record(s)`,
121
119
  ""
122
120
  ];
@@ -126,7 +124,7 @@ var LlmUsageCommandService = class {
126
124
  renderStats = (stats) => {
127
125
  const lines = [
128
126
  "LLM usage history stats",
129
- `History path: ${this.queryService.historyPath}`,
127
+ `History path: ${this.usageManager.historyPath}`,
130
128
  `Records: ${stats.totalRecords}`,
131
129
  `Usage records: ${stats.usageRecordCount}`,
132
130
  `Empty usage records: ${stats.emptyUsageRecordCount}`,
@@ -144,14 +142,6 @@ var LlmUsageCommandService = class {
144
142
  if (stats.models.length > 0) lines.push(`Models: ${stats.models.map((item) => `${item.value}=${item.count}`).join(", ")}`);
145
143
  return lines.join("\n");
146
144
  };
147
- resolveLimit = (value) => {
148
- if (typeof value === "number" && Number.isFinite(value) && value > 0) return Math.floor(value);
149
- if (typeof value === "string" && value.trim().length > 0) {
150
- const parsed = Number(value);
151
- if (Number.isFinite(parsed) && parsed > 0) return Math.floor(parsed);
152
- }
153
- return 10;
154
- };
155
145
  toPercent = (value) => {
156
146
  return `${(value * 100).toFixed(1)}%`;
157
147
  };
@@ -4,25 +4,18 @@ import { PluginChannelBinding } from "@nextclaw/openclaw-compat";
4
4
  //#region src/commands/channel/channel-list-view.service.d.ts
5
5
  type ChannelListEntry = {
6
6
  id: string;
7
- label: string;
8
- pluginId: string;
9
7
  enabled: boolean;
10
- outbound: {
11
- text: boolean;
12
- };
13
- auth: {
14
- login: boolean;
15
- };
16
8
  defaultAccountId?: string;
9
+ accounts?: ChannelListAccount[];
10
+ };
11
+ type ChannelListAccount = {
12
+ id: string;
13
+ userId?: string;
17
14
  };
18
15
  type ChannelListOutput = {
19
16
  channels: ChannelListEntry[];
20
17
  };
21
18
  declare class ChannelListViewService {
22
- private readonly params;
23
- constructor(params: {
24
- channelLabels: Record<string, string>;
25
- });
26
19
  build: (params: {
27
20
  config: Config;
28
21
  workspaceDir: string;
@@ -31,9 +24,9 @@ declare class ChannelListViewService {
31
24
  private toManifestChannelSources;
32
25
  private toPluginChannelSource;
33
26
  private toChannelListEntry;
27
+ private resolveAccounts;
34
28
  private mergeChannelSources;
35
- private discoverExtensionManifests;
36
29
  private resolveDefaultAccountId;
37
30
  }
38
31
  //#endregion
39
- export { ChannelListEntry, ChannelListOutput, ChannelListViewService };
32
+ export { ChannelListAccount, ChannelListEntry, ChannelListOutput, ChannelListViewService };
@@ -1,6 +1,5 @@
1
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";
2
+ import { listExtensionChannelIds } from "@nextclaw/kernel";
4
3
  //#region src/commands/channel/channel-list-view.service.ts
5
4
  function readRecord(value) {
6
5
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
@@ -10,67 +9,47 @@ function readString(value) {
10
9
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
11
10
  }
12
11
  var ChannelListViewService = class {
13
- constructor(params) {
14
- this.params = params;
15
- }
16
12
  build = (params) => {
17
13
  const { config, pluginBindings, workspaceDir } = params;
18
- const sources = this.mergeChannelSources(pluginBindings.map(this.toPluginChannelSource), this.toManifestChannelSources(this.discoverExtensionManifests(config, workspaceDir)));
14
+ const sources = this.mergeChannelSources(pluginBindings.map(this.toPluginChannelSource), this.toManifestChannelSources(listExtensionChannelIds({
15
+ config,
16
+ workspace: workspaceDir
17
+ })));
19
18
  const channelConfigs = readRecord(resolveChannelConfigView(config, pluginBindings).channels) ?? {};
20
19
  return { channels: sources.map((source) => this.toChannelListEntry(source, channelConfigs[source.id])).sort((left, right) => left.id.localeCompare(right.id)) };
21
20
  };
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
- };
21
+ toManifestChannelSources = (channelIds) => channelIds.map((id) => ({ id }));
40
22
  toPluginChannelSource = (binding) => ({
41
23
  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
24
  resolveDefaultAccountId: (channelConfig) => this.resolveDefaultAccountId(binding, channelConfig)
47
25
  });
48
26
  toChannelListEntry = (source, rawChannelConfig) => {
49
27
  const channelConfig = readRecord(rawChannelConfig);
50
28
  const defaultAccountId = readString(channelConfig?.defaultAccountId) ?? source.resolveDefaultAccountId?.(channelConfig);
29
+ const accounts = this.resolveAccounts(channelConfig);
51
30
  return {
52
31
  id: source.id,
53
- label: source.label,
54
- pluginId: source.pluginId,
55
32
  enabled: channelConfig?.enabled === true,
56
- outbound: { text: source.outboundText },
57
- auth: { login: source.login },
58
- ...defaultAccountId ? { defaultAccountId } : {}
33
+ ...defaultAccountId ? { defaultAccountId } : {},
34
+ ...accounts.length > 0 ? { accounts } : {}
59
35
  };
60
36
  };
37
+ resolveAccounts = (channelConfig) => {
38
+ const accounts = readRecord(channelConfig?.accounts);
39
+ if (!accounts) return [];
40
+ return Object.entries(accounts).map(([id, rawAccount]) => {
41
+ const userId = readString(readRecord(rawAccount)?.userId);
42
+ return {
43
+ id,
44
+ ...userId ? { userId } : {}
45
+ };
46
+ }).sort((left, right) => left.id.localeCompare(right.id));
47
+ };
61
48
  mergeChannelSources = (pluginSources, extensionSources) => {
62
49
  const sourcesByChannelId = /* @__PURE__ */ new Map();
63
50
  for (const source of [...pluginSources, ...extensionSources]) sourcesByChannelId.set(source.id, source);
64
51
  return [...sourcesByChannelId.values()];
65
52
  };
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
53
  resolveDefaultAccountId = (binding, channelConfig) => {
75
54
  const configAdapter = binding.channel.config?.defaultAccountId;
76
55
  if (!configAdapter) return;
@@ -11,7 +11,6 @@ const CHANNEL_LABELS = {
11
11
  whatsapp: "WhatsApp",
12
12
  discord: "Discord",
13
13
  feishu: "Feishu",
14
- mochat: "Mochat",
15
14
  dingtalk: "DingTalk",
16
15
  wecom: "WeCom",
17
16
  email: "Email",
@@ -24,7 +23,7 @@ function resolveChannelBindings(pluginRegistry) {
24
23
  return getPluginChannelBindings(pluginRegistry);
25
24
  }
26
25
  var ChannelCommands = class {
27
- channelListView = new ChannelListViewService({ channelLabels: CHANNEL_LABELS });
26
+ channelListView = new ChannelListViewService();
28
27
  constructor(deps) {
29
28
  this.deps = deps;
30
29
  }
@@ -61,13 +60,8 @@ var ChannelCommands = class {
61
60
  }
62
61
  console.log("Channels");
63
62
  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}`);
63
+ const flags = [channel.enabled ? "enabled" : "disabled", channel.defaultAccountId ? `defaultAccountId=${channel.defaultAccountId}` : void 0].filter(Boolean);
64
+ console.log(`- ${channel.id} [${flags.join(", ")}]`);
71
65
  }
72
66
  };
73
67
  login = async (opts = {}) => {
@@ -1,12 +1,10 @@
1
1
  import { PluginsInfoOptions, PluginsInstallOptions, PluginsListOptions, PluginsUninstallOptions } from "../../shared/types/cli.types.js";
2
- import { NextclawExtensionRegistry, toExtensionRegistry } from "./plugin-extension-registry.js";
3
- import { createEmptyPluginRegistry } from "./plugin-registry-loader.utils.js";
4
2
  import { Config } from "@nextclaw/core";
5
3
  import { PluginRegistry, mergePluginConfigView, toPluginConfigView } from "@nextclaw/openclaw-compat";
6
4
 
7
5
  //#region src/commands/plugin/index.d.ts
8
6
  declare function loadPluginRegistry(config: Config, workspaceDir: string): PluginRegistry;
9
- declare function logPluginDiagnostics(registry: PluginRegistry): void;
7
+ declare function logPluginDiagnostics(registry: Pick<PluginRegistry, "diagnostics">): void;
10
8
  declare class PluginCommands {
11
9
  list: (opts?: PluginsListOptions) => void;
12
10
  info: (id: string, opts?: PluginsInfoOptions) => void;
@@ -27,4 +25,4 @@ declare class PluginCommands {
27
25
  private buildUninstallConfigPreview;
28
26
  }
29
27
  //#endregion
30
- export { type NextclawExtensionRegistry, PluginCommands, createEmptyPluginRegistry, loadPluginRegistry, logPluginDiagnostics, mergePluginConfigView, toExtensionRegistry, toPluginConfigView };
28
+ export { PluginCommands, loadPluginRegistry, logPluginDiagnostics, mergePluginConfigView, toPluginConfigView };
@@ -1,27 +1,15 @@
1
- import { appendPluginCapabilityLines, buildReservedPluginLoadOptions } from "./plugin-command-utils.js";
2
- import { resolveDevFirstPartyPluginDir } from "./development-source/first-party-plugin-load-paths.utils.js";
3
- import { resolveDevPluginLoadingContext } from "./development-source/dev-plugin-overrides.utils.js";
4
- import { disablePluginMutation, enablePluginMutation, installPluginMutation, uninstallPluginMutation } from "./plugin-mutation-actions.js";
5
- import { toExtensionRegistry } from "./plugin-extension-registry.js";
6
- import { createEmptyPluginRegistry } from "./plugin-registry-loader.utils.js";
1
+ import { appendPluginCapabilityLines, buildReservedPluginLoadOptions } from "./plugin-command.utils.js";
2
+ import { disablePluginMutation, enablePluginMutation, installPluginMutation, uninstallPluginMutation } from "./plugin-mutation-actions.utils.js";
7
3
  import { getWorkspacePath, loadConfig } from "@nextclaw/core";
8
- import { buildPluginStatusReport, loadOpenClawPlugins, mergePluginConfigView, resolveUninstallDirectoryTargets, toPluginConfigView } from "@nextclaw/openclaw-compat";
4
+ import { ExtensionPluginRegistryService } from "@nextclaw/kernel";
5
+ import { buildPluginStatusReport, mergePluginConfigView, resolveUninstallDirectoryTargets, toPluginConfigView } from "@nextclaw/openclaw-compat";
9
6
  import { resolve } from "node:path";
10
7
  import { createInterface } from "node:readline";
11
8
  //#region src/commands/plugin/index.ts
12
9
  function loadPluginRegistry(config, workspaceDir) {
13
- const { configWithDevPluginOverrides, excludedRoots } = resolveDevPluginLoadingContext(config, resolveDevFirstPartyPluginDir(process.env.NEXTCLAW_DEV_FIRST_PARTY_PLUGIN_DIR));
14
- return loadOpenClawPlugins({
15
- config: configWithDevPluginOverrides,
16
- workspaceDir,
17
- excludeRoots: excludedRoots,
18
- ...buildReservedPluginLoadOptions(),
19
- logger: {
20
- info: (message) => console.log(message),
21
- warn: (message) => console.warn(message),
22
- error: (message) => console.error(message),
23
- debug: (message) => console.debug(message)
24
- }
10
+ return new ExtensionPluginRegistryService().load({
11
+ config,
12
+ workspace: workspaceDir
25
13
  });
26
14
  }
27
15
  function logPluginDiagnostics(registry) {
@@ -263,4 +251,4 @@ var PluginCommands = class {
263
251
  };
264
252
  };
265
253
  //#endregion
266
- export { PluginCommands, createEmptyPluginRegistry, loadPluginRegistry, logPluginDiagnostics, mergePluginConfigView, toExtensionRegistry, toPluginConfigView };
254
+ export { PluginCommands, loadPluginRegistry, logPluginDiagnostics, mergePluginConfigView, toPluginConfigView };
@@ -1,12 +1,11 @@
1
1
  import { PluginRegistry } from "@nextclaw/openclaw-compat";
2
2
 
3
- //#region src/commands/plugin/plugin-command-utils.d.ts
3
+ //#region src/commands/plugin/plugin-command.utils.d.ts
4
4
  declare const RESERVED_PROVIDER_IDS: string[];
5
5
  declare function buildReservedPluginLoadOptions(): {
6
6
  reservedToolNames: ("read_file" | "write_file" | "edit_file" | "list_dir" | "exec" | "web_search" | "web_fetch" | "message" | "spawn" | "sessions_list" | "sessions_history" | "memory_search" | "memory_get" | "subagents" | "gateway" | "cron")[];
7
7
  reservedChannelIds: string[];
8
8
  reservedProviderIds: string[];
9
- reservedNcpAgentRuntimeKinds: string[];
10
9
  };
11
10
  declare function appendPluginCapabilityLines(lines: string[], plugin: PluginRegistry["plugins"][number]): void;
12
11
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { builtinProviderIds } from "@nextclaw/runtime";
2
- //#region src/commands/plugin/plugin-command-utils.ts
2
+ //#region src/commands/plugin/plugin-command.utils.ts
3
3
  const RESERVED_PROVIDER_IDS = builtinProviderIds();
4
4
  const RESERVED_TOOL_NAMES = [
5
5
  "read_file",
@@ -23,15 +23,13 @@ function buildReservedPluginLoadOptions() {
23
23
  return {
24
24
  reservedToolNames: [...RESERVED_TOOL_NAMES],
25
25
  reservedChannelIds: [],
26
- reservedProviderIds: RESERVED_PROVIDER_IDS,
27
- reservedNcpAgentRuntimeKinds: ["native"]
26
+ reservedProviderIds: RESERVED_PROVIDER_IDS
28
27
  };
29
28
  }
30
29
  function appendPluginCapabilityLines(lines, plugin) {
31
30
  if (plugin.toolNames.length > 0) lines.push(`Tools: ${plugin.toolNames.join(", ")}`);
32
31
  if (plugin.channelIds.length > 0) lines.push(`Channels: ${plugin.channelIds.join(", ")}`);
33
32
  if (plugin.providerIds.length > 0) lines.push(`Providers: ${plugin.providerIds.join(", ")}`);
34
- if (plugin.ncpAgentRuntimeKinds.length > 0) lines.push(`NCP runtimes: ${plugin.ncpAgentRuntimeKinds.join(", ")}`);
35
33
  }
36
34
  //#endregion
37
35
  export { RESERVED_PROVIDER_IDS, appendPluginCapabilityLines, buildReservedPluginLoadOptions };
@@ -1,6 +1,6 @@
1
1
  import { PluginsInstallOptions, PluginsUninstallOptions } from "../../shared/types/cli.types.js";
2
2
 
3
- //#region src/commands/plugin/plugin-mutation-actions.d.ts
3
+ //#region src/commands/plugin/plugin-mutation-actions.utils.d.ts
4
4
  type PluginMutationResult = {
5
5
  message: string;
6
6
  };
@@ -1,9 +1,9 @@
1
- import { buildReservedPluginLoadOptions } from "./plugin-command-utils.js";
1
+ import { buildReservedPluginLoadOptions } from "./plugin-command.utils.js";
2
2
  import { expandHome, getWorkspacePath, loadConfig, saveConfig } from "@nextclaw/core";
3
3
  import { addPluginLoadPath, buildPluginStatusReport, disablePluginInConfig, enablePluginInConfig, installPluginFromNpmSpec, installPluginFromPath, recordPluginInstall, uninstallPlugin } from "@nextclaw/openclaw-compat";
4
4
  import { existsSync } from "node:fs";
5
5
  import { resolve } from "node:path";
6
- //#region src/commands/plugin/plugin-mutation-actions.ts
6
+ //#region src/commands/plugin/plugin-mutation-actions.utils.ts
7
7
  const pluginInstallLogger = {
8
8
  info: (message) => console.log(message),
9
9
  warn: (message) => console.warn(message)
@@ -1,7 +1,7 @@
1
1
  import { HostAutostartRuntimeService } from "./host-autostart-runtime.service.js";
2
2
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
- import { dirname, join, resolve } from "node:path";
4
3
  import { spawn } from "node:child_process";
4
+ import { dirname, join, resolve } from "node:path";
5
5
  import { homedir } from "node:os";
6
6
  //#region src/commands/service/services/autostart/linux-systemd-autostart.service.ts
7
7
  const DEFAULT_SYSTEMD_SERVICE_NAME = "nextclaw.service";
@@ -1,7 +1,7 @@
1
1
  import { HostAutostartRuntimeService } from "./host-autostart-runtime.service.js";
2
2
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
- import { dirname, resolve } from "node:path";
4
3
  import { spawn } from "node:child_process";
4
+ import { dirname, resolve } from "node:path";
5
5
  import { homedir } from "node:os";
6
6
  //#region src/commands/service/services/autostart/macos-launch-agent-autostart.service.ts
7
7
  const DEFAULT_LAUNCH_AGENT_LABEL = "io.nextclaw.host-agent";
@@ -1,7 +1,7 @@
1
1
  import { HostAutostartRuntimeService } from "./host-autostart-runtime.service.js";
2
2
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
- import { win32 } from "node:path";
4
3
  import { spawn } from "node:child_process";
4
+ import { win32 } from "node:path";
5
5
  //#region src/commands/service/services/autostart/windows-task-autostart.service.ts
6
6
  const DEFAULT_TASK_NAME = "NextClaw Host Autostart";
7
7
  const SUPPORTED_PLATFORM = "win32";
@@ -5,8 +5,8 @@ import { NpmRuntimeBundleService, shouldPreferPackagedNpmRuntime } from "./npm-r
5
5
  import { inferDefaultNpmRuntimeReleaseChannel } from "./npm-runtime-update-source.service.js";
6
6
  import { NpmRuntimeUpdateStateStore } from "./npm-runtime-update-state.store.js";
7
7
  import { createExternalCommandEnv } from "@nextclaw/core";
8
- import { dirname, resolve } from "node:path";
9
8
  import { spawnSync } from "node:child_process";
9
+ import { dirname, resolve } from "node:path";
10
10
  import { fileURLToPath } from "node:url";
11
11
  //#region src/launcher/npm-runtime-launcher.service.ts
12
12
  var NpmRuntimeLauncher = class {
@@ -1,5 +1,4 @@
1
1
  import { AgentCommandOptions, LoginCommandOptions, UpdateCommandOptions } from "./shared/types/cli.types.js";
2
- import { PluginCommands } from "./commands/plugin/index.js";
3
2
  import { AgentCommands } from "./cli/commands/agent/services/agent-commands.service.js";
4
3
  import { ConfigCommands } from "./cli/commands/config/services/config-commands.service.js";
5
4
  import { CronCommands } from "./cli/commands/cron/services/cron-commands.service.js";
@@ -16,6 +15,7 @@ import { StopCommands } from "./cli/commands/stop/index.js";
16
15
  import { UiCommands } from "./cli/commands/ui/index.js";
17
16
  import { LlmUsageCommandService } from "./cli/commands/usage/services/llm-usage-command.service.js";
18
17
  import { ChannelCommands } from "./commands/channel/index.js";
18
+ import { PluginCommands } from "./commands/plugin/index.js";
19
19
  import { ServiceCommands } from "./commands/service/index.js";
20
20
  import { RemoteRuntimeActions } from "@nextclaw/remote";
21
21