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,6 @@
1
+ import type { ToolRegistry } from "../tool-registry.js";
2
+ import type { MemoryIndex } from "../memory-index.js";
3
+ import type { BrowserService } from "../browser-service.js";
4
+ import type { Logger } from "../types.js";
5
+ export declare function registerBuiltinTools(registry: ToolRegistry, memoryIndex: MemoryIndex, logger: Logger, browserService?: BrowserService): void;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAa1C,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,cAAc,GAC9B,IAAI,CAuCN"}
@@ -0,0 +1,46 @@
1
+ import { bashTool } from "./bash.js";
2
+ import { readTool } from "./read.js";
3
+ import { writeTool } from "./write.js";
4
+ import { editTool } from "./edit.js";
5
+ import { globTool } from "./glob.js";
6
+ import { grepTool } from "./grep.js";
7
+ import { gitTool } from "./git.js";
8
+ import { webFetchTool } from "./web-fetch.js";
9
+ import { webSearchTool } from "./web-search.js";
10
+ import { createMemoryTools } from "./memory.js";
11
+ import { createBrowserTools } from "./browser.js";
12
+ export function registerBuiltinTools(registry, memoryIndex, logger, browserService) {
13
+ // group:fs
14
+ registry.register(readTool);
15
+ registry.register(writeTool);
16
+ registry.register(editTool);
17
+ registry.register(globTool);
18
+ registry.register(grepTool);
19
+ // group:runtime
20
+ registry.register(bashTool);
21
+ registry.register(gitTool);
22
+ // group:web
23
+ registry.register(webFetchTool);
24
+ registry.register(webSearchTool);
25
+ // group:memory
26
+ for (const tool of createMemoryTools(memoryIndex)) {
27
+ registry.register(tool);
28
+ }
29
+ // group:browser
30
+ if (browserService) {
31
+ for (const tool of createBrowserTools(browserService)) {
32
+ registry.register(tool);
33
+ }
34
+ }
35
+ const tools = [
36
+ readTool.name, writeTool.name, editTool.name, globTool.name, grepTool.name,
37
+ bashTool.name, gitTool.name,
38
+ webFetchTool.name, webSearchTool.name,
39
+ "memory_search", "memory_get", "memory_store",
40
+ ];
41
+ if (browserService) {
42
+ tools.push("browser_navigate", "browser_snapshot", "browser_screenshot", "browser_click", "browser_type", "browser_evaluate", "browser_content");
43
+ }
44
+ logger.info("Built-in tools registered", { count: tools.length, tools });
45
+ }
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,UAAU,oBAAoB,CAClC,QAAsB,EACtB,WAAwB,EACxB,MAAc,EACd,cAA+B;IAE/B,WAAW;IACX,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE5B,gBAAgB;IAChB,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE3B,YAAY;IACZ,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAEjC,eAAe;IACf,KAAK,MAAM,IAAI,IAAI,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QAClD,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,gBAAgB;IAChB,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,MAAM,IAAI,IAAI,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC;YACtD,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI;QAC1E,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI;QAC3B,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI;QACrC,eAAe,EAAE,YAAY,EAAE,cAAc;KAC9C,CAAC;IACF,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;IACnJ,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ import type { MemoryIndex } from "../memory-index.js";
3
+ export declare function createMemoryTools(memoryIndex: MemoryIndex): ToolDefinition[];
4
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/tools/memory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAgBtD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,cAAc,EAAE,CAyE5E"}
@@ -0,0 +1,64 @@
1
+ export function createMemoryTools(memoryIndex) {
2
+ const memorySearchTool = {
3
+ name: "memory_search",
4
+ description: "Search the memory index using hybrid vector + text search.",
5
+ parameters: {
6
+ type: "object",
7
+ properties: {
8
+ query: { type: "string", description: "The search query" },
9
+ limit: { type: "number", description: "Maximum number of results (default 10)" },
10
+ },
11
+ required: ["query"],
12
+ },
13
+ source: "builtin",
14
+ async execute(params) {
15
+ const { query, limit } = params;
16
+ const results = await memoryIndex.search(query, { limit });
17
+ if (results.length === 0) {
18
+ return { output: "No results found." };
19
+ }
20
+ const formatted = results.map((r, i) => `[${i + 1}] ${r.path} (score: ${r.score.toFixed(3)})\n${r.content.slice(0, 500)}`).join("\n\n---\n\n");
21
+ return { output: formatted };
22
+ },
23
+ };
24
+ const memoryGetTool = {
25
+ name: "memory_get",
26
+ description: "Retrieve the full content of a specific file from memory.",
27
+ parameters: {
28
+ type: "object",
29
+ properties: {
30
+ path: { type: "string", description: "The file path to retrieve" },
31
+ },
32
+ required: ["path"],
33
+ },
34
+ source: "builtin",
35
+ async execute(params) {
36
+ const { path } = params;
37
+ const content = memoryIndex.get(path);
38
+ if (!content) {
39
+ return { output: "", error: `File not found: ${path}` };
40
+ }
41
+ return { output: content };
42
+ },
43
+ };
44
+ const memoryStoreTool = {
45
+ name: "memory_store",
46
+ description: "Store content to a file in memory and index it for future search.",
47
+ parameters: {
48
+ type: "object",
49
+ properties: {
50
+ content: { type: "string", description: "The content to store" },
51
+ path: { type: "string", description: "The file path to store at" },
52
+ },
53
+ required: ["content", "path"],
54
+ },
55
+ source: "builtin",
56
+ async execute(params) {
57
+ const { content, path } = params;
58
+ await memoryIndex.store(content, path);
59
+ return { output: `Stored and indexed: ${path}` };
60
+ },
61
+ };
62
+ return [memorySearchTool, memoryGetTool, memoryStoreTool];
63
+ }
64
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/tools/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const readTool: ToolDefinition;
3
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,aAAa,CAAC;AAW3E,eAAO,MAAM,QAAQ,EAAE,cAkDtB,CAAC"}
@@ -0,0 +1,50 @@
1
+ // CRC: crc-ToolRegistry.md
2
+ // Built-in tool: read — from HomarUS
3
+ import { readFileSync, existsSync, statSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ const MAX_FILE_SIZE = 2 * 1024 * 1024;
6
+ const MAX_LINES = 2000;
7
+ export const readTool = {
8
+ name: "read",
9
+ description: "Read the contents of a file. Returns numbered lines.",
10
+ parameters: {
11
+ type: "object",
12
+ properties: {
13
+ path: { type: "string", description: "Absolute or relative path to the file" },
14
+ offset: { type: "number", description: "Line number to start reading from (1-based)" },
15
+ limit: { type: "number", description: "Maximum number of lines to return" },
16
+ },
17
+ required: ["path"],
18
+ },
19
+ source: "builtin",
20
+ async execute(params, context) {
21
+ const { path: filePath, offset, limit } = params;
22
+ const absPath = resolve(context.workingDir, filePath);
23
+ if (!existsSync(absPath)) {
24
+ return { output: "", error: `File not found: ${absPath}` };
25
+ }
26
+ const stat = statSync(absPath);
27
+ if (stat.isDirectory()) {
28
+ return { output: "", error: `Path is a directory: ${absPath}` };
29
+ }
30
+ if (stat.size > MAX_FILE_SIZE) {
31
+ return { output: "", error: `File too large (${stat.size} bytes). Max: ${MAX_FILE_SIZE}` };
32
+ }
33
+ const content = readFileSync(absPath, "utf-8");
34
+ const allLines = content.split("\n");
35
+ const startLine = (offset ?? 1) - 1;
36
+ const maxLines = limit ?? MAX_LINES;
37
+ const lines = allLines.slice(startLine, startLine + maxLines);
38
+ const numbered = lines.map((line, i) => {
39
+ const lineNum = startLine + i + 1;
40
+ const truncated = line.length > 2000 ? line.slice(0, 2000) + "..." : line;
41
+ return `${String(lineNum).padStart(6)}\t${truncated}`;
42
+ });
43
+ let output = numbered.join("\n");
44
+ if (startLine + maxLines < allLines.length) {
45
+ output += `\n... (${allLines.length - startLine - maxLines} more lines)`;
46
+ }
47
+ return { output };
48
+ },
49
+ };
50
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const webFetchTool: ToolDefinition;
3
+ //# sourceMappingURL=web-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../src/tools/web-fetch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,aAAa,CAAC;AAW3E,eAAO,MAAM,YAAY,EAAE,cAuD1B,CAAC"}
@@ -0,0 +1,51 @@
1
+ const MAX_RESPONSE = 100_000;
2
+ export const webFetchTool = {
3
+ name: "web_fetch",
4
+ description: "Fetch content from a URL. Returns the response body as text.",
5
+ parameters: {
6
+ type: "object",
7
+ properties: {
8
+ url: { type: "string", description: "The URL to fetch" },
9
+ method: { type: "string", description: "HTTP method (default GET)", enum: ["GET", "POST", "PUT", "DELETE", "PATCH"] },
10
+ headers: { type: "object", description: "Optional request headers" },
11
+ body: { type: "string", description: "Optional request body" },
12
+ },
13
+ required: ["url"],
14
+ },
15
+ source: "builtin",
16
+ async execute(params, context) {
17
+ const { url, method = "GET", headers, body } = params;
18
+ if (context.sandbox) {
19
+ return { output: "", error: "web_fetch tool is not available in sandbox mode" };
20
+ }
21
+ try {
22
+ const response = await fetch(url, {
23
+ method,
24
+ headers: headers ? new Headers(headers) : undefined,
25
+ body: body ?? undefined,
26
+ signal: AbortSignal.timeout(30_000),
27
+ });
28
+ const contentType = response.headers.get("content-type") ?? "";
29
+ let text;
30
+ if (contentType.includes("application/json")) {
31
+ const json = await response.json();
32
+ text = JSON.stringify(json, null, 2);
33
+ }
34
+ else {
35
+ text = await response.text();
36
+ }
37
+ if (text.length > MAX_RESPONSE) {
38
+ text = text.slice(0, MAX_RESPONSE) + `\n... (truncated, ${text.length} total chars)`;
39
+ }
40
+ const statusLine = `HTTP ${response.status} ${response.statusText}`;
41
+ if (!response.ok) {
42
+ return { output: text, error: statusLine };
43
+ }
44
+ return { output: `${statusLine}\n\n${text}` };
45
+ }
46
+ catch (err) {
47
+ return { output: "", error: `Fetch failed: ${String(err.message ?? err)}` };
48
+ }
49
+ },
50
+ };
51
+ //# sourceMappingURL=web-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-fetch.js","sourceRoot":"","sources":["../../src/tools/web-fetch.ts"],"names":[],"mappings":"AAIA,MAAM,YAAY,GAAG,OAAO,CAAC;AAS7B,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,8DAA8D;IAC3E,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE;YACxD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;YACrH,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;YACpE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;SAC/D;QACD,QAAQ,EAAE,CAAC,KAAK,CAAC;KAClB;IACD,MAAM,EAAE,SAAS;IAEjB,KAAK,CAAC,OAAO,CAAC,MAAe,EAAE,OAAoB;QACjD,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAwB,CAAC;QAExE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,iDAAiD,EAAE,CAAC;QAClF,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM;gBACN,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;gBACnD,IAAI,EAAE,IAAI,IAAI,SAAS;gBACvB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;aACpC,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAC/D,IAAI,IAAY,CAAC;YAEjB,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC/B,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;gBAC/B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,qBAAqB,IAAI,CAAC,MAAM,eAAe,CAAC;YACvF,CAAC;YAED,MAAM,UAAU,GAAG,QAAQ,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;YAEpE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;YAC7C,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,OAAO,IAAI,EAAE,EAAE,CAAC;QAChD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,MAAM,CAAE,GAAa,CAAC,OAAO,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;QACzF,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const webSearchTool: ToolDefinition;
3
+ //# sourceMappingURL=web-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,aAAa,CAAC;AA0D3E,eAAO,MAAM,aAAa,EAAE,cAoC3B,CAAC"}
@@ -0,0 +1,65 @@
1
+ async function duckduckgoSearch(query, limit) {
2
+ const encoded = encodeURIComponent(query);
3
+ const url = `https://html.duckduckgo.com/html/?q=${encoded}`;
4
+ const response = await fetch(url, {
5
+ headers: { "User-Agent": "Mozilla/5.0 (compatible; HomarUScc/1.0)" },
6
+ signal: AbortSignal.timeout(15_000),
7
+ });
8
+ if (!response.ok) {
9
+ throw new Error(`Search failed: HTTP ${response.status}`);
10
+ }
11
+ const html = await response.text();
12
+ const results = [];
13
+ const resultBlocks = html.split("class=\"result__body\"");
14
+ for (let i = 1; i < resultBlocks.length && results.length < limit; i++) {
15
+ const block = resultBlocks[i];
16
+ const linkMatch = block.match(/class="result__a"[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/);
17
+ if (!linkMatch)
18
+ continue;
19
+ let resultUrl = linkMatch[1];
20
+ const uddgMatch = resultUrl.match(/uddg=([^&]*)/);
21
+ if (uddgMatch) {
22
+ resultUrl = decodeURIComponent(uddgMatch[1]);
23
+ }
24
+ const title = linkMatch[2].replace(/<[^>]+>/g, "").trim();
25
+ const snippetMatch = block.match(/class="result__snippet"[^>]*>([\s\S]*?)<\/a>/);
26
+ const snippet = snippetMatch
27
+ ? snippetMatch[1].replace(/<[^>]+>/g, "").trim()
28
+ : "";
29
+ if (title && resultUrl) {
30
+ results.push({ title, url: resultUrl, snippet });
31
+ }
32
+ }
33
+ return results;
34
+ }
35
+ export const webSearchTool = {
36
+ name: "web_search",
37
+ description: "Search the web and return results with titles, URLs, and snippets.",
38
+ parameters: {
39
+ type: "object",
40
+ properties: {
41
+ query: { type: "string", description: "The search query" },
42
+ limit: { type: "number", description: "Maximum number of results (default 10)" },
43
+ },
44
+ required: ["query"],
45
+ },
46
+ source: "builtin",
47
+ async execute(params, context) {
48
+ if (context.sandbox) {
49
+ return { output: "", error: "web_search tool is not available in sandbox mode" };
50
+ }
51
+ const { query, limit = 10 } = params;
52
+ try {
53
+ const results = await duckduckgoSearch(query, limit);
54
+ if (results.length === 0) {
55
+ return { output: "No results found." };
56
+ }
57
+ const formatted = results.map((r, i) => `[${i + 1}] ${r.title}\n ${r.url}\n ${r.snippet}`).join("\n\n");
58
+ return { output: formatted };
59
+ }
60
+ catch (err) {
61
+ return { output: "", error: `Search failed: ${String(err.message ?? err)}` };
62
+ }
63
+ },
64
+ };
65
+ //# sourceMappingURL=web-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const writeTool: ToolDefinition;
3
+ //# sourceMappingURL=write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/tools/write.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,aAAa,CAAC;AAO3E,eAAO,MAAM,SAAS,EAAE,cA8BvB,CAAC"}
@@ -0,0 +1,32 @@
1
+ // CRC: crc-ToolRegistry.md
2
+ // Built-in tool: write — from HomarUS
3
+ import { writeFileSync, mkdirSync, existsSync } from "node:fs";
4
+ import { resolve, dirname } from "node:path";
5
+ export const writeTool = {
6
+ name: "write",
7
+ description: "Write content to a file, creating it if it doesn't exist.",
8
+ parameters: {
9
+ type: "object",
10
+ properties: {
11
+ path: { type: "string", description: "Absolute or relative path to the file" },
12
+ content: { type: "string", description: "The content to write" },
13
+ },
14
+ required: ["path", "content"],
15
+ },
16
+ source: "builtin",
17
+ async execute(params, context) {
18
+ const { path: filePath, content } = params;
19
+ const absPath = resolve(context.workingDir, filePath);
20
+ if (context.sandbox) {
21
+ return { output: "", error: "write tool is not available in sandbox mode" };
22
+ }
23
+ const dir = dirname(absPath);
24
+ if (!existsSync(dir)) {
25
+ mkdirSync(dir, { recursive: true });
26
+ }
27
+ writeFileSync(absPath, content);
28
+ const lines = content.split("\n").length;
29
+ return { output: `Wrote ${lines} lines to ${absPath}` };
30
+ },
31
+ };
32
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/tools/write.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,sCAAsC;AACtC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQ7C,MAAM,CAAC,MAAM,SAAS,GAAmB;IACvC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,2DAA2D;IACxE,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE;YAC9E,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;SACjE;QACD,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;KAC9B;IACD,MAAM,EAAE,SAAS;IAEjB,KAAK,CAAC,OAAO,CAAC,MAAe,EAAE,OAAoB;QACjD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAqB,CAAC;QAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAEtD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,6CAA6C,EAAE,CAAC;QAC9E,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACzC,OAAO,EAAE,MAAM,EAAE,SAAS,KAAK,aAAa,OAAO,EAAE,EAAE,CAAC;IAC1D,CAAC;CACF,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { Logger, Event } from "./types.js";
2
+ import type { MemoryIndex } from "./memory-index.js";
3
+ export declare class TranscriptLogger {
4
+ private buffer;
5
+ private transcriptDir;
6
+ private flushIntervalMs;
7
+ private flushTimer;
8
+ private enabled;
9
+ private memoryIndex;
10
+ private logger;
11
+ constructor(logger: Logger, memoryIndex: MemoryIndex, options?: {
12
+ enabled?: boolean;
13
+ directory?: string;
14
+ flushIntervalMs?: number;
15
+ });
16
+ start(): void;
17
+ stop(): Promise<void>;
18
+ logInbound(event: Event): void;
19
+ logOutbound(channel: string, text: string): void;
20
+ flush(): Promise<void>;
21
+ getBufferSize(): number;
22
+ }
23
+ //# sourceMappingURL=transcript-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-logger.d.ts","sourceRoot":"","sources":["../src/transcript-logger.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAkB,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAUrD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;QAC9D,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B;IASD,KAAK,IAAI,IAAI;IAiBP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAa9B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAW1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC5B,aAAa,IAAI,MAAM;CAGxB"}
@@ -0,0 +1,101 @@
1
+ // CRC: crc-TranscriptLogger.md | Seq: seq-transcript-capture.md
2
+ // Session transcript capture and indexing
3
+ import { existsSync, mkdirSync, appendFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ export class TranscriptLogger {
6
+ buffer = [];
7
+ transcriptDir;
8
+ flushIntervalMs;
9
+ flushTimer = null;
10
+ enabled;
11
+ memoryIndex;
12
+ logger;
13
+ constructor(logger, memoryIndex, options) {
14
+ this.logger = logger;
15
+ this.memoryIndex = memoryIndex;
16
+ this.enabled = options?.enabled ?? true;
17
+ this.transcriptDir = options?.directory ?? `${process.env.HOME ?? "."}/.homaruscc/transcripts`;
18
+ this.flushIntervalMs = options?.flushIntervalMs ?? 300_000;
19
+ }
20
+ // CRC: crc-TranscriptLogger.md | R98, R102
21
+ start() {
22
+ if (!this.enabled)
23
+ return;
24
+ // R106: Ensure directory exists once at startup
25
+ if (!existsSync(this.transcriptDir)) {
26
+ mkdirSync(this.transcriptDir, { recursive: true });
27
+ }
28
+ this.flushTimer = setInterval(() => {
29
+ this.flush().catch((err) => this.logger.warn("Transcript flush failed", { error: String(err) }));
30
+ }, this.flushIntervalMs);
31
+ this.logger.info("TranscriptLogger started", { dir: this.transcriptDir, intervalMs: this.flushIntervalMs });
32
+ }
33
+ // CRC: crc-TranscriptLogger.md | R103
34
+ async stop() {
35
+ if (this.flushTimer) {
36
+ clearInterval(this.flushTimer);
37
+ this.flushTimer = null;
38
+ }
39
+ await this.flush();
40
+ this.logger.info("TranscriptLogger stopped");
41
+ }
42
+ // CRC: crc-TranscriptLogger.md | R98
43
+ logInbound(event) {
44
+ if (!this.enabled)
45
+ return;
46
+ const payload = event.payload;
47
+ this.buffer.push({
48
+ timestamp: event.timestamp,
49
+ channel: payload.channel ?? event.source,
50
+ direction: "in",
51
+ sender: payload.from,
52
+ text: payload.text,
53
+ });
54
+ }
55
+ // CRC: crc-TranscriptLogger.md | R99
56
+ logOutbound(channel, text) {
57
+ if (!this.enabled)
58
+ return;
59
+ this.buffer.push({
60
+ timestamp: Date.now(),
61
+ channel,
62
+ direction: "out",
63
+ text,
64
+ });
65
+ }
66
+ // CRC: crc-TranscriptLogger.md | R100, R101, R104, R107
67
+ async flush() {
68
+ if (this.buffer.length === 0)
69
+ return;
70
+ const turns = this.buffer.splice(0);
71
+ const date = new Date().toISOString().slice(0, 10);
72
+ const filePath = join(this.transcriptDir, `${date}.md`);
73
+ const isNewFile = !existsSync(filePath);
74
+ const lines = [];
75
+ if (isNewFile) {
76
+ lines.push(`# Transcript: ${date}`, "");
77
+ }
78
+ for (const turn of turns) {
79
+ const time = new Date(turn.timestamp).toTimeString().slice(0, 8);
80
+ const label = `${turn.channel}:${turn.direction}`;
81
+ const header = turn.sender
82
+ ? `## ${time} [${label}] ${turn.sender}`
83
+ : `## ${time} [${label}]`;
84
+ lines.push(header, "", turn.text, "");
85
+ }
86
+ try {
87
+ appendFileSync(filePath, lines.join("\n"));
88
+ await this.memoryIndex.indexFile(filePath);
89
+ this.logger.debug("Transcript flushed", { file: filePath, turns: turns.length });
90
+ }
91
+ catch (err) {
92
+ // R107: Retain buffer on failure
93
+ this.buffer.unshift(...turns);
94
+ this.logger.warn("Transcript flush failed, retained buffer", { error: String(err) });
95
+ }
96
+ }
97
+ getBufferSize() {
98
+ return this.buffer.length;
99
+ }
100
+ }
101
+ //# sourceMappingURL=transcript-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-logger.js","sourceRoot":"","sources":["../src/transcript-logger.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,0CAA0C;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAYjC,MAAM,OAAO,gBAAgB;IACnB,MAAM,GAAqB,EAAE,CAAC;IAC9B,aAAa,CAAS;IACtB,eAAe,CAAS;IACxB,UAAU,GAA0C,IAAI,CAAC;IACzD,OAAO,CAAU;IACjB,WAAW,CAAc;IACzB,MAAM,CAAS;IAEvB,YAAY,MAAc,EAAE,WAAwB,EAAE,OAIrD;QACC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,aAAa,GAAG,OAAO,EAAE,SAAS,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,yBAAyB,CAAC;QAC/F,IAAI,CAAC,eAAe,GAAG,OAAO,EAAE,eAAe,IAAI,OAAO,CAAC;IAC7D,CAAC;IAED,2CAA2C;IAC3C,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAE1B,gDAAgD;QAChD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACpC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CACpE,CAAC;QACJ,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;IAC9G,CAAC;IAED,sCAAsC;IACtC,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC/C,CAAC;IAED,qCAAqC;IACrC,UAAU,CAAC,KAAY;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAyB,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM;YACxC,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,OAAO,CAAC,IAAI;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;IAED,qCAAqC;IACrC,WAAW,CAAC,OAAe,EAAE,IAAY;QACvC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,OAAO;YACP,SAAS,EAAE,KAAK;YAChB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,wDAAwD;IACxD,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAErC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;QAExD,MAAM,SAAS,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1C,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACjE,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;gBACxB,CAAC,CAAC,MAAM,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE;gBACxC,CAAC,CAAC,MAAM,IAAI,KAAK,KAAK,GAAG,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,CAAC;YACH,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3C,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACnF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iCAAiC;YACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;CACF"}