@mclawnet/agent 0.5.9 → 0.6.2
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/cli.js +168 -61
- package/dist/__tests__/cli.test.d.ts +2 -0
- package/dist/__tests__/cli.test.d.ts.map +1 -0
- package/dist/__tests__/service-config.test.d.ts +2 -0
- package/dist/__tests__/service-config.test.d.ts.map +1 -0
- package/dist/__tests__/service-linux.test.d.ts +2 -0
- package/dist/__tests__/service-linux.test.d.ts.map +1 -0
- package/dist/__tests__/service-macos.test.d.ts +2 -0
- package/dist/__tests__/service-macos.test.d.ts.map +1 -0
- package/dist/__tests__/service-windows.test.d.ts +2 -0
- package/dist/__tests__/service-windows.test.d.ts.map +1 -0
- package/dist/backend-adapter.d.ts +2 -0
- package/dist/backend-adapter.d.ts.map +1 -1
- package/dist/chunk-CBZIH6FY.js +93 -0
- package/dist/chunk-CBZIH6FY.js.map +1 -0
- package/dist/{chunk-KHPEQTWF.js → chunk-GLO5OZAY.js} +203 -213
- package/dist/chunk-GLO5OZAY.js.map +1 -0
- package/dist/chunk-RO47ET27.js +88 -0
- package/dist/chunk-RO47ET27.js.map +1 -0
- package/dist/hub-connection.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/linux-6AR7SXHW.js +176 -0
- package/dist/linux-6AR7SXHW.js.map +1 -0
- package/dist/macos-XVPWIH4C.js +174 -0
- package/dist/macos-XVPWIH4C.js.map +1 -0
- package/dist/service/config.d.ts +19 -0
- package/dist/service/config.d.ts.map +1 -0
- package/dist/service/index.d.ts +6 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +47 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/linux.d.ts +18 -0
- package/dist/service/linux.d.ts.map +1 -0
- package/dist/service/macos.d.ts +18 -0
- package/dist/service/macos.d.ts.map +1 -0
- package/dist/service/types.d.ts +19 -0
- package/dist/service/types.d.ts.map +1 -0
- package/dist/service/windows.d.ts +18 -0
- package/dist/service/windows.d.ts.map +1 -0
- package/dist/session-manager.d.ts +4 -7
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/skill-loader.d.ts +8 -0
- package/dist/skill-loader.d.ts.map +1 -0
- package/dist/start.d.ts.map +1 -1
- package/dist/start.js +2 -1
- package/dist/windows-NLONSCDA.js +165 -0
- package/dist/windows-NLONSCDA.js.map +1 -0
- package/package.json +7 -5
- package/skills/academic-search/SKILL.md +147 -0
- package/skills/architecture/SKILL.md +294 -0
- package/skills/changelog-generator/SKILL.md +112 -0
- package/skills/chart-visualization/SKILL.md +183 -0
- package/skills/code-review/SKILL.md +304 -0
- package/skills/codebase-health/SKILL.md +281 -0
- package/skills/consulting-analysis/SKILL.md +584 -0
- package/skills/content-research-writer/SKILL.md +546 -0
- package/skills/data-analysis/SKILL.md +194 -0
- package/skills/deep-research/SKILL.md +198 -0
- package/skills/docx/SKILL.md +211 -0
- package/skills/github-deep-research/SKILL.md +207 -0
- package/skills/image-generation/SKILL.md +209 -0
- package/skills/lead-research-assistant/SKILL.md +207 -0
- package/skills/mcp-builder/SKILL.md +304 -0
- package/skills/meeting-insights-analyzer/SKILL.md +335 -0
- package/skills/pair-programming/SKILL.md +196 -0
- package/skills/pdf/SKILL.md +309 -0
- package/skills/performance-analysis/SKILL.md +261 -0
- package/skills/podcast-generation/SKILL.md +224 -0
- package/skills/pptx/SKILL.md +497 -0
- package/skills/project-learnings/SKILL.md +280 -0
- package/skills/security-audit/SKILL.md +211 -0
- package/skills/skill-creator/SKILL.md +200 -0
- package/skills/technical-writing/SKILL.md +286 -0
- package/skills/testing/SKILL.md +363 -0
- package/skills/video-generation/SKILL.md +247 -0
- package/skills/web-design-guidelines/SKILL.md +203 -0
- package/skills/webapp-testing/SKILL.md +162 -0
- package/skills/workflow-automation/SKILL.md +299 -0
- package/skills/xlsx/SKILL.md +305 -0
- package/dist/chunk-KHPEQTWF.js.map +0 -1
package/cli.js
CHANGED
|
@@ -1,74 +1,181 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// Parse CLI flags
|
|
8
|
-
const opts = {};
|
|
9
|
-
for (let i = 1; i < args.length; i++) {
|
|
10
|
-
if ((args[i] === "--hub-url" || args[i] === "--server") && args[i + 1]) {
|
|
11
|
-
opts.hubUrl = args[++i];
|
|
12
|
-
} else if (args[i] === "--token" && args[i + 1]) {
|
|
13
|
-
opts.token = args[++i];
|
|
14
|
-
} else if (args[i] === "--name" && args[i + 1]) {
|
|
15
|
-
opts.name = args[++i];
|
|
16
|
-
} else if (args[i] === "--backend" && args[i + 1]) {
|
|
17
|
-
opts.backendType = args[++i];
|
|
18
|
-
}
|
|
19
|
-
}
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
|
|
6
|
+
const pkg = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf-8"));
|
|
20
7
|
|
|
21
|
-
|
|
22
|
-
const backendType = opts.backendType || "claude-code";
|
|
8
|
+
const program = new Command();
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
program
|
|
11
|
+
.name("clawnet-agent")
|
|
12
|
+
.description("ClawNet Agent — intelligent agent daemon service")
|
|
13
|
+
.version(pkg.version);
|
|
26
14
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
// === start (default command) ===
|
|
16
|
+
program
|
|
17
|
+
.command("start", { isDefault: true })
|
|
18
|
+
.description("Start Agent (daemon mode by default, use -f for foreground)")
|
|
19
|
+
.option("-f, --foreground", "Run in foreground (for development/debugging)")
|
|
20
|
+
.option("--hub-url <url>", "Hub WebSocket URL")
|
|
21
|
+
.option("--token <token>", "Agent token")
|
|
22
|
+
.option("--name <name>", "Agent name")
|
|
23
|
+
.option("--backend <type>", "Backend type", "claude-code")
|
|
24
|
+
.action(async (opts) => {
|
|
25
|
+
if (opts.foreground) {
|
|
26
|
+
// Foreground mode: directly run agent (existing behavior)
|
|
27
|
+
const config = {};
|
|
28
|
+
if (opts.hubUrl) config.hubUrl = opts.hubUrl;
|
|
29
|
+
if (opts.token) config.token = opts.token;
|
|
30
|
+
if (opts.name) config.name = opts.name;
|
|
31
|
+
if (opts.backend) config.backendType = opts.backend;
|
|
32
|
+
|
|
33
|
+
let adapter;
|
|
34
|
+
const backendType = opts.backend || "claude-code";
|
|
35
|
+
if (backendType === "claude-code") {
|
|
36
|
+
try {
|
|
37
|
+
const { ClaudeCodeAdapter } = await import("@mclawnet/claude-adapter");
|
|
38
|
+
adapter = new ClaudeCodeAdapter();
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error("[clawnet] Failed to load @mclawnet/claude-adapter:", err.message);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
console.error(`[clawnet] Unknown backend type: ${backendType}`);
|
|
34
45
|
process.exit(1);
|
|
35
46
|
}
|
|
47
|
+
|
|
48
|
+
const { startAgent } = await import("./dist/start.js");
|
|
49
|
+
await startAgent({ config, adapter });
|
|
36
50
|
} else {
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
// Daemon mode: register service + start
|
|
52
|
+
const { getServiceManager, mergeServiceConfig, saveServiceConfig, validateServiceConfig } =
|
|
53
|
+
await import("./dist/service/index.js");
|
|
54
|
+
|
|
55
|
+
const cliOpts = {};
|
|
56
|
+
if (opts.hubUrl) cliOpts.hubUrl = opts.hubUrl;
|
|
57
|
+
if (opts.token) cliOpts.token = opts.token;
|
|
58
|
+
if (opts.name) cliOpts.name = opts.name;
|
|
59
|
+
|
|
60
|
+
const config = mergeServiceConfig(cliOpts);
|
|
61
|
+
validateServiceConfig(config);
|
|
62
|
+
saveServiceConfig(config);
|
|
63
|
+
|
|
64
|
+
const manager = await getServiceManager();
|
|
65
|
+
const status = await manager.status();
|
|
66
|
+
|
|
67
|
+
if (status.running) {
|
|
68
|
+
console.log(`Agent is already running (PID: ${status.pid}). Use 'restart' to restart.`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
await manager.install();
|
|
73
|
+
await manager.start();
|
|
39
74
|
}
|
|
75
|
+
});
|
|
40
76
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
77
|
+
// === stop ===
|
|
78
|
+
program
|
|
79
|
+
.command("stop")
|
|
80
|
+
.description("Stop Agent service")
|
|
81
|
+
.action(async () => {
|
|
82
|
+
const { getServiceManager } = await import("./dist/service/index.js");
|
|
83
|
+
const manager = await getServiceManager();
|
|
84
|
+
await manager.stop();
|
|
85
|
+
});
|
|
44
86
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
87
|
+
// === restart ===
|
|
88
|
+
program
|
|
89
|
+
.command("restart")
|
|
90
|
+
.description("Restart Agent service")
|
|
91
|
+
.action(async () => {
|
|
92
|
+
const { getServiceManager } = await import("./dist/service/index.js");
|
|
93
|
+
const manager = await getServiceManager();
|
|
94
|
+
await manager.restart();
|
|
48
95
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
96
|
+
|
|
97
|
+
// === enable ===
|
|
98
|
+
program
|
|
99
|
+
.command("enable")
|
|
100
|
+
.description("Register system service (without starting)")
|
|
101
|
+
.option("--hub-url <url>", "Hub WebSocket URL")
|
|
102
|
+
.option("--token <token>", "Agent token")
|
|
103
|
+
.option("--name <name>", "Agent name")
|
|
104
|
+
.action(async (opts) => {
|
|
105
|
+
const { getServiceManager, mergeServiceConfig, saveServiceConfig, validateServiceConfig } =
|
|
106
|
+
await import("./dist/service/index.js");
|
|
107
|
+
|
|
108
|
+
const cliOpts = {};
|
|
109
|
+
if (opts.hubUrl) cliOpts.hubUrl = opts.hubUrl;
|
|
110
|
+
if (opts.token) cliOpts.token = opts.token;
|
|
111
|
+
if (opts.name) cliOpts.name = opts.name;
|
|
112
|
+
|
|
113
|
+
const config = mergeServiceConfig(cliOpts);
|
|
114
|
+
validateServiceConfig(config);
|
|
115
|
+
saveServiceConfig(config);
|
|
116
|
+
|
|
117
|
+
const manager = await getServiceManager();
|
|
118
|
+
await manager.install();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// === disable ===
|
|
122
|
+
program
|
|
123
|
+
.command("disable")
|
|
124
|
+
.description("Stop and remove system service")
|
|
125
|
+
.action(async () => {
|
|
126
|
+
const { getServiceManager } = await import("./dist/service/index.js");
|
|
127
|
+
const manager = await getServiceManager();
|
|
128
|
+
await manager.uninstall();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// === status ===
|
|
132
|
+
program
|
|
133
|
+
.command("status")
|
|
134
|
+
.description("Show Agent status")
|
|
135
|
+
.action(async () => {
|
|
136
|
+
const { getServiceManager } = await import("./dist/service/index.js");
|
|
137
|
+
const manager = await getServiceManager();
|
|
138
|
+
await manager.printStatus();
|
|
61
139
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
140
|
+
|
|
141
|
+
// === logs ===
|
|
142
|
+
program
|
|
143
|
+
.command("logs")
|
|
144
|
+
.description("View Agent logs")
|
|
145
|
+
.option("-f, --follow", "Follow log output in real-time")
|
|
146
|
+
.option("-n, --lines <number>", "Number of lines to show", "100")
|
|
147
|
+
.action(async (opts) => {
|
|
148
|
+
const { getServiceManager } = await import("./dist/service/index.js");
|
|
149
|
+
const manager = await getServiceManager();
|
|
150
|
+
await manager.logs({
|
|
151
|
+
follow: opts.follow,
|
|
152
|
+
lines: parseInt(opts.lines, 10),
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// === config ===
|
|
157
|
+
const configCmd = program
|
|
158
|
+
.command("config")
|
|
159
|
+
.description("View or modify configuration");
|
|
160
|
+
|
|
161
|
+
configCmd
|
|
162
|
+
.command("show")
|
|
163
|
+
.description("Show current configuration")
|
|
164
|
+
.action(async () => {
|
|
165
|
+
const { loadConfig } = await import("./dist/index.js");
|
|
166
|
+
console.log(JSON.stringify(loadConfig(), null, 2));
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
configCmd
|
|
170
|
+
.command("set <key> <value>")
|
|
171
|
+
.description("Set a configuration value")
|
|
172
|
+
.action(async (key, value) => {
|
|
173
|
+
const { saveConfig } = await import("./dist/index.js");
|
|
174
|
+
saveConfig({ [key]: value });
|
|
175
|
+
console.log(`Set ${key} = ${value}`);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
179
|
+
console.error("[clawnet] Fatal:", err.message || err);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/cli.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/service-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-linux.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/service-linux.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-macos.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/service-macos.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-windows.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/service-windows.test.ts"],"names":[],"mappings":""}
|
|
@@ -29,6 +29,8 @@ export interface SpawnOptions {
|
|
|
29
29
|
mcpConfigPath?: string;
|
|
30
30
|
/** Memory system role ID. When set, SessionManager auto-injects memory prompt + MCP config */
|
|
31
31
|
roleId?: string;
|
|
32
|
+
/** Extra directories to mount via --add-dir */
|
|
33
|
+
additionalDirs?: string[];
|
|
32
34
|
}
|
|
33
35
|
export interface BackendAdapter {
|
|
34
36
|
/** Backend type identifier */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-adapter.d.ts","sourceRoot":"","sources":["../src/backend-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"backend-adapter.d.ts","sourceRoot":"","sources":["../src/backend-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IAEb,kCAAkC;IAClC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEtD,qCAAqC;IACrC,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C,6CAA6C;IAC7C,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnD,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAEzE,qCAAqC;IACrC,cAAc,CAAC,CACb,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,CAAC,IAAI,EAAE;QACd,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAChD,KAAK,IAAI,GACT,IAAI,CAAC;IAER,6BAA6B;IAC7B,OAAO,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CAC1E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { homedir, hostname } from "os";
|
|
5
|
+
import { createLogger } from "@mclawnet/logger";
|
|
6
|
+
var log = createLogger({ module: "config" });
|
|
7
|
+
var CONFIG_DIR = join(homedir(), ".clawnet");
|
|
8
|
+
var SETTINGS_FILE = join(CONFIG_DIR, "settings.json");
|
|
9
|
+
var DEFAULT_HUB_URL = process.env.CLAWNET_DEFAULT_HUB_URL || "ws://localhost:3000/ws/agent";
|
|
10
|
+
var DEFAULTS = {
|
|
11
|
+
hubUrl: DEFAULT_HUB_URL,
|
|
12
|
+
token: "",
|
|
13
|
+
name: hostname(),
|
|
14
|
+
backendType: "claude-code"
|
|
15
|
+
};
|
|
16
|
+
function normalizeHubUrl(url) {
|
|
17
|
+
url = url.replace(/^https:\/\//, "wss://").replace(/^http:\/\//, "ws://");
|
|
18
|
+
if (!/^wss?:\/\//.test(url)) url = "wss://" + url;
|
|
19
|
+
if (url.endsWith("/ws/agent")) return url;
|
|
20
|
+
return url.replace(/\/+$/, "") + "/ws/agent";
|
|
21
|
+
}
|
|
22
|
+
function applyEmbeddingConfig(embedding) {
|
|
23
|
+
const mapping = [
|
|
24
|
+
["provider", "CLAWNET_EMBEDDING_PROVIDER"],
|
|
25
|
+
["openaiBaseUrl", "CLAWNET_OPENAI_BASE_URL"],
|
|
26
|
+
["openaiApiKey", "CLAWNET_OPENAI_API_KEY"],
|
|
27
|
+
["openaiModel", "CLAWNET_OPENAI_EMBEDDING_MODEL"],
|
|
28
|
+
["ollamaUrl", "CLAWNET_OLLAMA_URL"],
|
|
29
|
+
["ollamaModel", "CLAWNET_OLLAMA_MODEL"]
|
|
30
|
+
];
|
|
31
|
+
for (const [configKey, envKey] of mapping) {
|
|
32
|
+
const value = embedding[configKey];
|
|
33
|
+
if (value !== void 0 && process.env[envKey] === void 0) {
|
|
34
|
+
process.env[envKey] = value;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function loadConfig(cliOpts = {}) {
|
|
39
|
+
let fileConfig = {};
|
|
40
|
+
log.info({ path: SETTINGS_FILE }, "loading config");
|
|
41
|
+
if (existsSync(SETTINGS_FILE)) {
|
|
42
|
+
try {
|
|
43
|
+
fileConfig = JSON.parse(readFileSync(SETTINGS_FILE, "utf-8"));
|
|
44
|
+
log.info(
|
|
45
|
+
{ hubUrl: fileConfig.hubUrl, hasToken: !!fileConfig.token, name: fileConfig.name },
|
|
46
|
+
"settings.json loaded"
|
|
47
|
+
);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
log.warn({ err: e }, "failed to parse settings.json");
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
log.warn("settings.json not found");
|
|
53
|
+
}
|
|
54
|
+
if (fileConfig.embedding) {
|
|
55
|
+
applyEmbeddingConfig(fileConfig.embedding);
|
|
56
|
+
}
|
|
57
|
+
const hubUrl = cliOpts.hubUrl ?? process.env.CLAWNET_HUB_URL ?? fileConfig.hubUrl ?? DEFAULTS.hubUrl;
|
|
58
|
+
const resolved = {
|
|
59
|
+
hubUrl: normalizeHubUrl(hubUrl),
|
|
60
|
+
token: cliOpts.token ?? process.env.CLAWNET_TOKEN ?? fileConfig.token ?? DEFAULTS.token,
|
|
61
|
+
name: cliOpts.name ?? process.env.CLAWNET_NAME ?? fileConfig.name ?? DEFAULTS.name,
|
|
62
|
+
backendType: cliOpts.backendType ?? process.env.CLAWNET_BACKEND_TYPE ?? fileConfig.backendType ?? DEFAULTS.backendType,
|
|
63
|
+
embedding: fileConfig.embedding
|
|
64
|
+
};
|
|
65
|
+
log.info(
|
|
66
|
+
{
|
|
67
|
+
hubUrl: resolved.hubUrl,
|
|
68
|
+
hubUrlSource: cliOpts.hubUrl ? "cli" : process.env.CLAWNET_HUB_URL ? "env" : fileConfig.hubUrl ? "file" : "default",
|
|
69
|
+
tokenSource: cliOpts.token ? "cli" : process.env.CLAWNET_TOKEN ? "env" : fileConfig.token ? "file" : "default",
|
|
70
|
+
hasToken: !!resolved.token
|
|
71
|
+
},
|
|
72
|
+
"config resolved"
|
|
73
|
+
);
|
|
74
|
+
return resolved;
|
|
75
|
+
}
|
|
76
|
+
function saveConfig(config) {
|
|
77
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
78
|
+
let existing = {};
|
|
79
|
+
if (existsSync(SETTINGS_FILE)) {
|
|
80
|
+
try {
|
|
81
|
+
existing = JSON.parse(readFileSync(SETTINGS_FILE, "utf-8"));
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const merged = { ...existing, ...config };
|
|
86
|
+
writeFileSync(SETTINGS_FILE, JSON.stringify(merged, null, 2) + "\n");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
loadConfig,
|
|
91
|
+
saveConfig
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=chunk-CBZIH6FY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir, hostname } from \"node:os\";\nimport type { BackendType } from \"@mclawnet/shared\";\nimport { createLogger } from \"@mclawnet/logger\";\n\nconst log = createLogger({ module: \"config\" });\n\nexport interface EmbeddingConfig {\n /** Embedding provider mode: auto / openai / ollama / hash */\n provider?: string;\n /** OpenAI-compatible API base URL (e.g. http://localhost:4141/v1 for copilot proxy) */\n openaiBaseUrl?: string;\n /** OpenAI API key (use \"dummy\" for copilot proxy) */\n openaiApiKey?: string;\n /** OpenAI embedding model name */\n openaiModel?: string;\n /** Ollama server URL */\n ollamaUrl?: string;\n /** Ollama embedding model name */\n ollamaModel?: string;\n}\n\nexport interface AgentConfig {\n hubUrl: string;\n token: string;\n name: string;\n backendType: BackendType;\n embedding?: EmbeddingConfig;\n}\n\nconst CONFIG_DIR = join(homedir(), \".clawnet\");\nconst SETTINGS_FILE = join(CONFIG_DIR, \"settings.json\");\n\nconst DEFAULT_HUB_URL = process.env.CLAWNET_DEFAULT_HUB_URL || \"ws://localhost:3000/ws/agent\";\n\nconst DEFAULTS: AgentConfig = {\n hubUrl: DEFAULT_HUB_URL,\n token: \"\",\n name: hostname(),\n backendType: \"claude-code\",\n};\n\n/** Ensure hubUrl uses ws(s):// protocol and ends with /ws/agent */\nfunction normalizeHubUrl(url: string): string {\n // Convert http(s):// to ws(s)://\n url = url.replace(/^https:\\/\\//, \"wss://\").replace(/^http:\\/\\//, \"ws://\");\n // Default to wss:// if no protocol\n if (!/^wss?:\\/\\//.test(url)) url = \"wss://\" + url;\n if (url.endsWith(\"/ws/agent\")) return url;\n return url.replace(/\\/+$/, \"\") + \"/ws/agent\";\n}\n\n/**\n * Map structured embedding config to CLAWNET_* env vars.\n * Only sets vars that are not already defined in process.env.\n */\nfunction applyEmbeddingConfig(embedding: EmbeddingConfig): void {\n const mapping: Array<[keyof EmbeddingConfig, string]> = [\n [\"provider\", \"CLAWNET_EMBEDDING_PROVIDER\"],\n [\"openaiBaseUrl\", \"CLAWNET_OPENAI_BASE_URL\"],\n [\"openaiApiKey\", \"CLAWNET_OPENAI_API_KEY\"],\n [\"openaiModel\", \"CLAWNET_OPENAI_EMBEDDING_MODEL\"],\n [\"ollamaUrl\", \"CLAWNET_OLLAMA_URL\"],\n [\"ollamaModel\", \"CLAWNET_OLLAMA_MODEL\"],\n ];\n\n for (const [configKey, envKey] of mapping) {\n const value = embedding[configKey];\n if (value !== undefined && process.env[envKey] === undefined) {\n process.env[envKey] = value;\n }\n }\n}\n\n/** Load config: CLI opts > env vars > settings file > defaults */\nexport function loadConfig(cliOpts: Partial<AgentConfig> = {}): AgentConfig {\n let fileConfig: Partial<AgentConfig> = {};\n\n log.info({ path: SETTINGS_FILE }, \"loading config\");\n\n if (existsSync(SETTINGS_FILE)) {\n try {\n fileConfig = JSON.parse(readFileSync(SETTINGS_FILE, \"utf-8\"));\n log.info(\n { hubUrl: fileConfig.hubUrl, hasToken: !!fileConfig.token, name: fileConfig.name },\n \"settings.json loaded\"\n );\n } catch (e) {\n log.warn({ err: e }, \"failed to parse settings.json\");\n }\n } else {\n log.warn(\"settings.json not found\");\n }\n\n // Apply structured embedding config to process.env\n if (fileConfig.embedding) {\n applyEmbeddingConfig(fileConfig.embedding);\n }\n\n const hubUrl =\n cliOpts.hubUrl ??\n process.env.CLAWNET_HUB_URL ??\n fileConfig.hubUrl ??\n DEFAULTS.hubUrl;\n\n const resolved = {\n hubUrl: normalizeHubUrl(hubUrl),\n token:\n cliOpts.token ??\n process.env.CLAWNET_TOKEN ??\n fileConfig.token ??\n DEFAULTS.token,\n name:\n cliOpts.name ??\n process.env.CLAWNET_NAME ??\n fileConfig.name ??\n DEFAULTS.name,\n backendType:\n (cliOpts.backendType as BackendType) ??\n (process.env.CLAWNET_BACKEND_TYPE as BackendType) ??\n (fileConfig.backendType as BackendType) ??\n DEFAULTS.backendType,\n embedding: fileConfig.embedding,\n };\n\n log.info(\n {\n hubUrl: resolved.hubUrl,\n hubUrlSource: cliOpts.hubUrl ? \"cli\" : process.env.CLAWNET_HUB_URL ? \"env\" : fileConfig.hubUrl ? \"file\" : \"default\",\n tokenSource: cliOpts.token ? \"cli\" : process.env.CLAWNET_TOKEN ? \"env\" : fileConfig.token ? \"file\" : \"default\",\n hasToken: !!resolved.token,\n },\n \"config resolved\"\n );\n\n return resolved;\n}\n\n/** Save config to ~/.clawnet/settings.json */\nexport function saveConfig(config: Partial<AgentConfig>): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n\n let existing: Partial<AgentConfig> = {};\n if (existsSync(SETTINGS_FILE)) {\n try {\n existing = JSON.parse(readFileSync(SETTINGS_FILE, \"utf-8\"));\n } catch {\n // ignore\n }\n }\n\n const merged = { ...existing, ...config };\n writeFileSync(SETTINGS_FILE, JSON.stringify(merged, null, 2) + \"\\n\");\n}\n"],"mappings":";AAAA,SAAS,cAAc,eAAe,WAAW,kBAAkB;AACnE,SAAS,YAAY;AACrB,SAAS,SAAS,gBAAgB;AAElC,SAAS,oBAAoB;AAE7B,IAAM,MAAM,aAAa,EAAE,QAAQ,SAAS,CAAC;AAyB7C,IAAM,aAAa,KAAK,QAAQ,GAAG,UAAU;AAC7C,IAAM,gBAAgB,KAAK,YAAY,eAAe;AAEtD,IAAM,kBAAkB,QAAQ,IAAI,2BAA2B;AAE/D,IAAM,WAAwB;AAAA,EAC5B,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM,SAAS;AAAA,EACf,aAAa;AACf;AAGA,SAAS,gBAAgB,KAAqB;AAE5C,QAAM,IAAI,QAAQ,eAAe,QAAQ,EAAE,QAAQ,cAAc,OAAO;AAExE,MAAI,CAAC,aAAa,KAAK,GAAG,EAAG,OAAM,WAAW;AAC9C,MAAI,IAAI,SAAS,WAAW,EAAG,QAAO;AACtC,SAAO,IAAI,QAAQ,QAAQ,EAAE,IAAI;AACnC;AAMA,SAAS,qBAAqB,WAAkC;AAC9D,QAAM,UAAkD;AAAA,IACtD,CAAC,YAAY,4BAA4B;AAAA,IACzC,CAAC,iBAAiB,yBAAyB;AAAA,IAC3C,CAAC,gBAAgB,wBAAwB;AAAA,IACzC,CAAC,eAAe,gCAAgC;AAAA,IAChD,CAAC,aAAa,oBAAoB;AAAA,IAClC,CAAC,eAAe,sBAAsB;AAAA,EACxC;AAEA,aAAW,CAAC,WAAW,MAAM,KAAK,SAAS;AACzC,UAAM,QAAQ,UAAU,SAAS;AACjC,QAAI,UAAU,UAAa,QAAQ,IAAI,MAAM,MAAM,QAAW;AAC5D,cAAQ,IAAI,MAAM,IAAI;AAAA,IACxB;AAAA,EACF;AACF;AAGO,SAAS,WAAW,UAAgC,CAAC,GAAgB;AAC1E,MAAI,aAAmC,CAAC;AAExC,MAAI,KAAK,EAAE,MAAM,cAAc,GAAG,gBAAgB;AAElD,MAAI,WAAW,aAAa,GAAG;AAC7B,QAAI;AACF,mBAAa,KAAK,MAAM,aAAa,eAAe,OAAO,CAAC;AAC5D,UAAI;AAAA,QACF,EAAE,QAAQ,WAAW,QAAQ,UAAU,CAAC,CAAC,WAAW,OAAO,MAAM,WAAW,KAAK;AAAA,QACjF;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,UAAI,KAAK,EAAE,KAAK,EAAE,GAAG,+BAA+B;AAAA,IACtD;AAAA,EACF,OAAO;AACL,QAAI,KAAK,yBAAyB;AAAA,EACpC;AAGA,MAAI,WAAW,WAAW;AACxB,yBAAqB,WAAW,SAAS;AAAA,EAC3C;AAEA,QAAM,SACJ,QAAQ,UACR,QAAQ,IAAI,mBACZ,WAAW,UACX,SAAS;AAEX,QAAM,WAAW;AAAA,IACf,QAAQ,gBAAgB,MAAM;AAAA,IAC9B,OACE,QAAQ,SACR,QAAQ,IAAI,iBACZ,WAAW,SACX,SAAS;AAAA,IACX,MACE,QAAQ,QACR,QAAQ,IAAI,gBACZ,WAAW,QACX,SAAS;AAAA,IACX,aACG,QAAQ,eACR,QAAQ,IAAI,wBACZ,WAAW,eACZ,SAAS;AAAA,IACX,WAAW,WAAW;AAAA,EACxB;AAEA,MAAI;AAAA,IACF;AAAA,MACE,QAAQ,SAAS;AAAA,MACjB,cAAc,QAAQ,SAAS,QAAQ,QAAQ,IAAI,kBAAkB,QAAQ,WAAW,SAAS,SAAS;AAAA,MAC1G,aAAa,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,gBAAgB,QAAQ,WAAW,QAAQ,SAAS;AAAA,MACrG,UAAU,CAAC,CAAC,SAAS;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,WAAW,QAAoC;AAC7D,YAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAEzC,MAAI,WAAiC,CAAC;AACtC,MAAI,WAAW,aAAa,GAAG;AAC7B,QAAI;AACF,iBAAW,KAAK,MAAM,aAAa,eAAe,OAAO,CAAC;AAAA,IAC5D,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,SAAS,EAAE,GAAG,UAAU,GAAG,OAAO;AACxC,gBAAc,eAAe,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,IAAI;AACrE;","names":[]}
|