nextclaw 0.6.33 → 0.6.35
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 +193 -121
- package/package.json +4 -4
- package/templates/USAGE.md +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -20,7 +20,11 @@ import {
|
|
|
20
20
|
DEFAULT_WORKSPACE_DIR,
|
|
21
21
|
DEFAULT_WORKSPACE_PATH
|
|
22
22
|
} from "@nextclaw/core";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
getPluginChannelBindings as getPluginChannelBindings3,
|
|
25
|
+
resolvePluginChannelMessageToolHints as resolvePluginChannelMessageToolHints2,
|
|
26
|
+
setPluginRuntimeBridge as setPluginRuntimeBridge2
|
|
27
|
+
} from "@nextclaw/openclaw-compat";
|
|
24
28
|
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
25
29
|
import { join as join6, resolve as resolve9 } from "path";
|
|
26
30
|
import { createInterface as createInterface2 } from "readline";
|
|
@@ -614,8 +618,7 @@ function mergePluginConfigView(baseConfig, pluginViewConfig, bindings) {
|
|
|
614
618
|
return next;
|
|
615
619
|
}
|
|
616
620
|
var PluginCommands = class {
|
|
617
|
-
constructor(
|
|
618
|
-
this.deps = deps;
|
|
621
|
+
constructor() {
|
|
619
622
|
}
|
|
620
623
|
pluginsList(opts = {}) {
|
|
621
624
|
const config2 = loadConfig();
|
|
@@ -745,19 +748,15 @@ var PluginCommands = class {
|
|
|
745
748
|
const config2 = loadConfig();
|
|
746
749
|
const next = enablePluginInConfig(config2, id);
|
|
747
750
|
saveConfig(next);
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
manualMessage: `Enabled plugin "${id}". Restart the gateway to apply.`
|
|
751
|
-
});
|
|
751
|
+
console.log(`Enabled plugin "${id}".`);
|
|
752
|
+
console.log("If gateway is running, plugin changes are hot-applied automatically.");
|
|
752
753
|
}
|
|
753
754
|
async pluginsDisable(id) {
|
|
754
755
|
const config2 = loadConfig();
|
|
755
756
|
const next = disablePluginInConfig(config2, id);
|
|
756
757
|
saveConfig(next);
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
manualMessage: `Disabled plugin "${id}". Restart the gateway to apply.`
|
|
760
|
-
});
|
|
758
|
+
console.log(`Disabled plugin "${id}".`);
|
|
759
|
+
console.log("If gateway is running, plugin changes are hot-applied automatically.");
|
|
761
760
|
}
|
|
762
761
|
async pluginsUninstall(id, opts = {}) {
|
|
763
762
|
const config2 = loadConfig();
|
|
@@ -854,10 +853,7 @@ var PluginCommands = class {
|
|
|
854
853
|
removed.push("directory");
|
|
855
854
|
}
|
|
856
855
|
console.log(`Uninstalled plugin "${pluginId}". Removed: ${removed.length > 0 ? removed.join(", ") : "nothing"}.`);
|
|
857
|
-
|
|
858
|
-
reason: `plugin uninstalled: ${pluginId}`,
|
|
859
|
-
manualMessage: "Restart the gateway to apply changes."
|
|
860
|
-
});
|
|
856
|
+
console.log("If gateway is running, plugin changes are hot-applied automatically.");
|
|
861
857
|
}
|
|
862
858
|
async pluginsInstall(pathOrSpec, opts = {}) {
|
|
863
859
|
const fileSpec = this.resolveFileNpmSpecToLocalPath(pathOrSpec);
|
|
@@ -886,10 +882,7 @@ var PluginCommands = class {
|
|
|
886
882
|
});
|
|
887
883
|
saveConfig(next3);
|
|
888
884
|
console.log(`Linked plugin path: ${resolved}`);
|
|
889
|
-
|
|
890
|
-
reason: `plugin linked: ${probe.pluginId}`,
|
|
891
|
-
manualMessage: "Restart the gateway to load plugins."
|
|
892
|
-
});
|
|
885
|
+
console.log("If gateway is running, plugin changes are hot-applied automatically.");
|
|
893
886
|
return;
|
|
894
887
|
}
|
|
895
888
|
const result2 = await installPluginFromPath({
|
|
@@ -913,10 +906,7 @@ var PluginCommands = class {
|
|
|
913
906
|
});
|
|
914
907
|
saveConfig(next2);
|
|
915
908
|
console.log(`Installed plugin: ${result2.pluginId}`);
|
|
916
|
-
|
|
917
|
-
reason: `plugin installed: ${result2.pluginId}`,
|
|
918
|
-
manualMessage: "Restart the gateway to load plugins."
|
|
919
|
-
});
|
|
909
|
+
console.log("If gateway is running, plugin changes are hot-applied automatically.");
|
|
920
910
|
return;
|
|
921
911
|
}
|
|
922
912
|
if (opts.link) {
|
|
@@ -948,10 +938,7 @@ var PluginCommands = class {
|
|
|
948
938
|
});
|
|
949
939
|
saveConfig(next);
|
|
950
940
|
console.log(`Installed plugin: ${result.pluginId}`);
|
|
951
|
-
|
|
952
|
-
reason: `plugin installed: ${result.pluginId}`,
|
|
953
|
-
manualMessage: "Restart the gateway to load plugins."
|
|
954
|
-
});
|
|
941
|
+
console.log("If gateway is running, plugin changes are hot-applied automatically.");
|
|
955
942
|
}
|
|
956
943
|
pluginsDoctor() {
|
|
957
944
|
const config2 = loadConfig();
|
|
@@ -2194,6 +2181,9 @@ var ConfigReloader = class {
|
|
|
2194
2181
|
setApplyAgentRuntimeConfig(callback) {
|
|
2195
2182
|
this.options.applyAgentRuntimeConfig = callback;
|
|
2196
2183
|
}
|
|
2184
|
+
setReloadPlugins(callback) {
|
|
2185
|
+
this.options.reloadPlugins = callback;
|
|
2186
|
+
}
|
|
2197
2187
|
async applyReloadPlan(nextConfig) {
|
|
2198
2188
|
const changedPaths = diffConfigPaths2(this.currentConfig, nextConfig);
|
|
2199
2189
|
if (!changedPaths.length) {
|
|
@@ -2202,6 +2192,10 @@ var ConfigReloader = class {
|
|
|
2202
2192
|
this.currentConfig = nextConfig;
|
|
2203
2193
|
this.options.providerManager?.setConfig(nextConfig);
|
|
2204
2194
|
const plan = buildReloadPlan2(changedPaths);
|
|
2195
|
+
if (plan.reloadPlugins) {
|
|
2196
|
+
await this.reloadPlugins(nextConfig);
|
|
2197
|
+
console.log("Config reload: plugins reloaded.");
|
|
2198
|
+
}
|
|
2205
2199
|
if (plan.restartChannels) {
|
|
2206
2200
|
await this.reloadChannels(nextConfig);
|
|
2207
2201
|
console.log("Config reload: channels restarted.");
|
|
@@ -2297,6 +2291,12 @@ var ConfigReloader = class {
|
|
|
2297
2291
|
this.providerReloadTask = null;
|
|
2298
2292
|
}
|
|
2299
2293
|
}
|
|
2294
|
+
async reloadPlugins(nextConfig) {
|
|
2295
|
+
if (!this.options.reloadPlugins) {
|
|
2296
|
+
return;
|
|
2297
|
+
}
|
|
2298
|
+
await this.options.reloadPlugins(nextConfig);
|
|
2299
|
+
}
|
|
2300
2300
|
};
|
|
2301
2301
|
|
|
2302
2302
|
// src/cli/missing-provider.ts
|
|
@@ -2381,6 +2381,10 @@ var GatewayAgentRuntimePool = class {
|
|
|
2381
2381
|
this.routeResolver.updateConfig(config2);
|
|
2382
2382
|
this.rebuild(config2);
|
|
2383
2383
|
}
|
|
2384
|
+
applyExtensionRegistry(extensionRegistry) {
|
|
2385
|
+
this.options.extensionRegistry = extensionRegistry;
|
|
2386
|
+
this.rebuild(this.options.config);
|
|
2387
|
+
}
|
|
2384
2388
|
async processDirect(params) {
|
|
2385
2389
|
const message = {
|
|
2386
2390
|
channel: params.channel ?? "cli",
|
|
@@ -2497,8 +2501,8 @@ var ServiceCommands = class {
|
|
|
2497
2501
|
async startGateway(options = {}) {
|
|
2498
2502
|
const config2 = loadConfig5();
|
|
2499
2503
|
const workspace = getWorkspacePath5(config2.agents.defaults.workspace);
|
|
2500
|
-
|
|
2501
|
-
|
|
2504
|
+
let pluginRegistry = loadPluginRegistry(config2, workspace);
|
|
2505
|
+
let extensionRegistry = toExtensionRegistry(pluginRegistry);
|
|
2502
2506
|
logPluginDiagnostics(pluginRegistry);
|
|
2503
2507
|
const bus = new MessageBus();
|
|
2504
2508
|
const provider = options.allowMissingProvider === true ? this.makeProvider(config2, { allowMissing: true }) : this.makeProvider(config2);
|
|
@@ -2507,6 +2511,24 @@ var ServiceCommands = class {
|
|
|
2507
2511
|
config: config2
|
|
2508
2512
|
});
|
|
2509
2513
|
const sessionManager = new SessionManager(workspace);
|
|
2514
|
+
let pluginGatewayHandles = [];
|
|
2515
|
+
const pluginGatewayLogger = {
|
|
2516
|
+
info: (message) => console.log(`[plugins] ${message}`),
|
|
2517
|
+
warn: (message) => console.warn(`[plugins] ${message}`),
|
|
2518
|
+
error: (message) => console.error(`[plugins] ${message}`),
|
|
2519
|
+
debug: (message) => console.debug(`[plugins] ${message}`)
|
|
2520
|
+
};
|
|
2521
|
+
const logPluginGatewayDiagnostics = (diagnostics) => {
|
|
2522
|
+
for (const diag of diagnostics) {
|
|
2523
|
+
const prefix = diag.pluginId ? `${diag.pluginId}: ` : "";
|
|
2524
|
+
const text = `${prefix}${diag.message}`;
|
|
2525
|
+
if (diag.level === "error") {
|
|
2526
|
+
console.error(`[plugins] ${text}`);
|
|
2527
|
+
} else {
|
|
2528
|
+
console.warn(`[plugins] ${text}`);
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
};
|
|
2510
2532
|
const cronStorePath = join4(getDataDir5(), "cron", "jobs.json");
|
|
2511
2533
|
const cron2 = new CronService2(cronStorePath);
|
|
2512
2534
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
@@ -2568,7 +2590,26 @@ var ServiceCommands = class {
|
|
|
2568
2590
|
})
|
|
2569
2591
|
});
|
|
2570
2592
|
reloader.setApplyAgentRuntimeConfig((nextConfig) => runtimePool.applyRuntimeConfig(nextConfig));
|
|
2571
|
-
|
|
2593
|
+
reloader.setReloadPlugins(async (nextConfig) => {
|
|
2594
|
+
const nextWorkspace = getWorkspacePath5(nextConfig.agents.defaults.workspace);
|
|
2595
|
+
const nextPluginRegistry = loadPluginRegistry(nextConfig, nextWorkspace);
|
|
2596
|
+
const nextExtensionRegistry = toExtensionRegistry(nextPluginRegistry);
|
|
2597
|
+
logPluginDiagnostics(nextPluginRegistry);
|
|
2598
|
+
await stopPluginChannelGateways(pluginGatewayHandles);
|
|
2599
|
+
const startedPluginGateways = await startPluginChannelGateways({
|
|
2600
|
+
registry: nextPluginRegistry,
|
|
2601
|
+
logger: pluginGatewayLogger
|
|
2602
|
+
});
|
|
2603
|
+
pluginGatewayHandles = startedPluginGateways.handles;
|
|
2604
|
+
logPluginGatewayDiagnostics(startedPluginGateways.diagnostics);
|
|
2605
|
+
pluginRegistry = nextPluginRegistry;
|
|
2606
|
+
extensionRegistry = nextExtensionRegistry;
|
|
2607
|
+
pluginChannelBindings = getPluginChannelBindings2(nextPluginRegistry);
|
|
2608
|
+
runtimePool.applyExtensionRegistry(nextExtensionRegistry);
|
|
2609
|
+
runtimePool.applyRuntimeConfig(nextConfig);
|
|
2610
|
+
console.log("Config reload: plugin channel gateways restarted.");
|
|
2611
|
+
});
|
|
2612
|
+
let pluginChannelBindings = getPluginChannelBindings2(pluginRegistry);
|
|
2572
2613
|
setPluginRuntimeBridge({
|
|
2573
2614
|
loadConfig: () => toPluginConfigView(loadConfig5(), pluginChannelBindings),
|
|
2574
2615
|
writeConfigFile: async (nextConfigView) => {
|
|
@@ -2658,27 +2699,13 @@ var ServiceCommands = class {
|
|
|
2658
2699
|
watcher.on("unlink", () => reloader.scheduleReload("config unlink"));
|
|
2659
2700
|
await cron2.start();
|
|
2660
2701
|
await heartbeat.start();
|
|
2661
|
-
let pluginGatewayHandles = [];
|
|
2662
2702
|
try {
|
|
2663
2703
|
const startedPluginGateways = await startPluginChannelGateways({
|
|
2664
2704
|
registry: pluginRegistry,
|
|
2665
|
-
logger:
|
|
2666
|
-
info: (message) => console.log(`[plugins] ${message}`),
|
|
2667
|
-
warn: (message) => console.warn(`[plugins] ${message}`),
|
|
2668
|
-
error: (message) => console.error(`[plugins] ${message}`),
|
|
2669
|
-
debug: (message) => console.debug(`[plugins] ${message}`)
|
|
2670
|
-
}
|
|
2705
|
+
logger: pluginGatewayLogger
|
|
2671
2706
|
});
|
|
2672
2707
|
pluginGatewayHandles = startedPluginGateways.handles;
|
|
2673
|
-
|
|
2674
|
-
const prefix = diag.pluginId ? `${diag.pluginId}: ` : "";
|
|
2675
|
-
const text = `${prefix}${diag.message}`;
|
|
2676
|
-
if (diag.level === "error") {
|
|
2677
|
-
console.error(`[plugins] ${text}`);
|
|
2678
|
-
} else {
|
|
2679
|
-
console.warn(`[plugins] ${text}`);
|
|
2680
|
-
}
|
|
2681
|
-
}
|
|
2708
|
+
logPluginGatewayDiagnostics(startedPluginGateways.diagnostics);
|
|
2682
2709
|
await reloader.getChannels().startAll();
|
|
2683
2710
|
await this.wakeFromRestartSentinel({ bus, sessionManager });
|
|
2684
2711
|
await runtimePool.run();
|
|
@@ -3236,9 +3263,7 @@ var CliRuntime = class {
|
|
|
3236
3263
|
this.configCommands = new ConfigCommands({
|
|
3237
3264
|
requestRestart: (params) => this.requestRestart(params)
|
|
3238
3265
|
});
|
|
3239
|
-
this.pluginCommands = new PluginCommands(
|
|
3240
|
-
requestRestart: (params) => this.requestRestart(params)
|
|
3241
|
-
});
|
|
3266
|
+
this.pluginCommands = new PluginCommands();
|
|
3242
3267
|
this.channelCommands = new ChannelCommands({
|
|
3243
3268
|
logo: this.logo,
|
|
3244
3269
|
getBridgeDir: () => this.workspaceManager.getBridgeDir(),
|
|
@@ -3274,7 +3299,9 @@ var CliRuntime = class {
|
|
|
3274
3299
|
}
|
|
3275
3300
|
const uiHost = FORCED_PUBLIC_UI_HOST;
|
|
3276
3301
|
const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
|
|
3277
|
-
console.log(
|
|
3302
|
+
console.log(
|
|
3303
|
+
`Applying changes (${reason}): restarting ${APP_NAME4} background service...`
|
|
3304
|
+
);
|
|
3278
3305
|
await this.serviceCommands.stopService();
|
|
3279
3306
|
await this.serviceCommands.startService({
|
|
3280
3307
|
uiOverrides: {
|
|
@@ -3421,11 +3448,15 @@ var CliRuntime = class {
|
|
|
3421
3448
|
}
|
|
3422
3449
|
});
|
|
3423
3450
|
} catch (error) {
|
|
3424
|
-
console.warn(
|
|
3451
|
+
console.warn(
|
|
3452
|
+
`Warning: failed to write restart sentinel from exec context: ${String(error)}`
|
|
3453
|
+
);
|
|
3425
3454
|
}
|
|
3426
3455
|
}
|
|
3427
3456
|
async onboard() {
|
|
3428
|
-
console.warn(
|
|
3457
|
+
console.warn(
|
|
3458
|
+
`Warning: ${APP_NAME4} onboard is deprecated. Use "${APP_NAME4} init" instead.`
|
|
3459
|
+
);
|
|
3429
3460
|
await this.init({ source: "onboard" });
|
|
3430
3461
|
}
|
|
3431
3462
|
async init(options = {}) {
|
|
@@ -3444,7 +3475,10 @@ var CliRuntime = class {
|
|
|
3444
3475
|
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join6(getDataDir7(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
|
|
3445
3476
|
const workspaceExisted = existsSync8(workspacePath);
|
|
3446
3477
|
mkdirSync5(workspacePath, { recursive: true });
|
|
3447
|
-
const templateResult = this.workspaceManager.createWorkspaceTemplates(
|
|
3478
|
+
const templateResult = this.workspaceManager.createWorkspaceTemplates(
|
|
3479
|
+
workspacePath,
|
|
3480
|
+
{ force }
|
|
3481
|
+
);
|
|
3448
3482
|
if (createdConfig) {
|
|
3449
3483
|
console.log(`\u2713 ${prefix}: created config at ${configPath}`);
|
|
3450
3484
|
}
|
|
@@ -3464,7 +3498,9 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3464
3498
|
console.log(` 1. Add your API key to ${configPath}`);
|
|
3465
3499
|
console.log(` 2. Chat: ${APP_NAME4} agent -m "Hello!"`);
|
|
3466
3500
|
} else {
|
|
3467
|
-
console.log(
|
|
3501
|
+
console.log(
|
|
3502
|
+
`Tip: Run "${APP_NAME4} init${force ? " --force" : ""}" to re-run initialization if needed.`
|
|
3503
|
+
);
|
|
3468
3504
|
}
|
|
3469
3505
|
}
|
|
3470
3506
|
async gateway(opts) {
|
|
@@ -3491,7 +3527,10 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3491
3527
|
if (opts.port) {
|
|
3492
3528
|
uiOverrides.port = Number(opts.port);
|
|
3493
3529
|
}
|
|
3494
|
-
await this.serviceCommands.startGateway({
|
|
3530
|
+
await this.serviceCommands.startGateway({
|
|
3531
|
+
uiOverrides,
|
|
3532
|
+
allowMissingProvider: true
|
|
3533
|
+
});
|
|
3495
3534
|
}
|
|
3496
3535
|
async start(opts) {
|
|
3497
3536
|
await this.init({ source: "start", auto: true });
|
|
@@ -3545,74 +3584,103 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3545
3584
|
const pluginRegistry = loadPluginRegistry(config2, workspace);
|
|
3546
3585
|
const extensionRegistry = toExtensionRegistry(pluginRegistry);
|
|
3547
3586
|
logPluginDiagnostics(pluginRegistry);
|
|
3548
|
-
const
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
contextConfig: config2.agents.context,
|
|
3566
|
-
config: config2,
|
|
3567
|
-
extensionRegistry,
|
|
3568
|
-
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
|
|
3569
|
-
registry: pluginRegistry,
|
|
3570
|
-
channel,
|
|
3571
|
-
cfg: loadConfig6(),
|
|
3572
|
-
accountId
|
|
3573
|
-
})
|
|
3587
|
+
const pluginChannelBindings = getPluginChannelBindings3(pluginRegistry);
|
|
3588
|
+
setPluginRuntimeBridge2({
|
|
3589
|
+
loadConfig: () => toPluginConfigView(loadConfig6(), pluginChannelBindings),
|
|
3590
|
+
writeConfigFile: async (nextConfigView) => {
|
|
3591
|
+
if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
|
|
3592
|
+
throw new Error(
|
|
3593
|
+
"plugin runtime writeConfigFile expects an object config"
|
|
3594
|
+
);
|
|
3595
|
+
}
|
|
3596
|
+
const current = loadConfig6();
|
|
3597
|
+
const next = mergePluginConfigView(
|
|
3598
|
+
current,
|
|
3599
|
+
nextConfigView,
|
|
3600
|
+
pluginChannelBindings
|
|
3601
|
+
);
|
|
3602
|
+
saveConfig5(next);
|
|
3603
|
+
}
|
|
3574
3604
|
});
|
|
3575
|
-
|
|
3576
|
-
const
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
metadata: typeof opts.model === "string" && opts.model.trim() ? { model: opts.model.trim() } : {}
|
|
3605
|
+
try {
|
|
3606
|
+
const bus = new MessageBus2();
|
|
3607
|
+
const provider = this.serviceCommands.createProvider(config2) ?? this.serviceCommands.createMissingProvider(config2);
|
|
3608
|
+
const providerManager = new ProviderManager2({
|
|
3609
|
+
defaultProvider: provider,
|
|
3610
|
+
config: config2
|
|
3582
3611
|
});
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3612
|
+
const agentLoop = new AgentLoop2({
|
|
3613
|
+
bus,
|
|
3614
|
+
providerManager,
|
|
3615
|
+
workspace,
|
|
3616
|
+
model: config2.agents.defaults.model,
|
|
3617
|
+
maxIterations: config2.agents.defaults.maxToolIterations,
|
|
3618
|
+
maxTokens: config2.agents.defaults.maxTokens,
|
|
3619
|
+
contextTokens: config2.agents.defaults.contextTokens,
|
|
3620
|
+
braveApiKey: config2.tools.web.search.apiKey || void 0,
|
|
3621
|
+
execConfig: config2.tools.exec,
|
|
3622
|
+
restrictToWorkspace: config2.tools.restrictToWorkspace,
|
|
3623
|
+
contextConfig: config2.agents.context,
|
|
3624
|
+
config: config2,
|
|
3625
|
+
extensionRegistry,
|
|
3626
|
+
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
|
|
3627
|
+
registry: pluginRegistry,
|
|
3628
|
+
channel,
|
|
3629
|
+
cfg: loadConfig6(),
|
|
3630
|
+
accountId
|
|
3631
|
+
})
|
|
3632
|
+
});
|
|
3633
|
+
if (opts.message) {
|
|
3634
|
+
const response = await agentLoop.processDirect({
|
|
3635
|
+
content: opts.message,
|
|
3636
|
+
sessionKey: opts.session ?? "cli:default",
|
|
3637
|
+
channel: "cli",
|
|
3638
|
+
chatId: "direct",
|
|
3639
|
+
metadata: typeof opts.model === "string" && opts.model.trim() ? { model: opts.model.trim() } : {}
|
|
3640
|
+
});
|
|
3641
|
+
printAgentResponse(response);
|
|
3642
|
+
return;
|
|
3609
3643
|
}
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3644
|
+
console.log(
|
|
3645
|
+
`${this.logo} Interactive mode (type exit or Ctrl+C to quit)
|
|
3646
|
+
`
|
|
3647
|
+
);
|
|
3648
|
+
const historyFile = join6(getDataDir7(), "history", "cli_history");
|
|
3649
|
+
const historyDir = resolve9(historyFile, "..");
|
|
3650
|
+
mkdirSync5(historyDir, { recursive: true });
|
|
3651
|
+
const history = existsSync8(historyFile) ? readFileSync6(historyFile, "utf-8").split("\n").filter(Boolean) : [];
|
|
3652
|
+
const rl = createInterface2({
|
|
3653
|
+
input: process.stdin,
|
|
3654
|
+
output: process.stdout
|
|
3655
|
+
});
|
|
3656
|
+
rl.on("close", () => {
|
|
3657
|
+
const merged = history.concat(
|
|
3658
|
+
rl.history ?? []
|
|
3659
|
+
);
|
|
3660
|
+
writeFileSync4(historyFile, merged.join("\n"));
|
|
3661
|
+
process.exit(0);
|
|
3614
3662
|
});
|
|
3615
|
-
|
|
3663
|
+
let running = true;
|
|
3664
|
+
while (running) {
|
|
3665
|
+
const line = await prompt(rl, "You: ");
|
|
3666
|
+
const trimmed = line.trim();
|
|
3667
|
+
if (!trimmed) {
|
|
3668
|
+
continue;
|
|
3669
|
+
}
|
|
3670
|
+
if (EXIT_COMMANDS.has(trimmed.toLowerCase())) {
|
|
3671
|
+
rl.close();
|
|
3672
|
+
running = false;
|
|
3673
|
+
break;
|
|
3674
|
+
}
|
|
3675
|
+
const response = await agentLoop.processDirect({
|
|
3676
|
+
content: trimmed,
|
|
3677
|
+
sessionKey: opts.session ?? "cli:default",
|
|
3678
|
+
metadata: typeof opts.model === "string" && opts.model.trim() ? { model: opts.model.trim() } : {}
|
|
3679
|
+
});
|
|
3680
|
+
printAgentResponse(response);
|
|
3681
|
+
}
|
|
3682
|
+
} finally {
|
|
3683
|
+
setPluginRuntimeBridge2(null);
|
|
3616
3684
|
}
|
|
3617
3685
|
}
|
|
3618
3686
|
async update(opts) {
|
|
@@ -3620,7 +3688,9 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3620
3688
|
if (opts.timeout !== void 0) {
|
|
3621
3689
|
const parsed = Number(opts.timeout);
|
|
3622
3690
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
3623
|
-
console.error(
|
|
3691
|
+
console.error(
|
|
3692
|
+
"Invalid --timeout value. Provide milliseconds (e.g. 1200000)."
|
|
3693
|
+
);
|
|
3624
3694
|
process.exit(1);
|
|
3625
3695
|
}
|
|
3626
3696
|
timeoutMs = parsed;
|
|
@@ -3630,7 +3700,9 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3630
3700
|
const result = runSelfUpdate({ timeoutMs, cwd: process.cwd() });
|
|
3631
3701
|
const printSteps = () => {
|
|
3632
3702
|
for (const step of result.steps) {
|
|
3633
|
-
console.log(
|
|
3703
|
+
console.log(
|
|
3704
|
+
`- ${step.cmd} ${step.args.join(" ")} (code ${step.code ?? "?"})`
|
|
3705
|
+
);
|
|
3634
3706
|
if (step.stderr) {
|
|
3635
3707
|
console.log(` stderr: ${step.stderr}`);
|
|
3636
3708
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.35",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"chokidar": "^3.6.0",
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
|
-
"@nextclaw/core": "^0.6.
|
|
42
|
-
"@nextclaw/server": "^0.4.
|
|
43
|
-
"@nextclaw/openclaw-compat": "^0.1.
|
|
41
|
+
"@nextclaw/core": "^0.6.27",
|
|
42
|
+
"@nextclaw/server": "^0.4.16",
|
|
43
|
+
"@nextclaw/openclaw-compat": "^0.1.20"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^20.17.6",
|
package/templates/USAGE.md
CHANGED
|
@@ -136,13 +136,13 @@ When the gateway is already running, config changes from the UI or `nextclaw con
|
|
|
136
136
|
- `agents.defaults.contextTokens`
|
|
137
137
|
- `agents.context.*`
|
|
138
138
|
- `tools.*`
|
|
139
|
+
- `plugins.*` (v1 hot plugin runtime: plugin registry/channel gateways/channels are hot-reloaded)
|
|
139
140
|
|
|
140
141
|
Restart is still required for:
|
|
141
142
|
|
|
142
143
|
- UI bind port (`--port` / `--ui-port`)
|
|
143
|
-
- `plugins.*`
|
|
144
144
|
|
|
145
|
-
To confirm hot reload succeeded, check gateway console logs or `${NEXTCLAW_HOME:-~/.nextclaw}/logs/service.log` for messages like `Config reload:
|
|
145
|
+
To confirm hot reload succeeded, check gateway console logs or `${NEXTCLAW_HOME:-~/.nextclaw}/logs/service.log` for messages like `Config reload: plugins reloaded.` / `Config reload: plugin channel gateways restarted.` / `Config reload: channels restarted.`
|
|
146
146
|
|
|
147
147
|
UI note: **Model** page save now persists both `agents.defaults.model` and `agents.defaults.maxTokens` (refresh should keep the updated max token value).
|
|
148
148
|
|