nextclaw 0.6.34 → 0.6.36
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
CHANGED
|
@@ -20,11 +20,15 @@ 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";
|
|
27
|
-
import { fileURLToPath as
|
|
31
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
28
32
|
import { spawn as spawn3 } from "child_process";
|
|
29
33
|
|
|
30
34
|
// src/cli/restart-coordinator.ts
|
|
@@ -1861,6 +1865,7 @@ import { startUiServer } from "@nextclaw/server";
|
|
|
1861
1865
|
import { closeSync, mkdirSync as mkdirSync3, openSync } from "fs";
|
|
1862
1866
|
import { join as join4, resolve as resolve7 } from "path";
|
|
1863
1867
|
import { spawn as spawn2 } from "child_process";
|
|
1868
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1864
1869
|
import chokidar from "chokidar";
|
|
1865
1870
|
|
|
1866
1871
|
// src/cli/gateway/controller.ts
|
|
@@ -3046,7 +3051,14 @@ var ServiceCommands = class {
|
|
|
3046
3051
|
host: uiConfig.host,
|
|
3047
3052
|
port: uiConfig.port,
|
|
3048
3053
|
configPath: getConfigPath2(),
|
|
3049
|
-
staticDir: uiStaticDir ?? void 0
|
|
3054
|
+
staticDir: uiStaticDir ?? void 0,
|
|
3055
|
+
marketplace: {
|
|
3056
|
+
apiBaseUrl: process.env.NEXTCLAW_MARKETPLACE_API_BASE,
|
|
3057
|
+
installer: {
|
|
3058
|
+
installPlugin: (spec) => this.installMarketplacePlugin(spec),
|
|
3059
|
+
installSkill: (params) => this.installMarketplaceSkill(params)
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3050
3062
|
});
|
|
3051
3063
|
const uiUrl = `http://${uiServer.host}:${uiServer.port}`;
|
|
3052
3064
|
console.log(`\u2713 UI API: ${uiUrl}/api`);
|
|
@@ -3058,13 +3070,75 @@ var ServiceCommands = class {
|
|
|
3058
3070
|
openBrowser(uiUrl);
|
|
3059
3071
|
}
|
|
3060
3072
|
}
|
|
3073
|
+
async installMarketplacePlugin(spec) {
|
|
3074
|
+
const output = await this.runCliSubcommand(["plugins", "install", spec]);
|
|
3075
|
+
const summary = this.pickLastOutputLine(output) ?? `Installed plugin: ${spec}`;
|
|
3076
|
+
return { message: summary, output };
|
|
3077
|
+
}
|
|
3078
|
+
async installMarketplaceSkill(params) {
|
|
3079
|
+
const args = ["skills", "install", params.slug];
|
|
3080
|
+
if (params.version) {
|
|
3081
|
+
args.push("--version", params.version);
|
|
3082
|
+
}
|
|
3083
|
+
if (params.registry) {
|
|
3084
|
+
args.push("--registry", params.registry);
|
|
3085
|
+
}
|
|
3086
|
+
if (params.force) {
|
|
3087
|
+
args.push("--force");
|
|
3088
|
+
}
|
|
3089
|
+
const output = await this.runCliSubcommand(args);
|
|
3090
|
+
const summary = this.pickLastOutputLine(output) ?? `Installed skill: ${params.slug}`;
|
|
3091
|
+
return { message: summary, output };
|
|
3092
|
+
}
|
|
3093
|
+
runCliSubcommand(args, timeoutMs = 18e4) {
|
|
3094
|
+
const cliEntry = fileURLToPath2(new URL("../index.js", import.meta.url));
|
|
3095
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
3096
|
+
const child = spawn2(process.execPath, [...process.execArgv, cliEntry, ...args], {
|
|
3097
|
+
cwd: process.cwd(),
|
|
3098
|
+
env: process.env,
|
|
3099
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3100
|
+
});
|
|
3101
|
+
let stdout = "";
|
|
3102
|
+
let stderr = "";
|
|
3103
|
+
child.stdout?.setEncoding("utf-8");
|
|
3104
|
+
child.stderr?.setEncoding("utf-8");
|
|
3105
|
+
child.stdout?.on("data", (chunk) => {
|
|
3106
|
+
stdout += chunk;
|
|
3107
|
+
});
|
|
3108
|
+
child.stderr?.on("data", (chunk) => {
|
|
3109
|
+
stderr += chunk;
|
|
3110
|
+
});
|
|
3111
|
+
const timer = setTimeout(() => {
|
|
3112
|
+
child.kill("SIGTERM");
|
|
3113
|
+
rejectPromise(new Error(`CLI command timed out after ${timeoutMs}ms`));
|
|
3114
|
+
}, timeoutMs);
|
|
3115
|
+
child.on("error", (error) => {
|
|
3116
|
+
clearTimeout(timer);
|
|
3117
|
+
rejectPromise(new Error(`failed to start CLI command: ${String(error)}`));
|
|
3118
|
+
});
|
|
3119
|
+
child.on("close", (code) => {
|
|
3120
|
+
clearTimeout(timer);
|
|
3121
|
+
const output = `${stdout}
|
|
3122
|
+
${stderr}`.trim();
|
|
3123
|
+
if (code === 0) {
|
|
3124
|
+
resolvePromise(output);
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3127
|
+
rejectPromise(new Error(output || `CLI command failed with code ${code ?? 1}`));
|
|
3128
|
+
});
|
|
3129
|
+
});
|
|
3130
|
+
}
|
|
3131
|
+
pickLastOutputLine(output) {
|
|
3132
|
+
const lines = output.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
3133
|
+
return lines.length > 0 ? lines[lines.length - 1] : null;
|
|
3134
|
+
}
|
|
3061
3135
|
};
|
|
3062
3136
|
|
|
3063
3137
|
// src/cli/workspace.ts
|
|
3064
3138
|
import { cpSync, existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync5, readdirSync, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
3065
3139
|
import { createRequire } from "module";
|
|
3066
3140
|
import { dirname, join as join5, resolve as resolve8 } from "path";
|
|
3067
|
-
import { fileURLToPath as
|
|
3141
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3068
3142
|
import { APP_NAME as APP_NAME3, getDataDir as getDataDir6 } from "@nextclaw/core";
|
|
3069
3143
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
3070
3144
|
var WorkspaceManager = class {
|
|
@@ -3171,7 +3245,7 @@ var WorkspaceManager = class {
|
|
|
3171
3245
|
if (override) {
|
|
3172
3246
|
return override;
|
|
3173
3247
|
}
|
|
3174
|
-
const cliDir = resolve8(
|
|
3248
|
+
const cliDir = resolve8(fileURLToPath3(new URL(".", import.meta.url)));
|
|
3175
3249
|
const pkgRoot = resolve8(cliDir, "..", "..");
|
|
3176
3250
|
const candidates = [join5(pkgRoot, "templates")];
|
|
3177
3251
|
for (const candidate of candidates) {
|
|
@@ -3190,7 +3264,7 @@ var WorkspaceManager = class {
|
|
|
3190
3264
|
console.error("npm not found. Please install Node.js >= 18.");
|
|
3191
3265
|
process.exit(1);
|
|
3192
3266
|
}
|
|
3193
|
-
const cliDir = resolve8(
|
|
3267
|
+
const cliDir = resolve8(fileURLToPath3(new URL(".", import.meta.url)));
|
|
3194
3268
|
const pkgRoot = resolve8(cliDir, "..", "..");
|
|
3195
3269
|
const pkgBridge = join5(pkgRoot, "bridge");
|
|
3196
3270
|
const srcBridge = join5(pkgRoot, "..", "..", "bridge");
|
|
@@ -3295,7 +3369,9 @@ var CliRuntime = class {
|
|
|
3295
3369
|
}
|
|
3296
3370
|
const uiHost = FORCED_PUBLIC_UI_HOST;
|
|
3297
3371
|
const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
|
|
3298
|
-
console.log(
|
|
3372
|
+
console.log(
|
|
3373
|
+
`Applying changes (${reason}): restarting ${APP_NAME4} background service...`
|
|
3374
|
+
);
|
|
3299
3375
|
await this.serviceCommands.stopService();
|
|
3300
3376
|
await this.serviceCommands.startService({
|
|
3301
3377
|
uiOverrides: {
|
|
@@ -3327,7 +3403,7 @@ var CliRuntime = class {
|
|
|
3327
3403
|
}
|
|
3328
3404
|
const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
|
|
3329
3405
|
const delayMs = typeof params.delayMs === "number" && Number.isFinite(params.delayMs) ? Math.max(0, Math.floor(params.delayMs)) : 100;
|
|
3330
|
-
const cliPath = process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() ||
|
|
3406
|
+
const cliPath = process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() || fileURLToPath4(new URL("./index.js", import.meta.url));
|
|
3331
3407
|
const startArgs = [cliPath, "start", "--ui-port", String(uiPort)];
|
|
3332
3408
|
const serviceStatePath = resolve9(getDataDir7(), "run", "service.json");
|
|
3333
3409
|
const helperScript = [
|
|
@@ -3442,11 +3518,15 @@ var CliRuntime = class {
|
|
|
3442
3518
|
}
|
|
3443
3519
|
});
|
|
3444
3520
|
} catch (error) {
|
|
3445
|
-
console.warn(
|
|
3521
|
+
console.warn(
|
|
3522
|
+
`Warning: failed to write restart sentinel from exec context: ${String(error)}`
|
|
3523
|
+
);
|
|
3446
3524
|
}
|
|
3447
3525
|
}
|
|
3448
3526
|
async onboard() {
|
|
3449
|
-
console.warn(
|
|
3527
|
+
console.warn(
|
|
3528
|
+
`Warning: ${APP_NAME4} onboard is deprecated. Use "${APP_NAME4} init" instead.`
|
|
3529
|
+
);
|
|
3450
3530
|
await this.init({ source: "onboard" });
|
|
3451
3531
|
}
|
|
3452
3532
|
async init(options = {}) {
|
|
@@ -3465,7 +3545,10 @@ var CliRuntime = class {
|
|
|
3465
3545
|
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join6(getDataDir7(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
|
|
3466
3546
|
const workspaceExisted = existsSync8(workspacePath);
|
|
3467
3547
|
mkdirSync5(workspacePath, { recursive: true });
|
|
3468
|
-
const templateResult = this.workspaceManager.createWorkspaceTemplates(
|
|
3548
|
+
const templateResult = this.workspaceManager.createWorkspaceTemplates(
|
|
3549
|
+
workspacePath,
|
|
3550
|
+
{ force }
|
|
3551
|
+
);
|
|
3469
3552
|
if (createdConfig) {
|
|
3470
3553
|
console.log(`\u2713 ${prefix}: created config at ${configPath}`);
|
|
3471
3554
|
}
|
|
@@ -3485,7 +3568,9 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3485
3568
|
console.log(` 1. Add your API key to ${configPath}`);
|
|
3486
3569
|
console.log(` 2. Chat: ${APP_NAME4} agent -m "Hello!"`);
|
|
3487
3570
|
} else {
|
|
3488
|
-
console.log(
|
|
3571
|
+
console.log(
|
|
3572
|
+
`Tip: Run "${APP_NAME4} init${force ? " --force" : ""}" to re-run initialization if needed.`
|
|
3573
|
+
);
|
|
3489
3574
|
}
|
|
3490
3575
|
}
|
|
3491
3576
|
async gateway(opts) {
|
|
@@ -3512,7 +3597,10 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3512
3597
|
if (opts.port) {
|
|
3513
3598
|
uiOverrides.port = Number(opts.port);
|
|
3514
3599
|
}
|
|
3515
|
-
await this.serviceCommands.startGateway({
|
|
3600
|
+
await this.serviceCommands.startGateway({
|
|
3601
|
+
uiOverrides,
|
|
3602
|
+
allowMissingProvider: true
|
|
3603
|
+
});
|
|
3516
3604
|
}
|
|
3517
3605
|
async start(opts) {
|
|
3518
3606
|
await this.init({ source: "start", auto: true });
|
|
@@ -3566,74 +3654,103 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3566
3654
|
const pluginRegistry = loadPluginRegistry(config2, workspace);
|
|
3567
3655
|
const extensionRegistry = toExtensionRegistry(pluginRegistry);
|
|
3568
3656
|
logPluginDiagnostics(pluginRegistry);
|
|
3569
|
-
const
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
contextConfig: config2.agents.context,
|
|
3587
|
-
config: config2,
|
|
3588
|
-
extensionRegistry,
|
|
3589
|
-
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
|
|
3590
|
-
registry: pluginRegistry,
|
|
3591
|
-
channel,
|
|
3592
|
-
cfg: loadConfig6(),
|
|
3593
|
-
accountId
|
|
3594
|
-
})
|
|
3657
|
+
const pluginChannelBindings = getPluginChannelBindings3(pluginRegistry);
|
|
3658
|
+
setPluginRuntimeBridge2({
|
|
3659
|
+
loadConfig: () => toPluginConfigView(loadConfig6(), pluginChannelBindings),
|
|
3660
|
+
writeConfigFile: async (nextConfigView) => {
|
|
3661
|
+
if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
|
|
3662
|
+
throw new Error(
|
|
3663
|
+
"plugin runtime writeConfigFile expects an object config"
|
|
3664
|
+
);
|
|
3665
|
+
}
|
|
3666
|
+
const current = loadConfig6();
|
|
3667
|
+
const next = mergePluginConfigView(
|
|
3668
|
+
current,
|
|
3669
|
+
nextConfigView,
|
|
3670
|
+
pluginChannelBindings
|
|
3671
|
+
);
|
|
3672
|
+
saveConfig5(next);
|
|
3673
|
+
}
|
|
3595
3674
|
});
|
|
3596
|
-
|
|
3597
|
-
const
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
metadata: typeof opts.model === "string" && opts.model.trim() ? { model: opts.model.trim() } : {}
|
|
3675
|
+
try {
|
|
3676
|
+
const bus = new MessageBus2();
|
|
3677
|
+
const provider = this.serviceCommands.createProvider(config2) ?? this.serviceCommands.createMissingProvider(config2);
|
|
3678
|
+
const providerManager = new ProviderManager2({
|
|
3679
|
+
defaultProvider: provider,
|
|
3680
|
+
config: config2
|
|
3603
3681
|
});
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3682
|
+
const agentLoop = new AgentLoop2({
|
|
3683
|
+
bus,
|
|
3684
|
+
providerManager,
|
|
3685
|
+
workspace,
|
|
3686
|
+
model: config2.agents.defaults.model,
|
|
3687
|
+
maxIterations: config2.agents.defaults.maxToolIterations,
|
|
3688
|
+
maxTokens: config2.agents.defaults.maxTokens,
|
|
3689
|
+
contextTokens: config2.agents.defaults.contextTokens,
|
|
3690
|
+
braveApiKey: config2.tools.web.search.apiKey || void 0,
|
|
3691
|
+
execConfig: config2.tools.exec,
|
|
3692
|
+
restrictToWorkspace: config2.tools.restrictToWorkspace,
|
|
3693
|
+
contextConfig: config2.agents.context,
|
|
3694
|
+
config: config2,
|
|
3695
|
+
extensionRegistry,
|
|
3696
|
+
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
|
|
3697
|
+
registry: pluginRegistry,
|
|
3698
|
+
channel,
|
|
3699
|
+
cfg: loadConfig6(),
|
|
3700
|
+
accountId
|
|
3701
|
+
})
|
|
3702
|
+
});
|
|
3703
|
+
if (opts.message) {
|
|
3704
|
+
const response = await agentLoop.processDirect({
|
|
3705
|
+
content: opts.message,
|
|
3706
|
+
sessionKey: opts.session ?? "cli:default",
|
|
3707
|
+
channel: "cli",
|
|
3708
|
+
chatId: "direct",
|
|
3709
|
+
metadata: typeof opts.model === "string" && opts.model.trim() ? { model: opts.model.trim() } : {}
|
|
3710
|
+
});
|
|
3711
|
+
printAgentResponse(response);
|
|
3712
|
+
return;
|
|
3630
3713
|
}
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3714
|
+
console.log(
|
|
3715
|
+
`${this.logo} Interactive mode (type exit or Ctrl+C to quit)
|
|
3716
|
+
`
|
|
3717
|
+
);
|
|
3718
|
+
const historyFile = join6(getDataDir7(), "history", "cli_history");
|
|
3719
|
+
const historyDir = resolve9(historyFile, "..");
|
|
3720
|
+
mkdirSync5(historyDir, { recursive: true });
|
|
3721
|
+
const history = existsSync8(historyFile) ? readFileSync6(historyFile, "utf-8").split("\n").filter(Boolean) : [];
|
|
3722
|
+
const rl = createInterface2({
|
|
3723
|
+
input: process.stdin,
|
|
3724
|
+
output: process.stdout
|
|
3635
3725
|
});
|
|
3636
|
-
|
|
3726
|
+
rl.on("close", () => {
|
|
3727
|
+
const merged = history.concat(
|
|
3728
|
+
rl.history ?? []
|
|
3729
|
+
);
|
|
3730
|
+
writeFileSync4(historyFile, merged.join("\n"));
|
|
3731
|
+
process.exit(0);
|
|
3732
|
+
});
|
|
3733
|
+
let running = true;
|
|
3734
|
+
while (running) {
|
|
3735
|
+
const line = await prompt(rl, "You: ");
|
|
3736
|
+
const trimmed = line.trim();
|
|
3737
|
+
if (!trimmed) {
|
|
3738
|
+
continue;
|
|
3739
|
+
}
|
|
3740
|
+
if (EXIT_COMMANDS.has(trimmed.toLowerCase())) {
|
|
3741
|
+
rl.close();
|
|
3742
|
+
running = false;
|
|
3743
|
+
break;
|
|
3744
|
+
}
|
|
3745
|
+
const response = await agentLoop.processDirect({
|
|
3746
|
+
content: trimmed,
|
|
3747
|
+
sessionKey: opts.session ?? "cli:default",
|
|
3748
|
+
metadata: typeof opts.model === "string" && opts.model.trim() ? { model: opts.model.trim() } : {}
|
|
3749
|
+
});
|
|
3750
|
+
printAgentResponse(response);
|
|
3751
|
+
}
|
|
3752
|
+
} finally {
|
|
3753
|
+
setPluginRuntimeBridge2(null);
|
|
3637
3754
|
}
|
|
3638
3755
|
}
|
|
3639
3756
|
async update(opts) {
|
|
@@ -3641,7 +3758,9 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3641
3758
|
if (opts.timeout !== void 0) {
|
|
3642
3759
|
const parsed = Number(opts.timeout);
|
|
3643
3760
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
3644
|
-
console.error(
|
|
3761
|
+
console.error(
|
|
3762
|
+
"Invalid --timeout value. Provide milliseconds (e.g. 1200000)."
|
|
3763
|
+
);
|
|
3645
3764
|
process.exit(1);
|
|
3646
3765
|
}
|
|
3647
3766
|
timeoutMs = parsed;
|
|
@@ -3651,7 +3770,9 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
3651
3770
|
const result = runSelfUpdate({ timeoutMs, cwd: process.cwd() });
|
|
3652
3771
|
const printSteps = () => {
|
|
3653
3772
|
for (const step of result.steps) {
|
|
3654
|
-
console.log(
|
|
3773
|
+
console.log(
|
|
3774
|
+
`- ${step.cmd} ${step.args.join(" ")} (code ${step.code ?? "?"})`
|
|
3775
|
+
);
|
|
3655
3776
|
if (step.stderr) {
|
|
3656
3777
|
console.log(` stderr: ${step.stderr}`);
|
|
3657
3778
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.36",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"chokidar": "^3.6.0",
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
41
|
"@nextclaw/core": "^0.6.27",
|
|
42
|
-
"@nextclaw/server": "^0.4.
|
|
42
|
+
"@nextclaw/server": "^0.4.17",
|
|
43
43
|
"@nextclaw/openclaw-compat": "^0.1.20"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|