homaruscc 0.2.0

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.
Files changed (171) hide show
  1. package/.env.example +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +307 -0
  4. package/bin/event-loop +60 -0
  5. package/config.example.json +55 -0
  6. package/dist/agent-registry.d.ts +38 -0
  7. package/dist/agent-registry.d.ts.map +1 -0
  8. package/dist/agent-registry.js +207 -0
  9. package/dist/agent-registry.js.map +1 -0
  10. package/dist/backend.d.ts +3 -0
  11. package/dist/backend.d.ts.map +1 -0
  12. package/dist/backend.js +59 -0
  13. package/dist/backend.js.map +1 -0
  14. package/dist/browser-service.d.ts +19 -0
  15. package/dist/browser-service.d.ts.map +1 -0
  16. package/dist/browser-service.js +101 -0
  17. package/dist/browser-service.js.map +1 -0
  18. package/dist/channel-adapter.d.ts +22 -0
  19. package/dist/channel-adapter.d.ts.map +1 -0
  20. package/dist/channel-adapter.js +62 -0
  21. package/dist/channel-adapter.js.map +1 -0
  22. package/dist/channel-manager.d.ts +18 -0
  23. package/dist/channel-manager.d.ts.map +1 -0
  24. package/dist/channel-manager.js +73 -0
  25. package/dist/channel-manager.js.map +1 -0
  26. package/dist/compaction-manager.d.ts +23 -0
  27. package/dist/compaction-manager.d.ts.map +1 -0
  28. package/dist/compaction-manager.js +135 -0
  29. package/dist/compaction-manager.js.map +1 -0
  30. package/dist/config.d.ts +21 -0
  31. package/dist/config.d.ts.map +1 -0
  32. package/dist/config.js +169 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/dashboard-adapter.d.ts +17 -0
  35. package/dist/dashboard-adapter.d.ts.map +1 -0
  36. package/dist/dashboard-adapter.js +41 -0
  37. package/dist/dashboard-adapter.js.map +1 -0
  38. package/dist/dashboard-server.d.ts +29 -0
  39. package/dist/dashboard-server.d.ts.map +1 -0
  40. package/dist/dashboard-server.js +381 -0
  41. package/dist/dashboard-server.js.map +1 -0
  42. package/dist/embedding-provider.d.ts +28 -0
  43. package/dist/embedding-provider.d.ts.map +1 -0
  44. package/dist/embedding-provider.js +91 -0
  45. package/dist/embedding-provider.js.map +1 -0
  46. package/dist/event-bus.d.ts +18 -0
  47. package/dist/event-bus.d.ts.map +1 -0
  48. package/dist/event-bus.js +41 -0
  49. package/dist/event-bus.js.map +1 -0
  50. package/dist/event-queue.d.ts +18 -0
  51. package/dist/event-queue.d.ts.map +1 -0
  52. package/dist/event-queue.js +68 -0
  53. package/dist/event-queue.js.map +1 -0
  54. package/dist/homaruscc.d.ts +69 -0
  55. package/dist/homaruscc.d.ts.map +1 -0
  56. package/dist/homaruscc.js +337 -0
  57. package/dist/homaruscc.js.map +1 -0
  58. package/dist/identity-manager.d.ts +36 -0
  59. package/dist/identity-manager.d.ts.map +1 -0
  60. package/dist/identity-manager.js +142 -0
  61. package/dist/identity-manager.js.map +1 -0
  62. package/dist/mcp-proxy.d.ts +3 -0
  63. package/dist/mcp-proxy.d.ts.map +1 -0
  64. package/dist/mcp-proxy.js +259 -0
  65. package/dist/mcp-proxy.js.map +1 -0
  66. package/dist/mcp-resources.d.ts +10 -0
  67. package/dist/mcp-resources.d.ts.map +1 -0
  68. package/dist/mcp-resources.js +67 -0
  69. package/dist/mcp-resources.js.map +1 -0
  70. package/dist/mcp-server.d.ts +3 -0
  71. package/dist/mcp-server.d.ts.map +1 -0
  72. package/dist/mcp-server.js +169 -0
  73. package/dist/mcp-server.js.map +1 -0
  74. package/dist/mcp-tools.d.ts +14 -0
  75. package/dist/mcp-tools.d.ts.map +1 -0
  76. package/dist/mcp-tools.js +408 -0
  77. package/dist/mcp-tools.js.map +1 -0
  78. package/dist/memory-index.d.ts +79 -0
  79. package/dist/memory-index.d.ts.map +1 -0
  80. package/dist/memory-index.js +437 -0
  81. package/dist/memory-index.js.map +1 -0
  82. package/dist/session-checkpoint.d.ts +22 -0
  83. package/dist/session-checkpoint.d.ts.map +1 -0
  84. package/dist/session-checkpoint.js +100 -0
  85. package/dist/session-checkpoint.js.map +1 -0
  86. package/dist/skill-manager.d.ts +26 -0
  87. package/dist/skill-manager.d.ts.map +1 -0
  88. package/dist/skill-manager.js +156 -0
  89. package/dist/skill-manager.js.map +1 -0
  90. package/dist/skill-transport.d.ts +45 -0
  91. package/dist/skill-transport.d.ts.map +1 -0
  92. package/dist/skill-transport.js +111 -0
  93. package/dist/skill-transport.js.map +1 -0
  94. package/dist/skill.d.ts +22 -0
  95. package/dist/skill.d.ts.map +1 -0
  96. package/dist/skill.js +106 -0
  97. package/dist/skill.js.map +1 -0
  98. package/dist/telegram-adapter.d.ts +43 -0
  99. package/dist/telegram-adapter.d.ts.map +1 -0
  100. package/dist/telegram-adapter.js +188 -0
  101. package/dist/telegram-adapter.js.map +1 -0
  102. package/dist/timer-service.d.ts +30 -0
  103. package/dist/timer-service.d.ts.map +1 -0
  104. package/dist/timer-service.js +176 -0
  105. package/dist/timer-service.js.map +1 -0
  106. package/dist/tool-registry.d.ts +30 -0
  107. package/dist/tool-registry.d.ts.map +1 -0
  108. package/dist/tool-registry.js +108 -0
  109. package/dist/tool-registry.js.map +1 -0
  110. package/dist/tools/bash.d.ts +3 -0
  111. package/dist/tools/bash.d.ts.map +1 -0
  112. package/dist/tools/bash.js +67 -0
  113. package/dist/tools/bash.js.map +1 -0
  114. package/dist/tools/browser.d.ts +4 -0
  115. package/dist/tools/browser.d.ts.map +1 -0
  116. package/dist/tools/browser.js +138 -0
  117. package/dist/tools/browser.js.map +1 -0
  118. package/dist/tools/edit.d.ts +3 -0
  119. package/dist/tools/edit.d.ts.map +1 -0
  120. package/dist/tools/edit.js +47 -0
  121. package/dist/tools/edit.js.map +1 -0
  122. package/dist/tools/git.d.ts +3 -0
  123. package/dist/tools/git.d.ts.map +1 -0
  124. package/dist/tools/git.js +105 -0
  125. package/dist/tools/git.js.map +1 -0
  126. package/dist/tools/glob.d.ts +3 -0
  127. package/dist/tools/glob.d.ts.map +1 -0
  128. package/dist/tools/glob.js +84 -0
  129. package/dist/tools/glob.js.map +1 -0
  130. package/dist/tools/grep.d.ts +3 -0
  131. package/dist/tools/grep.d.ts.map +1 -0
  132. package/dist/tools/grep.js +168 -0
  133. package/dist/tools/grep.js.map +1 -0
  134. package/dist/tools/index.d.ts +6 -0
  135. package/dist/tools/index.d.ts.map +1 -0
  136. package/dist/tools/index.js +46 -0
  137. package/dist/tools/index.js.map +1 -0
  138. package/dist/tools/memory.d.ts +4 -0
  139. package/dist/tools/memory.d.ts.map +1 -0
  140. package/dist/tools/memory.js +64 -0
  141. package/dist/tools/memory.js.map +1 -0
  142. package/dist/tools/read.d.ts +3 -0
  143. package/dist/tools/read.d.ts.map +1 -0
  144. package/dist/tools/read.js +50 -0
  145. package/dist/tools/read.js.map +1 -0
  146. package/dist/tools/web-fetch.d.ts +3 -0
  147. package/dist/tools/web-fetch.d.ts.map +1 -0
  148. package/dist/tools/web-fetch.js +51 -0
  149. package/dist/tools/web-fetch.js.map +1 -0
  150. package/dist/tools/web-search.d.ts +3 -0
  151. package/dist/tools/web-search.d.ts.map +1 -0
  152. package/dist/tools/web-search.js +65 -0
  153. package/dist/tools/web-search.js.map +1 -0
  154. package/dist/tools/write.d.ts +3 -0
  155. package/dist/tools/write.d.ts.map +1 -0
  156. package/dist/tools/write.js +32 -0
  157. package/dist/tools/write.js.map +1 -0
  158. package/dist/transcript-logger.d.ts +23 -0
  159. package/dist/transcript-logger.d.ts.map +1 -0
  160. package/dist/transcript-logger.js +101 -0
  161. package/dist/transcript-logger.js.map +1 -0
  162. package/dist/types.d.ts +190 -0
  163. package/dist/types.d.ts.map +1 -0
  164. package/dist/types.js +14 -0
  165. package/dist/types.js.map +1 -0
  166. package/identity.example/disagreements.md +9 -0
  167. package/identity.example/preferences.md +11 -0
  168. package/identity.example/soul.md +12 -0
  169. package/identity.example/state.md +21 -0
  170. package/identity.example/user.md +14 -0
  171. package/package.json +60 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction-manager.d.ts","sourceRoot":"","sources":["../src/compaction-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAY;gBAEZ,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM;IAK3C,gBAAgB,IAAI,MAAM;IAsD1B,iBAAiB,IAAI,MAAM;IAuE3B;;;;OAIG;IACH,qBAAqB,IAAI,OAAO;IAQhC,aAAa,IAAI;QAAE,gBAAgB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE;CAM3E"}
