nextclaw 0.12.5 → 0.12.7
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/cli/index.js +370 -231
- package/package.json +7 -7
- package/ui-dist/assets/{ChannelsList-DhvjpZcs.js → ChannelsList-i00X_bon.js} +1 -1
- package/ui-dist/assets/ChatPage-BEkVUTgU.js +38 -0
- package/ui-dist/assets/{DocBrowser-LpzGe8An.js → DocBrowser-DhSfSjNp.js} +1 -1
- package/ui-dist/assets/{LogoBadge-Be4lktJN.js → LogoBadge-E8XCymGk.js} +1 -1
- package/ui-dist/assets/MarketplacePage-DSa7G0ro.js +49 -0
- package/ui-dist/assets/McpMarketplacePage-bDGyqSad.js +40 -0
- package/ui-dist/assets/{ModelConfig-DuImUHIX.js → ModelConfig-Dvsyt1Tg.js} +1 -1
- package/ui-dist/assets/{ProvidersList-Ccleg25k.js → ProvidersList-DMbXOYsb.js} +1 -1
- package/ui-dist/assets/{RuntimeConfig-C6iqpJR_.js → RuntimeConfig-ToBbIBNn.js} +1 -1
- package/ui-dist/assets/{SearchConfig-Dvp1TAXu.js → SearchConfig-BV_SO-L3.js} +1 -1
- package/ui-dist/assets/{SecretsConfig-D5Ymlvt9.js → SecretsConfig-D5J_q_Za.js} +1 -1
- package/ui-dist/assets/{SessionsConfig-CIA_jA1P.js → SessionsConfig-B8gi8Vbi.js} +1 -1
- package/ui-dist/assets/{chat-message-B60Fh9kI.js → chat-message-v-cXhn7X.js} +1 -1
- package/ui-dist/assets/index-BXJPYlRo.js +8 -0
- package/ui-dist/assets/index-BoDFsNXm.css +1 -0
- package/ui-dist/assets/{index-CPDASUXh.js → index-ElnZdv5o.js} +1 -1
- package/ui-dist/assets/{label-D4fGx6Wb.js → label-352ph_Yg.js} +1 -1
- package/ui-dist/assets/marketplace-localization-Dk31LJJJ.js +1 -0
- package/ui-dist/assets/{page-layout-twy8gmBE.js → page-layout-BwIR7lB8.js} +1 -1
- package/ui-dist/assets/{popover-DYbYpt1j.js → popover-BdOI7aUv.js} +1 -1
- package/ui-dist/assets/{security-config-BcIZ4rpb.js → security-config-BEhAoZux.js} +1 -1
- package/ui-dist/assets/skeleton-C3DLX_PO.js +1 -0
- package/ui-dist/assets/{switch-DqA6r5XR.js → switch-CgUsIol7.js} +1 -1
- package/ui-dist/assets/{tabs-custom-C6enKKs1.js → tabs-custom-Dc_3h5fO.js} +1 -1
- package/ui-dist/assets/{useConfirmDialog-CHBf5Of7.js → useConfirmDialog-DSrny346.js} +2 -2
- package/ui-dist/assets/{vendor-DKBNiC31.js → vendor-425xp8cv.js} +1 -1
- package/ui-dist/index.html +3 -3
- package/ui-dist/assets/ChatPage-B8VBaMQm.js +0 -38
- package/ui-dist/assets/MarketplacePage-Cx9AI3_h.js +0 -49
- package/ui-dist/assets/index-BiPDnzv0.js +0 -8
- package/ui-dist/assets/index-C8GsgIUn.css +0 -1
- package/ui-dist/assets/skeleton-DypBy7jp.js +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -6,12 +6,12 @@ import { APP_NAME as APP_NAME5, APP_TAGLINE } from "@nextclaw/core";
|
|
|
6
6
|
|
|
7
7
|
// src/cli/runtime.ts
|
|
8
8
|
import {
|
|
9
|
-
loadConfig as
|
|
10
|
-
saveConfig as
|
|
9
|
+
loadConfig as loadConfig11,
|
|
10
|
+
saveConfig as saveConfig8,
|
|
11
11
|
getConfigPath as getConfigPath4,
|
|
12
12
|
getDataDir as getDataDir8,
|
|
13
13
|
ConfigSchema as ConfigSchema2,
|
|
14
|
-
getWorkspacePath as
|
|
14
|
+
getWorkspacePath as getWorkspacePath10,
|
|
15
15
|
expandHome as expandHome2,
|
|
16
16
|
MessageBus as MessageBus2,
|
|
17
17
|
AgentLoop,
|
|
@@ -26,8 +26,8 @@ import {
|
|
|
26
26
|
resolvePluginChannelMessageToolHints as resolvePluginChannelMessageToolHints2,
|
|
27
27
|
setPluginRuntimeBridge as setPluginRuntimeBridge2
|
|
28
28
|
} from "@nextclaw/openclaw-compat";
|
|
29
|
-
import { existsSync as
|
|
30
|
-
import { join as
|
|
29
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
|
|
30
|
+
import { join as join8, resolve as resolve12 } from "path";
|
|
31
31
|
import { createInterface as createInterface2 } from "readline";
|
|
32
32
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
33
33
|
import { spawn as spawn3 } from "child_process";
|
|
@@ -2118,7 +2118,11 @@ var ConfigCommands = class {
|
|
|
2118
2118
|
|
|
2119
2119
|
// src/cli/commands/mcp.ts
|
|
2120
2120
|
import { loadConfig as loadConfig4, saveConfig as saveConfig3 } from "@nextclaw/core";
|
|
2121
|
-
import {
|
|
2121
|
+
import {
|
|
2122
|
+
McpDoctorFacade,
|
|
2123
|
+
McpMutationService,
|
|
2124
|
+
McpRegistryService
|
|
2125
|
+
} from "@nextclaw/mcp";
|
|
2122
2126
|
function normalizeOptionalString(value) {
|
|
2123
2127
|
if (typeof value !== "string") {
|
|
2124
2128
|
return void 0;
|
|
@@ -2155,12 +2159,12 @@ function parseTimeoutMs(value) {
|
|
|
2155
2159
|
function buildMcpServerDefinition(command, opts) {
|
|
2156
2160
|
const transport = (normalizeOptionalString(opts.transport) ?? "stdio").toLowerCase();
|
|
2157
2161
|
const disabled = Boolean(opts.disabled);
|
|
2158
|
-
const allAgents = Boolean(opts.allAgents);
|
|
2159
2162
|
const explicitAgents = Array.from(
|
|
2160
2163
|
new Set(
|
|
2161
2164
|
(opts.agent ?? []).map((agentId) => normalizeOptionalString(agentId)).filter((agentId) => Boolean(agentId))
|
|
2162
2165
|
)
|
|
2163
2166
|
);
|
|
2167
|
+
const allAgents = explicitAgents.length === 0 ? true : Boolean(opts.allAgents);
|
|
2164
2168
|
if (transport === "stdio") {
|
|
2165
2169
|
if (command.length === 0) {
|
|
2166
2170
|
throw new Error("stdio transport requires a command after --");
|
|
@@ -2177,11 +2181,15 @@ function buildMcpServerDefinition(command, opts) {
|
|
|
2177
2181
|
},
|
|
2178
2182
|
scope: {
|
|
2179
2183
|
allAgents,
|
|
2180
|
-
agents: explicitAgents
|
|
2184
|
+
agents: allAgents ? [] : explicitAgents
|
|
2181
2185
|
},
|
|
2182
2186
|
policy: {
|
|
2183
2187
|
trust: "explicit",
|
|
2184
2188
|
start: "eager"
|
|
2189
|
+
},
|
|
2190
|
+
metadata: {
|
|
2191
|
+
source: "manual",
|
|
2192
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2185
2193
|
}
|
|
2186
2194
|
};
|
|
2187
2195
|
}
|
|
@@ -2194,11 +2202,15 @@ function buildMcpServerDefinition(command, opts) {
|
|
|
2194
2202
|
enabled: !disabled,
|
|
2195
2203
|
scope: {
|
|
2196
2204
|
allAgents,
|
|
2197
|
-
agents: explicitAgents
|
|
2205
|
+
agents: allAgents ? [] : explicitAgents
|
|
2198
2206
|
},
|
|
2199
2207
|
policy: {
|
|
2200
2208
|
trust: "explicit",
|
|
2201
2209
|
start: "eager"
|
|
2210
|
+
},
|
|
2211
|
+
metadata: {
|
|
2212
|
+
source: "manual",
|
|
2213
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2202
2214
|
}
|
|
2203
2215
|
};
|
|
2204
2216
|
if (transport === "http") {
|
|
@@ -2257,26 +2269,28 @@ var McpCommands = class {
|
|
|
2257
2269
|
}
|
|
2258
2270
|
}
|
|
2259
2271
|
async mcpAdd(name, command, opts) {
|
|
2260
|
-
const
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2272
|
+
const mutation = new McpMutationService({
|
|
2273
|
+
getConfig: () => loadConfig4(),
|
|
2274
|
+
saveConfig: (config2) => saveConfig3(config2)
|
|
2275
|
+
});
|
|
2276
|
+
const result = mutation.addServer(name, buildMcpServerDefinition(command, opts));
|
|
2277
|
+
if (!result.changed) {
|
|
2278
|
+
reportUserInputIssue(result.message);
|
|
2264
2279
|
return;
|
|
2265
2280
|
}
|
|
2266
|
-
|
|
2267
|
-
saveConfig3(config2);
|
|
2268
|
-
console.log(`Added MCP server ${normalizedName}.`);
|
|
2281
|
+
console.log(result.message);
|
|
2269
2282
|
}
|
|
2270
2283
|
async mcpRemove(name) {
|
|
2271
|
-
const
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2284
|
+
const mutation = new McpMutationService({
|
|
2285
|
+
getConfig: () => loadConfig4(),
|
|
2286
|
+
saveConfig: (config2) => saveConfig3(config2)
|
|
2287
|
+
});
|
|
2288
|
+
const result = mutation.removeServer(name);
|
|
2289
|
+
if (!result.changed) {
|
|
2290
|
+
reportUserInputIssue(result.message);
|
|
2275
2291
|
return;
|
|
2276
2292
|
}
|
|
2277
|
-
|
|
2278
|
-
saveConfig3(config2);
|
|
2279
|
-
console.log(`Removed MCP server ${normalizedName}.`);
|
|
2293
|
+
console.log(result.message);
|
|
2280
2294
|
}
|
|
2281
2295
|
async mcpEnable(name) {
|
|
2282
2296
|
await this.toggleEnabled(name, true);
|
|
@@ -2288,7 +2302,7 @@ var McpCommands = class {
|
|
|
2288
2302
|
const registry = new McpRegistryService({
|
|
2289
2303
|
getConfig: () => loadConfig4()
|
|
2290
2304
|
});
|
|
2291
|
-
const doctor = new
|
|
2305
|
+
const doctor = new McpDoctorFacade({
|
|
2292
2306
|
getConfig: () => loadConfig4(),
|
|
2293
2307
|
registryService: registry
|
|
2294
2308
|
});
|
|
@@ -2314,16 +2328,16 @@ var McpCommands = class {
|
|
|
2314
2328
|
}
|
|
2315
2329
|
}
|
|
2316
2330
|
async toggleEnabled(name, enabled) {
|
|
2317
|
-
const
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2331
|
+
const mutation = new McpMutationService({
|
|
2332
|
+
getConfig: () => loadConfig4(),
|
|
2333
|
+
saveConfig: (config2) => saveConfig3(config2)
|
|
2334
|
+
});
|
|
2335
|
+
const result = mutation.toggleEnabled(name, enabled);
|
|
2336
|
+
if (!result.changed) {
|
|
2337
|
+
reportUserInputIssue(result.message);
|
|
2322
2338
|
return;
|
|
2323
2339
|
}
|
|
2324
|
-
|
|
2325
|
-
saveConfig3(config2);
|
|
2326
|
-
console.log(`${enabled ? "Enabled" : "Disabled"} MCP server ${normalizedName}.`);
|
|
2340
|
+
console.log(result.message);
|
|
2327
2341
|
}
|
|
2328
2342
|
};
|
|
2329
2343
|
function reportUserInputIssue(message) {
|
|
@@ -3195,8 +3209,8 @@ import {
|
|
|
3195
3209
|
stopPluginChannelGateways as stopPluginChannelGateways2
|
|
3196
3210
|
} from "@nextclaw/openclaw-compat";
|
|
3197
3211
|
import { startUiServer } from "@nextclaw/server";
|
|
3198
|
-
import { appendFileSync, closeSync, cpSync as cpSync2, existsSync as
|
|
3199
|
-
import { dirname as dirname2, join as
|
|
3212
|
+
import { appendFileSync, closeSync, cpSync as cpSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, openSync } from "fs";
|
|
3213
|
+
import { dirname as dirname2, join as join6, resolve as resolve10 } from "path";
|
|
3200
3214
|
import { spawn as spawn2 } from "child_process";
|
|
3201
3215
|
import { request as httpRequest } from "http";
|
|
3202
3216
|
import { request as httpsRequest } from "https";
|
|
@@ -3674,8 +3688,242 @@ var MissingProvider = class extends LLMProvider {
|
|
|
3674
3688
|
}
|
|
3675
3689
|
};
|
|
3676
3690
|
|
|
3691
|
+
// src/cli/commands/service-marketplace-installer.ts
|
|
3692
|
+
import { getWorkspacePath as getWorkspacePath5, loadConfig as loadConfig9 } from "@nextclaw/core";
|
|
3693
|
+
import { existsSync as existsSync8, rmSync as rmSync4 } from "fs";
|
|
3694
|
+
import { join as join4 } from "path";
|
|
3695
|
+
|
|
3696
|
+
// src/cli/commands/service-marketplace-helpers.ts
|
|
3697
|
+
var containsAbsoluteFsPath = (line) => {
|
|
3698
|
+
const normalized = line.trim();
|
|
3699
|
+
if (!normalized) {
|
|
3700
|
+
return false;
|
|
3701
|
+
}
|
|
3702
|
+
const lowered = normalized.toLowerCase();
|
|
3703
|
+
if (lowered.includes("http://") || lowered.includes("https://")) {
|
|
3704
|
+
return false;
|
|
3705
|
+
}
|
|
3706
|
+
if (/^[A-Za-z]:\\/.test(normalized)) {
|
|
3707
|
+
return true;
|
|
3708
|
+
}
|
|
3709
|
+
return /(?:^|\s)(?:~\/|\/[^\s]+)/.test(normalized);
|
|
3710
|
+
};
|
|
3711
|
+
var pickUserFacingCommandSummary = (output, fallback) => {
|
|
3712
|
+
const lines = output.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
3713
|
+
if (lines.length === 0) {
|
|
3714
|
+
return fallback;
|
|
3715
|
+
}
|
|
3716
|
+
const visibleLines = lines.filter((line) => {
|
|
3717
|
+
if (/^(path|install path|source path|destination|location)\s*:/i.test(line)) {
|
|
3718
|
+
return false;
|
|
3719
|
+
}
|
|
3720
|
+
if (containsAbsoluteFsPath(line)) {
|
|
3721
|
+
return false;
|
|
3722
|
+
}
|
|
3723
|
+
return true;
|
|
3724
|
+
});
|
|
3725
|
+
if (visibleLines.length === 0) {
|
|
3726
|
+
return fallback;
|
|
3727
|
+
}
|
|
3728
|
+
const preferred = [...visibleLines].reverse().find(
|
|
3729
|
+
(line) => /\b(installed|enabled|disabled|uninstalled|published|updated|already installed|removed)\b/i.test(line)
|
|
3730
|
+
);
|
|
3731
|
+
return preferred ?? visibleLines[visibleLines.length - 1] ?? fallback;
|
|
3732
|
+
};
|
|
3733
|
+
var buildMarketplaceSkillInstallArgs = (params) => {
|
|
3734
|
+
const args = ["skills", "install", params.slug, "--workdir", params.workspace];
|
|
3735
|
+
if (params.force) {
|
|
3736
|
+
args.push("--force");
|
|
3737
|
+
}
|
|
3738
|
+
return args;
|
|
3739
|
+
};
|
|
3740
|
+
|
|
3741
|
+
// src/cli/commands/service-mcp-marketplace-ops.ts
|
|
3742
|
+
import { loadConfig as loadConfig8, saveConfig as saveConfig6 } from "@nextclaw/core";
|
|
3743
|
+
import { McpDoctorFacade as McpDoctorFacade2, McpMutationService as McpMutationService2 } from "@nextclaw/mcp";
|
|
3744
|
+
var ServiceMcpMarketplaceOps = class {
|
|
3745
|
+
constructor(options) {
|
|
3746
|
+
this.options = options;
|
|
3747
|
+
}
|
|
3748
|
+
async install(params) {
|
|
3749
|
+
if (!params.template) {
|
|
3750
|
+
throw new Error(`Missing MCP marketplace template for ${params.spec}`);
|
|
3751
|
+
}
|
|
3752
|
+
const template = params.template;
|
|
3753
|
+
const result = this.createMutationService().installFromTemplate({
|
|
3754
|
+
template,
|
|
3755
|
+
name: params.name,
|
|
3756
|
+
enabled: params.enabled,
|
|
3757
|
+
scope: {
|
|
3758
|
+
allAgents: params.allAgents ?? true,
|
|
3759
|
+
agents: params.allAgents === false ? params.agents ?? [] : []
|
|
3760
|
+
},
|
|
3761
|
+
inputs: params.inputs,
|
|
3762
|
+
metadata: {
|
|
3763
|
+
source: "marketplace",
|
|
3764
|
+
catalogSlug: params.spec,
|
|
3765
|
+
displayName: template.defaultName
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
if (!result.changed) {
|
|
3769
|
+
throw new Error(result.message);
|
|
3770
|
+
}
|
|
3771
|
+
await this.options.applyLiveConfigReload?.();
|
|
3772
|
+
return {
|
|
3773
|
+
name: result.name,
|
|
3774
|
+
message: result.message
|
|
3775
|
+
};
|
|
3776
|
+
}
|
|
3777
|
+
async enable(name) {
|
|
3778
|
+
const result = this.createMutationService().toggleEnabled(name, true);
|
|
3779
|
+
if (!result.changed) {
|
|
3780
|
+
throw new Error(result.message);
|
|
3781
|
+
}
|
|
3782
|
+
await this.options.applyLiveConfigReload?.();
|
|
3783
|
+
return { message: result.message };
|
|
3784
|
+
}
|
|
3785
|
+
async disable(name) {
|
|
3786
|
+
const result = this.createMutationService().toggleEnabled(name, false);
|
|
3787
|
+
if (!result.changed) {
|
|
3788
|
+
throw new Error(result.message);
|
|
3789
|
+
}
|
|
3790
|
+
await this.options.applyLiveConfigReload?.();
|
|
3791
|
+
return { message: result.message };
|
|
3792
|
+
}
|
|
3793
|
+
async remove(name) {
|
|
3794
|
+
const result = this.createMutationService().removeServer(name);
|
|
3795
|
+
if (!result.changed) {
|
|
3796
|
+
throw new Error(result.message);
|
|
3797
|
+
}
|
|
3798
|
+
await this.options.applyLiveConfigReload?.();
|
|
3799
|
+
return { message: result.message };
|
|
3800
|
+
}
|
|
3801
|
+
async doctor(name) {
|
|
3802
|
+
const report = await this.createDoctorFacade().inspectOne(name);
|
|
3803
|
+
if (!report) {
|
|
3804
|
+
throw new Error(`Unknown MCP server: ${name}`);
|
|
3805
|
+
}
|
|
3806
|
+
return report;
|
|
3807
|
+
}
|
|
3808
|
+
createMutationService() {
|
|
3809
|
+
return new McpMutationService2({
|
|
3810
|
+
getConfig: () => loadConfig8(),
|
|
3811
|
+
saveConfig: (config2) => saveConfig6(config2)
|
|
3812
|
+
});
|
|
3813
|
+
}
|
|
3814
|
+
createDoctorFacade() {
|
|
3815
|
+
return new McpDoctorFacade2({
|
|
3816
|
+
getConfig: () => loadConfig8()
|
|
3817
|
+
});
|
|
3818
|
+
}
|
|
3819
|
+
};
|
|
3820
|
+
|
|
3821
|
+
// src/cli/commands/service-marketplace-installer.ts
|
|
3822
|
+
var ServiceMarketplaceInstaller = class {
|
|
3823
|
+
constructor(deps) {
|
|
3824
|
+
this.deps = deps;
|
|
3825
|
+
}
|
|
3826
|
+
createInstaller() {
|
|
3827
|
+
return {
|
|
3828
|
+
installPlugin: (spec) => this.installPlugin(spec),
|
|
3829
|
+
installSkill: (params) => this.installSkill(params),
|
|
3830
|
+
installMcp: (params) => this.installMcp(params),
|
|
3831
|
+
enablePlugin: (id) => this.enablePlugin(id),
|
|
3832
|
+
disablePlugin: (id) => this.disablePlugin(id),
|
|
3833
|
+
uninstallPlugin: (id) => this.uninstallPlugin(id),
|
|
3834
|
+
uninstallSkill: (slug) => this.uninstallSkill(slug),
|
|
3835
|
+
enableMcp: (name) => this.enableMcp(name),
|
|
3836
|
+
disableMcp: (name) => this.disableMcp(name),
|
|
3837
|
+
removeMcp: (name) => this.removeMcp(name),
|
|
3838
|
+
doctorMcp: (name) => this.doctorMcp(name)
|
|
3839
|
+
};
|
|
3840
|
+
}
|
|
3841
|
+
async installPlugin(spec) {
|
|
3842
|
+
const result = await installPluginMutation(spec);
|
|
3843
|
+
await this.deps.applyLiveConfigReload?.();
|
|
3844
|
+
return { message: result.message };
|
|
3845
|
+
}
|
|
3846
|
+
async installSkill(params) {
|
|
3847
|
+
if (params.kind === "builtin") {
|
|
3848
|
+
const result = this.deps.installBuiltinSkill(params.slug, params.force);
|
|
3849
|
+
if (!result) {
|
|
3850
|
+
throw new Error(`Builtin skill not found: ${params.slug}`);
|
|
3851
|
+
}
|
|
3852
|
+
return result;
|
|
3853
|
+
}
|
|
3854
|
+
if (params.kind && params.kind !== "marketplace") {
|
|
3855
|
+
throw new Error(`Unsupported marketplace skill kind: ${params.kind}`);
|
|
3856
|
+
}
|
|
3857
|
+
const workspace = getWorkspacePath5(loadConfig9().agents.defaults.workspace);
|
|
3858
|
+
const args = buildMarketplaceSkillInstallArgs({
|
|
3859
|
+
slug: params.slug,
|
|
3860
|
+
workspace,
|
|
3861
|
+
force: params.force
|
|
3862
|
+
});
|
|
3863
|
+
try {
|
|
3864
|
+
const output = await this.deps.runCliSubcommand(args);
|
|
3865
|
+
const summary = pickUserFacingCommandSummary(output, `Installed skill: ${params.slug}`);
|
|
3866
|
+
return { message: summary };
|
|
3867
|
+
} catch (error) {
|
|
3868
|
+
const fallback = this.deps.installBuiltinSkill(params.slug, params.force);
|
|
3869
|
+
if (!fallback) {
|
|
3870
|
+
throw error;
|
|
3871
|
+
}
|
|
3872
|
+
return fallback;
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
async installMcp(params) {
|
|
3876
|
+
return await this.createMcpMarketplaceOps().install(params);
|
|
3877
|
+
}
|
|
3878
|
+
async enablePlugin(id) {
|
|
3879
|
+
const result = await enablePluginMutation(id);
|
|
3880
|
+
await this.deps.applyLiveConfigReload?.();
|
|
3881
|
+
return { message: result.message };
|
|
3882
|
+
}
|
|
3883
|
+
async disablePlugin(id) {
|
|
3884
|
+
const result = await disablePluginMutation(id);
|
|
3885
|
+
await this.deps.applyLiveConfigReload?.();
|
|
3886
|
+
return { message: result.message };
|
|
3887
|
+
}
|
|
3888
|
+
async uninstallPlugin(id) {
|
|
3889
|
+
await disablePluginMutation(id);
|
|
3890
|
+
await this.deps.applyLiveConfigReload?.();
|
|
3891
|
+
const result = await uninstallPluginMutation(id, { force: true });
|
|
3892
|
+
await this.deps.applyLiveConfigReload?.();
|
|
3893
|
+
return { message: result.message };
|
|
3894
|
+
}
|
|
3895
|
+
async uninstallSkill(slug) {
|
|
3896
|
+
const workspace = getWorkspacePath5(loadConfig9().agents.defaults.workspace);
|
|
3897
|
+
const targetDir = join4(workspace, "skills", slug);
|
|
3898
|
+
if (!existsSync8(targetDir)) {
|
|
3899
|
+
throw new Error(`Skill not installed in workspace: ${slug}`);
|
|
3900
|
+
}
|
|
3901
|
+
rmSync4(targetDir, { recursive: true, force: true });
|
|
3902
|
+
return {
|
|
3903
|
+
message: `Uninstalled skill: ${slug}`
|
|
3904
|
+
};
|
|
3905
|
+
}
|
|
3906
|
+
async enableMcp(name) {
|
|
3907
|
+
return await this.createMcpMarketplaceOps().enable(name);
|
|
3908
|
+
}
|
|
3909
|
+
async disableMcp(name) {
|
|
3910
|
+
return await this.createMcpMarketplaceOps().disable(name);
|
|
3911
|
+
}
|
|
3912
|
+
async removeMcp(name) {
|
|
3913
|
+
return await this.createMcpMarketplaceOps().remove(name);
|
|
3914
|
+
}
|
|
3915
|
+
async doctorMcp(name) {
|
|
3916
|
+
return await this.createMcpMarketplaceOps().doctor(name);
|
|
3917
|
+
}
|
|
3918
|
+
createMcpMarketplaceOps() {
|
|
3919
|
+
return new ServiceMcpMarketplaceOps({
|
|
3920
|
+
applyLiveConfigReload: this.deps.applyLiveConfigReload
|
|
3921
|
+
});
|
|
3922
|
+
}
|
|
3923
|
+
};
|
|
3924
|
+
|
|
3677
3925
|
// src/cli/commands/service-plugin-reload.ts
|
|
3678
|
-
import { getWorkspacePath as
|
|
3926
|
+
import { getWorkspacePath as getWorkspacePath6 } from "@nextclaw/core";
|
|
3679
3927
|
import {
|
|
3680
3928
|
getPluginChannelBindings as getPluginChannelBindings2,
|
|
3681
3929
|
startPluginChannelGateways,
|
|
@@ -3741,7 +3989,7 @@ function shouldRestartChannelsForPluginReload(params) {
|
|
|
3741
3989
|
|
|
3742
3990
|
// src/cli/commands/service-plugin-reload.ts
|
|
3743
3991
|
async function reloadServicePlugins(params) {
|
|
3744
|
-
const nextWorkspace =
|
|
3992
|
+
const nextWorkspace = getWorkspacePath6(params.nextConfig.agents.defaults.workspace);
|
|
3745
3993
|
const nextPluginRegistry = loadPluginRegistry(params.nextConfig, nextWorkspace);
|
|
3746
3994
|
const nextExtensionRegistry = toExtensionRegistry(nextPluginRegistry);
|
|
3747
3995
|
const nextPluginChannelBindings = getPluginChannelBindings2(nextPluginRegistry);
|
|
@@ -3779,7 +4027,7 @@ import {
|
|
|
3779
4027
|
createAssistantStreamDeltaControlMessage,
|
|
3780
4028
|
createAssistantStreamResetControlMessage,
|
|
3781
4029
|
AgentRouteResolver,
|
|
3782
|
-
getWorkspacePath as
|
|
4030
|
+
getWorkspacePath as getWorkspacePath7,
|
|
3783
4031
|
parseAgentScopedSessionKey
|
|
3784
4032
|
} from "@nextclaw/core";
|
|
3785
4033
|
function normalizeAgentId(value) {
|
|
@@ -3824,7 +4072,7 @@ function resolveAgentProfiles(config2) {
|
|
|
3824
4072
|
}
|
|
3825
4073
|
return Array.from(unique.values()).map((entry) => ({
|
|
3826
4074
|
id: entry.id,
|
|
3827
|
-
workspace:
|
|
4075
|
+
workspace: getWorkspacePath7(entry.workspace ?? defaults.workspace),
|
|
3828
4076
|
model: entry.model ?? defaults.model,
|
|
3829
4077
|
engine: normalizeEngineKind(entry.engine ?? defaults.engine),
|
|
3830
4078
|
engineConfig: entry.engineConfig ?? toRecord(defaults.engineConfig),
|
|
@@ -4089,7 +4337,7 @@ var GatewayAgentRuntimePool = class {
|
|
|
4089
4337
|
const normalizedAgentId = normalizeAgentId(agentId);
|
|
4090
4338
|
return this.resolvedProfiles.find((profile) => profile.id === normalizedAgentId) ?? this.resolvedProfiles.find((profile) => profile.id === this.defaultAgentId) ?? this.resolvedProfiles[0] ?? {
|
|
4091
4339
|
id: this.defaultAgentId,
|
|
4092
|
-
workspace:
|
|
4340
|
+
workspace: getWorkspacePath7(this.options.config.agents.defaults.workspace),
|
|
4093
4341
|
model: this.options.config.agents.defaults.model,
|
|
4094
4342
|
maxIterations: this.options.config.agents.defaults.maxToolIterations,
|
|
4095
4343
|
contextTokens: this.options.config.agents.defaults.contextTokens,
|
|
@@ -4297,7 +4545,7 @@ import { createAgentClientFromServer, DefaultNcpAgentBackend } from "@nextclaw/n
|
|
|
4297
4545
|
import {
|
|
4298
4546
|
ContextBuilder,
|
|
4299
4547
|
InputBudgetPruner,
|
|
4300
|
-
getWorkspacePath as
|
|
4548
|
+
getWorkspacePath as getWorkspacePath8,
|
|
4301
4549
|
parseThinkingLevel,
|
|
4302
4550
|
resolveThinkingLevel
|
|
4303
4551
|
} from "@nextclaw/core";
|
|
@@ -4795,7 +5043,7 @@ function resolvePrimaryAgentProfile(config2) {
|
|
|
4795
5043
|
const profile = config2.agents.list.find((entry) => entry.id.trim() === configuredDefaultAgentId);
|
|
4796
5044
|
return {
|
|
4797
5045
|
agentId: configuredDefaultAgentId,
|
|
4798
|
-
workspace:
|
|
5046
|
+
workspace: getWorkspacePath8(profile?.workspace ?? config2.agents.defaults.workspace),
|
|
4799
5047
|
model: profile?.model ?? config2.agents.defaults.model,
|
|
4800
5048
|
maxIterations: profile?.maxToolIterations ?? config2.agents.defaults.maxToolIterations,
|
|
4801
5049
|
contextTokens: profile?.contextTokens ?? config2.agents.defaults.contextTokens,
|
|
@@ -5595,60 +5843,15 @@ async function createUiNcpAgent(params) {
|
|
|
5595
5843
|
};
|
|
5596
5844
|
}
|
|
5597
5845
|
|
|
5598
|
-
// src/cli/commands/service-marketplace-helpers.ts
|
|
5599
|
-
var containsAbsoluteFsPath = (line) => {
|
|
5600
|
-
const normalized = line.trim();
|
|
5601
|
-
if (!normalized) {
|
|
5602
|
-
return false;
|
|
5603
|
-
}
|
|
5604
|
-
const lowered = normalized.toLowerCase();
|
|
5605
|
-
if (lowered.includes("http://") || lowered.includes("https://")) {
|
|
5606
|
-
return false;
|
|
5607
|
-
}
|
|
5608
|
-
if (/^[A-Za-z]:\\/.test(normalized)) {
|
|
5609
|
-
return true;
|
|
5610
|
-
}
|
|
5611
|
-
return /(?:^|\s)(?:~\/|\/[^\s]+)/.test(normalized);
|
|
5612
|
-
};
|
|
5613
|
-
var pickUserFacingCommandSummary = (output, fallback) => {
|
|
5614
|
-
const lines = output.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
5615
|
-
if (lines.length === 0) {
|
|
5616
|
-
return fallback;
|
|
5617
|
-
}
|
|
5618
|
-
const visibleLines = lines.filter((line) => {
|
|
5619
|
-
if (/^(path|install path|source path|destination|location)\s*:/i.test(line)) {
|
|
5620
|
-
return false;
|
|
5621
|
-
}
|
|
5622
|
-
if (containsAbsoluteFsPath(line)) {
|
|
5623
|
-
return false;
|
|
5624
|
-
}
|
|
5625
|
-
return true;
|
|
5626
|
-
});
|
|
5627
|
-
if (visibleLines.length === 0) {
|
|
5628
|
-
return fallback;
|
|
5629
|
-
}
|
|
5630
|
-
const preferred = [...visibleLines].reverse().find(
|
|
5631
|
-
(line) => /\b(installed|enabled|disabled|uninstalled|published|updated|already installed|removed)\b/i.test(line)
|
|
5632
|
-
);
|
|
5633
|
-
return preferred ?? visibleLines[visibleLines.length - 1] ?? fallback;
|
|
5634
|
-
};
|
|
5635
|
-
var buildMarketplaceSkillInstallArgs = (params) => {
|
|
5636
|
-
const args = ["skills", "install", params.slug, "--workdir", params.workspace];
|
|
5637
|
-
if (params.force) {
|
|
5638
|
-
args.push("--force");
|
|
5639
|
-
}
|
|
5640
|
-
return args;
|
|
5641
|
-
};
|
|
5642
|
-
|
|
5643
5846
|
// src/cli/commands/ui-chat-run-coordinator.ts
|
|
5644
|
-
import { existsSync as
|
|
5645
|
-
import { join as
|
|
5847
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
|
|
5848
|
+
import { join as join5 } from "path";
|
|
5646
5849
|
import {
|
|
5647
5850
|
getDataDir as getDataDir5,
|
|
5648
5851
|
parseAgentScopedSessionKey as parseAgentScopedSessionKey2,
|
|
5649
5852
|
safeFilename
|
|
5650
5853
|
} from "@nextclaw/core";
|
|
5651
|
-
var RUNS_DIR =
|
|
5854
|
+
var RUNS_DIR = join5(getDataDir5(), "runs");
|
|
5652
5855
|
var NON_TERMINAL_STATES = /* @__PURE__ */ new Set(["queued", "running"]);
|
|
5653
5856
|
var DEFAULT_SESSION_TYPE = "native";
|
|
5654
5857
|
var SESSION_TYPE_METADATA_KEY = "session_type";
|
|
@@ -6174,7 +6377,7 @@ var UiChatRunCoordinator = class {
|
|
|
6174
6377
|
};
|
|
6175
6378
|
}
|
|
6176
6379
|
getRunPath(runId) {
|
|
6177
|
-
return
|
|
6380
|
+
return join5(RUNS_DIR, `${safeFilename(runId)}.json`);
|
|
6178
6381
|
}
|
|
6179
6382
|
persistRun(run) {
|
|
6180
6383
|
const persisted = {
|
|
@@ -6196,14 +6399,14 @@ var UiChatRunCoordinator = class {
|
|
|
6196
6399
|
`);
|
|
6197
6400
|
}
|
|
6198
6401
|
loadPersistedRuns() {
|
|
6199
|
-
if (!
|
|
6402
|
+
if (!existsSync9(RUNS_DIR)) {
|
|
6200
6403
|
return;
|
|
6201
6404
|
}
|
|
6202
6405
|
for (const entry of readdirSync2(RUNS_DIR, { withFileTypes: true })) {
|
|
6203
6406
|
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
6204
6407
|
continue;
|
|
6205
6408
|
}
|
|
6206
|
-
const path2 =
|
|
6409
|
+
const path2 = join5(RUNS_DIR, entry.name);
|
|
6207
6410
|
try {
|
|
6208
6411
|
const parsed = JSON.parse(readFileSync8(path2, "utf-8"));
|
|
6209
6412
|
const runId = readOptionalString(parsed.runId);
|
|
@@ -6268,14 +6471,14 @@ var {
|
|
|
6268
6471
|
getDataDir: getDataDir6,
|
|
6269
6472
|
getProvider,
|
|
6270
6473
|
getProviderName,
|
|
6271
|
-
getWorkspacePath:
|
|
6474
|
+
getWorkspacePath: getWorkspacePath9,
|
|
6272
6475
|
HeartbeatService,
|
|
6273
6476
|
LiteLLMProvider,
|
|
6274
|
-
loadConfig:
|
|
6477
|
+
loadConfig: loadConfig10,
|
|
6275
6478
|
MessageBus,
|
|
6276
6479
|
ProviderManager,
|
|
6277
6480
|
resolveConfigSecrets: resolveConfigSecrets2,
|
|
6278
|
-
saveConfig:
|
|
6481
|
+
saveConfig: saveConfig7,
|
|
6279
6482
|
SessionManager,
|
|
6280
6483
|
parseAgentScopedSessionKey: parseAgentScopedSessionKey3
|
|
6281
6484
|
} = NextclawCore;
|
|
@@ -6296,8 +6499,8 @@ var ServiceCommands = class {
|
|
|
6296
6499
|
this.applyLiveConfigReload = null;
|
|
6297
6500
|
this.liveUiNcpAgent = null;
|
|
6298
6501
|
const runtimeConfigPath = getConfigPath3();
|
|
6299
|
-
const config2 = resolveConfigSecrets2(
|
|
6300
|
-
const workspace =
|
|
6502
|
+
const config2 = resolveConfigSecrets2(loadConfig10(), { configPath: runtimeConfigPath });
|
|
6503
|
+
const workspace = getWorkspacePath9(config2.agents.defaults.workspace);
|
|
6301
6504
|
let pluginRegistry = loadPluginRegistry(config2, workspace);
|
|
6302
6505
|
let extensionRegistry = toExtensionRegistry(pluginRegistry);
|
|
6303
6506
|
logPluginDiagnostics(pluginRegistry);
|
|
@@ -6326,7 +6529,7 @@ var ServiceCommands = class {
|
|
|
6326
6529
|
}
|
|
6327
6530
|
}
|
|
6328
6531
|
};
|
|
6329
|
-
const cronStorePath =
|
|
6532
|
+
const cronStorePath = join6(getDataDir6(), "cron", "jobs.json");
|
|
6330
6533
|
const cron2 = new CronService2(cronStorePath);
|
|
6331
6534
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
6332
6535
|
const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
|
|
@@ -6341,7 +6544,7 @@ var ServiceCommands = class {
|
|
|
6341
6544
|
sessionManager,
|
|
6342
6545
|
providerManager,
|
|
6343
6546
|
makeProvider: (nextConfig) => this.makeProvider(nextConfig, { allowMissing: true }) ?? this.makeMissingProvider(nextConfig),
|
|
6344
|
-
loadConfig: () => resolveConfigSecrets2(
|
|
6547
|
+
loadConfig: () => resolveConfigSecrets2(loadConfig10(), { configPath: runtimeConfigPath }),
|
|
6345
6548
|
getExtensionChannels: () => extensionRegistry.channels,
|
|
6346
6549
|
onRestartRequired: (paths) => {
|
|
6347
6550
|
void this.deps.requestRestart({
|
|
@@ -6352,14 +6555,14 @@ var ServiceCommands = class {
|
|
|
6352
6555
|
}
|
|
6353
6556
|
});
|
|
6354
6557
|
this.applyLiveConfigReload = async () => {
|
|
6355
|
-
await reloader.applyReloadPlan(resolveConfigSecrets2(
|
|
6558
|
+
await reloader.applyReloadPlan(resolveConfigSecrets2(loadConfig10(), { configPath: runtimeConfigPath }));
|
|
6356
6559
|
};
|
|
6357
6560
|
const gatewayController = new GatewayControllerImpl({
|
|
6358
6561
|
reloader,
|
|
6359
6562
|
cron: cron2,
|
|
6360
6563
|
sessionManager,
|
|
6361
6564
|
getConfigPath: getConfigPath3,
|
|
6362
|
-
saveConfig:
|
|
6565
|
+
saveConfig: saveConfig7,
|
|
6363
6566
|
requestRestart: async (options2) => {
|
|
6364
6567
|
await this.deps.requestRestart({
|
|
6365
6568
|
reason: options2?.reason ?? "gateway tool restart",
|
|
@@ -6385,7 +6588,7 @@ var ServiceCommands = class {
|
|
|
6385
6588
|
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
|
|
6386
6589
|
registry: pluginRegistry,
|
|
6387
6590
|
channel,
|
|
6388
|
-
cfg: resolveConfigSecrets2(
|
|
6591
|
+
cfg: resolveConfigSecrets2(loadConfig10(), { configPath: runtimeConfigPath }),
|
|
6389
6592
|
accountId
|
|
6390
6593
|
})
|
|
6391
6594
|
});
|
|
@@ -6418,14 +6621,14 @@ var ServiceCommands = class {
|
|
|
6418
6621
|
});
|
|
6419
6622
|
let pluginChannelBindings = getPluginChannelBindings3(pluginRegistry);
|
|
6420
6623
|
setPluginRuntimeBridge({
|
|
6421
|
-
loadConfig: () => toPluginConfigView(resolveConfigSecrets2(
|
|
6624
|
+
loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig10(), { configPath: runtimeConfigPath }), pluginChannelBindings),
|
|
6422
6625
|
writeConfigFile: async (nextConfigView) => {
|
|
6423
6626
|
if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
|
|
6424
6627
|
throw new Error("plugin runtime writeConfigFile expects an object config");
|
|
6425
6628
|
}
|
|
6426
|
-
const current =
|
|
6629
|
+
const current = loadConfig10();
|
|
6427
6630
|
const next = mergePluginConfigView(current, nextConfigView, pluginChannelBindings);
|
|
6428
|
-
|
|
6631
|
+
saveConfig7(next);
|
|
6429
6632
|
},
|
|
6430
6633
|
dispatchReplyWithBufferedBlockDispatcher: async ({ ctx, dispatcherOptions }) => {
|
|
6431
6634
|
const bodyForAgent = typeof ctx.BodyForAgent === "string" ? ctx.BodyForAgent : "";
|
|
@@ -6499,12 +6702,12 @@ var ServiceCommands = class {
|
|
|
6499
6702
|
providerManager,
|
|
6500
6703
|
bus,
|
|
6501
6704
|
gatewayController,
|
|
6502
|
-
() => resolveConfigSecrets2(
|
|
6705
|
+
() => resolveConfigSecrets2(loadConfig10(), { configPath: runtimeConfigPath }),
|
|
6503
6706
|
() => extensionRegistry,
|
|
6504
6707
|
({ channel, accountId }) => resolvePluginChannelMessageToolHints({
|
|
6505
6708
|
registry: pluginRegistry,
|
|
6506
6709
|
channel,
|
|
6507
|
-
cfg: resolveConfigSecrets2(
|
|
6710
|
+
cfg: resolveConfigSecrets2(loadConfig10(), { configPath: runtimeConfigPath }),
|
|
6508
6711
|
accountId
|
|
6509
6712
|
})
|
|
6510
6713
|
);
|
|
@@ -6662,7 +6865,7 @@ var ServiceCommands = class {
|
|
|
6662
6865
|
});
|
|
6663
6866
|
}
|
|
6664
6867
|
async runForeground(options) {
|
|
6665
|
-
const config2 =
|
|
6868
|
+
const config2 = loadConfig10();
|
|
6666
6869
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
6667
6870
|
const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
|
|
6668
6871
|
if (options.open) {
|
|
@@ -6675,7 +6878,7 @@ var ServiceCommands = class {
|
|
|
6675
6878
|
});
|
|
6676
6879
|
}
|
|
6677
6880
|
async startService(options) {
|
|
6678
|
-
const config2 =
|
|
6881
|
+
const config2 = loadConfig10();
|
|
6679
6882
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
6680
6883
|
const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
|
|
6681
6884
|
const apiUrl = `${uiUrl}/api`;
|
|
@@ -7208,6 +7411,11 @@ var ServiceCommands = class {
|
|
|
7208
7411
|
})
|
|
7209
7412
|
});
|
|
7210
7413
|
this.liveUiNcpAgent = ncpAgent;
|
|
7414
|
+
const marketplaceInstaller = new ServiceMarketplaceInstaller({
|
|
7415
|
+
applyLiveConfigReload: this.applyLiveConfigReload ?? void 0,
|
|
7416
|
+
runCliSubcommand: (args) => this.runCliSubcommand(args),
|
|
7417
|
+
installBuiltinSkill: (slug, force) => this.installBuiltinMarketplaceSkill(slug, force)
|
|
7418
|
+
}).createInstaller();
|
|
7211
7419
|
const uiServer = startUiServer({
|
|
7212
7420
|
host: uiConfig.host,
|
|
7213
7421
|
port: uiConfig.port,
|
|
@@ -7217,14 +7425,7 @@ var ServiceCommands = class {
|
|
|
7217
7425
|
cronService,
|
|
7218
7426
|
marketplace: {
|
|
7219
7427
|
apiBaseUrl: process.env.NEXTCLAW_MARKETPLACE_API_BASE,
|
|
7220
|
-
installer:
|
|
7221
|
-
installPlugin: (spec) => this.installMarketplacePlugin(spec),
|
|
7222
|
-
installSkill: (params) => this.installMarketplaceSkill(params),
|
|
7223
|
-
enablePlugin: (id) => this.enableMarketplacePlugin(id),
|
|
7224
|
-
disablePlugin: (id) => this.disableMarketplacePlugin(id),
|
|
7225
|
-
uninstallPlugin: (id) => this.uninstallMarketplacePlugin(id),
|
|
7226
|
-
uninstallSkill: (slug) => this.uninstallMarketplaceSkill(slug)
|
|
7227
|
-
}
|
|
7428
|
+
installer: marketplaceInstaller
|
|
7228
7429
|
},
|
|
7229
7430
|
ncpAgent,
|
|
7230
7431
|
chatRuntime: {
|
|
@@ -7305,73 +7506,11 @@ var ServiceCommands = class {
|
|
|
7305
7506
|
openBrowser(uiUrl);
|
|
7306
7507
|
}
|
|
7307
7508
|
}
|
|
7308
|
-
async installMarketplacePlugin(spec) {
|
|
7309
|
-
const result = await installPluginMutation(spec);
|
|
7310
|
-
await this.applyLiveConfigReload?.();
|
|
7311
|
-
return { message: result.message };
|
|
7312
|
-
}
|
|
7313
|
-
async installMarketplaceSkill(params) {
|
|
7314
|
-
if (params.kind === "builtin") {
|
|
7315
|
-
const result = this.installBuiltinMarketplaceSkill(params.slug, params.force);
|
|
7316
|
-
if (!result) {
|
|
7317
|
-
throw new Error(`Builtin skill not found: ${params.slug}`);
|
|
7318
|
-
}
|
|
7319
|
-
return result;
|
|
7320
|
-
}
|
|
7321
|
-
if (params.kind && params.kind !== "marketplace") {
|
|
7322
|
-
throw new Error(`Unsupported marketplace skill kind: ${params.kind}`);
|
|
7323
|
-
}
|
|
7324
|
-
const workspace = getWorkspacePath8(loadConfig8().agents.defaults.workspace);
|
|
7325
|
-
const args = buildMarketplaceSkillInstallArgs({
|
|
7326
|
-
slug: params.slug,
|
|
7327
|
-
workspace,
|
|
7328
|
-
force: params.force
|
|
7329
|
-
});
|
|
7330
|
-
try {
|
|
7331
|
-
const output = await this.runCliSubcommand(args);
|
|
7332
|
-
const summary = pickUserFacingCommandSummary(output, `Installed skill: ${params.slug}`);
|
|
7333
|
-
return { message: summary };
|
|
7334
|
-
} catch (error) {
|
|
7335
|
-
const fallback = this.installBuiltinMarketplaceSkill(params.slug, params.force);
|
|
7336
|
-
if (!fallback) {
|
|
7337
|
-
throw error;
|
|
7338
|
-
}
|
|
7339
|
-
return fallback;
|
|
7340
|
-
}
|
|
7341
|
-
}
|
|
7342
|
-
async enableMarketplacePlugin(id) {
|
|
7343
|
-
const result = await enablePluginMutation(id);
|
|
7344
|
-
await this.applyLiveConfigReload?.();
|
|
7345
|
-
return { message: result.message };
|
|
7346
|
-
}
|
|
7347
|
-
async disableMarketplacePlugin(id) {
|
|
7348
|
-
const result = await disablePluginMutation(id);
|
|
7349
|
-
await this.applyLiveConfigReload?.();
|
|
7350
|
-
return { message: result.message };
|
|
7351
|
-
}
|
|
7352
|
-
async uninstallMarketplacePlugin(id) {
|
|
7353
|
-
await disablePluginMutation(id);
|
|
7354
|
-
await this.applyLiveConfigReload?.();
|
|
7355
|
-
const result = await uninstallPluginMutation(id, { force: true });
|
|
7356
|
-
await this.applyLiveConfigReload?.();
|
|
7357
|
-
return { message: result.message };
|
|
7358
|
-
}
|
|
7359
|
-
async uninstallMarketplaceSkill(slug) {
|
|
7360
|
-
const workspace = getWorkspacePath8(loadConfig8().agents.defaults.workspace);
|
|
7361
|
-
const targetDir = join5(workspace, "skills", slug);
|
|
7362
|
-
if (!existsSync9(targetDir)) {
|
|
7363
|
-
throw new Error(`Skill not installed in workspace: ${slug}`);
|
|
7364
|
-
}
|
|
7365
|
-
rmSync4(targetDir, { recursive: true, force: true });
|
|
7366
|
-
return {
|
|
7367
|
-
message: `Uninstalled skill: ${slug}`
|
|
7368
|
-
};
|
|
7369
|
-
}
|
|
7370
7509
|
installBuiltinMarketplaceSkill(slug, force) {
|
|
7371
|
-
const workspace =
|
|
7372
|
-
const destination =
|
|
7373
|
-
const destinationSkillFile =
|
|
7374
|
-
if (
|
|
7510
|
+
const workspace = getWorkspacePath9(loadConfig10().agents.defaults.workspace);
|
|
7511
|
+
const destination = join6(workspace, "skills", slug);
|
|
7512
|
+
const destinationSkillFile = join6(destination, "SKILL.md");
|
|
7513
|
+
if (existsSync10(destinationSkillFile) && !force) {
|
|
7375
7514
|
return {
|
|
7376
7515
|
message: `${slug} is already installed`
|
|
7377
7516
|
};
|
|
@@ -7379,14 +7518,14 @@ var ServiceCommands = class {
|
|
|
7379
7518
|
const loader = createSkillsLoader(workspace);
|
|
7380
7519
|
const builtin = (loader?.listSkills(false) ?? []).find((skill) => skill.name === slug && skill.source === "builtin");
|
|
7381
7520
|
if (!builtin) {
|
|
7382
|
-
if (
|
|
7521
|
+
if (existsSync10(destinationSkillFile)) {
|
|
7383
7522
|
return {
|
|
7384
7523
|
message: `${slug} is already installed`
|
|
7385
7524
|
};
|
|
7386
7525
|
}
|
|
7387
7526
|
return null;
|
|
7388
7527
|
}
|
|
7389
|
-
mkdirSync5(
|
|
7528
|
+
mkdirSync5(join6(workspace, "skills"), { recursive: true });
|
|
7390
7529
|
cpSync2(dirname2(builtin.path), destination, { recursive: true, force: true });
|
|
7391
7530
|
return {
|
|
7392
7531
|
message: `Installed skill: ${slug}`
|
|
@@ -7446,9 +7585,9 @@ ${stderr}`.trim();
|
|
|
7446
7585
|
};
|
|
7447
7586
|
|
|
7448
7587
|
// src/cli/workspace.ts
|
|
7449
|
-
import { cpSync as cpSync3, existsSync as
|
|
7588
|
+
import { cpSync as cpSync3, existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9, readdirSync as readdirSync3, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
7450
7589
|
import { createRequire as createRequire2 } from "module";
|
|
7451
|
-
import { dirname as dirname3, join as
|
|
7590
|
+
import { dirname as dirname3, join as join7, resolve as resolve11 } from "path";
|
|
7452
7591
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7453
7592
|
import { APP_NAME as APP_NAME3, getDataDir as getDataDir7 } from "@nextclaw/core";
|
|
7454
7593
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
@@ -7478,12 +7617,12 @@ var WorkspaceManager = class {
|
|
|
7478
7617
|
{ source: "memory/MEMORY.md", target: "memory/MEMORY.md" }
|
|
7479
7618
|
];
|
|
7480
7619
|
for (const entry of templateFiles) {
|
|
7481
|
-
const filePath =
|
|
7482
|
-
if (!force &&
|
|
7620
|
+
const filePath = join7(workspace, entry.target);
|
|
7621
|
+
if (!force && existsSync11(filePath)) {
|
|
7483
7622
|
continue;
|
|
7484
7623
|
}
|
|
7485
|
-
const templatePath =
|
|
7486
|
-
if (!
|
|
7624
|
+
const templatePath = join7(templateDir, entry.source);
|
|
7625
|
+
if (!existsSync11(templatePath)) {
|
|
7487
7626
|
console.warn(`Warning: Template file missing: ${templatePath}`);
|
|
7488
7627
|
continue;
|
|
7489
7628
|
}
|
|
@@ -7493,15 +7632,15 @@ var WorkspaceManager = class {
|
|
|
7493
7632
|
writeFileSync5(filePath, content);
|
|
7494
7633
|
created.push(entry.target);
|
|
7495
7634
|
}
|
|
7496
|
-
const memoryDir =
|
|
7497
|
-
if (!
|
|
7635
|
+
const memoryDir = join7(workspace, "memory");
|
|
7636
|
+
if (!existsSync11(memoryDir)) {
|
|
7498
7637
|
mkdirSync6(memoryDir, { recursive: true });
|
|
7499
|
-
created.push(
|
|
7638
|
+
created.push(join7("memory", ""));
|
|
7500
7639
|
}
|
|
7501
|
-
const skillsDir =
|
|
7502
|
-
if (!
|
|
7640
|
+
const skillsDir = join7(workspace, "skills");
|
|
7641
|
+
if (!existsSync11(skillsDir)) {
|
|
7503
7642
|
mkdirSync6(skillsDir, { recursive: true });
|
|
7504
|
-
created.push(
|
|
7643
|
+
created.push(join7("skills", ""));
|
|
7505
7644
|
}
|
|
7506
7645
|
const seeded = this.seedBuiltinSkills(skillsDir, { force });
|
|
7507
7646
|
if (seeded > 0) {
|
|
@@ -7520,12 +7659,12 @@ var WorkspaceManager = class {
|
|
|
7520
7659
|
if (!entry.isDirectory()) {
|
|
7521
7660
|
continue;
|
|
7522
7661
|
}
|
|
7523
|
-
const src =
|
|
7524
|
-
if (!
|
|
7662
|
+
const src = join7(sourceDir, entry.name);
|
|
7663
|
+
if (!existsSync11(join7(src, "SKILL.md"))) {
|
|
7525
7664
|
continue;
|
|
7526
7665
|
}
|
|
7527
|
-
const dest =
|
|
7528
|
-
if (!force &&
|
|
7666
|
+
const dest = join7(targetDir, entry.name);
|
|
7667
|
+
if (!force && existsSync11(dest)) {
|
|
7529
7668
|
continue;
|
|
7530
7669
|
}
|
|
7531
7670
|
try {
|
|
@@ -7543,12 +7682,12 @@ var WorkspaceManager = class {
|
|
|
7543
7682
|
const require3 = createRequire2(import.meta.url);
|
|
7544
7683
|
const entry = require3.resolve("@nextclaw/core");
|
|
7545
7684
|
const pkgRoot = resolve11(dirname3(entry), "..");
|
|
7546
|
-
const distSkills =
|
|
7547
|
-
if (
|
|
7685
|
+
const distSkills = join7(pkgRoot, "dist", "skills");
|
|
7686
|
+
if (existsSync11(distSkills)) {
|
|
7548
7687
|
return distSkills;
|
|
7549
7688
|
}
|
|
7550
|
-
const srcSkills =
|
|
7551
|
-
if (
|
|
7689
|
+
const srcSkills = join7(pkgRoot, "src", "agent", "skills");
|
|
7690
|
+
if (existsSync11(srcSkills)) {
|
|
7552
7691
|
return srcSkills;
|
|
7553
7692
|
}
|
|
7554
7693
|
return null;
|
|
@@ -7563,17 +7702,17 @@ var WorkspaceManager = class {
|
|
|
7563
7702
|
}
|
|
7564
7703
|
const cliDir = resolve11(fileURLToPath3(new URL(".", import.meta.url)));
|
|
7565
7704
|
const pkgRoot = resolve11(cliDir, "..", "..");
|
|
7566
|
-
const candidates = [
|
|
7705
|
+
const candidates = [join7(pkgRoot, "templates")];
|
|
7567
7706
|
for (const candidate of candidates) {
|
|
7568
|
-
if (
|
|
7707
|
+
if (existsSync11(candidate)) {
|
|
7569
7708
|
return candidate;
|
|
7570
7709
|
}
|
|
7571
7710
|
}
|
|
7572
7711
|
return null;
|
|
7573
7712
|
}
|
|
7574
7713
|
getBridgeDir() {
|
|
7575
|
-
const userBridge =
|
|
7576
|
-
if (
|
|
7714
|
+
const userBridge = join7(getDataDir7(), "bridge");
|
|
7715
|
+
if (existsSync11(join7(userBridge, "dist", "index.js"))) {
|
|
7577
7716
|
return userBridge;
|
|
7578
7717
|
}
|
|
7579
7718
|
if (!which("npm")) {
|
|
@@ -7582,12 +7721,12 @@ var WorkspaceManager = class {
|
|
|
7582
7721
|
}
|
|
7583
7722
|
const cliDir = resolve11(fileURLToPath3(new URL(".", import.meta.url)));
|
|
7584
7723
|
const pkgRoot = resolve11(cliDir, "..", "..");
|
|
7585
|
-
const pkgBridge =
|
|
7586
|
-
const srcBridge =
|
|
7724
|
+
const pkgBridge = join7(pkgRoot, "bridge");
|
|
7725
|
+
const srcBridge = join7(pkgRoot, "..", "..", "bridge");
|
|
7587
7726
|
let source = null;
|
|
7588
|
-
if (
|
|
7727
|
+
if (existsSync11(join7(pkgBridge, "package.json"))) {
|
|
7589
7728
|
source = pkgBridge;
|
|
7590
|
-
} else if (
|
|
7729
|
+
} else if (existsSync11(join7(srcBridge, "package.json"))) {
|
|
7591
7730
|
source = srcBridge;
|
|
7592
7731
|
}
|
|
7593
7732
|
if (!source) {
|
|
@@ -7596,7 +7735,7 @@ var WorkspaceManager = class {
|
|
|
7596
7735
|
}
|
|
7597
7736
|
console.log(`${this.logo} Setting up bridge...`);
|
|
7598
7737
|
mkdirSync6(resolve11(userBridge, ".."), { recursive: true });
|
|
7599
|
-
if (
|
|
7738
|
+
if (existsSync11(userBridge)) {
|
|
7600
7739
|
rmSync5(userBridge, { recursive: true, force: true });
|
|
7601
7740
|
}
|
|
7602
7741
|
cpSync3(source, userBridge, {
|
|
@@ -7632,7 +7771,7 @@ function resolveSkillsInstallWorkdir(params) {
|
|
|
7632
7771
|
if (params.explicitWorkdir) {
|
|
7633
7772
|
return expandHome2(params.explicitWorkdir);
|
|
7634
7773
|
}
|
|
7635
|
-
return
|
|
7774
|
+
return getWorkspacePath10(params.configuredWorkspace);
|
|
7636
7775
|
}
|
|
7637
7776
|
var CliRuntime = class {
|
|
7638
7777
|
logo;
|
|
@@ -7863,15 +8002,15 @@ var CliRuntime = class {
|
|
|
7863
8002
|
const force = Boolean(options.force);
|
|
7864
8003
|
const configPath = getConfigPath4();
|
|
7865
8004
|
let createdConfig = false;
|
|
7866
|
-
if (!
|
|
8005
|
+
if (!existsSync12(configPath)) {
|
|
7867
8006
|
const config3 = ConfigSchema2.parse({});
|
|
7868
|
-
|
|
8007
|
+
saveConfig8(config3);
|
|
7869
8008
|
createdConfig = true;
|
|
7870
8009
|
}
|
|
7871
|
-
const config2 =
|
|
8010
|
+
const config2 = loadConfig11();
|
|
7872
8011
|
const workspaceSetting = config2.agents.defaults.workspace;
|
|
7873
|
-
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ?
|
|
7874
|
-
const workspaceExisted =
|
|
8012
|
+
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir8(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
|
|
8013
|
+
const workspaceExisted = existsSync12(workspacePath);
|
|
7875
8014
|
mkdirSync7(workspacePath, { recursive: true });
|
|
7876
8015
|
const templateResult = this.workspaceManager.createWorkspaceTemplates(
|
|
7877
8016
|
workspacePath,
|
|
@@ -7904,7 +8043,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
7904
8043
|
async login(opts = {}) {
|
|
7905
8044
|
await this.init({ source: "login", auto: true });
|
|
7906
8045
|
const configPath = getConfigPath4();
|
|
7907
|
-
const config2 =
|
|
8046
|
+
const config2 = loadConfig11(configPath);
|
|
7908
8047
|
const providers = config2.providers;
|
|
7909
8048
|
const nextclawProvider = providers.nextclaw ?? {
|
|
7910
8049
|
displayName: "",
|
|
@@ -7966,7 +8105,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
7966
8105
|
nextclawProvider.apiBase = v1Base;
|
|
7967
8106
|
nextclawProvider.apiKey = token;
|
|
7968
8107
|
providers.nextclaw = nextclawProvider;
|
|
7969
|
-
|
|
8108
|
+
saveConfig8(config2, configPath);
|
|
7970
8109
|
console.log(`\u2713 Logged in to NextClaw platform (${platformBase})`);
|
|
7971
8110
|
console.log(`\u2713 Account: ${email} (${role})`);
|
|
7972
8111
|
console.log(`\u2713 Token saved into providers.nextclaw.apiKey`);
|
|
@@ -8061,15 +8200,15 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8061
8200
|
}
|
|
8062
8201
|
async agent(opts) {
|
|
8063
8202
|
const configPath = getConfigPath4();
|
|
8064
|
-
const config2 = resolveConfigSecrets3(
|
|
8065
|
-
const workspace =
|
|
8203
|
+
const config2 = resolveConfigSecrets3(loadConfig11(), { configPath });
|
|
8204
|
+
const workspace = getWorkspacePath10(config2.agents.defaults.workspace);
|
|
8066
8205
|
const pluginRegistry = loadPluginRegistry(config2, workspace);
|
|
8067
8206
|
const extensionRegistry = toExtensionRegistry(pluginRegistry);
|
|
8068
8207
|
logPluginDiagnostics(pluginRegistry);
|
|
8069
8208
|
const pluginChannelBindings = getPluginChannelBindings4(pluginRegistry);
|
|
8070
8209
|
setPluginRuntimeBridge2({
|
|
8071
8210
|
loadConfig: () => toPluginConfigView(
|
|
8072
|
-
resolveConfigSecrets3(
|
|
8211
|
+
resolveConfigSecrets3(loadConfig11(), { configPath }),
|
|
8073
8212
|
pluginChannelBindings
|
|
8074
8213
|
),
|
|
8075
8214
|
writeConfigFile: async (nextConfigView) => {
|
|
@@ -8078,13 +8217,13 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8078
8217
|
"plugin runtime writeConfigFile expects an object config"
|
|
8079
8218
|
);
|
|
8080
8219
|
}
|
|
8081
|
-
const current =
|
|
8220
|
+
const current = loadConfig11();
|
|
8082
8221
|
const next = mergePluginConfigView(
|
|
8083
8222
|
current,
|
|
8084
8223
|
nextConfigView,
|
|
8085
8224
|
pluginChannelBindings
|
|
8086
8225
|
);
|
|
8087
|
-
|
|
8226
|
+
saveConfig8(next);
|
|
8088
8227
|
}
|
|
8089
8228
|
});
|
|
8090
8229
|
try {
|
|
@@ -8110,7 +8249,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8110
8249
|
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
|
|
8111
8250
|
registry: pluginRegistry,
|
|
8112
8251
|
channel,
|
|
8113
|
-
cfg: resolveConfigSecrets3(
|
|
8252
|
+
cfg: resolveConfigSecrets3(loadConfig11(), { configPath }),
|
|
8114
8253
|
accountId
|
|
8115
8254
|
})
|
|
8116
8255
|
});
|
|
@@ -8129,10 +8268,10 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8129
8268
|
`${this.logo} Interactive mode (type exit or Ctrl+C to quit)
|
|
8130
8269
|
`
|
|
8131
8270
|
);
|
|
8132
|
-
const historyFile =
|
|
8271
|
+
const historyFile = join8(getDataDir8(), "history", "cli_history");
|
|
8133
8272
|
const historyDir = resolve12(historyFile, "..");
|
|
8134
8273
|
mkdirSync7(historyDir, { recursive: true });
|
|
8135
|
-
const history =
|
|
8274
|
+
const history = existsSync12(historyFile) ? readFileSync10(historyFile, "utf-8").split("\n").filter(Boolean) : [];
|
|
8136
8275
|
const rl = createInterface2({
|
|
8137
8276
|
input: process.stdin,
|
|
8138
8277
|
output: process.stdout
|
|
@@ -8305,7 +8444,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8305
8444
|
await this.diagnosticsCommands.doctor(opts);
|
|
8306
8445
|
}
|
|
8307
8446
|
async skillsInstall(options) {
|
|
8308
|
-
const config2 =
|
|
8447
|
+
const config2 = loadConfig11();
|
|
8309
8448
|
const workdir = resolveSkillsInstallWorkdir({
|
|
8310
8449
|
explicitWorkdir: options.workdir,
|
|
8311
8450
|
configuredWorkspace: config2.agents.defaults.workspace
|