nextclaw 0.3.2 → 0.3.3
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 +92 -51
- package/package.json +3 -2
- package/templates/AGENTS.md +10 -0
- package/templates/SOUL.md +15 -0
- package/templates/USER.md +9 -0
- package/templates/memory/MEMORY.md +15 -0
package/dist/cli/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
buildReloadPlan,
|
|
18
18
|
diffConfigPaths,
|
|
19
19
|
getWorkspacePath,
|
|
20
|
+
expandHome,
|
|
20
21
|
MessageBus,
|
|
21
22
|
AgentLoop,
|
|
22
23
|
LiteLLMProvider,
|
|
@@ -26,7 +27,9 @@ import {
|
|
|
26
27
|
CronService,
|
|
27
28
|
HeartbeatService,
|
|
28
29
|
PROVIDERS,
|
|
29
|
-
APP_NAME
|
|
30
|
+
APP_NAME,
|
|
31
|
+
DEFAULT_WORKSPACE_DIR,
|
|
32
|
+
DEFAULT_WORKSPACE_PATH
|
|
30
33
|
} from "nextclaw-core";
|
|
31
34
|
import { startUiServer } from "nextclaw-server";
|
|
32
35
|
import {
|
|
@@ -39,7 +42,7 @@ import {
|
|
|
39
42
|
rmSync as rmSync2,
|
|
40
43
|
writeFileSync as writeFileSync2
|
|
41
44
|
} from "fs";
|
|
42
|
-
import { join as join2, resolve as resolve2 } from "path";
|
|
45
|
+
import { dirname, join as join2, resolve as resolve2 } from "path";
|
|
43
46
|
import { spawn as spawn2, spawnSync } from "child_process";
|
|
44
47
|
import { createInterface } from "readline";
|
|
45
48
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -294,21 +297,46 @@ var CliRuntime = class {
|
|
|
294
297
|
return getPackageVersion();
|
|
295
298
|
}
|
|
296
299
|
async onboard() {
|
|
300
|
+
console.warn(`Warning: ${APP_NAME} onboard is deprecated. Use "${APP_NAME} init" instead.`);
|
|
301
|
+
await this.init({ source: "onboard" });
|
|
302
|
+
}
|
|
303
|
+
async init(options = {}) {
|
|
304
|
+
const source = options.source ?? "init";
|
|
305
|
+
const prefix = options.auto ? "Auto init" : "Init";
|
|
297
306
|
const configPath = getConfigPath();
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
307
|
+
let createdConfig = false;
|
|
308
|
+
if (!existsSync2(configPath)) {
|
|
309
|
+
const config2 = ConfigSchema.parse({});
|
|
310
|
+
saveConfig(config2);
|
|
311
|
+
createdConfig = true;
|
|
312
|
+
}
|
|
313
|
+
const config = loadConfig();
|
|
314
|
+
const workspaceSetting = config.agents.defaults.workspace;
|
|
315
|
+
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join2(getDataDir2(), DEFAULT_WORKSPACE_DIR) : expandHome(workspaceSetting);
|
|
316
|
+
const workspaceExisted = existsSync2(workspacePath);
|
|
317
|
+
mkdirSync2(workspacePath, { recursive: true });
|
|
318
|
+
const templateResult = this.createWorkspaceTemplates(workspacePath);
|
|
319
|
+
if (createdConfig) {
|
|
320
|
+
console.log(`\u2713 ${prefix}: created config at ${configPath}`);
|
|
321
|
+
}
|
|
322
|
+
if (!workspaceExisted) {
|
|
323
|
+
console.log(`\u2713 ${prefix}: created workspace at ${workspacePath}`);
|
|
324
|
+
}
|
|
325
|
+
for (const file of templateResult.created) {
|
|
326
|
+
console.log(`\u2713 ${prefix}: created ${file}`);
|
|
327
|
+
}
|
|
328
|
+
if (!createdConfig && workspaceExisted && templateResult.created.length === 0) {
|
|
329
|
+
console.log(`${prefix}: already initialized.`);
|
|
330
|
+
}
|
|
331
|
+
if (!options.auto) {
|
|
332
|
+
console.log(`
|
|
333
|
+
${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
334
|
+
console.log("\nNext steps:");
|
|
335
|
+
console.log(` 1. Add your API key to ${configPath}`);
|
|
336
|
+
console.log(` 2. Chat: ${APP_NAME} agent -m "Hello!"`);
|
|
337
|
+
} else {
|
|
338
|
+
console.log(`Tip: Run "${APP_NAME} init" to re-run initialization if needed.`);
|
|
339
|
+
}
|
|
312
340
|
}
|
|
313
341
|
async gateway(opts) {
|
|
314
342
|
const uiOverrides = {};
|
|
@@ -340,6 +368,7 @@ ${this.logo} ${APP_NAME} is ready!`);
|
|
|
340
368
|
await this.startGateway({ uiOverrides, allowMissingProvider: true });
|
|
341
369
|
}
|
|
342
370
|
async start(opts) {
|
|
371
|
+
await this.init({ source: "start", auto: true });
|
|
343
372
|
const uiOverrides = {
|
|
344
373
|
enabled: true,
|
|
345
374
|
open: false
|
|
@@ -930,44 +959,55 @@ ${this.logo} ${APP_NAME} is ready!`);
|
|
|
930
959
|
});
|
|
931
960
|
}
|
|
932
961
|
createWorkspaceTemplates(workspace) {
|
|
933
|
-
const
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
## Personality
|
|
940
|
-
|
|
941
|
-
- Helpful and friendly
|
|
942
|
-
- Concise and to the point
|
|
943
|
-
- Curious and eager to learn
|
|
944
|
-
|
|
945
|
-
## Values
|
|
946
|
-
|
|
947
|
-
- Accuracy over speed
|
|
948
|
-
- User privacy and safety
|
|
949
|
-
- Transparency in actions
|
|
950
|
-
|
|
951
|
-
`,
|
|
952
|
-
"USER.md": "# User\n\nInformation about the user goes here.\n\n## Preferences\n\n- Communication style: (casual/formal)\n- Timezone: (your timezone)\n- Language: (your preferred language)\n"
|
|
953
|
-
};
|
|
954
|
-
for (const [filename, content] of Object.entries(templates)) {
|
|
955
|
-
const filePath = join2(workspace, filename);
|
|
956
|
-
if (!existsSync2(filePath)) {
|
|
957
|
-
writeFileSync2(filePath, content);
|
|
958
|
-
}
|
|
962
|
+
const created = [];
|
|
963
|
+
const templateDir = this.resolveTemplateDir();
|
|
964
|
+
if (!templateDir) {
|
|
965
|
+
console.warn("Warning: Template directory not found. Skipping workspace templates.");
|
|
966
|
+
return { created };
|
|
959
967
|
}
|
|
960
|
-
const
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
);
|
|
968
|
+
const templateFiles = [
|
|
969
|
+
{ source: "AGENTS.md", target: "AGENTS.md" },
|
|
970
|
+
{ source: "SOUL.md", target: "SOUL.md" },
|
|
971
|
+
{ source: "USER.md", target: "USER.md" },
|
|
972
|
+
{ source: join2("memory", "MEMORY.md"), target: join2("memory", "MEMORY.md") }
|
|
973
|
+
];
|
|
974
|
+
for (const entry of templateFiles) {
|
|
975
|
+
const filePath = join2(workspace, entry.target);
|
|
976
|
+
if (existsSync2(filePath)) {
|
|
977
|
+
continue;
|
|
978
|
+
}
|
|
979
|
+
const templatePath = join2(templateDir, entry.source);
|
|
980
|
+
if (!existsSync2(templatePath)) {
|
|
981
|
+
console.warn(`Warning: Template file missing: ${templatePath}`);
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
const raw = readFileSync2(templatePath, "utf-8");
|
|
985
|
+
const content = raw.replace(/\$\{APP_NAME\}/g, APP_NAME);
|
|
986
|
+
mkdirSync2(dirname(filePath), { recursive: true });
|
|
987
|
+
writeFileSync2(filePath, content);
|
|
988
|
+
created.push(entry.target);
|
|
968
989
|
}
|
|
969
990
|
const skillsDir = join2(workspace, "skills");
|
|
970
|
-
|
|
991
|
+
if (!existsSync2(skillsDir)) {
|
|
992
|
+
mkdirSync2(skillsDir, { recursive: true });
|
|
993
|
+
created.push(join2("skills", ""));
|
|
994
|
+
}
|
|
995
|
+
return { created };
|
|
996
|
+
}
|
|
997
|
+
resolveTemplateDir() {
|
|
998
|
+
const override = process.env.NEXTCLAW_TEMPLATE_DIR?.trim();
|
|
999
|
+
if (override) {
|
|
1000
|
+
return override;
|
|
1001
|
+
}
|
|
1002
|
+
const cliDir = resolve2(fileURLToPath2(new URL(".", import.meta.url)));
|
|
1003
|
+
const pkgRoot = resolve2(cliDir, "..", "..");
|
|
1004
|
+
const candidates = [join2(pkgRoot, "templates")];
|
|
1005
|
+
for (const candidate of candidates) {
|
|
1006
|
+
if (existsSync2(candidate)) {
|
|
1007
|
+
return candidate;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
return null;
|
|
971
1011
|
}
|
|
972
1012
|
getBridgeDir() {
|
|
973
1013
|
const userBridge = join2(getDataDir2(), "bridge");
|
|
@@ -1027,6 +1067,7 @@ var program = new Command();
|
|
|
1027
1067
|
var runtime = new CliRuntime({ logo: LOGO });
|
|
1028
1068
|
program.name(APP_NAME2).description(`${LOGO} ${APP_NAME2} - ${APP_TAGLINE}`).version(getPackageVersion(), "-v, --version", "show version");
|
|
1029
1069
|
program.command("onboard").description(`Initialize ${APP_NAME2} configuration and workspace`).action(async () => runtime.onboard());
|
|
1070
|
+
program.command("init").description(`Initialize ${APP_NAME2} configuration and workspace`).action(async () => runtime.init());
|
|
1030
1071
|
program.command("gateway").description(`Start the ${APP_NAME2} gateway`).option("-p, --port <port>", "Gateway port", "18790").option("-v, --verbose", "Verbose output", false).option("--ui", "Enable UI server", false).option("--ui-host <host>", "UI host").option("--ui-port <port>", "UI port").option("--ui-open", "Open browser when UI starts", false).action(async (opts) => runtime.gateway(opts));
|
|
1031
1072
|
program.command("ui").description(`Start the ${APP_NAME2} UI with gateway`).option("--host <host>", "UI host").option("--port <port>", "UI port").option("--no-open", "Disable opening browser").action(async (opts) => runtime.ui(opts));
|
|
1032
1073
|
program.command("start").description(`Start the ${APP_NAME2} gateway + UI in the background`).option("--ui-host <host>", "UI host").option("--ui-port <port>", "UI port").option("--frontend", "Start UI frontend dev server").option("--frontend-port <port>", "UI frontend dev server port").option("--open", "Open browser after start", false).action(async (opts) => runtime.start(opts));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
34
34
|
"bridge",
|
|
35
|
-
"ui-dist"
|
|
35
|
+
"ui-dist",
|
|
36
|
+
"templates"
|
|
36
37
|
],
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"chokidar": "^3.6.0",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Agent Instructions
|
|
2
|
+
|
|
3
|
+
You are a helpful AI assistant. Be concise, accurate, and friendly.
|
|
4
|
+
|
|
5
|
+
## Guidelines
|
|
6
|
+
|
|
7
|
+
- Always explain what you're doing before taking actions
|
|
8
|
+
- Ask for clarification when the request is ambiguous
|
|
9
|
+
- Use tools to help accomplish tasks
|
|
10
|
+
- Remember important information in your memory files
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Soul
|
|
2
|
+
|
|
3
|
+
I am ${APP_NAME}, a lightweight AI assistant.
|
|
4
|
+
|
|
5
|
+
## Personality
|
|
6
|
+
|
|
7
|
+
- Helpful and friendly
|
|
8
|
+
- Concise and to the point
|
|
9
|
+
- Curious and eager to learn
|
|
10
|
+
|
|
11
|
+
## Values
|
|
12
|
+
|
|
13
|
+
- Accuracy over speed
|
|
14
|
+
- User privacy and safety
|
|
15
|
+
- Transparency in actions
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Long-term Memory
|
|
2
|
+
|
|
3
|
+
This file stores important information that should persist across sessions.
|
|
4
|
+
|
|
5
|
+
## User Information
|
|
6
|
+
|
|
7
|
+
(Important facts about the user)
|
|
8
|
+
|
|
9
|
+
## Preferences
|
|
10
|
+
|
|
11
|
+
(User preferences learned over time)
|
|
12
|
+
|
|
13
|
+
## Important Notes
|
|
14
|
+
|
|
15
|
+
(Things to remember)
|