@mclawnet/agent 0.6.19 → 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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadConfig,
3
3
  saveConfig
4
- } from "./chunk-CBZIH6FY.js";
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-RO47ET27.js.map
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 || "ws://localhost:3000/ws/agent";
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-CBZIH6FY.js.map
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-CBZIH6FY.js";
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-MSDIRBXF.js.map
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-MSDIRBXF.js";
7
+ } from "./chunk-RIK7IXSW.js";
8
8
  import {
9
9
  loadConfig,
10
10
  saveConfig
11
- } from "./chunk-CBZIH6FY.js";
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-RO47ET27.js";
8
- import "./chunk-CBZIH6FY.js";
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-6AR7SXHW.js.map
176
+ //# sourceMappingURL=linux-IHA4O633.js.map
@@ -4,8 +4,8 @@ import {
4
4
  getLogDir,
5
5
  getNodePath,
6
6
  loadServiceConfig
7
- } from "./chunk-RO47ET27.js";
8
- import "./chunk-CBZIH6FY.js";
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";
@@ -29,6 +29,11 @@ function generatePlist(config) {
29
29
  const cliPath = getCliPath();
30
30
  const logDir = getLogDir();
31
31
  const envEntries = [];
32
+ const pathEnv = process.env.PATH;
33
+ if (pathEnv) {
34
+ envEntries.push(` <key>PATH</key>
35
+ <string>${escapeXml(pathEnv)}</string>`);
36
+ }
32
37
  if (config.hubUrl) {
33
38
  envEntries.push(` <key>CLAWNET_HUB_URL</key>
34
39
  <string>${escapeXml(config.hubUrl)}</string>`);
@@ -189,4 +194,4 @@ export {
189
194
  generatePlist,
190
195
  getPlistPath
191
196
  };
192
- //# sourceMappingURL=macos-BTP5JW3U.js.map
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, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\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":[]}
@@ -9,22 +9,22 @@ import {
9
9
  mergeServiceConfig,
10
10
  saveServiceConfig,
11
11
  validateServiceConfig
12
- } from "../chunk-RO47ET27.js";
13
- import "../chunk-CBZIH6FY.js";
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-BTP5JW3U.js");
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-6AR7SXHW.js");
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-IQNSUMN6.js");
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;AAmBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAkD3D;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"}
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
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  startAgent
3
- } from "./chunk-MSDIRBXF.js";
4
- import "./chunk-CBZIH6FY.js";
3
+ } from "./chunk-RIK7IXSW.js";
4
+ import "./chunk-PJ5M6Q36.js";
5
5
  export {
6
6
  startAgent
7
7
  };
@@ -5,8 +5,8 @@ import {
5
5
  getLogDir,
6
6
  getNodePath,
7
7
  loadServiceConfig
8
- } from "./chunk-RO47ET27.js";
9
- import "./chunk-CBZIH6FY.js";
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-IQNSUMN6.js.map
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.19",
3
+ "version": "0.6.20",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -22,13 +22,13 @@
22
22
  "dependencies": {
23
23
  "commander": "^14.0.3",
24
24
  "ws": "^8.19.0",
25
- "@mclawnet/claude-adapter": "0.1.13",
25
+ "@mclawnet/claude-adapter": "0.1.14",
26
26
  "@mclawnet/logger": "0.1.5",
27
- "@mclawnet/memory": "0.1.4",
28
- "@mclawnet/skill-manager": "0.1.3",
29
27
  "@mclawnet/shared": "0.1.2",
28
+ "@mclawnet/swarm": "0.1.4",
30
29
  "@mclawnet/mcp-server": "0.1.3",
31
- "@mclawnet/swarm": "0.1.4"
30
+ "@mclawnet/skill-manager": "0.1.3",
31
+ "@mclawnet/memory": "0.1.4"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^22",
@@ -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 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, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\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 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":[]}