@aitne/daemon 0.1.4 → 0.1.6

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 (268) hide show
  1. package/dist/adapters/notification-manager.d.ts +12 -0
  2. package/dist/adapters/notification-manager.d.ts.map +1 -1
  3. package/dist/adapters/notification-manager.js +39 -1
  4. package/dist/adapters/notification-manager.js.map +1 -1
  5. package/dist/api/routes/agent.d.ts.map +1 -1
  6. package/dist/api/routes/agent.js +7 -0
  7. package/dist/api/routes/agent.js.map +1 -1
  8. package/dist/api/routes/commands.d.ts.map +1 -1
  9. package/dist/api/routes/commands.js +16 -13
  10. package/dist/api/routes/commands.js.map +1 -1
  11. package/dist/api/routes/context.d.ts.map +1 -1
  12. package/dist/api/routes/context.js +13 -2
  13. package/dist/api/routes/context.js.map +1 -1
  14. package/dist/api/routes/dashboard.d.ts.map +1 -1
  15. package/dist/api/routes/dashboard.js +28 -0
  16. package/dist/api/routes/dashboard.js.map +1 -1
  17. package/dist/api/routes/fs.d.ts +23 -0
  18. package/dist/api/routes/fs.d.ts.map +1 -0
  19. package/dist/api/routes/fs.js +156 -0
  20. package/dist/api/routes/fs.js.map +1 -0
  21. package/dist/api/routes/fs.logic.d.ts +62 -0
  22. package/dist/api/routes/fs.logic.d.ts.map +1 -0
  23. package/dist/api/routes/fs.logic.js +137 -0
  24. package/dist/api/routes/fs.logic.js.map +1 -0
  25. package/dist/api/routes/health.d.ts.map +1 -1
  26. package/dist/api/routes/health.js +4 -2
  27. package/dist/api/routes/health.js.map +1 -1
  28. package/dist/api/routes/integrations.d.ts.map +1 -1
  29. package/dist/api/routes/integrations.js +8 -6
  30. package/dist/api/routes/integrations.js.map +1 -1
  31. package/dist/api/routes/metrics.d.ts +1 -0
  32. package/dist/api/routes/metrics.d.ts.map +1 -1
  33. package/dist/api/routes/metrics.js +24 -0
  34. package/dist/api/routes/metrics.js.map +1 -1
  35. package/dist/api/routes/observations.d.ts.map +1 -1
  36. package/dist/api/routes/observations.js +538 -25
  37. package/dist/api/routes/observations.js.map +1 -1
  38. package/dist/api/routes/skills.d.ts +9 -1
  39. package/dist/api/routes/skills.d.ts.map +1 -1
  40. package/dist/api/routes/skills.js +38 -16
  41. package/dist/api/routes/skills.js.map +1 -1
  42. package/dist/api/routes/wiki.d.ts +4 -0
  43. package/dist/api/routes/wiki.d.ts.map +1 -0
  44. package/dist/api/routes/wiki.js +1075 -0
  45. package/dist/api/routes/wiki.js.map +1 -0
  46. package/dist/api/server.d.ts +13 -0
  47. package/dist/api/server.d.ts.map +1 -1
  48. package/dist/api/server.js +27 -1
  49. package/dist/api/server.js.map +1 -1
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +26 -0
  52. package/dist/config.js.map +1 -1
  53. package/dist/core/agent-core.d.ts +25 -0
  54. package/dist/core/agent-core.d.ts.map +1 -1
  55. package/dist/core/agent-core.js.map +1 -1
  56. package/dist/core/backends/backend-router.d.ts +5 -1
  57. package/dist/core/backends/backend-router.d.ts.map +1 -1
  58. package/dist/core/backends/backend-router.js +10 -1
  59. package/dist/core/backends/backend-router.js.map +1 -1
  60. package/dist/core/backends/claude-code-core.d.ts.map +1 -1
  61. package/dist/core/backends/claude-code-core.js +62 -4
  62. package/dist/core/backends/claude-code-core.js.map +1 -1
  63. package/dist/core/backends/claude-tool-collection.d.ts +1 -1
  64. package/dist/core/backends/claude-tool-collection.d.ts.map +1 -1
  65. package/dist/core/backends/claude-tool-collection.js +327 -65
  66. package/dist/core/backends/claude-tool-collection.js.map +1 -1
  67. package/dist/core/backends/codex-core.d.ts.map +1 -1
  68. package/dist/core/backends/codex-core.js +36 -0
  69. package/dist/core/backends/codex-core.js.map +1 -1
  70. package/dist/core/backends/gemini-cli-core.d.ts +24 -5
  71. package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
  72. package/dist/core/backends/gemini-cli-core.js +62 -30
  73. package/dist/core/backends/gemini-cli-core.js.map +1 -1
  74. package/dist/core/backends/plan-presets.d.ts +3 -1
  75. package/dist/core/backends/plan-presets.d.ts.map +1 -1
  76. package/dist/core/backends/plan-presets.js +42 -2
  77. package/dist/core/backends/plan-presets.js.map +1 -1
  78. package/dist/core/bang-commands/commands-help.d.ts +5 -0
  79. package/dist/core/bang-commands/commands-help.d.ts.map +1 -0
  80. package/dist/core/bang-commands/commands-help.js +69 -0
  81. package/dist/core/bang-commands/commands-help.js.map +1 -0
  82. package/dist/core/bang-commands/commands-wiki.d.ts +75 -0
  83. package/dist/core/bang-commands/commands-wiki.d.ts.map +1 -0
  84. package/dist/core/bang-commands/commands-wiki.js +574 -0
  85. package/dist/core/bang-commands/commands-wiki.js.map +1 -0
  86. package/dist/core/bang-commands/index.d.ts +4 -2
  87. package/dist/core/bang-commands/index.d.ts.map +1 -1
  88. package/dist/core/bang-commands/index.js +15 -1
  89. package/dist/core/bang-commands/index.js.map +1 -1
  90. package/dist/core/bang-commands/registry.d.ts +47 -4
  91. package/dist/core/bang-commands/registry.d.ts.map +1 -1
  92. package/dist/core/bang-commands/registry.js +85 -15
  93. package/dist/core/bang-commands/registry.js.map +1 -1
  94. package/dist/core/context-builder.d.ts +17 -0
  95. package/dist/core/context-builder.d.ts.map +1 -1
  96. package/dist/core/context-builder.js +64 -6
  97. package/dist/core/context-builder.js.map +1 -1
  98. package/dist/core/daemon-api-cli.d.ts.map +1 -1
  99. package/dist/core/daemon-api-cli.js +50 -2
  100. package/dist/core/daemon-api-cli.js.map +1 -1
  101. package/dist/core/dispatcher-message-handler.d.ts.map +1 -1
  102. package/dist/core/dispatcher-message-handler.js +10 -0
  103. package/dist/core/dispatcher-message-handler.js.map +1 -1
  104. package/dist/core/dispatcher-morning-routine.d.ts.map +1 -1
  105. package/dist/core/dispatcher-morning-routine.js +17 -2
  106. package/dist/core/dispatcher-morning-routine.js.map +1 -1
  107. package/dist/core/dispatcher-result-processor.d.ts +23 -0
  108. package/dist/core/dispatcher-result-processor.d.ts.map +1 -1
  109. package/dist/core/dispatcher-result-processor.js +124 -5
  110. package/dist/core/dispatcher-result-processor.js.map +1 -1
  111. package/dist/core/dispatcher-scheduled-tasks.d.ts.map +1 -1
  112. package/dist/core/dispatcher-scheduled-tasks.js +114 -80
  113. package/dist/core/dispatcher-scheduled-tasks.js.map +1 -1
  114. package/dist/core/dispatcher-types.d.ts +116 -1
  115. package/dist/core/dispatcher-types.d.ts.map +1 -1
  116. package/dist/core/dispatcher-types.js.map +1 -1
  117. package/dist/core/dispatcher.d.ts +36 -0
  118. package/dist/core/dispatcher.d.ts.map +1 -1
  119. package/dist/core/dispatcher.js +94 -1
  120. package/dist/core/dispatcher.js.map +1 -1
  121. package/dist/core/integration-lifecycle.d.ts.map +1 -1
  122. package/dist/core/integration-lifecycle.js +6 -8
  123. package/dist/core/integration-lifecycle.js.map +1 -1
  124. package/dist/core/metrics.d.ts +127 -0
  125. package/dist/core/metrics.d.ts.map +1 -1
  126. package/dist/core/metrics.js +256 -1
  127. package/dist/core/metrics.js.map +1 -1
  128. package/dist/core/prompts.d.ts +2 -1
  129. package/dist/core/prompts.d.ts.map +1 -1
  130. package/dist/core/prompts.js +40 -0
  131. package/dist/core/prompts.js.map +1 -1
  132. package/dist/core/roadmap-validate.js +13 -1
  133. package/dist/core/roadmap-validate.js.map +1 -1
  134. package/dist/core/routine-acquisition-plan.d.ts +51 -0
  135. package/dist/core/routine-acquisition-plan.d.ts.map +1 -1
  136. package/dist/core/routine-acquisition-plan.js +111 -12
  137. package/dist/core/routine-acquisition-plan.js.map +1 -1
  138. package/dist/core/routine-fetch-window-retry.d.ts +109 -0
  139. package/dist/core/routine-fetch-window-retry.d.ts.map +1 -0
  140. package/dist/core/routine-fetch-window-retry.js +210 -0
  141. package/dist/core/routine-fetch-window-retry.js.map +1 -0
  142. package/dist/core/routine-fetch-window-runner.d.ts +258 -32
  143. package/dist/core/routine-fetch-window-runner.d.ts.map +1 -1
  144. package/dist/core/routine-fetch-window-runner.js +1115 -185
  145. package/dist/core/routine-fetch-window-runner.js.map +1 -1
  146. package/dist/core/routine-windows.d.ts +19 -4
  147. package/dist/core/routine-windows.d.ts.map +1 -1
  148. package/dist/core/routine-windows.js +47 -0
  149. package/dist/core/routine-windows.js.map +1 -1
  150. package/dist/core/scheduler.d.ts +50 -2
  151. package/dist/core/scheduler.d.ts.map +1 -1
  152. package/dist/core/scheduler.js +88 -7
  153. package/dist/core/scheduler.js.map +1 -1
  154. package/dist/core/skill-curation/declarations.d.ts.map +1 -1
  155. package/dist/core/skill-curation/declarations.js +11 -12
  156. package/dist/core/skill-curation/declarations.js.map +1 -1
  157. package/dist/core/skill-source-paths.d.ts +14 -0
  158. package/dist/core/skill-source-paths.d.ts.map +1 -0
  159. package/dist/core/skill-source-paths.js +82 -0
  160. package/dist/core/skill-source-paths.js.map +1 -0
  161. package/dist/core/skills-compiler.d.ts +18 -0
  162. package/dist/core/skills-compiler.d.ts.map +1 -1
  163. package/dist/core/skills-compiler.js +65 -18
  164. package/dist/core/skills-compiler.js.map +1 -1
  165. package/dist/core/skills-manifest.d.ts.map +1 -1
  166. package/dist/core/skills-manifest.js +46 -0
  167. package/dist/core/skills-manifest.js.map +1 -1
  168. package/dist/core/system-reset.d.ts +25 -0
  169. package/dist/core/system-reset.d.ts.map +1 -1
  170. package/dist/core/system-reset.js +47 -0
  171. package/dist/core/system-reset.js.map +1 -1
  172. package/dist/core/wiki/approval-queue.d.ts +31 -0
  173. package/dist/core/wiki/approval-queue.d.ts.map +1 -0
  174. package/dist/core/wiki/approval-queue.js +44 -0
  175. package/dist/core/wiki/approval-queue.js.map +1 -0
  176. package/dist/core/wiki/bridge.d.ts +74 -0
  177. package/dist/core/wiki/bridge.d.ts.map +1 -0
  178. package/dist/core/wiki/bridge.js +405 -0
  179. package/dist/core/wiki/bridge.js.map +1 -0
  180. package/dist/core/wiki/compile-lock.d.ts +42 -0
  181. package/dist/core/wiki/compile-lock.d.ts.map +1 -0
  182. package/dist/core/wiki/compile-lock.js +55 -0
  183. package/dist/core/wiki/compile-lock.js.map +1 -0
  184. package/dist/core/wiki/compile-preview.d.ts +8 -0
  185. package/dist/core/wiki/compile-preview.d.ts.map +1 -0
  186. package/dist/core/wiki/compile-preview.js +200 -0
  187. package/dist/core/wiki/compile-preview.js.map +1 -0
  188. package/dist/core/wiki/cost-estimate.d.ts +30 -0
  189. package/dist/core/wiki/cost-estimate.d.ts.map +1 -0
  190. package/dist/core/wiki/cost-estimate.js +243 -0
  191. package/dist/core/wiki/cost-estimate.js.map +1 -0
  192. package/dist/core/wiki/dispatcher.d.ts +48 -0
  193. package/dist/core/wiki/dispatcher.d.ts.map +1 -0
  194. package/dist/core/wiki/dispatcher.js +92 -0
  195. package/dist/core/wiki/dispatcher.js.map +1 -0
  196. package/dist/core/wiki/git-precompile.d.ts +86 -0
  197. package/dist/core/wiki/git-precompile.d.ts.map +1 -0
  198. package/dist/core/wiki/git-precompile.js +96 -0
  199. package/dist/core/wiki/git-precompile.js.map +1 -0
  200. package/dist/core/wiki/import-migrate.d.ts +38 -0
  201. package/dist/core/wiki/import-migrate.d.ts.map +1 -0
  202. package/dist/core/wiki/import-migrate.js +310 -0
  203. package/dist/core/wiki/import-migrate.js.map +1 -0
  204. package/dist/core/wiki/import-probe.d.ts +76 -0
  205. package/dist/core/wiki/import-probe.d.ts.map +1 -0
  206. package/dist/core/wiki/import-probe.js +245 -0
  207. package/dist/core/wiki/import-probe.js.map +1 -0
  208. package/dist/core/wiki/index-cache.d.ts +39 -0
  209. package/dist/core/wiki/index-cache.d.ts.map +1 -0
  210. package/dist/core/wiki/index-cache.js +152 -0
  211. package/dist/core/wiki/index-cache.js.map +1 -0
  212. package/dist/core/wiki/multi-url-dispatch.d.ts +52 -0
  213. package/dist/core/wiki/multi-url-dispatch.d.ts.map +1 -0
  214. package/dist/core/wiki/multi-url-dispatch.js +72 -0
  215. package/dist/core/wiki/multi-url-dispatch.js.map +1 -0
  216. package/dist/core/wiki/wiki-fts.d.ts +75 -0
  217. package/dist/core/wiki/wiki-fts.d.ts.map +1 -0
  218. package/dist/core/wiki/wiki-fts.js +265 -0
  219. package/dist/core/wiki/wiki-fts.js.map +1 -0
  220. package/dist/core/wiki/workspaces.d.ts +101 -0
  221. package/dist/core/wiki/workspaces.d.ts.map +1 -0
  222. package/dist/core/wiki/workspaces.js +352 -0
  223. package/dist/core/wiki/workspaces.js.map +1 -0
  224. package/dist/core/wiki/write-strategy.d.ts +70 -0
  225. package/dist/core/wiki/write-strategy.d.ts.map +1 -0
  226. package/dist/core/wiki/write-strategy.js +112 -0
  227. package/dist/core/wiki/write-strategy.js.map +1 -0
  228. package/dist/core/workdir.d.ts +8 -1
  229. package/dist/core/workdir.d.ts.map +1 -1
  230. package/dist/core/workdir.js +4 -1
  231. package/dist/core/workdir.js.map +1 -1
  232. package/dist/db/schema.d.ts.map +1 -1
  233. package/dist/db/schema.js +122 -0
  234. package/dist/db/schema.js.map +1 -1
  235. package/dist/db/wiki-store.d.ts +3 -0
  236. package/dist/db/wiki-store.d.ts.map +1 -0
  237. package/dist/db/wiki-store.js +7 -0
  238. package/dist/db/wiki-store.js.map +1 -0
  239. package/dist/index.js +80 -4
  240. package/dist/index.js.map +1 -1
  241. package/dist/messaging/url-extract.d.ts +8 -0
  242. package/dist/messaging/url-extract.d.ts.map +1 -0
  243. package/dist/messaging/url-extract.js +41 -0
  244. package/dist/messaging/url-extract.js.map +1 -0
  245. package/dist/observers/delegated-sync-worker.d.ts +33 -25
  246. package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
  247. package/dist/observers/delegated-sync-worker.js +38 -31
  248. package/dist/observers/delegated-sync-worker.js.map +1 -1
  249. package/dist/observers/imminent-event-scheduler.d.ts +20 -7
  250. package/dist/observers/imminent-event-scheduler.d.ts.map +1 -1
  251. package/dist/observers/imminent-event-scheduler.js +134 -29
  252. package/dist/observers/imminent-event-scheduler.js.map +1 -1
  253. package/dist/safety/always-disallowed.d.ts +65 -0
  254. package/dist/safety/always-disallowed.d.ts.map +1 -1
  255. package/dist/safety/always-disallowed.js +106 -10
  256. package/dist/safety/always-disallowed.js.map +1 -1
  257. package/dist/safety/audit.d.ts +46 -1
  258. package/dist/safety/audit.d.ts.map +1 -1
  259. package/dist/safety/audit.js +79 -16
  260. package/dist/safety/audit.js.map +1 -1
  261. package/dist/safety/risk-classifier.d.ts.map +1 -1
  262. package/dist/safety/risk-classifier.js +29 -0
  263. package/dist/safety/risk-classifier.js.map +1 -1
  264. package/dist/settings/runtime-settings.d.ts +12 -1
  265. package/dist/settings/runtime-settings.d.ts.map +1 -1
  266. package/dist/settings/runtime-settings.js +59 -1
  267. package/dist/settings/runtime-settings.js.map +1 -1
  268. package/package.json +2 -2
