@mclawnet/agent 0.6.18 → 0.6.20
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 +170 -1
- package/dist/{chunk-RO47ET27.js → chunk-M2CDVPQF.js} +2 -2
- package/dist/{chunk-CBZIH6FY.js → chunk-PJ5M6Q36.js} +2 -2
- package/dist/chunk-PJ5M6Q36.js.map +1 -0
- package/dist/{chunk-MSDIRBXF.js → chunk-RIK7IXSW.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{linux-6AR7SXHW.js → linux-IHA4O633.js} +3 -3
- package/dist/{macos-XVPWIH4C.js → macos-G4VK2253.js} +32 -9
- package/dist/macos-G4VK2253.js.map +1 -0
- package/dist/service/index.js +5 -5
- package/dist/service/macos.d.ts.map +1 -1
- package/dist/start.js +2 -2
- package/dist/{windows-IQNSUMN6.js → windows-P6U3JLUZ.js} +3 -3
- package/package.json +4 -4
- package/dist/chunk-CBZIH6FY.js.map +0 -1
- package/dist/macos-XVPWIH4C.js.map +0 -1
- /package/dist/{chunk-RO47ET27.js.map → chunk-M2CDVPQF.js.map} +0 -0
- /package/dist/{chunk-MSDIRBXF.js.map → chunk-RIK7IXSW.js.map} +0 -0
- /package/dist/{linux-6AR7SXHW.js.map → linux-IHA4O633.js.map} +0 -0
- /package/dist/{windows-IQNSUMN6.js.map → windows-P6U3JLUZ.js.map} +0 -0
package/cli.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { readFileSync } from "fs";
|
|
5
|
+
import { hostname } from "os";
|
|
6
|
+
import { createInterface } from "readline";
|
|
5
7
|
|
|
6
8
|
const pkg = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf-8"));
|
|
7
9
|
|
|
@@ -12,6 +14,74 @@ program
|
|
|
12
14
|
.description("ClawNet Agent — intelligent agent daemon service")
|
|
13
15
|
.version(pkg.version);
|
|
14
16
|
|
|
17
|
+
// --- helpers ---
|
|
18
|
+
function prompt(question) {
|
|
19
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
20
|
+
return new Promise((resolve) => rl.question(question, (ans) => { rl.close(); resolve(ans); }));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function validateToken(t) {
|
|
24
|
+
if (!t) return "Token is required.";
|
|
25
|
+
if (!t.startsWith("clw_")) return "Token must start with 'clw_'.";
|
|
26
|
+
if (t.length < 24) return "Token looks too short.";
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function printNeedsInit() {
|
|
31
|
+
process.stderr.write(
|
|
32
|
+
"\n✗ Agent not configured.\n\n" +
|
|
33
|
+
" Token is missing. Run:\n\n" +
|
|
34
|
+
" clawnet-agent init\n\n" +
|
|
35
|
+
" Get your token from https://mclaw.work/settings → Security\n\n"
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// === init ===
|
|
40
|
+
program
|
|
41
|
+
.command("init")
|
|
42
|
+
.description("Initialize ~/.clawnet/settings.json (token + name)")
|
|
43
|
+
.option("--token <token>", "Agent token (skip interactive prompt)")
|
|
44
|
+
.option("--name <name>", "Agent name (skip interactive prompt)")
|
|
45
|
+
.option("--hub-url <url>", "Hub WebSocket URL (defaults to wss://mclaw.work/ws/agent)")
|
|
46
|
+
.action(async (opts) => {
|
|
47
|
+
const { saveConfig, loadConfig } = await import("./dist/index.js");
|
|
48
|
+
|
|
49
|
+
const existing = loadConfig();
|
|
50
|
+
|
|
51
|
+
let token = opts.token;
|
|
52
|
+
if (!token) {
|
|
53
|
+
while (true) {
|
|
54
|
+
const ans = (await prompt("Token (from https://mclaw.work/settings → Security): ")).trim();
|
|
55
|
+
const err = validateToken(ans);
|
|
56
|
+
if (err) {
|
|
57
|
+
process.stderr.write(` ${err}\n`);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
token = ans;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
const err = validateToken(token);
|
|
65
|
+
if (err) {
|
|
66
|
+
console.error(`[clawnet] ${err}`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let name = opts.name;
|
|
72
|
+
if (!name) {
|
|
73
|
+
const def = existing.name || hostname();
|
|
74
|
+
const ans = (await prompt(`Agent name [${def}]: `)).trim();
|
|
75
|
+
name = ans || def;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const hubUrl = opts.hubUrl || existing.hubUrl || "wss://mclaw.work/ws/agent";
|
|
79
|
+
|
|
80
|
+
saveConfig({ token, name, hubUrl, backendType: "claude-code" });
|
|
81
|
+
console.log("\n✓ Saved to ~/.clawnet/settings.json");
|
|
82
|
+
console.log(" Run 'clawnet-agent start' to start the agent.\n");
|
|
83
|
+
});
|
|
84
|
+
|
|
15
85
|
// === start (default command) ===
|
|
16
86
|
program
|
|
17
87
|
.command("start", { isDefault: true })
|
|
@@ -24,12 +94,20 @@ program
|
|
|
24
94
|
.action(async (opts) => {
|
|
25
95
|
if (opts.foreground) {
|
|
26
96
|
// Foreground mode: directly run agent (existing behavior)
|
|
97
|
+
const { loadConfig } = await import("./dist/index.js");
|
|
98
|
+
const fileConfig = loadConfig();
|
|
27
99
|
const config = {};
|
|
28
100
|
if (opts.hubUrl) config.hubUrl = opts.hubUrl;
|
|
29
101
|
if (opts.token) config.token = opts.token;
|
|
30
102
|
if (opts.name) config.name = opts.name;
|
|
31
103
|
if (opts.backend) config.backendType = opts.backend;
|
|
32
104
|
|
|
105
|
+
const effectiveToken = config.token || fileConfig.token;
|
|
106
|
+
if (!effectiveToken) {
|
|
107
|
+
printNeedsInit();
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
33
111
|
let adapter;
|
|
34
112
|
const backendType = opts.backend || "claude-code";
|
|
35
113
|
if (backendType === "claude-code") {
|
|
@@ -58,7 +136,15 @@ program
|
|
|
58
136
|
if (opts.name) cliOpts.name = opts.name;
|
|
59
137
|
|
|
60
138
|
const config = mergeServiceConfig(cliOpts);
|
|
61
|
-
|
|
139
|
+
try {
|
|
140
|
+
validateServiceConfig(config);
|
|
141
|
+
} catch (err) {
|
|
142
|
+
if (/token/i.test(err.message)) {
|
|
143
|
+
printNeedsInit();
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
62
148
|
saveServiceConfig(config);
|
|
63
149
|
|
|
64
150
|
const manager = await getServiceManager();
|
|
@@ -175,6 +261,89 @@ configCmd
|
|
|
175
261
|
console.log(`Set ${key} = ${value}`);
|
|
176
262
|
});
|
|
177
263
|
|
|
264
|
+
const CONFIG_SCHEMA = [
|
|
265
|
+
{
|
|
266
|
+
key: "hubUrl",
|
|
267
|
+
description: "Hub WebSocket URL the agent connects to.",
|
|
268
|
+
default: "wss://mclaw.work/ws/agent",
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
key: "token",
|
|
272
|
+
description: "Agent auth token. Generate at https://mclaw.work/settings → Security.",
|
|
273
|
+
default: "(required, no default)",
|
|
274
|
+
secret: true,
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
key: "name",
|
|
278
|
+
description: "Display name for this agent in the hub.",
|
|
279
|
+
default: "<os.hostname()>",
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
key: "backendType",
|
|
283
|
+
description: "LLM backend implementation. Currently only 'claude-code' is supported.",
|
|
284
|
+
default: "claude-code",
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
key: "embedding.provider",
|
|
288
|
+
description: "Embedding provider for semantic memory: auto | openai | ollama | hash.",
|
|
289
|
+
default: "auto (falls back to hash if no provider reachable)",
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
key: "embedding.openaiBaseUrl",
|
|
293
|
+
description: "OpenAI-compatible API base URL (e.g. http://localhost:4141/v1 for copilot proxy).",
|
|
294
|
+
default: "(unset)",
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
key: "embedding.openaiApiKey",
|
|
298
|
+
description: "OpenAI API key (use 'dummy' for copilot proxy).",
|
|
299
|
+
default: "(unset)",
|
|
300
|
+
secret: true,
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
key: "embedding.openaiModel",
|
|
304
|
+
description: "OpenAI embedding model name.",
|
|
305
|
+
default: "text-embedding-3-small",
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
key: "embedding.ollamaUrl",
|
|
309
|
+
description: "Ollama server URL.",
|
|
310
|
+
default: "http://localhost:11434",
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
key: "embedding.ollamaModel",
|
|
314
|
+
description: "Ollama embedding model name.",
|
|
315
|
+
default: "nomic-embed-text",
|
|
316
|
+
},
|
|
317
|
+
];
|
|
318
|
+
|
|
319
|
+
function getByPath(obj, path) {
|
|
320
|
+
return path.split(".").reduce((o, k) => (o == null ? undefined : o[k]), obj);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function maskValue(v) {
|
|
324
|
+
if (typeof v !== "string") return v;
|
|
325
|
+
if (v.length <= 8) return "•".repeat(v.length);
|
|
326
|
+
return v.slice(0, 4) + "…" + "•".repeat(8);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
configCmd
|
|
330
|
+
.command("list")
|
|
331
|
+
.description("List all configurable fields with descriptions and current values")
|
|
332
|
+
.action(async () => {
|
|
333
|
+
const { loadConfig } = await import("./dist/index.js");
|
|
334
|
+
const cfg = loadConfig();
|
|
335
|
+
console.log("ClawNet Agent configuration (~/.clawnet/settings.json)\n");
|
|
336
|
+
for (const entry of CONFIG_SCHEMA) {
|
|
337
|
+
const cur = getByPath(cfg, entry.key);
|
|
338
|
+
const display = cur === undefined ? "(unset)" : entry.secret ? maskValue(cur) : JSON.stringify(cur);
|
|
339
|
+
console.log(` ${entry.key}`);
|
|
340
|
+
console.log(` ${entry.description}`);
|
|
341
|
+
console.log(` default : ${entry.default}`);
|
|
342
|
+
console.log(` current : ${display}\n`);
|
|
343
|
+
}
|
|
344
|
+
console.log("Edit via 'clawnet-agent config set <key> <value>' or by editing ~/.clawnet/settings.json directly.");
|
|
345
|
+
});
|
|
346
|
+
|
|
178
347
|
program.parseAsync(process.argv).catch((err) => {
|
|
179
348
|
console.error("[clawnet] Fatal:", err.message || err);
|
|
180
349
|
process.exit(1);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig,
|
|
3
3
|
saveConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PJ5M6Q36.js";
|
|
5
5
|
|
|
6
6
|
// src/service/config.ts
|
|
7
7
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -85,4 +85,4 @@ export {
|
|
|
85
85
|
validateServiceConfig,
|
|
86
86
|
mergeServiceConfig
|
|
87
87
|
};
|
|
88
|
-
//# sourceMappingURL=chunk-
|
|
88
|
+
//# sourceMappingURL=chunk-M2CDVPQF.js.map
|
|
@@ -6,7 +6,7 @@ import { createLogger } from "@mclawnet/logger";
|
|
|
6
6
|
var log = createLogger({ module: "config" });
|
|
7
7
|
var CONFIG_DIR = join(homedir(), ".clawnet");
|
|
8
8
|
var SETTINGS_FILE = join(CONFIG_DIR, "settings.json");
|
|
9
|
-
var DEFAULT_HUB_URL = process.env.CLAWNET_DEFAULT_HUB_URL || "
|
|
9
|
+
var DEFAULT_HUB_URL = process.env.CLAWNET_DEFAULT_HUB_URL || "wss://mclaw.work/ws/agent";
|
|
10
10
|
var DEFAULTS = {
|
|
11
11
|
hubUrl: DEFAULT_HUB_URL,
|
|
12
12
|
token: "",
|
|
@@ -90,4 +90,4 @@ export {
|
|
|
90
90
|
loadConfig,
|
|
91
91
|
saveConfig
|
|
92
92
|
};
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
93
|
+
//# sourceMappingURL=chunk-PJ5M6Q36.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 || \"wss://mclaw.work/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":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PJ5M6Q36.js";
|
|
4
4
|
|
|
5
5
|
// src/start.ts
|
|
6
6
|
import { homedir as homedir3 } from "os";
|
|
@@ -1816,4 +1816,4 @@ export {
|
|
|
1816
1816
|
FsBridge,
|
|
1817
1817
|
startAgent
|
|
1818
1818
|
};
|
|
1819
|
-
//# sourceMappingURL=chunk-
|
|
1819
|
+
//# sourceMappingURL=chunk-RIK7IXSW.js.map
|
package/dist/index.js
CHANGED
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
HubConnection,
|
|
5
5
|
SessionManager,
|
|
6
6
|
startAgent
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RIK7IXSW.js";
|
|
8
8
|
import {
|
|
9
9
|
loadConfig,
|
|
10
10
|
saveConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-PJ5M6Q36.js";
|
|
12
12
|
|
|
13
13
|
// src/index.ts
|
|
14
14
|
import {
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
getLogDir,
|
|
5
5
|
getNodePath,
|
|
6
6
|
loadServiceConfig
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-M2CDVPQF.js";
|
|
8
|
+
import "./chunk-PJ5M6Q36.js";
|
|
9
9
|
|
|
10
10
|
// src/service/linux.ts
|
|
11
11
|
import { execSync, spawn } from "child_process";
|
|
@@ -173,4 +173,4 @@ export {
|
|
|
173
173
|
generateUnit,
|
|
174
174
|
getUnitPath
|
|
175
175
|
};
|
|
176
|
-
//# sourceMappingURL=linux-
|
|
176
|
+
//# sourceMappingURL=linux-IHA4O633.js.map
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
getLogDir,
|
|
5
5
|
getNodePath,
|
|
6
6
|
loadServiceConfig
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-M2CDVPQF.js";
|
|
8
|
+
import "./chunk-PJ5M6Q36.js";
|
|
9
9
|
|
|
10
10
|
// src/service/macos.ts
|
|
11
11
|
import { execSync, spawn } from "child_process";
|
|
@@ -15,6 +15,12 @@ import { homedir } from "os";
|
|
|
15
15
|
function getPlistPath() {
|
|
16
16
|
return join(homedir(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`);
|
|
17
17
|
}
|
|
18
|
+
function getDomainTarget() {
|
|
19
|
+
return `gui/${process.getuid()}`;
|
|
20
|
+
}
|
|
21
|
+
function getServiceTarget() {
|
|
22
|
+
return `${getDomainTarget()}/${SERVICE_LABEL}`;
|
|
23
|
+
}
|
|
18
24
|
function escapeXml(str) {
|
|
19
25
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
20
26
|
}
|
|
@@ -23,6 +29,11 @@ function generatePlist(config) {
|
|
|
23
29
|
const cliPath = getCliPath();
|
|
24
30
|
const logDir = getLogDir();
|
|
25
31
|
const envEntries = [];
|
|
32
|
+
const pathEnv = process.env.PATH;
|
|
33
|
+
if (pathEnv) {
|
|
34
|
+
envEntries.push(` <key>PATH</key>
|
|
35
|
+
<string>${escapeXml(pathEnv)}</string>`);
|
|
36
|
+
}
|
|
26
37
|
if (config.hubUrl) {
|
|
27
38
|
envEntries.push(` <key>CLAWNET_HUB_URL</key>
|
|
28
39
|
<string>${escapeXml(config.hubUrl)}</string>`);
|
|
@@ -78,7 +89,7 @@ var MacOSServiceManager = class {
|
|
|
78
89
|
const launchAgentsDir = join(homedir(), "Library", "LaunchAgents");
|
|
79
90
|
if (existsSync(plistPath)) {
|
|
80
91
|
try {
|
|
81
|
-
execSync(`launchctl
|
|
92
|
+
execSync(`launchctl bootout ${getServiceTarget()}`, { stdio: "ignore" });
|
|
82
93
|
} catch {
|
|
83
94
|
}
|
|
84
95
|
}
|
|
@@ -95,7 +106,7 @@ var MacOSServiceManager = class {
|
|
|
95
106
|
return;
|
|
96
107
|
}
|
|
97
108
|
try {
|
|
98
|
-
execSync(`launchctl
|
|
109
|
+
execSync(`launchctl bootout ${getServiceTarget()}`, { stdio: "ignore" });
|
|
99
110
|
} catch {
|
|
100
111
|
}
|
|
101
112
|
unlinkSync(plistPath);
|
|
@@ -106,7 +117,11 @@ var MacOSServiceManager = class {
|
|
|
106
117
|
if (!existsSync(plistPath)) {
|
|
107
118
|
throw new Error("Service not registered. Run clawnet-agent enable first.");
|
|
108
119
|
}
|
|
109
|
-
|
|
120
|
+
try {
|
|
121
|
+
execSync(`launchctl bootstrap ${getDomainTarget()} "${plistPath}"`, { stdio: "ignore" });
|
|
122
|
+
} catch {
|
|
123
|
+
}
|
|
124
|
+
execSync(`launchctl kickstart -k ${getServiceTarget()}`, { stdio: "inherit" });
|
|
110
125
|
console.log("\u2713 Service started");
|
|
111
126
|
}
|
|
112
127
|
async stop() {
|
|
@@ -116,15 +131,23 @@ var MacOSServiceManager = class {
|
|
|
116
131
|
return;
|
|
117
132
|
}
|
|
118
133
|
try {
|
|
119
|
-
execSync(`launchctl
|
|
134
|
+
execSync(`launchctl bootout ${getServiceTarget()}`, { stdio: "inherit" });
|
|
120
135
|
console.log("\u2713 Service stopped");
|
|
121
136
|
} catch {
|
|
122
137
|
console.log("Service not running");
|
|
123
138
|
}
|
|
124
139
|
}
|
|
125
140
|
async restart() {
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
const plistPath = getPlistPath();
|
|
142
|
+
if (!existsSync(plistPath)) {
|
|
143
|
+
throw new Error("Service not registered. Run clawnet-agent enable first.");
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
execSync(`launchctl bootstrap ${getDomainTarget()} "${plistPath}"`, { stdio: "ignore" });
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
execSync(`launchctl kickstart -k ${getServiceTarget()}`, { stdio: "inherit" });
|
|
150
|
+
console.log("\u2713 Service restarted");
|
|
128
151
|
}
|
|
129
152
|
async status() {
|
|
130
153
|
try {
|
|
@@ -171,4 +194,4 @@ export {
|
|
|
171
194
|
generatePlist,
|
|
172
195
|
getPlistPath
|
|
173
196
|
};
|
|
174
|
-
//# sourceMappingURL=macos-
|
|
197
|
+
//# sourceMappingURL=macos-G4VK2253.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/service/macos.ts"],"sourcesContent":["import { execSync, spawn } from \"child_process\";\nimport { existsSync, writeFileSync, unlinkSync, mkdirSync, chmodSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport type { ServiceManager, ServiceStatus } from \"./types.js\";\nimport {\n SERVICE_LABEL,\n getLogDir,\n getNodePath,\n getCliPath,\n loadServiceConfig,\n type ServiceConfig,\n} from \"./config.js\";\n\nexport function getPlistPath(): string {\n return join(homedir(), \"Library\", \"LaunchAgents\", `${SERVICE_LABEL}.plist`);\n}\n\nfunction getDomainTarget(): string {\n return `gui/${process.getuid!()}`;\n}\n\nfunction getServiceTarget(): string {\n return `${getDomainTarget()}/${SERVICE_LABEL}`;\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nexport function generatePlist(config: ServiceConfig): string {\n const nodePath = getNodePath();\n const cliPath = getCliPath();\n const logDir = getLogDir();\n\n const envEntries: string[] = [];\n // Snapshot the user's interactive shell PATH at registration time.\n // launchd otherwise hands the daemon a minimal PATH (/usr/bin:/bin:/usr/sbin:/sbin),\n // which prevents the claude CLI subprocess from finding git/node/etc.\n const pathEnv = process.env.PATH;\n if (pathEnv) {\n envEntries.push(` <key>PATH</key>\\n <string>${escapeXml(pathEnv)}</string>`);\n }\n if (config.hubUrl) {\n envEntries.push(` <key>CLAWNET_HUB_URL</key>\\n <string>${escapeXml(config.hubUrl)}</string>`);\n }\n if (config.token) {\n envEntries.push(` <key>CLAWNET_TOKEN</key>\\n <string>${escapeXml(config.token)}</string>`);\n }\n if (config.name) {\n envEntries.push(` <key>CLAWNET_NAME</key>\\n <string>${escapeXml(config.name)}</string>`);\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${SERVICE_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${nodePath}</string>\n <string>${cliPath}</string>\n <string>start</string>\n <string>-f</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${homedir()}</string>\n <key>EnvironmentVariables</key>\n <dict>\n${envEntries.join(\"\\n\")}\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>StandardOutPath</key>\n <string>${logDir}/out.log</string>\n <key>StandardErrorPath</key>\n <string>${logDir}/error.log</string>\n</dict>\n</plist>`;\n}\n\nexport class MacOSServiceManager implements ServiceManager {\n async install(): Promise<void> {\n const config = loadServiceConfig();\n const plistPath = getPlistPath();\n const logDir = getLogDir();\n const launchAgentsDir = join(homedir(), \"Library\", \"LaunchAgents\");\n\n if (existsSync(plistPath)) {\n try {\n execSync(`launchctl bootout ${getServiceTarget()}`, { stdio: \"ignore\" });\n } catch { /* not loaded */ }\n }\n\n if (!existsSync(launchAgentsDir)) mkdirSync(launchAgentsDir, { recursive: true });\n if (!existsSync(logDir)) mkdirSync(logDir, { recursive: true });\n\n writeFileSync(plistPath, generatePlist(config), \"utf-8\");\n chmodSync(plistPath, 0o600);\n console.log(`✓ Service registered: ${plistPath}`);\n }\n\n async uninstall(): Promise<void> {\n const plistPath = getPlistPath();\n if (!existsSync(plistPath)) {\n console.log(\"Service not registered\");\n return;\n }\n try {\n execSync(`launchctl bootout ${getServiceTarget()}`, { stdio: \"ignore\" });\n } catch { /* not loaded */ }\n unlinkSync(plistPath);\n console.log(\"✓ Service removed\");\n }\n\n async start(): Promise<void> {\n const plistPath = getPlistPath();\n if (!existsSync(plistPath)) {\n throw new Error(\"Service not registered. Run clawnet-agent enable first.\");\n }\n try {\n execSync(`launchctl bootstrap ${getDomainTarget()} \"${plistPath}\"`, { stdio: \"ignore\" });\n } catch { /* already bootstrapped */ }\n execSync(`launchctl kickstart -k ${getServiceTarget()}`, { stdio: \"inherit\" });\n console.log(\"✓ Service started\");\n }\n\n async stop(): Promise<void> {\n const plistPath = getPlistPath();\n if (!existsSync(plistPath)) {\n console.log(\"Service not registered\");\n return;\n }\n try {\n execSync(`launchctl bootout ${getServiceTarget()}`, { stdio: \"inherit\" });\n console.log(\"✓ Service stopped\");\n } catch {\n console.log(\"Service not running\");\n }\n }\n\n async restart(): Promise<void> {\n const plistPath = getPlistPath();\n if (!existsSync(plistPath)) {\n throw new Error(\"Service not registered. Run clawnet-agent enable first.\");\n }\n try {\n execSync(`launchctl bootstrap ${getDomainTarget()} \"${plistPath}\"`, { stdio: \"ignore\" });\n } catch { /* already bootstrapped */ }\n execSync(`launchctl kickstart -k ${getServiceTarget()}`, { stdio: \"inherit\" });\n console.log(\"✓ Service restarted\");\n }\n\n async status(): Promise<ServiceStatus> {\n try {\n const output = execSync(\n `launchctl list | grep ${SERVICE_LABEL}`,\n { encoding: \"utf-8\" }\n ).trim();\n if (!output) return { running: false };\n const [pidStr, exitCodeStr] = output.split(/\\s+/);\n const pid = pidStr === \"-\" ? undefined : parseInt(pidStr, 10);\n const exitCode = parseInt(exitCodeStr, 10);\n return { running: pid !== undefined, pid, exitCode };\n } catch {\n return { running: false };\n }\n }\n\n async printStatus(): Promise<void> {\n const s = await this.status();\n console.log(\"ClawNet Agent\");\n console.log(` Status: ${s.running ? \"Running ✓\" : \"Stopped ✗\"}`);\n if (s.pid) console.log(` PID: ${s.pid}`);\n if (s.exitCode !== undefined && !s.running) console.log(` Exit code: ${s.exitCode}`);\n console.log(\" Platform: macOS (launchd)\");\n }\n\n async logs(options: { follow?: boolean; lines?: number } = {}): Promise<void> {\n const logDir = getLogDir();\n const outLog = join(logDir, \"out.log\");\n const errLog = join(logDir, \"error.log\");\n\n const files: string[] = [];\n if (existsSync(outLog)) files.push(outLog);\n if (existsSync(errLog)) files.push(errLog);\n\n if (files.length === 0) {\n console.log(\"No logs yet\");\n return;\n }\n\n const lines = options.lines || 100;\n const args = options.follow\n ? [\"-f\", \"-n\", String(lines), ...files]\n : [\"-n\", String(lines), ...files];\n\n const child = spawn(\"tail\", args, { stdio: \"inherit\" });\n await new Promise<void>((resolve) => child.on(\"close\", resolve));\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/service/index.js
CHANGED
|
@@ -9,22 +9,22 @@ import {
|
|
|
9
9
|
mergeServiceConfig,
|
|
10
10
|
saveServiceConfig,
|
|
11
11
|
validateServiceConfig
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-M2CDVPQF.js";
|
|
13
|
+
import "../chunk-PJ5M6Q36.js";
|
|
14
14
|
|
|
15
15
|
// src/service/index.ts
|
|
16
16
|
async function getServiceManager() {
|
|
17
17
|
switch (process.platform) {
|
|
18
18
|
case "darwin": {
|
|
19
|
-
const { MacOSServiceManager } = await import("../macos-
|
|
19
|
+
const { MacOSServiceManager } = await import("../macos-G4VK2253.js");
|
|
20
20
|
return new MacOSServiceManager();
|
|
21
21
|
}
|
|
22
22
|
case "linux": {
|
|
23
|
-
const { LinuxServiceManager } = await import("../linux-
|
|
23
|
+
const { LinuxServiceManager } = await import("../linux-IHA4O633.js");
|
|
24
24
|
return new LinuxServiceManager();
|
|
25
25
|
}
|
|
26
26
|
case "win32": {
|
|
27
|
-
const { WindowsServiceManager } = await import("../windows-
|
|
27
|
+
const { WindowsServiceManager } = await import("../windows-P6U3JLUZ.js");
|
|
28
28
|
return new WindowsServiceManager();
|
|
29
29
|
}
|
|
30
30
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"macos.d.ts","sourceRoot":"","sources":["../../src/service/macos.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,wBAAgB,YAAY,IAAI,MAAM,CAErC;
|
|
1
|
+
{"version":3,"file":"macos.d.ts","sourceRoot":"","sources":["../../src/service/macos.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAmBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAyD3D;AAED,qBAAa,mBAAoB,YAAW,cAAc;IAClD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBxB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAa1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAcrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAYxB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IAgBhC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,IAAI,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAsB9E"}
|
package/dist/start.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
getLogDir,
|
|
6
6
|
getNodePath,
|
|
7
7
|
loadServiceConfig
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-M2CDVPQF.js";
|
|
9
|
+
import "./chunk-PJ5M6Q36.js";
|
|
10
10
|
|
|
11
11
|
// src/service/windows.ts
|
|
12
12
|
import { execSync, spawn } from "child_process";
|
|
@@ -162,4 +162,4 @@ export {
|
|
|
162
162
|
generateEcosystem,
|
|
163
163
|
getEcosystemPath
|
|
164
164
|
};
|
|
165
|
-
//# sourceMappingURL=windows-
|
|
165
|
+
//# sourceMappingURL=windows-P6U3JLUZ.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mclawnet/agent",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"commander": "^14.0.3",
|
|
24
24
|
"ws": "^8.19.0",
|
|
25
|
-
"@mclawnet/
|
|
25
|
+
"@mclawnet/claude-adapter": "0.1.14",
|
|
26
26
|
"@mclawnet/logger": "0.1.5",
|
|
27
|
-
"@mclawnet/
|
|
28
|
-
"@mclawnet/claude-adapter": "0.1.12",
|
|
27
|
+
"@mclawnet/shared": "0.1.2",
|
|
29
28
|
"@mclawnet/swarm": "0.1.4",
|
|
30
29
|
"@mclawnet/mcp-server": "0.1.3",
|
|
30
|
+
"@mclawnet/skill-manager": "0.1.3",
|
|
31
31
|
"@mclawnet/memory": "0.1.4"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
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":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/service/macos.ts"],"sourcesContent":["import { execSync, spawn } from \"child_process\";\nimport { existsSync, writeFileSync, unlinkSync, mkdirSync, chmodSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport type { ServiceManager, ServiceStatus } from \"./types.js\";\nimport {\n SERVICE_LABEL,\n getLogDir,\n getNodePath,\n getCliPath,\n loadServiceConfig,\n type ServiceConfig,\n} from \"./config.js\";\n\nexport function getPlistPath(): string {\n return join(homedir(), \"Library\", \"LaunchAgents\", `${SERVICE_LABEL}.plist`);\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nexport function generatePlist(config: ServiceConfig): string {\n const nodePath = getNodePath();\n const cliPath = getCliPath();\n const logDir = getLogDir();\n\n const envEntries: string[] = [];\n if (config.hubUrl) {\n envEntries.push(` <key>CLAWNET_HUB_URL</key>\\n <string>${escapeXml(config.hubUrl)}</string>`);\n }\n if (config.token) {\n envEntries.push(` <key>CLAWNET_TOKEN</key>\\n <string>${escapeXml(config.token)}</string>`);\n }\n if (config.name) {\n envEntries.push(` <key>CLAWNET_NAME</key>\\n <string>${escapeXml(config.name)}</string>`);\n }\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${SERVICE_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${nodePath}</string>\n <string>${cliPath}</string>\n <string>start</string>\n <string>-f</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${homedir()}</string>\n <key>EnvironmentVariables</key>\n <dict>\n${envEntries.join(\"\\n\")}\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>StandardOutPath</key>\n <string>${logDir}/out.log</string>\n <key>StandardErrorPath</key>\n <string>${logDir}/error.log</string>\n</dict>\n</plist>`;\n}\n\nexport class MacOSServiceManager implements ServiceManager {\n async install(): Promise<void> {\n const config = loadServiceConfig();\n const plistPath = getPlistPath();\n const logDir = getLogDir();\n const launchAgentsDir = join(homedir(), \"Library\", \"LaunchAgents\");\n\n if (existsSync(plistPath)) {\n try {\n execSync(`launchctl unload \"${plistPath}\"`, { stdio: \"ignore\" });\n } catch { /* ignore */ }\n }\n\n if (!existsSync(launchAgentsDir)) mkdirSync(launchAgentsDir, { recursive: true });\n if (!existsSync(logDir)) mkdirSync(logDir, { recursive: true });\n\n writeFileSync(plistPath, generatePlist(config), \"utf-8\");\n chmodSync(plistPath, 0o600);\n console.log(`✓ Service registered: ${plistPath}`);\n }\n\n async uninstall(): Promise<void> {\n const plistPath = getPlistPath();\n if (!existsSync(plistPath)) {\n console.log(\"Service not registered\");\n return;\n }\n try {\n execSync(`launchctl unload \"${plistPath}\"`, { stdio: \"ignore\" });\n } catch { /* ignore */ }\n unlinkSync(plistPath);\n console.log(\"✓ Service removed\");\n }\n\n async start(): Promise<void> {\n const plistPath = getPlistPath();\n if (!existsSync(plistPath)) {\n throw new Error(\"Service not registered. Run clawnet-agent enable first.\");\n }\n execSync(`launchctl load \"${plistPath}\"`, { stdio: \"inherit\" });\n console.log(\"✓ Service started\");\n }\n\n async stop(): Promise<void> {\n const plistPath = getPlistPath();\n if (!existsSync(plistPath)) {\n console.log(\"Service not registered\");\n return;\n }\n try {\n execSync(`launchctl unload \"${plistPath}\"`, { stdio: \"inherit\" });\n console.log(\"✓ Service stopped\");\n } catch {\n console.log(\"Service not running\");\n }\n }\n\n async restart(): Promise<void> {\n await this.stop();\n await this.start();\n }\n\n async status(): Promise<ServiceStatus> {\n try {\n const output = execSync(\n `launchctl list | grep ${SERVICE_LABEL}`,\n { encoding: \"utf-8\" }\n ).trim();\n if (!output) return { running: false };\n const [pidStr, exitCodeStr] = output.split(/\\s+/);\n const pid = pidStr === \"-\" ? undefined : parseInt(pidStr, 10);\n const exitCode = parseInt(exitCodeStr, 10);\n return { running: pid !== undefined, pid, exitCode };\n } catch {\n return { running: false };\n }\n }\n\n async printStatus(): Promise<void> {\n const s = await this.status();\n console.log(\"ClawNet Agent\");\n console.log(` Status: ${s.running ? \"Running ✓\" : \"Stopped ✗\"}`);\n if (s.pid) console.log(` PID: ${s.pid}`);\n if (s.exitCode !== undefined && !s.running) console.log(` Exit code: ${s.exitCode}`);\n console.log(\" Platform: macOS (launchd)\");\n }\n\n async logs(options: { follow?: boolean; lines?: number } = {}): Promise<void> {\n const logDir = getLogDir();\n const outLog = join(logDir, \"out.log\");\n const errLog = join(logDir, \"error.log\");\n\n const files: string[] = [];\n if (existsSync(outLog)) files.push(outLog);\n if (existsSync(errLog)) files.push(errLog);\n\n if (files.length === 0) {\n console.log(\"No logs yet\");\n return;\n }\n\n const lines = options.lines || 100;\n const args = options.follow\n ? [\"-f\", \"-n\", String(lines), ...files]\n : [\"-n\", String(lines), ...files];\n\n const child = spawn(\"tail\", args, { stdio: \"inherit\" });\n await new Promise<void>((resolve) => child.on(\"close\", resolve));\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,UAAU,aAAa;AAChC,SAAS,YAAY,eAAe,YAAY,WAAW,iBAAiB;AAC5E,SAAS,YAAY;AACrB,SAAS,eAAe;AAWjB,SAAS,eAAuB;AACrC,SAAO,KAAK,QAAQ,GAAG,WAAW,gBAAgB,GAAG,aAAa,QAAQ;AAC5E;AAEA,SAAS,UAAU,KAAqB;AACtC,SAAO,IACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAC3B;AAEO,SAAS,cAAc,QAA+B;AAC3D,QAAM,WAAW,YAAY;AAC7B,QAAM,UAAU,WAAW;AAC3B,QAAM,SAAS,UAAU;AAEzB,QAAM,aAAuB,CAAC;AAC9B,MAAI,OAAO,QAAQ;AACjB,eAAW,KAAK;AAAA,gBAAmD,UAAU,OAAO,MAAM,CAAC,WAAW;AAAA,EACxG;AACA,MAAI,OAAO,OAAO;AAChB,eAAW,KAAK;AAAA,gBAAiD,UAAU,OAAO,KAAK,CAAC,WAAW;AAAA,EACrG;AACA,MAAI,OAAO,MAAM;AACf,eAAW,KAAK;AAAA,gBAAgD,UAAU,OAAO,IAAI,CAAC,WAAW;AAAA,EACnG;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,cAKK,aAAa;AAAA;AAAA;AAAA,kBAGT,QAAQ;AAAA,kBACR,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,cAKX,QAAQ,CAAC;AAAA;AAAA;AAAA,EAGrB,WAAW,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYT,MAAM;AAAA;AAAA,cAEN,MAAM;AAAA;AAAA;AAGpB;AAEO,IAAM,sBAAN,MAAoD;AAAA,EACzD,MAAM,UAAyB;AAC7B,UAAM,SAAS,kBAAkB;AACjC,UAAM,YAAY,aAAa;AAC/B,UAAM,SAAS,UAAU;AACzB,UAAM,kBAAkB,KAAK,QAAQ,GAAG,WAAW,cAAc;AAEjE,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI;AACF,iBAAS,qBAAqB,SAAS,KAAK,EAAE,OAAO,SAAS,CAAC;AAAA,MACjE,QAAQ;AAAA,MAAe;AAAA,IACzB;AAEA,QAAI,CAAC,WAAW,eAAe,EAAG,WAAU,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAChF,QAAI,CAAC,WAAW,MAAM,EAAG,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAE9D,kBAAc,WAAW,cAAc,MAAM,GAAG,OAAO;AACvD,cAAU,WAAW,GAAK;AAC1B,YAAQ,IAAI,8BAAyB,SAAS,EAAE;AAAA,EAClD;AAAA,EAEA,MAAM,YAA2B;AAC/B,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,cAAQ,IAAI,wBAAwB;AACpC;AAAA,IACF;AACA,QAAI;AACF,eAAS,qBAAqB,SAAS,KAAK,EAAE,OAAO,SAAS,CAAC;AAAA,IACjE,QAAQ;AAAA,IAAe;AACvB,eAAW,SAAS;AACpB,YAAQ,IAAI,wBAAmB;AAAA,EACjC;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AACA,aAAS,mBAAmB,SAAS,KAAK,EAAE,OAAO,UAAU,CAAC;AAC9D,YAAQ,IAAI,wBAAmB;AAAA,EACjC;AAAA,EAEA,MAAM,OAAsB;AAC1B,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,cAAQ,IAAI,wBAAwB;AACpC;AAAA,IACF;AACA,QAAI;AACF,eAAS,qBAAqB,SAAS,KAAK,EAAE,OAAO,UAAU,CAAC;AAChE,cAAQ,IAAI,wBAAmB;AAAA,IACjC,QAAQ;AACN,cAAQ,IAAI,qBAAqB;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,MAAM;AAAA,EACnB;AAAA,EAEA,MAAM,SAAiC;AACrC,QAAI;AACF,YAAM,SAAS;AAAA,QACb,yBAAyB,aAAa;AAAA,QACtC,EAAE,UAAU,QAAQ;AAAA,MACtB,EAAE,KAAK;AACP,UAAI,CAAC,OAAQ,QAAO,EAAE,SAAS,MAAM;AACrC,YAAM,CAAC,QAAQ,WAAW,IAAI,OAAO,MAAM,KAAK;AAChD,YAAM,MAAM,WAAW,MAAM,SAAY,SAAS,QAAQ,EAAE;AAC5D,YAAM,WAAW,SAAS,aAAa,EAAE;AACzC,aAAO,EAAE,SAAS,QAAQ,QAAW,KAAK,SAAS;AAAA,IACrD,QAAQ;AACN,aAAO,EAAE,SAAS,MAAM;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,MAAM,cAA6B;AACjC,UAAM,IAAI,MAAM,KAAK,OAAO;AAC5B,YAAQ,IAAI,eAAe;AAC3B,YAAQ,IAAI,aAAa,EAAE,UAAU,mBAAc,gBAAW,EAAE;AAChE,QAAI,EAAE,IAAK,SAAQ,IAAI,UAAU,EAAE,GAAG,EAAE;AACxC,QAAI,EAAE,aAAa,UAAa,CAAC,EAAE,QAAS,SAAQ,IAAI,gBAAgB,EAAE,QAAQ,EAAE;AACpF,YAAQ,IAAI,6BAA6B;AAAA,EAC3C;AAAA,EAEA,MAAM,KAAK,UAAgD,CAAC,GAAkB;AAC5E,UAAM,SAAS,UAAU;AACzB,UAAM,SAAS,KAAK,QAAQ,SAAS;AACrC,UAAM,SAAS,KAAK,QAAQ,WAAW;AAEvC,UAAM,QAAkB,CAAC;AACzB,QAAI,WAAW,MAAM,EAAG,OAAM,KAAK,MAAM;AACzC,QAAI,WAAW,MAAM,EAAG,OAAM,KAAK,MAAM;AAEzC,QAAI,MAAM,WAAW,GAAG;AACtB,cAAQ,IAAI,aAAa;AACzB;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,SAAS;AAC/B,UAAM,OAAO,QAAQ,SACjB,CAAC,MAAM,MAAM,OAAO,KAAK,GAAG,GAAG,KAAK,IACpC,CAAC,MAAM,OAAO,KAAK,GAAG,GAAG,KAAK;AAElC,UAAM,QAAQ,MAAM,QAAQ,MAAM,EAAE,OAAO,UAAU,CAAC;AACtD,UAAM,IAAI,QAAc,CAAC,YAAY,MAAM,GAAG,SAAS,OAAO,CAAC;AAAA,EACjE;AACF;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|