@@ -0,0 +1,135 @@
1
+ // CRC: crc-CompactionManager.md | Seq: seq-compaction-flush.md
2
+ // Auto-flush before context compaction — from HomarUS
3
+ import { randomUUID } from "node:crypto";
4
+ export class CompactionManager {
5
+ flushedThisCycle = false;
6
+ lastFlushTimestamp = 0;
7
+ compactedSinceLastWake = false; // R150: track compaction for digest vs full delivery
8
+ logger;
9
+ loop;
10
+ constructor(loop, logger) {
11
+ this.loop = loop;
12
+ this.logger = logger;
13
+ }
14
+ handlePreCompact() {
15
+ if (this.flushedThisCycle) {
16
+ this.logger.info("Pre-compact flush already fired this cycle, skipping");
17
+ return "";
18
+ }
19
+ this.flushedThisCycle = true;
20
+ this.lastFlushTimestamp = Date.now();
21
+ this.compactedSinceLastWake = true; // Set here since only PreCompact hook exists in Claude Code
22
+ this.loop.emit({
23
+ id: randomUUID(),
24
+ type: "pre_compact",
25
+ source: "compaction",
26
+ timestamp: this.lastFlushTimestamp,
27
+ payload: { flushed: true },
28
+ });
29
+ this.logger.info("Pre-compact flush triggered");
30
+ // R108: Flush transcript buffer before compaction
31
+ this.loop.getTranscriptLogger()?.flush().catch((err) => this.logger.warn("Transcript flush during compaction failed", { error: String(err) }));
32
+ const timerNames = this.loop.getTimerService().getAll().map((t) => t.name);
33
+ const memoryStats = this.loop.getMemoryIndex().getStats();
34
+ const recentEvents = this.loop.getEventHistory().slice(-10);
35
+ const eventSummary = recentEvents
36
+ .map((e) => `[${e.type}] ${e.source}: ${JSON.stringify(e.payload).slice(0, 100)}`)
37
+ .join("\n");
38
+ // R128: Save checkpoint before compaction
39
+ const checkpoint = this.loop.getSessionCheckpoint();
40
+ checkpoint.update({ modifiedFiles: [] }); // trigger timestamp update
41
+ return [
42
+ "IMPORTANT: Context compaction is about to occur. Save any important session state to memory NOW.",
43
+ "Use the memory_store tool to persist anything valuable from this session that hasn't been saved yet.",
44
+ "",
45
+ "What to save:",
46
+ "- Decisions made during this session",
47
+ "- Task progress and current status",
48
+ "- Important observations or findings",
49
+ "- Any user preferences or corrections learned",
50
+ "",
51
+ `Active timers: ${timerNames.length > 0 ? timerNames.join(", ") : "none"}`,
52
+ `Memory: ${memoryStats.fileCount} files, ${memoryStats.chunkCount} chunks indexed`,
53
+ "",
54
+ "Recent events:",
55
+ eventSummary,
56
+ ].join("\n");
57
+ }
58
+ handlePostCompact() {
59
+ this.flushedThisCycle = false;
60
+ this.compactedSinceLastWake = true;
61
+ this.loop.emit({
62
+ id: randomUUID(),
63
+ type: "post_compact",
64
+ source: "compaction",
65
+ timestamp: Date.now(),
66
+ payload: { reset: true },
67
+ });
68
+ this.logger.info("Post-compact context re-injection");
69
+ const timerNames = this.loop.getTimerService().getAll().map((t) => `${t.name} (${t.type})`);
70
+ const memoryStats = this.loop.getMemoryIndex().getStats();
71
+ const recentPaths = this.loop.getMemoryIndex().getRecentPaths(10);
72
+ const watermark = this.loop.getDeliveryWatermark();
73
+ const recentEvents = this.loop.getEventHistory().slice(-5);
74
+ const lines = [
75
+ "Context was just compacted. Here is critical state:",
76
+ "",
77
+ `Event delivery watermark: ${watermark} (${watermark ? new Date(watermark).toISOString() : "none"})`,
78
+ "The event loop will NOT replay events before this watermark — you are safe to restart it.",
79
+ "",
80
+ ];
81
+ if (timerNames.length > 0) {
82
+ lines.push(`Active timers: ${timerNames.join(", ")}`);
83
+ }
84
+ lines.push(`Memory index: ${memoryStats.fileCount} files, ${memoryStats.chunkCount} chunks`);
85
+ if (recentPaths.length > 0) {
86
+ lines.push(`Recent memory keys: ${recentPaths.join(", ")}`);
87
+ }
88
+ if (this.loop.getIdentityManager().getSoul()) {
89
+ lines.push("Identity: soul.md and user.md are loaded");
90
+ }
91
+ if (recentEvents.length > 0) {
92
+ lines.push("", "Last 5 events (already handled — do NOT re-process):");
93
+ for (const e of recentEvents) {
94
+ const ts = new Date(e.timestamp).toISOString();
95
+ const summary = JSON.stringify(e.payload).slice(0, 80);
96
+ lines.push(` [${ts}] ${e.type}/${e.source}: ${summary}`);
97
+ }
98
+ }
99
+ // R129: Include session checkpoint in post-compact context
100
+ const checkpoint = this.loop.getSessionCheckpoint();
101
+ const checkpointText = checkpoint.toContextString();
102
+ if (checkpointText) {
103
+ lines.push("", "--- Session Checkpoint (what you were doing before compaction) ---", checkpointText);
104
+ }
105
+ // Include active agents
106
+ const agents = this.loop.getAgentRegistry().getAll().filter(a => a.status === "running");
107
+ if (agents.length > 0) {
108
+ lines.push("", "Running background agents:");
109
+ for (const a of agents) {
110
+ lines.push(` - ${a.id}: ${a.description} (started ${new Date(a.startTime).toISOString()})`);
111
+ }
112
+ }
113
+ return lines.join("\n");
114
+ }
115
+ // R150: Consume-once compaction flag for digest vs full identity delivery
116
+ /**
117
+ * Returns true if compaction occurred since the last /api/wait delivery.
118
+ * Consuming this resets the flag — the next call returns false until
119
+ * another compaction happens.
120
+ */
121
+ consumeCompactionFlag() {
122
+ if (this.compactedSinceLastWake) {
123
+ this.compactedSinceLastWake = false;
124
+ return true;
125
+ }
126
+ return false;
127
+ }
128
+ getFlushState() {
129
+ return {
130
+ flushedThisCycle: this.flushedThisCycle,
131
+ lastFlushTimestamp: this.lastFlushTimestamp,
132
+ };
133
+ }
134
+ }
135
+ //# sourceMappingURL=compaction-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction-manager.js","sourceRoot":"","sources":["../src/compaction-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ConfigData, Logger } from "./types.js";
2
+ export declare class Config {
3
+ private data;
4
+ private configPath;
5
+ private watching;
6
+ private logger;
7
+ constructor(logger: Logger, configPath?: string);
8
+ load(path?: string): ConfigData;
9
+ get<T = unknown>(key: string): T | undefined;
10
+ getSection<T = unknown>(section: string): T;
11
+ getAll(): ConfigData;
12
+ private resolveEnvVars;
13
+ private loadEnvFile;
14
+ startWatching(onChange: (safeChange: boolean) => void): void;
15
+ stopWatching(): void;
16
+ private isSafeChange;
17
+ private resolveConfigPath;
18
+ private merge;
19
+ private flatten;
20
+ }
21
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAmBrD,qBAAa,MAAM;IACjB,OAAO,CAAC,IAAI,CAA+C;IAC3D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAK/C,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU;IAiB/B,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAU5C,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC;IAI3C,MAAM,IAAI,UAAU;IAIpB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,WAAW;IAQnB,aAAa,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAmB5D,YAAY,IAAI,IAAI;IAMpB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,KAAK;IAkBb,OAAO,CAAC,OAAO;CAchB"}
package/dist/config.js ADDED
@@ -0,0 +1,169 @@
1
+ // CRC: crc-Config.md | Seq: seq-startup.md
2
+ // Config system — adapted from HomarUS for homaruscc
3
+ import { readFileSync, existsSync, watchFile, unwatchFile } from "node:fs";
4
+ import { resolve, dirname } from "node:path";
5
+ import { config as loadDotenv } from "dotenv";
6
+ const DEFAULT_CONFIG = {
7
+ channels: {},
8
+ memory: { search: { vectorWeight: 0.7, ftsWeight: 0.3 } },
9
+ skills: { paths: [] },
10
+ dashboard: { port: 3120, enabled: true },
11
+ timers: { enabled: true },
12
+ identity: {},
13
+ browser: { enabled: false, headless: true },
14
+ };
15
+ const SAFE_KEYS = new Set([
16
+ "memory.search",
17
+ "skills.paths",
18
+ "timers.enabled",
19
+ "dashboard.enabled",
20
+ ]);
21
+ export class Config {
22
+ data = structuredClone(DEFAULT_CONFIG);
23
+ configPath;
24
+ watching = false;
25
+ logger;
26
+ constructor(logger, configPath) {
27
+ this.logger = logger;
28
+ this.configPath = configPath ?? this.resolveConfigPath();
29
+ }
30
+ load(path) {
31
+ if (path)
32
+ this.configPath = path;
33
+ this.loadEnvFile();
34
+ if (!existsSync(this.configPath)) {
35
+ this.logger.info("No config file found, using defaults", { path: this.configPath });
36
+ return this.data;
37
+ }
38
+ const raw = readFileSync(this.configPath, "utf-8");
39
+ const parsed = JSON.parse(raw);
40
+ const resolved = this.resolveEnvVars(parsed);
41
+ this.data = this.merge(DEFAULT_CONFIG, resolved);
42
+ this.logger.info("Config loaded", { path: this.configPath });
43
+ return this.data;
44
+ }
45
+ get(key) {
46
+ const parts = key.split(".");
47
+ let current = this.data;
48
+ for (const part of parts) {
49
+ if (current == null || typeof current !== "object")
50
+ return undefined;
51
+ current = current[part];
52
+ }
53
+ return current;
54
+ }
55
+ getSection(section) {
56
+ return this.data[section];
57
+ }
58
+ getAll() {
59
+ return this.data;
60
+ }
61
+ resolveEnvVars(obj) {
62
+ if (typeof obj === "string") {
63
+ return obj.replace(/\$\{([^}]+)\}/g, (_, varName) => {
64
+ return process.env[varName] ?? "";
65
+ });
66
+ }
67
+ if (Array.isArray(obj)) {
68
+ return obj.map((item) => this.resolveEnvVars(item));
69
+ }
70
+ if (obj !== null && typeof obj === "object") {
71
+ const result = {};
72
+ for (const [key, value] of Object.entries(obj)) {
73
+ result[key] = this.resolveEnvVars(value);
74
+ }
75
+ return result;
76
+ }
77
+ return obj;
78
+ }
79
+ loadEnvFile() {
80
+ const envPath = resolve(dirname(this.configPath), ".env");
81
+ if (existsSync(envPath)) {
82
+ loadDotenv({ path: envPath });
83
+ this.logger.debug("Loaded .env file", { path: envPath });
84
+ }
85
+ }
86
+ startWatching(onChange) {
87
+ if (this.watching)
88
+ return;
89
+ this.watching = true;
90
+ watchFile(this.configPath, { interval: 2000 }, () => {
91
+ try {
92
+ const oldData = structuredClone(this.data);
93
+ this.load();
94
+ const safe = this.isSafeChange(oldData, this.data);
95
+ if (!safe) {
96
+ this.logger.warn("Config change requires restart for full effect");
97
+ }
98
+ onChange(safe);
99
+ }
100
+ catch (err) {
101
+ this.logger.error("Failed to reload config", { error: String(err) });
102
+ }
103
+ });
104
+ }
105
+ stopWatching() {
106
+ if (!this.watching)
107
+ return;
108
+ unwatchFile(this.configPath);
109
+ this.watching = false;
110
+ }
111
+ isSafeChange(oldConfig, newConfig) {
112
+ const oldJson = JSON.stringify(oldConfig);
113
+ const newJson = JSON.stringify(newConfig);
114
+ if (oldJson === newJson)
115
+ return true;
116
+ const oldFlat = this.flatten(oldConfig);
117
+ const newFlat = this.flatten(newConfig);
118
+ const allKeys = new Set([...Object.keys(oldFlat), ...Object.keys(newFlat)]);
119
+ for (const key of allKeys) {
120
+ if (JSON.stringify(oldFlat[key]) !== JSON.stringify(newFlat[key])) {
121
+ const isSafe = [...SAFE_KEYS].some((sk) => key.startsWith(sk));
122
+ if (!isSafe)
123
+ return false;
124
+ }
125
+ }
126
+ return true;
127
+ }
128
+ resolveConfigPath() {
129
+ const projectPath = resolve(process.cwd(), "homaruscc.json");
130
+ if (existsSync(projectPath))
131
+ return projectPath;
132
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "~";
133
+ return resolve(home, ".homaruscc", "config.json");
134
+ }
135
+ merge(defaults, overrides) {
136
+ const result = structuredClone(defaults);
137
+ for (const [key, value] of Object.entries(overrides)) {
138
+ if (value !== undefined && value !== null) {
139
+ const resultObj = result;
140
+ if (typeof value === "object" && !Array.isArray(value) && typeof resultObj[key] === "object") {
141
+ resultObj[key] = {
142
+ ...resultObj[key],
143
+ ...value,
144
+ };
145
+ }
146
+ else {
147
+ resultObj[key] = value;
148
+ }
149
+ }
150
+ }
151
+ return result;
152
+ }
153
+ flatten(obj, prefix = "") {
154
+ const result = {};
155
+ if (obj !== null && typeof obj === "object" && !Array.isArray(obj)) {
156
+ for (const [key, value] of Object.entries(obj)) {
157
+ const fullKey = prefix ? `${prefix}.${key}` : key;
158
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
159
+ Object.assign(result, this.flatten(value, fullKey));
160
+ }
161
+ else {
162
+ result[fullKey] = value;
163
+ }
164
+ }
165
+ }
166
+ return result;
167
+ }
168
+ }
169
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { OutboundMessage, HealthStatus, Logger } from "./types.js";
2
+ import { ChannelAdapter } from "./channel-adapter.js";
3
+ export type DashboardMessageHandler = (message: {
4
+ from: string;
5
+ text: string;
6
+ }) => void;
7
+ export declare class DashboardAdapter extends ChannelAdapter {
8
+ private outboundHandler;
9
+ constructor(logger: Logger);
10
+ connect(): Promise<void>;
11
+ disconnect(): Promise<void>;
12
+ send(target: string, message: OutboundMessage): Promise<void>;
13
+ health(): HealthStatus;
14
+ receiveFromDashboard(from: string, text: string): void;
15
+ setOutboundHandler(fn: (target: string, message: OutboundMessage) => void): void;
16
+ }
17
+ //# sourceMappingURL=dashboard-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-adapter.d.ts","sourceRoot":"","sources":["../src/dashboard-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAExF,qBAAa,gBAAiB,SAAQ,cAAc;IAClD,OAAO,CAAC,eAAe,CAAqE;gBAEhF,MAAM,EAAE,MAAM;IAIpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnE,MAAM,IAAI,YAAY;IAQtB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAYtD,kBAAkB,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;CAGjF"}
@@ -0,0 +1,41 @@
1
+ import { ChannelAdapter } from "./channel-adapter.js";
2
+ export class DashboardAdapter extends ChannelAdapter {
3
+ outboundHandler = null;
4
+ constructor(logger) {
5
+ super("dashboard", logger, "open", "always_on");
6
+ }
7
+ async connect() {
8
+ this.state = "connected";
9
+ this.logger.info("Dashboard adapter connected");
10
+ }
11
+ async disconnect() {
12
+ this.state = "disconnected";
13
+ this.logger.info("Dashboard adapter disconnected");
14
+ }
15
+ async send(target, message) {
16
+ // Forward to WebSocket clients via the handler
17
+ this.outboundHandler?.(target, message);
18
+ }
19
+ health() {
20
+ return {
21
+ healthy: this.state === "connected",
22
+ lastCheck: Date.now(),
23
+ };
24
+ }
25
+ // Called by DashboardServer when WebSocket clients send messages
26
+ receiveFromDashboard(from, text) {
27
+ this.deliver({
28
+ from,
29
+ channel: "dashboard",
30
+ text,
31
+ isGroup: false,
32
+ isMention: false,
33
+ raw: { from, text },
34
+ });
35
+ }
36
+ // Set handler for outbound messages to dashboard WebSocket clients
37
+ setOutboundHandler(fn) {
38
+ this.outboundHandler = fn;
39
+ }
40
+ }
41
+ //# sourceMappingURL=dashboard-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-adapter.js","sourceRoot":"","sources":["../src/dashboard-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAItD,MAAM,OAAO,gBAAiB,SAAQ,cAAc;IAC1C,eAAe,GAAgE,IAAI,CAAC;IAE5F,YAAY,MAAc;QACxB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,OAAwB;QACjD,+CAA+C;QAC/C,IAAI,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM;QACJ,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,KAAK,KAAK,WAAW;YACnC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,oBAAoB,CAAC,IAAY,EAAE,IAAY;QAC7C,IAAI,CAAC,OAAO,CAAC;YACX,IAAI;YACJ,OAAO,EAAE,WAAW;YACpB,IAAI;YACJ,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;YAChB,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SACpB,CAAC,CAAC;IACL,CAAC;IAED,mEAAmE;IACnE,kBAAkB,CAAC,EAAsD;QACvE,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { Logger, Event } from "./types.js";
2
+ import type { HomarUScc } from "./homaruscc.js";
3
+ import type { DashboardAdapter } from "./dashboard-adapter.js";
4
+ export declare class DashboardServer {
5
+ private app;
6
+ private httpServer;
7
+ private wss;
8
+ private clients;
9
+ private port;
10
+ private logger;
11
+ private loop;
12
+ private dashboardAdapter;
13
+ private mcpTools;
14
+ private mcpResources;
15
+ private compactionManager;
16
+ constructor(logger: Logger, port: number, loop: HomarUScc, dashboardAdapter: DashboardAdapter);
17
+ start(): Promise<void>;
18
+ private listen;
19
+ private killStaleProcess;
20
+ stop(): Promise<void>;
21
+ broadcastEvent(event: Event): void;
22
+ private setupRoutes;
23
+ private setupWebSocket;
24
+ private handleWsMessage;
25
+ private wireAdapter;
26
+ private sendTo;
27
+ private broadcast;
28
+ }
29
+ //# sourceMappingURL=dashboard-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-server.d.ts","sourceRoot":"","sources":["../src/dashboard-server.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAe/D,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,iBAAiB,CAAoB;gBAEjC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB;IAkBvF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB5B,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,gBAAgB;IAclB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAalC,OAAO,CAAC,WAAW;IAmLnB,OAAO,CAAC,cAAc;IA4CtB,OAAO,CAAC,eAAe;IAuCvB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,SAAS;CAQlB"}