@@ -0,0 +1,245 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync, } from "node:fs";
2
+ import { join, relative } from "node:path";
3
+ const LAYER_DIRS = ["00_inbox", "10_raw", "20_wiki", "30_outputs", "90_meta"];
4
+ const EXPECTED_SCHEMAS = {
5
+ raw: ["title", "url", "captured_at", "type", "tags"],
6
+ wiki: ["title", "type", "status", "tags", "source", "created"],
7
+ output: ["title", "type", "generated_at", "sources", "tags"],
8
+ };
9
+ export function probeExistingWikiVault(rootPath) {
10
+ const layers = LAYER_DIRS.map((dir) => inventoryLayer(rootPath, dir));
11
+ const existingLayerCount = layers.filter((layer) => layer.exists).length;
12
+ let kind = "empty";
13
+ if (existingLayerCount >= 2) {
14
+ kind = "wiki";
15
+ }
16
+ else if (existingLayerCount === 1) {
17
+ kind = hasMarkdownFiles(rootPath) ? "partial" : "empty";
18
+ }
19
+ else if (hasMarkdownFiles(rootPath)) {
20
+ kind = "partial";
21
+ }
22
+ const schemas = computeSchemaDeltas(rootPath);
23
+ const topTypes = collectTopTypeValues(rootPath, layers);
24
+ const unexpectedSubdirectories = layers.flatMap((layer) => layer.subdirectories
25
+ .filter((sub) => !isExpectedSubdir(layer.dir, sub))
26
+ .map((sub) => ({ layer: layer.dir, subdir: sub })));
27
+ return {
28
+ rootPath,
29
+ kind,
30
+ layers,
31
+ schemas,
32
+ topTypes,
33
+ unexpectedSubdirectories,
34
+ taxonomyPresent: existsAsFile(join(rootPath, "90_meta/taxonomy.md")),
35
+ indexPresent: existsAsFile(join(rootPath, "20_wiki/_index.md")),
36
+ isGitRepo: isGitRepository(rootPath),
37
+ };
38
+ }
39
+ function inventoryLayer(rootPath, dir) {
40
+ const full = join(rootPath, dir);
41
+ if (!existsSync(full)) {
42
+ return {
43
+ dir,
44
+ exists: false,
45
+ isSymlink: false,
46
+ fileCount: 0,
47
+ subdirectories: [],
48
+ lastModifiedAt: null,
49
+ };
50
+ }
51
+ let stat;
52
+ try {
53
+ stat = statSync(full);
54
+ }
55
+ catch {
56
+ return {
57
+ dir,
58
+ exists: false,
59
+ isSymlink: false,
60
+ fileCount: 0,
61
+ subdirectories: [],
62
+ lastModifiedAt: null,
63
+ };
64
+ }
65
+ let lastModifiedAt = null;
66
+ let fileCount = 0;
67
+ const subdirectories = [];
68
+ for (const entry of readdirSync(full, { withFileTypes: true })) {
69
+ const childPath = join(full, entry.name);
70
+ if (entry.isDirectory()) {
71
+ subdirectories.push(entry.name);
72
+ }
73
+ else if (entry.isFile() && entry.name.endsWith(".md")) {
74
+ fileCount += 1;
75
+ try {
76
+ const childStat = statSync(childPath);
77
+ const iso = childStat.mtime.toISOString();
78
+ if (!lastModifiedAt || iso > lastModifiedAt)
79
+ lastModifiedAt = iso;
80
+ }
81
+ catch {
82
+ /* skip unreadable file */
83
+ }
84
+ }
85
+ }
86
+ return {
87
+ dir,
88
+ exists: true,
89
+ isSymlink: stat.isSymbolicLink(),
90
+ fileCount,
91
+ subdirectories: subdirectories.sort(),
92
+ lastModifiedAt,
93
+ };
94
+ }
95
+ function hasMarkdownFiles(rootPath) {
96
+ if (!existsSync(rootPath))
97
+ return false;
98
+ for (const entry of readdirSync(rootPath, { withFileTypes: true })) {
99
+ if (entry.isFile() && entry.name.endsWith(".md"))
100
+ return true;
101
+ }
102
+ return false;
103
+ }
104
+ function computeSchemaDeltas(rootPath) {
105
+ return Object.keys(EXPECTED_SCHEMAS).map((schema) => {
106
+ const path = join(rootPath, `90_meta/schemas/${schema}.md`);
107
+ if (!existsAsFile(path)) {
108
+ return {
109
+ schema,
110
+ present: false,
111
+ expectedKeys: EXPECTED_SCHEMAS[schema],
112
+ foundKeys: [],
113
+ missingKeys: EXPECTED_SCHEMAS[schema],
114
+ extraKeys: [],
115
+ };
116
+ }
117
+ const content = readFileSafely(path);
118
+ const found = extractFrontmatterKeys(content);
119
+ const expected = EXPECTED_SCHEMAS[schema];
120
+ return {
121
+ schema,
122
+ present: true,
123
+ expectedKeys: expected,
124
+ foundKeys: found,
125
+ missingKeys: expected.filter((key) => !found.includes(key)),
126
+ extraKeys: found.filter((key) => !expected.includes(key)),
127
+ };
128
+ });
129
+ }
130
+ function collectTopTypeValues(rootPath, layers) {
131
+ const counts = new Map();
132
+ for (const layer of layers) {
133
+ if (!layer.exists)
134
+ continue;
135
+ const dir = join(rootPath, layer.dir);
136
+ for (const file of walkMarkdown(dir)) {
137
+ const text = readFileSafely(file);
138
+ const value = extractFrontmatterValue(text, "type");
139
+ if (!value)
140
+ continue;
141
+ counts.set(value, (counts.get(value) ?? 0) + 1);
142
+ }
143
+ }
144
+ return [...counts.entries()]
145
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
146
+ .slice(0, 20)
147
+ .map(([value, count]) => ({ value, count }));
148
+ }
149
+ function isExpectedSubdir(layer, sub) {
150
+ if (layer === "10_raw")
151
+ return sub === "images";
152
+ if (layer === "90_meta")
153
+ return sub === "schemas" || sub === "health";
154
+ return false;
155
+ }
156
+ function existsAsFile(path) {
157
+ try {
158
+ return existsSync(path) && statSync(path).isFile();
159
+ }
160
+ catch {
161
+ return false;
162
+ }
163
+ }
164
+ function readFileSafely(path) {
165
+ try {
166
+ return readFileSync(path, "utf-8");
167
+ }
168
+ catch {
169
+ return "";
170
+ }
171
+ }
172
+ function isGitRepository(rootPath) {
173
+ const gitDir = join(rootPath, ".git");
174
+ if (!existsSync(gitDir))
175
+ return false;
176
+ try {
177
+ const stat = statSync(gitDir);
178
+ return stat.isDirectory() || stat.isFile();
179
+ }
180
+ catch {
181
+ return false;
182
+ }
183
+ }
184
+ const FRONTMATTER_DELIMITER = "---";
185
+ export function extractFrontmatter(content) {
186
+ if (!content.startsWith(FRONTMATTER_DELIMITER))
187
+ return null;
188
+ const lines = content.split(/\r?\n/);
189
+ if (lines[0] !== FRONTMATTER_DELIMITER)
190
+ return null;
191
+ const endIdx = lines.findIndex((line, idx) => idx > 0 && line === FRONTMATTER_DELIMITER);
192
+ if (endIdx < 0)
193
+ return null;
194
+ const map = {};
195
+ for (let i = 1; i < endIdx; i += 1) {
196
+ const raw = lines[i];
197
+ if (!raw.trim() || raw.trimStart().startsWith("#"))
198
+ continue;
199
+ // We only support flat scalar `key: value` lines — Bases-era schema (§2.4).
200
+ const match = /^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/.exec(raw);
201
+ if (!match)
202
+ continue;
203
+ const [, key, valueRaw] = match;
204
+ map[key] = valueRaw.trim();
205
+ }
206
+ return map;
207
+ }
208
+ function extractFrontmatterKeys(content) {
209
+ const fm = extractFrontmatter(content);
210
+ return fm ? Object.keys(fm) : [];
211
+ }
212
+ function extractFrontmatterValue(content, key) {
213
+ const fm = extractFrontmatter(content);
214
+ if (!fm)
215
+ return null;
216
+ const value = fm[key];
217
+ if (!value)
218
+ return null;
219
+ // Strip surrounding quotes if present.
220
+ return value.replace(/^['"]|['"]$/g, "").trim();
221
+ }
222
+ function* walkMarkdown(rootDir) {
223
+ if (!existsSync(rootDir))
224
+ return;
225
+ let entries;
226
+ try {
227
+ entries = readdirSync(rootDir, { withFileTypes: true });
228
+ }
229
+ catch {
230
+ return;
231
+ }
232
+ for (const entry of entries) {
233
+ const full = join(rootDir, entry.name);
234
+ if (entry.isDirectory()) {
235
+ yield* walkMarkdown(full);
236
+ }
237
+ else if (entry.isFile() && entry.name.endsWith(".md")) {
238
+ yield full;
239
+ }
240
+ }
241
+ }
242
+ export function formatProbeRelativePath(rootPath, abs) {
243
+ return relative(rootPath, abs).split(/[\\/]/).join("/");
244
+ }
245
+ //# sourceMappingURL=import-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-probe.js","sourceRoot":"","sources":["../../../src/core/wiki/import-probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { WikiWorkspaceRow } from "./workspaces.js";
2
+ export interface WikiIndexSnapshot {
3
+ exists: boolean;
4
+ /** Raw markdown contents — present only when `exists` is true. */
5
+ content: string | null;
6
+ /** mtimeMs from the underlying file — for cache freshness assertions. */
7
+ mtimeMs: number | null;
8
+ /** When this snapshot was loaded from disk. */
9
+ loadedAtMs: number;
10
+ }
11
+ export declare class WikiIndexCache {
12
+ private readonly entries;
13
+ /**
14
+ * Read the cached snapshot, populating from disk on a miss / staleness.
15
+ * Returns a `{ exists: false }` snapshot when the workspace is not
16
+ * external (the caller is expected to short-circuit before reaching
17
+ * here, but this is a safe no-op for them too).
18
+ */
19
+ get(workspace: WikiWorkspaceRow): WikiIndexSnapshot;
20
+ /**
21
+ * Force a re-read from disk. Used by chokidar callbacks and by the
22
+ * write path immediately after an `_index.md` mutation so the next
23
+ * reader observes the just-written content.
24
+ */
25
+ refresh(workspace: WikiWorkspaceRow): WikiIndexSnapshot;
26
+ /**
27
+ * Invalidate the cached snapshot without re-reading. Useful when the
28
+ * write path knows the watcher is about to fire and wants the next
29
+ * reader to observe the post-write state without two reads in a row.
30
+ */
31
+ invalidate(workspaceId: number): void;
32
+ /**
33
+ * Tear down a workspace's cache + watcher. Called by the workspace
34
+ * deactivation path so an archived workspace no longer holds an fd.
35
+ */
36
+ release(workspaceId: number): Promise<void>;
37
+ shutdown(): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=index-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-cache.d.ts","sourceRoot":"","sources":["../../../src/core/wiki/index-cache.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AA6BxD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,yEAAyE;IACzE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;CACpB;AASD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IAEpD;;;;;OAKG;IACH,GAAG,CAAC,SAAS,EAAE,gBAAgB,GAAG,iBAAiB;IAWnD;;;;OAIG;IACH,OAAO,CAAC,SAAS,EAAE,gBAAgB,GAAG,iBAAiB;IAmDvD;;;;OAIG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMrC;;;OAGG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB3C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAIhC"}
@@ -0,0 +1,152 @@
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import * as chokidar from "chokidar";
4
+ import { createLogger } from "../../logging.js";
5
+ const logger = createLogger("wiki-index-cache");
6
+ /**
7
+ * Per-workspace in-process cache of `20_wiki/_index.md`.
8
+ *
9
+ * WIKI_BUILDER_DESIGN.md §14 Q6 — external-mode workspaces only.
10
+ * Internal-mode reads hit a local SSD inside dataDir, so the chokidar
11
+ * + TTL bookkeeping is a net cost and the manager refuses to register
12
+ * a watcher there.
13
+ *
14
+ * Invalidation:
15
+ * - chokidar watcher rooted on `<root>/20_wiki/_index.md` for fs events
16
+ * (the canonical signal once the file exists on disk).
17
+ * - 5-minute TTL fallback covers iCloud-FUSE missed events; iCloud and
18
+ * similar FUSE filesystems are known to occasionally drop change
19
+ * notifications, so a stale TTL is the belt-and-braces guard.
20
+ *
21
+ * The cache is read-through: a miss reads from disk + reparses; a hit
22
+ * returns the cached parsed snapshot.
23
+ *
24
+ * Note: this module is intentionally tolerant of the index file not
25
+ * existing yet. A freshly-seeded workspace has no `_index.md` until the
26
+ * first `wiki.compile` writes one, and consumers should observe a
27
+ * `{ exists: false }` snapshot in that window rather than throwing.
28
+ */
29
+ const TTL_MS = 5 * 60 * 1000;
30
+ export class WikiIndexCache {
31
+ entries = new Map();
32
+ /**
33
+ * Read the cached snapshot, populating from disk on a miss / staleness.
34
+ * Returns a `{ exists: false }` snapshot when the workspace is not
35
+ * external (the caller is expected to short-circuit before reaching
36
+ * here, but this is a safe no-op for them too).
37
+ */
38
+ get(workspace) {
39
+ if (workspace.kind !== "external") {
40
+ return readSnapshotFromDisk(workspace);
41
+ }
42
+ const existing = this.entries.get(workspace.id);
43
+ if (existing && existing.expiresAtMs > Date.now()) {
44
+ return existing.snapshot;
45
+ }
46
+ return this.refresh(workspace);
47
+ }
48
+ /**
49
+ * Force a re-read from disk. Used by chokidar callbacks and by the
50
+ * write path immediately after an `_index.md` mutation so the next
51
+ * reader observes the just-written content.
52
+ */
53
+ refresh(workspace) {
54
+ const snapshot = readSnapshotFromDisk(workspace);
55
+ const expiresAtMs = Date.now() + TTL_MS;
56
+ const existing = this.entries.get(workspace.id);
57
+ if (existing) {
58
+ existing.snapshot = snapshot;
59
+ existing.expiresAtMs = expiresAtMs;
60
+ return snapshot;
61
+ }
62
+ const entry = {
63
+ snapshot,
64
+ expiresAtMs,
65
+ watcher: null,
66
+ watchedPath: workspace.kind === "external"
67
+ ? join(workspace.root_path, "20_wiki/_index.md")
68
+ : "",
69
+ };
70
+ if (workspace.kind === "external") {
71
+ try {
72
+ entry.watcher = chokidar
73
+ .watch(entry.watchedPath, {
74
+ ignoreInitial: true,
75
+ persistent: false,
76
+ awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 },
77
+ })
78
+ .on("add", () => {
79
+ this.refresh(workspace);
80
+ })
81
+ .on("change", () => {
82
+ this.refresh(workspace);
83
+ })
84
+ .on("unlink", () => {
85
+ this.refresh(workspace);
86
+ })
87
+ .on("error", (err) => {
88
+ logger.warn({ workspace: workspace.name, err: err instanceof Error ? err.message : String(err) }, "wiki-index-cache watcher error — relying on TTL fallback");
89
+ });
90
+ }
91
+ catch (err) {
92
+ logger.warn({ workspace: workspace.name, err: err instanceof Error ? err.message : String(err) }, "wiki-index-cache failed to start watcher — falling back to TTL only");
93
+ }
94
+ }
95
+ this.entries.set(workspace.id, entry);
96
+ return snapshot;
97
+ }
98
+ /**
99
+ * Invalidate the cached snapshot without re-reading. Useful when the
100
+ * write path knows the watcher is about to fire and wants the next
101
+ * reader to observe the post-write state without two reads in a row.
102
+ */
103
+ invalidate(workspaceId) {
104
+ const entry = this.entries.get(workspaceId);
105
+ if (!entry)
106
+ return;
107
+ entry.expiresAtMs = 0;
108
+ }
109
+ /**
110
+ * Tear down a workspace's cache + watcher. Called by the workspace
111
+ * deactivation path so an archived workspace no longer holds an fd.
112
+ */
113
+ async release(workspaceId) {
114
+ const entry = this.entries.get(workspaceId);
115
+ if (!entry)
116
+ return;
117
+ if (entry.watcher) {
118
+ try {
119
+ await entry.watcher.close();
120
+ }
121
+ catch (err) {
122
+ logger.warn({ err: err instanceof Error ? err.message : String(err) }, "wiki-index-cache failed to close watcher");
123
+ }
124
+ }
125
+ this.entries.delete(workspaceId);
126
+ }
127
+ async shutdown() {
128
+ const ids = [...this.entries.keys()];
129
+ await Promise.all(ids.map((id) => this.release(id)));
130
+ }
131
+ }
132
+ function readSnapshotFromDisk(workspace) {
133
+ const path = join(workspace.root_path, "20_wiki/_index.md");
134
+ if (!existsSync(path)) {
135
+ return { exists: false, content: null, mtimeMs: null, loadedAtMs: Date.now() };
136
+ }
137
+ try {
138
+ const stat = statSync(path);
139
+ const content = readFileSync(path, "utf-8");
140
+ return {
141
+ exists: true,
142
+ content,
143
+ mtimeMs: stat.mtimeMs,
144
+ loadedAtMs: Date.now(),
145
+ };
146
+ }
147
+ catch (err) {
148
+ logger.warn({ workspace: workspace.name, err: err instanceof Error ? err.message : String(err) }, "wiki-index-cache failed to read _index.md");
149
+ return { exists: false, content: null, mtimeMs: null, loadedAtMs: Date.now() };
150
+ }
151
+ }
152
+ //# sourceMappingURL=index-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-cache.js","sourceRoot":"","sources":["../../../src/core/wiki/index-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { Event } from "@aitne/shared";
2
+ export interface DispatchWikiUrlBatchInput {
3
+ workspace: string;
4
+ urls: readonly string[];
5
+ /** Hard cap for the parallel worker pool. Ignored in serial mode. */
6
+ concurrencyCap: number;
7
+ /** `parallel` fans out up to `concurrencyCap`; `serial` enqueues one at a time. */
8
+ mode: "parallel" | "serial";
9
+ sourceEvent?: Event;
10
+ enqueue: (event: Event) => Promise<void>;
11
+ }
12
+ export interface DispatchWikiUrlBatchResult {
13
+ batchId: string;
14
+ queued: number;
15
+ mode: "parallel" | "serial";
16
+ }
17
+ /**
18
+ * Fan out a `!ingest` batch of URLs into one `wiki.ingest_url` event per URL.
19
+ *
20
+ * WIKI_BUILDER_DESIGN.md §3.4 — every URL gets its own session, audit row,
21
+ * and budget envelope. The batch_id grouping (§11.1) lets the dashboard
22
+ * timeline collapse a multi-URL run back into a single user gesture.
23
+ *
24
+ * Modes:
25
+ * - `parallel` (P1 default): a worker pool of `min(concurrencyCap, urls.length)`
26
+ * pulls from the URL queue. Each `enqueue` returns immediately after the
27
+ * EventBus accepts the event; the actual agent sessions run independently
28
+ * inside the dispatcher.
29
+ * - `serial` (added in P2): the enqueue calls happen one after another so
30
+ * the *submitted order* is the *enqueue order*. We deliberately do NOT
31
+ * wait for one session to *complete* before enqueuing the next, because
32
+ * the queue contract is "accept and run".
33
+ *
34
+ * **Known gap (tracked, not blocking P2)**: full completion-ordered
35
+ * execution requires a per-process-key semaphore in the dispatcher,
36
+ * which does not exist today — the dispatcher's only concurrency limit
37
+ * is the global `maxConcurrentSessions` (default 3). With <=3 URLs the
38
+ * global semaphore happens to coincide with serial-enough behaviour;
39
+ * above that, two `wiki.ingest_url` sessions can run in parallel even
40
+ * when `dispatch_mode='serial'`. The heap-order guarantee from this
41
+ * function still holds — only the actual session-start spacing is
42
+ * weaker than the design specifies. A follow-up that adds
43
+ * per-process-key concurrency caps to `process_backend_config` would
44
+ * close this gap; this function is already structured to feed that
45
+ * cap a value of `1` for serial mode.
46
+ *
47
+ * Failure isolation: a thrown error from `enqueue` aborts the rest of the
48
+ * batch in both modes. This matches the existing dispatcher behaviour
49
+ * where a failed enqueue is a daemon-level fault, not a per-URL one.
50
+ */
51
+ export declare function dispatchWikiUrlBatch(input: DispatchWikiUrlBatchInput): Promise<DispatchWikiUrlBatchResult>;
52
+ //# sourceMappingURL=multi-url-dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-url-dispatch.d.ts","sourceRoot":"","sources":["../../../src/core/wiki/multi-url-dispatch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAG3C,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,0BAA0B,CAAC,CA0CrC"}
@@ -0,0 +1,72 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { createWikiCommandEvent } from "./dispatcher.js";
3
+ /**
4
+ * Fan out a `!ingest` batch of URLs into one `wiki.ingest_url` event per URL.
5
+ *
6
+ * WIKI_BUILDER_DESIGN.md §3.4 — every URL gets its own session, audit row,
7
+ * and budget envelope. The batch_id grouping (§11.1) lets the dashboard
8
+ * timeline collapse a multi-URL run back into a single user gesture.
9
+ *
10
+ * Modes:
11
+ * - `parallel` (P1 default): a worker pool of `min(concurrencyCap, urls.length)`
12
+ * pulls from the URL queue. Each `enqueue` returns immediately after the
13
+ * EventBus accepts the event; the actual agent sessions run independently
14
+ * inside the dispatcher.
15
+ * - `serial` (added in P2): the enqueue calls happen one after another so
16
+ * the *submitted order* is the *enqueue order*. We deliberately do NOT
17
+ * wait for one session to *complete* before enqueuing the next, because
18
+ * the queue contract is "accept and run".
19
+ *
20
+ * **Known gap (tracked, not blocking P2)**: full completion-ordered
21
+ * execution requires a per-process-key semaphore in the dispatcher,
22
+ * which does not exist today — the dispatcher's only concurrency limit
23
+ * is the global `maxConcurrentSessions` (default 3). With <=3 URLs the
24
+ * global semaphore happens to coincide with serial-enough behaviour;
25
+ * above that, two `wiki.ingest_url` sessions can run in parallel even
26
+ * when `dispatch_mode='serial'`. The heap-order guarantee from this
27
+ * function still holds — only the actual session-start spacing is
28
+ * weaker than the design specifies. A follow-up that adds
29
+ * per-process-key concurrency caps to `process_backend_config` would
30
+ * close this gap; this function is already structured to feed that
31
+ * cap a value of `1` for serial mode.
32
+ *
33
+ * Failure isolation: a thrown error from `enqueue` aborts the rest of the
34
+ * batch in both modes. This matches the existing dispatcher behaviour
35
+ * where a failed enqueue is a daemon-level fault, not a per-URL one.
36
+ */
37
+ export async function dispatchWikiUrlBatch(input) {
38
+ const batchId = randomUUID();
39
+ const urls = [...input.urls];
40
+ if (urls.length === 0) {
41
+ return { batchId, queued: 0, mode: input.mode };
42
+ }
43
+ if (input.mode === "serial") {
44
+ for (const url of urls) {
45
+ await input.enqueue(createWikiCommandEvent({
46
+ processKey: "wiki.ingest_url",
47
+ workspace: input.workspace,
48
+ sourceEvent: input.sourceEvent,
49
+ batchId,
50
+ data: { url },
51
+ }));
52
+ }
53
+ return { batchId, queued: urls.length, mode: "serial" };
54
+ }
55
+ const cap = Math.max(1, Math.min(10, Math.floor(input.concurrencyCap)));
56
+ let cursor = 0;
57
+ async function worker() {
58
+ while (cursor < urls.length) {
59
+ const url = urls[cursor++];
60
+ await input.enqueue(createWikiCommandEvent({
61
+ processKey: "wiki.ingest_url",
62
+ workspace: input.workspace,
63
+ sourceEvent: input.sourceEvent,
64
+ batchId,
65
+ data: { url },
66
+ }));
67
+ }
68
+ }
69
+ await Promise.all(Array.from({ length: Math.min(cap, urls.length) }, worker));
70
+ return { batchId, queued: urls.length, mode: "parallel" };
71
+ }
72
+ //# sourceMappingURL=multi-url-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-url-dispatch.js","sourceRoot":"","sources":["../../../src/core/wiki/multi-url-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAmBzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAgC;IAEhC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,CAAC,OAAO,CACjB,sBAAsB,CAAC;gBACrB,UAAU,EAAE,iBAAiB;gBAC7B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,OAAO;gBACP,IAAI,EAAE,EAAE,GAAG,EAAE;aACd,CAAC,CACH,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IACxE,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,UAAU,MAAM;QACnB,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3B,MAAM,KAAK,CAAC,OAAO,CACjB,sBAAsB,CAAC;gBACrB,UAAU,EAAE,iBAAiB;gBAC7B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,OAAO;gBACP,IAAI,EAAE,EAAE,GAAG,EAAE;aACd,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC5D,CAAC"}