@mclawnet/agent 0.6.1 → 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/dist/chunk-CBZIH6FY.js +93 -0
- package/dist/chunk-CBZIH6FY.js.map +1 -0
- package/dist/{chunk-KITKMSBE.js → chunk-GLO5OZAY.js} +136 -222
- package/dist/chunk-GLO5OZAY.js.map +1 -0
- package/dist/{chunk-W3LSW4XY.js → chunk-RO47ET27.js} +14 -21
- package/dist/chunk-RO47ET27.js.map +1 -0
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/{linux-5KQ4SCAA.js → linux-6AR7SXHW.js} +3 -2
- package/dist/{linux-5KQ4SCAA.js.map → linux-6AR7SXHW.js.map} +1 -1
- package/dist/{macos-FGY546NC.js → macos-XVPWIH4C.js} +3 -2
- package/dist/{macos-FGY546NC.js.map → macos-XVPWIH4C.js.map} +1 -1
- package/dist/service/config.d.ts.map +1 -1
- package/dist/service/index.js +5 -4
- package/dist/service/index.js.map +1 -1
- package/dist/start.js +2 -1
- package/dist/{windows-PIJ4CMWX.js → windows-NLONSCDA.js} +3 -2
- package/dist/{windows-PIJ4CMWX.js.map → windows-NLONSCDA.js.map} +1 -1
- package/package.json +3 -3
- package/dist/chunk-KITKMSBE.js.map +0 -1
- package/dist/chunk-W3LSW4XY.js.map +0 -1
|
@@ -1,90 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
loadConfig
|
|
3
|
+
} from "./chunk-CBZIH6FY.js";
|
|
88
4
|
|
|
89
5
|
// src/hub-connection.ts
|
|
90
6
|
import { hostname as osHostname } from "os";
|
|
@@ -99,12 +15,12 @@ import { listRecoverableSwarms, recoverSwarm, listRoles, loadRole, listRecoverab
|
|
|
99
15
|
|
|
100
16
|
// src/fs-handler.ts
|
|
101
17
|
import { readdir } from "fs/promises";
|
|
102
|
-
import { existsSync
|
|
103
|
-
import { homedir
|
|
104
|
-
import { join
|
|
18
|
+
import { existsSync, readdirSync, statSync, readFileSync } from "fs";
|
|
19
|
+
import { homedir } from "os";
|
|
20
|
+
import { join } from "path";
|
|
105
21
|
var SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", "__pycache__", ".next", ".nuxt", ".cache"]);
|
|
106
22
|
async function handleListDir(path) {
|
|
107
|
-
const target = path ||
|
|
23
|
+
const target = path || homedir();
|
|
108
24
|
const dirents = await readdir(target, { withFileTypes: true });
|
|
109
25
|
const entries = dirents.filter((d) => !(d.isDirectory() && SKIP_DIRS.has(d.name))).map((d) => ({
|
|
110
26
|
name: d.name,
|
|
@@ -116,14 +32,14 @@ async function handleListDir(path) {
|
|
|
116
32
|
return { path: target, entries };
|
|
117
33
|
}
|
|
118
34
|
function getClaudeProjectsDir() {
|
|
119
|
-
return
|
|
35
|
+
return join(homedir(), ".claude", "projects");
|
|
120
36
|
}
|
|
121
37
|
function pathToProjectFolder(workDir) {
|
|
122
38
|
return workDir.replace(/:/g, "-").replace(/[/\\]/g, "-");
|
|
123
39
|
}
|
|
124
40
|
function extractWorkDirFromSessionFile(filePath) {
|
|
125
41
|
try {
|
|
126
|
-
const content =
|
|
42
|
+
const content = readFileSync(filePath, "utf-8");
|
|
127
43
|
const lines = content.split("\n").filter((l) => l.trim());
|
|
128
44
|
for (const line of lines.slice(0, 5)) {
|
|
129
45
|
try {
|
|
@@ -141,7 +57,7 @@ function getWorkDirFromProjectFolder(folderPath, folderName) {
|
|
|
141
57
|
const files = readdirSync(folderPath);
|
|
142
58
|
for (const file of files) {
|
|
143
59
|
if (file.endsWith(".jsonl")) {
|
|
144
|
-
const workDir = extractWorkDirFromSessionFile(
|
|
60
|
+
const workDir = extractWorkDirFromSessionFile(join(folderPath, file));
|
|
145
61
|
if (workDir) return workDir;
|
|
146
62
|
}
|
|
147
63
|
}
|
|
@@ -158,10 +74,10 @@ function getWorkDirFromProjectFolder(folderPath, folderName) {
|
|
|
158
74
|
async function handleListFolders() {
|
|
159
75
|
const projectsDir = getClaudeProjectsDir();
|
|
160
76
|
const folders = [];
|
|
161
|
-
if (!
|
|
77
|
+
if (!existsSync(projectsDir)) return { folders };
|
|
162
78
|
const entries = readdirSync(projectsDir);
|
|
163
79
|
for (const entry of entries) {
|
|
164
|
-
const entryPath =
|
|
80
|
+
const entryPath = join(projectsDir, entry);
|
|
165
81
|
let entryStat;
|
|
166
82
|
try {
|
|
167
83
|
entryStat = statSync(entryPath);
|
|
@@ -179,7 +95,7 @@ async function handleListFolders() {
|
|
|
179
95
|
if (file.endsWith(".jsonl")) {
|
|
180
96
|
sessionCount++;
|
|
181
97
|
try {
|
|
182
|
-
const fileStats = statSync(
|
|
98
|
+
const fileStats = statSync(join(entryPath, file));
|
|
183
99
|
if (fileStats.mtime.getTime() > lastModified) {
|
|
184
100
|
lastModified = fileStats.mtime.getTime();
|
|
185
101
|
}
|
|
@@ -197,8 +113,8 @@ async function handleListFolders() {
|
|
|
197
113
|
async function handleListHistorySessions(workDir) {
|
|
198
114
|
const projectsDir = getClaudeProjectsDir();
|
|
199
115
|
const projectFolder = pathToProjectFolder(workDir);
|
|
200
|
-
const projectPath =
|
|
201
|
-
if (!
|
|
116
|
+
const projectPath = join(projectsDir, projectFolder);
|
|
117
|
+
if (!existsSync(projectPath)) {
|
|
202
118
|
return { workDir, sessions: [] };
|
|
203
119
|
}
|
|
204
120
|
const sessions = [];
|
|
@@ -206,7 +122,7 @@ async function handleListHistorySessions(workDir) {
|
|
|
206
122
|
for (const file of files) {
|
|
207
123
|
if (!file.endsWith(".jsonl")) continue;
|
|
208
124
|
const sessionId = file.replace(".jsonl", "");
|
|
209
|
-
const filePath =
|
|
125
|
+
const filePath = join(projectPath, file);
|
|
210
126
|
let fileStats;
|
|
211
127
|
try {
|
|
212
128
|
fileStats = statSync(filePath);
|
|
@@ -218,7 +134,7 @@ async function handleListHistorySessions(workDir) {
|
|
|
218
134
|
let customTitle = "";
|
|
219
135
|
let jsonlSummary = "";
|
|
220
136
|
try {
|
|
221
|
-
const content =
|
|
137
|
+
const content = readFileSync(filePath, "utf-8");
|
|
222
138
|
const lines = content.split("\n").filter((l) => l.trim());
|
|
223
139
|
for (const line of lines) {
|
|
224
140
|
try {
|
|
@@ -256,13 +172,13 @@ async function handleListHistorySessions(workDir) {
|
|
|
256
172
|
async function handleLoadSessionHistory(workDir, claudeSessionId) {
|
|
257
173
|
const projectsDir = getClaudeProjectsDir();
|
|
258
174
|
const projectFolder = pathToProjectFolder(workDir);
|
|
259
|
-
const filePath =
|
|
260
|
-
if (!
|
|
175
|
+
const filePath = join(projectsDir, projectFolder, `${claudeSessionId}.jsonl`);
|
|
176
|
+
if (!existsSync(filePath)) {
|
|
261
177
|
return { messages: [] };
|
|
262
178
|
}
|
|
263
179
|
const messages = [];
|
|
264
180
|
try {
|
|
265
|
-
const content =
|
|
181
|
+
const content = readFileSync(filePath, "utf-8");
|
|
266
182
|
const lines = content.split("\n").filter((l) => l.trim());
|
|
267
183
|
for (const line of lines) {
|
|
268
184
|
try {
|
|
@@ -324,8 +240,8 @@ async function handleLoadSessionHistory(workDir, claudeSessionId) {
|
|
|
324
240
|
}
|
|
325
241
|
|
|
326
242
|
// src/hub-connection.ts
|
|
327
|
-
import { createLogger
|
|
328
|
-
var
|
|
243
|
+
import { createLogger } from "@mclawnet/logger";
|
|
244
|
+
var log = createLogger({ module: "agent" });
|
|
329
245
|
var HubConnection = class {
|
|
330
246
|
ws = null;
|
|
331
247
|
heartbeatTimer = null;
|
|
@@ -407,7 +323,7 @@ var HubConnection = class {
|
|
|
407
323
|
return;
|
|
408
324
|
}
|
|
409
325
|
if (this.authState === "pending" && data.type === "auth_required") {
|
|
410
|
-
|
|
326
|
+
log.info("hub requires auth, sending credentials");
|
|
411
327
|
this.authState = "authenticating";
|
|
412
328
|
this.sendRaw({
|
|
413
329
|
type: "auth",
|
|
@@ -419,7 +335,7 @@ var HubConnection = class {
|
|
|
419
335
|
return;
|
|
420
336
|
}
|
|
421
337
|
if (this.authState === "authenticating" && data.type === "registered") {
|
|
422
|
-
|
|
338
|
+
log.info({ agentId: data.agentId }, "registered with hub");
|
|
423
339
|
this.authState = "authenticated";
|
|
424
340
|
this.agentId = data.agentId ?? null;
|
|
425
341
|
this.startHeartbeat();
|
|
@@ -433,18 +349,18 @@ var HubConnection = class {
|
|
|
433
349
|
}
|
|
434
350
|
});
|
|
435
351
|
this.ws.on("close", (code, reason) => {
|
|
436
|
-
|
|
352
|
+
log.warn({ code, reason: reason.toString() }, "disconnected from hub");
|
|
437
353
|
this.stopHeartbeat();
|
|
438
354
|
this.authState = "pending";
|
|
439
355
|
this.onDisconnect?.(code, reason.toString());
|
|
440
356
|
if (code === WS_CLOSE_INVALID_TOKEN) {
|
|
441
|
-
|
|
357
|
+
log.error("auth failed \u2014 not reconnecting, check your token");
|
|
442
358
|
return;
|
|
443
359
|
}
|
|
444
360
|
this.scheduleReconnect();
|
|
445
361
|
});
|
|
446
362
|
this.ws.on("error", (err) => {
|
|
447
|
-
|
|
363
|
+
log.error({ err }, "ws connection error");
|
|
448
364
|
this.onError?.(err);
|
|
449
365
|
});
|
|
450
366
|
}
|
|
@@ -462,11 +378,11 @@ var HubConnection = class {
|
|
|
462
378
|
// ── Session message handling ─────────────────────────────────────
|
|
463
379
|
handleSessionMessage(msg) {
|
|
464
380
|
if (msg.type === "fs.list_dir") {
|
|
465
|
-
|
|
381
|
+
log.info({ path: msg.path }, "fs.list_dir");
|
|
466
382
|
handleListDir(msg.path).then((result) => {
|
|
467
383
|
this.send({ type: "fs.list_dir_result", requestId: msg.requestId, ...result });
|
|
468
384
|
}).catch((err) => {
|
|
469
|
-
|
|
385
|
+
log.error({ err, path: msg.path }, "fs.list_dir failed");
|
|
470
386
|
this.send({
|
|
471
387
|
type: "fs.list_dir_result",
|
|
472
388
|
requestId: msg.requestId,
|
|
@@ -477,21 +393,21 @@ var HubConnection = class {
|
|
|
477
393
|
return true;
|
|
478
394
|
}
|
|
479
395
|
if (msg.type === "list_folders") {
|
|
480
|
-
|
|
396
|
+
log.info("list_folders");
|
|
481
397
|
handleListFolders().then((result) => {
|
|
482
398
|
this.send({ type: "folders_list_result", requestId: msg.requestId, ...result });
|
|
483
399
|
}).catch((err) => {
|
|
484
|
-
|
|
400
|
+
log.error({ err }, "list_folders failed");
|
|
485
401
|
this.send({ type: "folders_list_result", requestId: msg.requestId, folders: [] });
|
|
486
402
|
});
|
|
487
403
|
return true;
|
|
488
404
|
}
|
|
489
405
|
if (msg.type === "list_history_sessions") {
|
|
490
|
-
|
|
406
|
+
log.info({ workDir: msg.workDir }, "list_history_sessions");
|
|
491
407
|
handleListHistorySessions(msg.workDir).then((result) => {
|
|
492
408
|
this.send({ type: "history_sessions_result", requestId: msg.requestId, ...result });
|
|
493
409
|
}).catch((err) => {
|
|
494
|
-
|
|
410
|
+
log.error({ err, workDir: msg.workDir }, "list_history_sessions failed");
|
|
495
411
|
this.send({
|
|
496
412
|
type: "history_sessions_result",
|
|
497
413
|
requestId: msg.requestId,
|
|
@@ -502,17 +418,17 @@ var HubConnection = class {
|
|
|
502
418
|
return true;
|
|
503
419
|
}
|
|
504
420
|
if (msg.type === "load_session_history") {
|
|
505
|
-
|
|
421
|
+
log.info({ workDir: msg.workDir, claudeSessionId: msg.claudeSessionId }, "load_session_history");
|
|
506
422
|
handleLoadSessionHistory(msg.workDir, msg.claudeSessionId).then((result) => {
|
|
507
423
|
this.send({ type: "session_history_result", requestId: msg.requestId, ...result });
|
|
508
424
|
}).catch((err) => {
|
|
509
|
-
|
|
425
|
+
log.error({ err, workDir: msg.workDir }, "load_session_history failed");
|
|
510
426
|
this.send({ type: "session_history_result", requestId: msg.requestId, messages: [] });
|
|
511
427
|
});
|
|
512
428
|
return true;
|
|
513
429
|
}
|
|
514
430
|
if (msg.type === "list_roles") {
|
|
515
|
-
|
|
431
|
+
log.info("list_roles");
|
|
516
432
|
const roleNames = listRoles();
|
|
517
433
|
const roles = roleNames.map((name) => {
|
|
518
434
|
try {
|
|
@@ -538,7 +454,7 @@ var HubConnection = class {
|
|
|
538
454
|
return true;
|
|
539
455
|
}
|
|
540
456
|
if (msg.type === "list_templates") {
|
|
541
|
-
|
|
457
|
+
log.info("list_templates");
|
|
542
458
|
try {
|
|
543
459
|
const names = listTemplates();
|
|
544
460
|
const templates = names.map((name) => {
|
|
@@ -557,7 +473,7 @@ var HubConnection = class {
|
|
|
557
473
|
templates
|
|
558
474
|
});
|
|
559
475
|
} catch (err) {
|
|
560
|
-
|
|
476
|
+
log.error({ err }, "list_templates failed");
|
|
561
477
|
this.send({
|
|
562
478
|
type: "templates_list_result",
|
|
563
479
|
sessionId: msg.sessionId,
|
|
@@ -569,9 +485,9 @@ var HubConnection = class {
|
|
|
569
485
|
if (msg.type === "generic.request") {
|
|
570
486
|
const handler = this.namespaceHandlers.get(msg.namespace);
|
|
571
487
|
if (handler) {
|
|
572
|
-
|
|
488
|
+
log.info({ namespace: msg.namespace, action: msg.action, requestId: msg.requestId }, "generic.request received");
|
|
573
489
|
handler(msg).then((result) => {
|
|
574
|
-
|
|
490
|
+
log.info({ namespace: msg.namespace, action: msg.action, requestId: msg.requestId }, "generic.request handled OK");
|
|
575
491
|
this.send({
|
|
576
492
|
type: "generic.response",
|
|
577
493
|
namespace: msg.namespace,
|
|
@@ -580,7 +496,7 @@ var HubConnection = class {
|
|
|
580
496
|
requestId: msg.requestId
|
|
581
497
|
});
|
|
582
498
|
}).catch((err) => {
|
|
583
|
-
|
|
499
|
+
log.error({ namespace: msg.namespace, action: msg.action, requestId: msg.requestId, err }, "generic.request handler error");
|
|
584
500
|
this.send({
|
|
585
501
|
type: "generic.response",
|
|
586
502
|
namespace: msg.namespace,
|
|
@@ -592,7 +508,7 @@ var HubConnection = class {
|
|
|
592
508
|
});
|
|
593
509
|
return true;
|
|
594
510
|
}
|
|
595
|
-
|
|
511
|
+
log.warn({ namespace: msg.namespace, action: msg.action, requestId: msg.requestId }, "generic.request unknown namespace");
|
|
596
512
|
this.send({
|
|
597
513
|
type: "generic.response",
|
|
598
514
|
namespace: msg.namespace,
|
|
@@ -606,7 +522,7 @@ var HubConnection = class {
|
|
|
606
522
|
if (msg.type === "swarm.execute" && this.swarmCoordinator) {
|
|
607
523
|
const { sessionId, content, workDir, targetInstance, crewConfig } = msg;
|
|
608
524
|
if (this.swarmCoordinator.hasSwarm(sessionId)) {
|
|
609
|
-
|
|
525
|
+
log.info({ sessionId, targetInstance }, "swarm.execute: forwarding to existing swarm");
|
|
610
526
|
this.swarmCoordinator.handleUserMessage(sessionId, content, targetInstance).catch((err) => {
|
|
611
527
|
this.send({
|
|
612
528
|
type: "session.error",
|
|
@@ -615,7 +531,7 @@ var HubConnection = class {
|
|
|
615
531
|
});
|
|
616
532
|
});
|
|
617
533
|
} else if (this.finishedSwarms.has(sessionId)) {
|
|
618
|
-
|
|
534
|
+
log.info({ sessionId }, "swarm.execute ignored: swarm already finished");
|
|
619
535
|
this.send({
|
|
620
536
|
type: "session.error",
|
|
621
537
|
sessionId,
|
|
@@ -624,7 +540,7 @@ var HubConnection = class {
|
|
|
624
540
|
} else if (crewConfig?.templateName || crewConfig?.roles) {
|
|
625
541
|
const templateName = crewConfig.templateName;
|
|
626
542
|
const roles = crewConfig.roles;
|
|
627
|
-
|
|
543
|
+
log.info({ sessionId, templateName, rolesCount: roles?.length }, "swarm.execute: creating new swarm");
|
|
628
544
|
this.swarmCoordinator.create(sessionId, { workDir, templateName, roles, task: content }).catch((err) => {
|
|
629
545
|
this.send({
|
|
630
546
|
type: "session.error",
|
|
@@ -633,7 +549,7 @@ var HubConnection = class {
|
|
|
633
549
|
});
|
|
634
550
|
});
|
|
635
551
|
} else {
|
|
636
|
-
|
|
552
|
+
log.info({ sessionId }, "swarm.execute ignored: swarm not found, no config");
|
|
637
553
|
this.send({
|
|
638
554
|
type: "session.error",
|
|
639
555
|
sessionId,
|
|
@@ -645,7 +561,7 @@ var HubConnection = class {
|
|
|
645
561
|
if (!this.sessionManager) return false;
|
|
646
562
|
if (msg.type === "abort_execution") {
|
|
647
563
|
const { sessionId } = msg;
|
|
648
|
-
|
|
564
|
+
log.info({ sessionId }, "abort_execution");
|
|
649
565
|
if (this.sessionManager?.hasSession(sessionId)) {
|
|
650
566
|
this.sessionManager.abortSession(sessionId).then(() => {
|
|
651
567
|
this.send({ type: "execution_aborted", sessionId });
|
|
@@ -660,10 +576,10 @@ var HubConnection = class {
|
|
|
660
576
|
if (msg.type === "claude.execute") {
|
|
661
577
|
const { sessionId, content, workDir, claudeSessionId, useBrainCore } = msg;
|
|
662
578
|
if (this.sessionManager.hasSession(sessionId)) {
|
|
663
|
-
|
|
579
|
+
log.info({ sessionId }, "claude.execute: reusing existing session");
|
|
664
580
|
this.sessionManager.sendInput(sessionId, content);
|
|
665
581
|
} else {
|
|
666
|
-
|
|
582
|
+
log.info({ sessionId, workDir, roleId: "role-__assistant__" }, "claude.execute: creating new session with memory injection");
|
|
667
583
|
this.sessionManager.createSession({ sessionId, workDir, resumeId: claudeSessionId, useBrainCore, roleId: "role-__assistant__" }).then(() => {
|
|
668
584
|
this.sessionManager.sendInput(sessionId, content);
|
|
669
585
|
}).catch((err) => {
|
|
@@ -677,7 +593,7 @@ var HubConnection = class {
|
|
|
677
593
|
return true;
|
|
678
594
|
}
|
|
679
595
|
if (msg.type === "session.create") {
|
|
680
|
-
|
|
596
|
+
log.info({ sessionId: msg.sessionId, roleId: "role-__assistant__" }, "session.create with memory injection");
|
|
681
597
|
this.sessionManager.createSession({
|
|
682
598
|
sessionId: msg.sessionId,
|
|
683
599
|
workDir: msg.workDir,
|
|
@@ -699,13 +615,13 @@ var HubConnection = class {
|
|
|
699
615
|
return true;
|
|
700
616
|
}
|
|
701
617
|
if (msg.type === "session.close") {
|
|
702
|
-
|
|
618
|
+
log.info({ sessionId: msg.sessionId }, "session.close");
|
|
703
619
|
this.sessionManager.closeSession(msg.sessionId).catch(() => {
|
|
704
620
|
});
|
|
705
621
|
return true;
|
|
706
622
|
}
|
|
707
623
|
if (msg.type === "claude.input") {
|
|
708
|
-
|
|
624
|
+
log.info({ sessionId: msg.sessionId }, "claude.input");
|
|
709
625
|
this.sessionManager.sendInput(msg.sessionId, msg.content);
|
|
710
626
|
return true;
|
|
711
627
|
}
|
|
@@ -721,17 +637,17 @@ var HubConnection = class {
|
|
|
721
637
|
for (const id of allIds) {
|
|
722
638
|
if (!recoverableIds.has(id)) {
|
|
723
639
|
deleteSwarmSnapshot(id);
|
|
724
|
-
|
|
640
|
+
log.info({ swarmId: id }, "cleaned up non-recoverable swarm snapshot");
|
|
725
641
|
}
|
|
726
642
|
}
|
|
727
643
|
for (const snap of snapshots) {
|
|
728
|
-
|
|
644
|
+
log.info({ swarmId: snap.id }, "recovering swarm");
|
|
729
645
|
recoverSwarm(this.swarmCoordinator, snap).catch((err) => {
|
|
730
|
-
|
|
646
|
+
log.error({ err, swarmId: snap.id }, "failed to recover swarm");
|
|
731
647
|
});
|
|
732
648
|
}
|
|
733
649
|
} catch (err) {
|
|
734
|
-
|
|
650
|
+
log.error({ err }, "swarm recovery failed");
|
|
735
651
|
}
|
|
736
652
|
}
|
|
737
653
|
sendRaw(data) {
|
|
@@ -753,7 +669,7 @@ var HubConnection = class {
|
|
|
753
669
|
}
|
|
754
670
|
scheduleReconnect() {
|
|
755
671
|
if (this.destroyed) return;
|
|
756
|
-
|
|
672
|
+
log.warn({ delayMs: this.reconnectDelay }, "reconnecting to hub...");
|
|
757
673
|
this.reconnectTimer = setTimeout(() => {
|
|
758
674
|
this.connect();
|
|
759
675
|
}, this.reconnectDelay);
|
|
@@ -778,9 +694,9 @@ var HubConnection = class {
|
|
|
778
694
|
};
|
|
779
695
|
|
|
780
696
|
// src/session-manager.ts
|
|
781
|
-
import { createLogger as
|
|
697
|
+
import { createLogger as createLogger2 } from "@mclawnet/logger";
|
|
782
698
|
import { buildMemorySection } from "@mclawnet/memory";
|
|
783
|
-
var
|
|
699
|
+
var log2 = createLogger2({ module: "agent/session-manager" });
|
|
784
700
|
var DEFAULT_MAX_PROCESSES = 10;
|
|
785
701
|
var MAX_PROCESSES = Number(process.env.CLAWNET_MAX_PROCESSES) || DEFAULT_MAX_PROCESSES;
|
|
786
702
|
var SessionManager = class {
|
|
@@ -814,9 +730,9 @@ var SessionManager = class {
|
|
|
814
730
|
options.systemPrompt = options.systemPrompt ? `${memorySection}${roleHint}
|
|
815
731
|
|
|
816
732
|
${options.systemPrompt}` : `${memorySection}${roleHint}`;
|
|
817
|
-
|
|
733
|
+
log2.debug({ roleId: options.roleId, sessionId: options.sessionId }, "memory prompt + roleId hint injected");
|
|
818
734
|
} catch (err) {
|
|
819
|
-
|
|
735
|
+
log2.warn({ err, roleId: options.roleId }, "failed to build memory section, proceeding without");
|
|
820
736
|
}
|
|
821
737
|
}
|
|
822
738
|
try {
|
|
@@ -902,71 +818,71 @@ ${options.systemPrompt}` : `${memorySection}${roleHint}`;
|
|
|
902
818
|
import { SwarmCoordinator, initRoles } from "@mclawnet/swarm";
|
|
903
819
|
|
|
904
820
|
// src/skill-loader.ts
|
|
905
|
-
import { existsSync as
|
|
906
|
-
import { join as
|
|
907
|
-
import { homedir as
|
|
821
|
+
import { existsSync as existsSync2, mkdirSync, copyFileSync, readdirSync as readdirSync2, writeFileSync } from "fs";
|
|
822
|
+
import { join as join2, dirname } from "path";
|
|
823
|
+
import { homedir as homedir2 } from "os";
|
|
908
824
|
import { createRequire } from "module";
|
|
909
825
|
import { fileURLToPath } from "url";
|
|
910
|
-
import { createLogger as
|
|
911
|
-
var
|
|
912
|
-
var CLAWNET_DIR =
|
|
913
|
-
var SKILLS_DIR =
|
|
914
|
-
var MCP_CONFIG_PATH =
|
|
826
|
+
import { createLogger as createLogger3 } from "@mclawnet/logger";
|
|
827
|
+
var log3 = createLogger3({ module: "agent/skill-loader" });
|
|
828
|
+
var CLAWNET_DIR = join2(homedir2(), ".clawnet");
|
|
829
|
+
var SKILLS_DIR = join2(CLAWNET_DIR, ".claude", "skills");
|
|
830
|
+
var MCP_CONFIG_PATH = join2(CLAWNET_DIR, "mcp.json");
|
|
915
831
|
async function initSkills() {
|
|
916
832
|
ensureSkillsDir();
|
|
917
833
|
copyBuiltinSkills();
|
|
918
834
|
ensureMcpConfig();
|
|
919
835
|
}
|
|
920
836
|
function ensureSkillsDir() {
|
|
921
|
-
if (!
|
|
922
|
-
|
|
923
|
-
|
|
837
|
+
if (!existsSync2(SKILLS_DIR)) {
|
|
838
|
+
mkdirSync(SKILLS_DIR, { recursive: true });
|
|
839
|
+
log3.info({ dir: SKILLS_DIR }, "created skills directory");
|
|
924
840
|
}
|
|
925
841
|
}
|
|
926
842
|
function copyBuiltinSkills() {
|
|
927
843
|
const thisFile = fileURLToPath(import.meta.url);
|
|
928
|
-
const srcDir =
|
|
929
|
-
if (!
|
|
930
|
-
|
|
844
|
+
const srcDir = join2(dirname(thisFile), "..", "skills");
|
|
845
|
+
if (!existsSync2(srcDir)) {
|
|
846
|
+
log3.debug({ srcDir }, "no built-in skills directory found, skipping");
|
|
931
847
|
return;
|
|
932
848
|
}
|
|
933
849
|
let entries;
|
|
934
850
|
try {
|
|
935
851
|
entries = readdirSync2(srcDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
936
852
|
} catch {
|
|
937
|
-
|
|
853
|
+
log3.warn({ srcDir }, "failed to read built-in skills directory");
|
|
938
854
|
return;
|
|
939
855
|
}
|
|
940
856
|
for (const skillName of entries) {
|
|
941
|
-
const srcSkillMd =
|
|
942
|
-
const destDir =
|
|
943
|
-
const destSkillMd =
|
|
944
|
-
if (!
|
|
945
|
-
if (
|
|
946
|
-
|
|
857
|
+
const srcSkillMd = join2(srcDir, skillName, "SKILL.md");
|
|
858
|
+
const destDir = join2(SKILLS_DIR, skillName);
|
|
859
|
+
const destSkillMd = join2(destDir, "SKILL.md");
|
|
860
|
+
if (!existsSync2(srcSkillMd)) continue;
|
|
861
|
+
if (existsSync2(destSkillMd)) {
|
|
862
|
+
log3.debug({ skill: skillName }, "skill already exists, skipping");
|
|
947
863
|
continue;
|
|
948
864
|
}
|
|
949
865
|
try {
|
|
950
|
-
|
|
866
|
+
mkdirSync(destDir, { recursive: true });
|
|
951
867
|
copyFileSync(srcSkillMd, destSkillMd);
|
|
952
|
-
|
|
868
|
+
log3.info({ skill: skillName }, "copied built-in skill");
|
|
953
869
|
} catch (err) {
|
|
954
|
-
|
|
870
|
+
log3.warn({ skill: skillName, err }, "failed to copy built-in skill");
|
|
955
871
|
}
|
|
956
872
|
}
|
|
957
873
|
}
|
|
958
874
|
function ensureMcpConfig() {
|
|
959
|
-
if (
|
|
960
|
-
|
|
875
|
+
if (existsSync2(MCP_CONFIG_PATH)) {
|
|
876
|
+
log3.debug("mcp.json already exists, skipping");
|
|
961
877
|
return;
|
|
962
878
|
}
|
|
963
879
|
let mcpServerPath;
|
|
964
880
|
try {
|
|
965
881
|
const req = createRequire(import.meta.url);
|
|
966
882
|
const memoryPkgDir = dirname(req.resolve("@mclawnet/memory/package.json"));
|
|
967
|
-
mcpServerPath =
|
|
883
|
+
mcpServerPath = join2(memoryPkgDir, "dist", "mcp", "server.js");
|
|
968
884
|
} catch {
|
|
969
|
-
|
|
885
|
+
log3.warn("could not resolve @mclawnet/memory package path, skipping mcp.json generation");
|
|
970
886
|
return;
|
|
971
887
|
}
|
|
972
888
|
const config = {
|
|
@@ -978,27 +894,27 @@ function ensureMcpConfig() {
|
|
|
978
894
|
}
|
|
979
895
|
};
|
|
980
896
|
try {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
897
|
+
mkdirSync(CLAWNET_DIR, { recursive: true });
|
|
898
|
+
writeFileSync(MCP_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n");
|
|
899
|
+
log3.info({ path: MCP_CONFIG_PATH }, "generated default mcp.json");
|
|
984
900
|
} catch (err) {
|
|
985
|
-
|
|
901
|
+
log3.warn({ err }, "failed to generate mcp.json");
|
|
986
902
|
}
|
|
987
903
|
}
|
|
988
904
|
|
|
989
905
|
// src/brain-bridge.ts
|
|
990
|
-
import { existsSync as
|
|
991
|
-
import { join as
|
|
992
|
-
import { createLogger as
|
|
993
|
-
var
|
|
906
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, readdirSync as readdirSync3 } from "fs";
|
|
907
|
+
import { join as join3 } from "path";
|
|
908
|
+
import { createLogger as createLogger4 } from "@mclawnet/logger";
|
|
909
|
+
var log4 = createLogger4({ module: "brain-bridge" });
|
|
994
910
|
var BrainBridge = class {
|
|
995
911
|
constructor(hub, options) {
|
|
996
912
|
this.hub = hub;
|
|
997
913
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
998
|
-
this.brainHome = options?.brainHomePath || process.env.BRAIN_HOME ||
|
|
999
|
-
this.brainCorePath = options?.brainCorePath ||
|
|
914
|
+
this.brainHome = options?.brainHomePath || process.env.BRAIN_HOME || join3(home, "BrainData");
|
|
915
|
+
this.brainCorePath = options?.brainCorePath || join3(home, ".brain", "BrainCore");
|
|
1000
916
|
this.hub.registerNamespace("brain", (msg) => this.handleRequest(msg));
|
|
1001
|
-
|
|
917
|
+
log4.info(
|
|
1002
918
|
{ brainHome: this.brainHome, brainCorePath: this.brainCorePath },
|
|
1003
919
|
"BrainBridge initialized"
|
|
1004
920
|
);
|
|
@@ -1006,11 +922,11 @@ var BrainBridge = class {
|
|
|
1006
922
|
brainHome;
|
|
1007
923
|
brainCorePath;
|
|
1008
924
|
async handleRequest(msg) {
|
|
1009
|
-
|
|
925
|
+
log4.info({ action: msg.action, requestId: msg.requestId }, "brain request");
|
|
1010
926
|
switch (msg.action) {
|
|
1011
927
|
case "setup_status": {
|
|
1012
928
|
const status = this.checkSetup();
|
|
1013
|
-
|
|
929
|
+
log4.info({ status }, "setup_status result");
|
|
1014
930
|
return { status };
|
|
1015
931
|
}
|
|
1016
932
|
case "get_briefing":
|
|
@@ -1018,20 +934,20 @@ var BrainBridge = class {
|
|
|
1018
934
|
case "get_meeting_recap":
|
|
1019
935
|
return await this.getMeetingRecap(msg.params.recapPath);
|
|
1020
936
|
default:
|
|
1021
|
-
|
|
937
|
+
log4.warn({ action: msg.action }, "unknown brain action");
|
|
1022
938
|
throw new Error(`Unknown brain action: ${msg.action}`);
|
|
1023
939
|
}
|
|
1024
940
|
}
|
|
1025
941
|
checkSetup() {
|
|
1026
|
-
if (!
|
|
942
|
+
if (!existsSync3(this.brainCorePath)) {
|
|
1027
943
|
return "not_installed";
|
|
1028
944
|
}
|
|
1029
945
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
1030
|
-
const installJson =
|
|
1031
|
-
if (!
|
|
946
|
+
const installJson = join3(home, ".brain", "install.json");
|
|
947
|
+
if (!existsSync3(installJson)) {
|
|
1032
948
|
return "needs_config";
|
|
1033
949
|
}
|
|
1034
|
-
if (!
|
|
950
|
+
if (!existsSync3(this.brainHome)) {
|
|
1035
951
|
return "needs_config";
|
|
1036
952
|
}
|
|
1037
953
|
return "ready";
|
|
@@ -1039,25 +955,25 @@ var BrainBridge = class {
|
|
|
1039
955
|
/** Read the most recent daily briefing report */
|
|
1040
956
|
async getBriefing(date) {
|
|
1041
957
|
const targetDate = date || (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1042
|
-
const reportsDir =
|
|
1043
|
-
if (!
|
|
1044
|
-
|
|
958
|
+
const reportsDir = join3(this.brainHome, "reports", "daily");
|
|
959
|
+
if (!existsSync3(reportsDir)) {
|
|
960
|
+
log4.info({ reportsDir }, "get_briefing: reports dir not found");
|
|
1045
961
|
return { briefing: null, actions: [], projects: [], meetings: [], feed: [] };
|
|
1046
962
|
}
|
|
1047
963
|
const files = readdirSync3(reportsDir).filter((f) => f.includes(targetDate) && f.endsWith(".md")).sort().reverse();
|
|
1048
964
|
if (files.length === 0) {
|
|
1049
|
-
|
|
965
|
+
log4.info({ targetDate }, "get_briefing: no report for date");
|
|
1050
966
|
return { briefing: null, actions: [], projects: [], meetings: [], feed: [] };
|
|
1051
967
|
}
|
|
1052
|
-
|
|
1053
|
-
const content =
|
|
968
|
+
log4.info({ targetDate, file: files[0] }, "get_briefing: reading report");
|
|
969
|
+
const content = readFileSync2(join3(reportsDir, files[0]), "utf-8");
|
|
1054
970
|
const tldrMatch = content.match(/## TL;DR\n([\s\S]*?)(?=\n---|\n## )/);
|
|
1055
971
|
const tldr = tldrMatch ? tldrMatch[1].trim() : content.slice(0, 200);
|
|
1056
972
|
const actions = this.parseActions(content);
|
|
1057
973
|
const projects = this.parseProjects(content);
|
|
1058
974
|
const meetings = this.parseMeetings(content);
|
|
1059
975
|
const feed = this.parseFeed(content);
|
|
1060
|
-
|
|
976
|
+
log4.info(
|
|
1061
977
|
{ actions: actions.length, projects: projects.length, meetings: meetings.length, feed: feed.length },
|
|
1062
978
|
"get_briefing: parsed"
|
|
1063
979
|
);
|
|
@@ -1249,12 +1165,12 @@ var BrainBridge = class {
|
|
|
1249
1165
|
if (!recapPath) {
|
|
1250
1166
|
return { error: "No recap path provided" };
|
|
1251
1167
|
}
|
|
1252
|
-
const fullPath =
|
|
1253
|
-
if (!
|
|
1254
|
-
|
|
1168
|
+
const fullPath = join3(this.brainHome, recapPath);
|
|
1169
|
+
if (!existsSync3(fullPath)) {
|
|
1170
|
+
log4.warn({ fullPath }, "meeting recap file not found");
|
|
1255
1171
|
return { error: "Recap file not found" };
|
|
1256
1172
|
}
|
|
1257
|
-
const content =
|
|
1173
|
+
const content = readFileSync2(fullPath, "utf-8");
|
|
1258
1174
|
return { recap: this.parseRecapMarkdown(content) };
|
|
1259
1175
|
}
|
|
1260
1176
|
/** Parse meeting recap markdown into structured sections */
|
|
@@ -1287,10 +1203,10 @@ var BrainBridge = class {
|
|
|
1287
1203
|
};
|
|
1288
1204
|
|
|
1289
1205
|
// src/fs-bridge.ts
|
|
1290
|
-
import { existsSync as
|
|
1206
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
|
|
1291
1207
|
import { extname, isAbsolute } from "path";
|
|
1292
|
-
import { createLogger as
|
|
1293
|
-
var
|
|
1208
|
+
import { createLogger as createLogger5 } from "@mclawnet/logger";
|
|
1209
|
+
var log5 = createLogger5({ module: "fs-bridge" });
|
|
1294
1210
|
var MAX_TEXT_SIZE = 5 * 1024 * 1024;
|
|
1295
1211
|
var MIME_MAP = {
|
|
1296
1212
|
".ts": "text/typescript",
|
|
@@ -1328,10 +1244,10 @@ var FsBridge = class {
|
|
|
1328
1244
|
constructor(hub) {
|
|
1329
1245
|
this.hub = hub;
|
|
1330
1246
|
this.hub.registerNamespace("fs", (msg) => this.handleRequest(msg));
|
|
1331
|
-
|
|
1247
|
+
log5.info("FsBridge initialized");
|
|
1332
1248
|
}
|
|
1333
1249
|
async handleRequest(msg) {
|
|
1334
|
-
|
|
1250
|
+
log5.info({ action: msg.action, requestId: msg.requestId }, "fs request");
|
|
1335
1251
|
switch (msg.action) {
|
|
1336
1252
|
case "read":
|
|
1337
1253
|
return this.readFile(msg.params);
|
|
@@ -1345,7 +1261,7 @@ var FsBridge = class {
|
|
|
1345
1261
|
if (!isAbsolute(filePath)) {
|
|
1346
1262
|
throw new Error(`Access denied: only absolute paths allowed`);
|
|
1347
1263
|
}
|
|
1348
|
-
if (!
|
|
1264
|
+
if (!existsSync4(filePath)) {
|
|
1349
1265
|
throw new Error(`File not found: ${filePath}`);
|
|
1350
1266
|
}
|
|
1351
1267
|
const stat2 = statSync2(filePath);
|
|
@@ -1355,12 +1271,12 @@ var FsBridge = class {
|
|
|
1355
1271
|
const mimeType = getMimeType(filePath);
|
|
1356
1272
|
const totalSize = stat2.size;
|
|
1357
1273
|
if (isTextMime(mimeType)) {
|
|
1358
|
-
const raw =
|
|
1274
|
+
const raw = readFileSync3(filePath, "utf-8");
|
|
1359
1275
|
const truncated2 = raw.length > MAX_TEXT_SIZE;
|
|
1360
1276
|
const content = truncated2 ? raw.slice(0, MAX_TEXT_SIZE) : raw;
|
|
1361
1277
|
return { content, encoding: "utf-8", size: content.length, totalSize, mimeType, truncated: truncated2 };
|
|
1362
1278
|
}
|
|
1363
|
-
const buf =
|
|
1279
|
+
const buf = readFileSync3(filePath);
|
|
1364
1280
|
const truncated = buf.length > MAX_TEXT_SIZE;
|
|
1365
1281
|
const slice = truncated ? buf.subarray(0, MAX_TEXT_SIZE) : buf;
|
|
1366
1282
|
return { content: slice.toString("base64"), encoding: "base64", size: slice.length, totalSize, mimeType, truncated };
|
|
@@ -1368,16 +1284,16 @@ var FsBridge = class {
|
|
|
1368
1284
|
};
|
|
1369
1285
|
|
|
1370
1286
|
// src/start.ts
|
|
1371
|
-
import { createLogger as
|
|
1372
|
-
var
|
|
1287
|
+
import { createLogger as createLogger6 } from "@mclawnet/logger";
|
|
1288
|
+
var log6 = createLogger6({ module: "agent" });
|
|
1373
1289
|
async function startAgent(options) {
|
|
1374
1290
|
const config = loadConfig(options.config);
|
|
1375
1291
|
if (!config.token) {
|
|
1376
|
-
|
|
1292
|
+
log6.error("no token configured \u2014 set CLAWNET_TOKEN or use --token");
|
|
1377
1293
|
process.exit(1);
|
|
1378
1294
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1295
|
+
log6.info({ backend: options.adapter.type }, "starting agent");
|
|
1296
|
+
log6.info({ hubUrl: config.hubUrl }, "connecting to hub");
|
|
1381
1297
|
await initRoles();
|
|
1382
1298
|
await initSkills();
|
|
1383
1299
|
const hub = new HubConnection({
|
|
@@ -1385,13 +1301,13 @@ async function startAgent(options) {
|
|
|
1385
1301
|
token: config.token,
|
|
1386
1302
|
hostname: config.name,
|
|
1387
1303
|
onConnect: (agentId) => {
|
|
1388
|
-
|
|
1304
|
+
log6.info({ agentId }, "connected to hub");
|
|
1389
1305
|
},
|
|
1390
1306
|
onDisconnect: (code, reason) => {
|
|
1391
|
-
|
|
1307
|
+
log6.info({ code, reason }, "disconnected from hub");
|
|
1392
1308
|
},
|
|
1393
1309
|
onError: (err) => {
|
|
1394
|
-
|
|
1310
|
+
log6.error({ err }, "hub connection error");
|
|
1395
1311
|
}
|
|
1396
1312
|
});
|
|
1397
1313
|
let swarmCoordinator;
|
|
@@ -1429,7 +1345,7 @@ async function startAgent(options) {
|
|
|
1429
1345
|
const brainBridge = new BrainBridge(hub);
|
|
1430
1346
|
const fsBridge = new FsBridge(hub);
|
|
1431
1347
|
const shutdown = async () => {
|
|
1432
|
-
|
|
1348
|
+
log6.info("shutting down");
|
|
1433
1349
|
await sessionManager.closeAll();
|
|
1434
1350
|
hub.destroy();
|
|
1435
1351
|
process.exit(0);
|
|
@@ -1443,10 +1359,8 @@ async function startAgent(options) {
|
|
|
1443
1359
|
export {
|
|
1444
1360
|
HubConnection,
|
|
1445
1361
|
SessionManager,
|
|
1446
|
-
loadConfig,
|
|
1447
|
-
saveConfig,
|
|
1448
1362
|
BrainBridge,
|
|
1449
1363
|
FsBridge,
|
|
1450
1364
|
startAgent
|
|
1451
1365
|
};
|
|
1452
|
-
//# sourceMappingURL=chunk-
|
|
1366
|
+
//# sourceMappingURL=chunk-GLO5OZAY.js.map
|