@cavelang/cli 0.27.14 → 0.29.1

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 (321) hide show
  1. package/Authors.md +5 -0
  2. package/License.md +6 -0
  3. package/README.md +122 -24
  4. package/dist/internal/act/action.d.ts +69 -0
  5. package/dist/internal/act/action.d.ts.map +1 -0
  6. package/dist/internal/act/action.js +201 -0
  7. package/dist/internal/act/action.js.map +1 -0
  8. package/dist/internal/act/declare.d.ts +102 -0
  9. package/dist/internal/act/declare.d.ts.map +1 -0
  10. package/dist/internal/act/declare.js +270 -0
  11. package/dist/internal/act/declare.js.map +1 -0
  12. package/dist/internal/act/engine.d.ts +103 -0
  13. package/dist/internal/act/engine.d.ts.map +1 -0
  14. package/dist/internal/act/engine.js +298 -0
  15. package/dist/internal/act/engine.js.map +1 -0
  16. package/dist/internal/act/index.d.ts +27 -0
  17. package/dist/internal/act/index.d.ts.map +1 -0
  18. package/dist/internal/act/index.js +25 -0
  19. package/dist/internal/act/index.js.map +1 -0
  20. package/dist/internal/automate/automation.d.ts +78 -0
  21. package/dist/internal/automate/automation.d.ts.map +1 -0
  22. package/dist/internal/automate/automation.js +135 -0
  23. package/dist/internal/automate/automation.js.map +1 -0
  24. package/dist/internal/automate/declare.d.ts +84 -0
  25. package/dist/internal/automate/declare.d.ts.map +1 -0
  26. package/dist/internal/automate/declare.js +233 -0
  27. package/dist/internal/automate/declare.js.map +1 -0
  28. package/dist/internal/automate/engine.d.ts +125 -0
  29. package/dist/internal/automate/engine.d.ts.map +1 -0
  30. package/dist/internal/automate/engine.js +388 -0
  31. package/dist/internal/automate/engine.js.map +1 -0
  32. package/dist/internal/automate/index.d.ts +28 -0
  33. package/dist/internal/automate/index.d.ts.map +1 -0
  34. package/dist/internal/automate/index.js +26 -0
  35. package/dist/internal/automate/index.js.map +1 -0
  36. package/dist/internal/automate/main.d.ts +26 -0
  37. package/dist/internal/automate/main.d.ts.map +1 -0
  38. package/dist/internal/automate/main.js +298 -0
  39. package/dist/internal/automate/main.js.map +1 -0
  40. package/dist/internal/connect/index.d.ts +26 -0
  41. package/dist/internal/connect/index.d.ts.map +1 -0
  42. package/dist/internal/connect/index.js +24 -0
  43. package/dist/internal/connect/index.js.map +1 -0
  44. package/dist/internal/connect/main.d.ts +23 -0
  45. package/dist/internal/connect/main.d.ts.map +1 -0
  46. package/dist/internal/connect/main.js +330 -0
  47. package/dist/internal/connect/main.js.map +1 -0
  48. package/dist/internal/connect/run.d.ts +85 -0
  49. package/dist/internal/connect/run.d.ts.map +1 -0
  50. package/dist/internal/connect/run.js +242 -0
  51. package/dist/internal/connect/run.js.map +1 -0
  52. package/dist/internal/connect/source.d.ts +44 -0
  53. package/dist/internal/connect/source.d.ts.map +1 -0
  54. package/dist/internal/connect/source.js +215 -0
  55. package/dist/internal/connect/source.js.map +1 -0
  56. package/dist/internal/connect/template.d.ts +69 -0
  57. package/dist/internal/connect/template.d.ts.map +1 -0
  58. package/dist/internal/connect/template.js +221 -0
  59. package/dist/internal/connect/template.js.map +1 -0
  60. package/dist/internal/eval/index.d.ts +28 -0
  61. package/dist/internal/eval/index.d.ts.map +1 -0
  62. package/dist/internal/eval/index.js +27 -0
  63. package/dist/internal/eval/index.js.map +1 -0
  64. package/dist/internal/eval/judge.d.ts +30 -0
  65. package/dist/internal/eval/judge.d.ts.map +1 -0
  66. package/dist/internal/eval/judge.js +101 -0
  67. package/dist/internal/eval/judge.js.map +1 -0
  68. package/dist/internal/eval/loop.d.ts +64 -0
  69. package/dist/internal/eval/loop.d.ts.map +1 -0
  70. package/dist/internal/eval/loop.js +123 -0
  71. package/dist/internal/eval/loop.js.map +1 -0
  72. package/dist/internal/eval/main.d.ts +17 -0
  73. package/dist/internal/eval/main.d.ts.map +1 -0
  74. package/dist/internal/eval/main.js +236 -0
  75. package/dist/internal/eval/main.js.map +1 -0
  76. package/dist/internal/eval/queries.d.ts +74 -0
  77. package/dist/internal/eval/queries.d.ts.map +1 -0
  78. package/dist/internal/eval/queries.js +161 -0
  79. package/dist/internal/eval/queries.js.map +1 -0
  80. package/dist/internal/eval/run.d.ts +143 -0
  81. package/dist/internal/eval/run.d.ts.map +1 -0
  82. package/dist/internal/eval/run.js +376 -0
  83. package/dist/internal/eval/run.js.map +1 -0
  84. package/dist/internal/eval/score.d.ts +81 -0
  85. package/dist/internal/eval/score.d.ts.map +1 -0
  86. package/dist/internal/eval/score.js +126 -0
  87. package/dist/internal/eval/score.js.map +1 -0
  88. package/dist/internal/eval/suite.d.ts +66 -0
  89. package/dist/internal/eval/suite.d.ts.map +1 -0
  90. package/dist/internal/eval/suite.js +130 -0
  91. package/dist/internal/eval/suite.js.map +1 -0
  92. package/dist/internal/ingest/context.d.ts +20 -0
  93. package/dist/internal/ingest/context.d.ts.map +1 -0
  94. package/dist/internal/ingest/context.js +59 -0
  95. package/dist/internal/ingest/context.js.map +1 -0
  96. package/dist/internal/ingest/files.d.ts +46 -0
  97. package/dist/internal/ingest/files.d.ts.map +1 -0
  98. package/dist/internal/ingest/files.js +115 -0
  99. package/dist/internal/ingest/files.js.map +1 -0
  100. package/dist/internal/ingest/index.d.ts +31 -0
  101. package/dist/internal/ingest/index.d.ts.map +1 -0
  102. package/dist/internal/ingest/index.js +29 -0
  103. package/dist/internal/ingest/index.js.map +1 -0
  104. package/dist/internal/ingest/main.d.ts +12 -0
  105. package/dist/internal/ingest/main.d.ts.map +1 -0
  106. package/dist/internal/ingest/main.js +180 -0
  107. package/dist/internal/ingest/main.js.map +1 -0
  108. package/dist/internal/ingest/prompt.d.ts +32 -0
  109. package/dist/internal/ingest/prompt.d.ts.map +1 -0
  110. package/dist/internal/ingest/prompt.js +75 -0
  111. package/dist/internal/ingest/prompt.js.map +1 -0
  112. package/dist/internal/ingest/run.d.ts +142 -0
  113. package/dist/internal/ingest/run.d.ts.map +1 -0
  114. package/dist/internal/ingest/run.js +350 -0
  115. package/dist/internal/ingest/run.js.map +1 -0
  116. package/dist/internal/ingest/web.d.ts +48 -0
  117. package/dist/internal/ingest/web.d.ts.map +1 -0
  118. package/dist/internal/ingest/web.js +140 -0
  119. package/dist/internal/ingest/web.js.map +1 -0
  120. package/dist/internal/loop/demo.d.ts +22 -0
  121. package/dist/internal/loop/demo.d.ts.map +1 -0
  122. package/dist/internal/loop/demo.js +67 -0
  123. package/dist/internal/loop/demo.js.map +1 -0
  124. package/dist/internal/loop/index.d.ts +20 -0
  125. package/dist/internal/loop/index.d.ts.map +1 -0
  126. package/dist/internal/loop/index.js +17 -0
  127. package/dist/internal/loop/index.js.map +1 -0
  128. package/dist/internal/loop/llm.d.ts +99 -0
  129. package/dist/internal/loop/llm.d.ts.map +1 -0
  130. package/dist/internal/loop/llm.js +231 -0
  131. package/dist/internal/loop/llm.js.map +1 -0
  132. package/dist/internal/loop/reconstruct.d.ts +87 -0
  133. package/dist/internal/loop/reconstruct.d.ts.map +1 -0
  134. package/dist/internal/loop/reconstruct.js +157 -0
  135. package/dist/internal/loop/reconstruct.js.map +1 -0
  136. package/dist/internal/loop/sqlite.d.ts +13 -0
  137. package/dist/internal/loop/sqlite.d.ts.map +1 -0
  138. package/dist/internal/loop/sqlite.js +33 -0
  139. package/dist/internal/loop/sqlite.js.map +1 -0
  140. package/dist/internal/loop/store.d.ts +50 -0
  141. package/dist/internal/loop/store.d.ts.map +1 -0
  142. package/dist/internal/loop/store.js +100 -0
  143. package/dist/internal/loop/store.js.map +1 -0
  144. package/dist/internal/mcp/bin.d.ts +7 -0
  145. package/dist/internal/mcp/bin.d.ts.map +1 -0
  146. package/dist/internal/mcp/bin.js +8 -0
  147. package/dist/internal/mcp/bin.js.map +1 -0
  148. package/dist/internal/mcp/index.d.ts +25 -0
  149. package/dist/internal/mcp/index.d.ts.map +1 -0
  150. package/dist/internal/mcp/index.js +23 -0
  151. package/dist/internal/mcp/index.js.map +1 -0
  152. package/dist/internal/mcp/main.d.ts +23 -0
  153. package/dist/internal/mcp/main.d.ts.map +1 -0
  154. package/dist/internal/mcp/main.js +156 -0
  155. package/dist/internal/mcp/main.js.map +1 -0
  156. package/dist/internal/mcp/server.d.ts +92 -0
  157. package/dist/internal/mcp/server.d.ts.map +1 -0
  158. package/dist/internal/mcp/server.js +251 -0
  159. package/dist/internal/mcp/server.js.map +1 -0
  160. package/dist/internal/mcp/tools.d.ts +91 -0
  161. package/dist/internal/mcp/tools.d.ts.map +1 -0
  162. package/dist/internal/mcp/tools.js +584 -0
  163. package/dist/internal/mcp/tools.js.map +1 -0
  164. package/dist/internal/rules/declare.d.ts +58 -0
  165. package/dist/internal/rules/declare.d.ts.map +1 -0
  166. package/dist/internal/rules/declare.js +152 -0
  167. package/dist/internal/rules/declare.js.map +1 -0
  168. package/dist/internal/rules/engine.d.ts +125 -0
  169. package/dist/internal/rules/engine.d.ts.map +1 -0
  170. package/dist/internal/rules/engine.js +575 -0
  171. package/dist/internal/rules/engine.js.map +1 -0
  172. package/dist/internal/rules/index.d.ts +23 -0
  173. package/dist/internal/rules/index.d.ts.map +1 -0
  174. package/dist/internal/rules/index.js +21 -0
  175. package/dist/internal/rules/index.js.map +1 -0
  176. package/dist/internal/rules/rule.d.ts +88 -0
  177. package/dist/internal/rules/rule.d.ts.map +1 -0
  178. package/dist/internal/rules/rule.js +221 -0
  179. package/dist/internal/rules/rule.js.map +1 -0
  180. package/dist/internal/shape/check.d.ts +118 -0
  181. package/dist/internal/shape/check.d.ts.map +1 -0
  182. package/dist/internal/shape/check.js +331 -0
  183. package/dist/internal/shape/check.js.map +1 -0
  184. package/dist/internal/shape/client.d.ts +31 -0
  185. package/dist/internal/shape/client.d.ts.map +1 -0
  186. package/dist/internal/shape/client.js +170 -0
  187. package/dist/internal/shape/client.js.map +1 -0
  188. package/dist/internal/shape/gate.d.ts +33 -0
  189. package/dist/internal/shape/gate.d.ts.map +1 -0
  190. package/dist/internal/shape/gate.js +0 -0
  191. package/dist/internal/shape/gate.js.map +1 -0
  192. package/dist/internal/shape/index.d.ts +27 -0
  193. package/dist/internal/shape/index.d.ts.map +1 -0
  194. package/dist/internal/shape/index.js +23 -0
  195. package/dist/internal/shape/index.js.map +1 -0
  196. package/dist/internal/shape/suggest.d.ts +82 -0
  197. package/dist/internal/shape/suggest.d.ts.map +1 -0
  198. package/dist/internal/shape/suggest.js +374 -0
  199. package/dist/internal/shape/suggest.js.map +1 -0
  200. package/dist/internal/sync/index.d.ts +22 -0
  201. package/dist/internal/sync/index.d.ts.map +1 -0
  202. package/dist/internal/sync/index.js +21 -0
  203. package/dist/internal/sync/index.js.map +1 -0
  204. package/dist/internal/sync/sync.d.ts +95 -0
  205. package/dist/internal/sync/sync.d.ts.map +1 -0
  206. package/dist/internal/sync/sync.js +342 -0
  207. package/dist/internal/sync/sync.js.map +1 -0
  208. package/dist/internal/view/api.d.ts +196 -0
  209. package/dist/internal/view/api.d.ts.map +1 -0
  210. package/dist/internal/view/api.js +189 -0
  211. package/dist/internal/view/api.js.map +1 -0
  212. package/dist/internal/view/index.d.ts +33 -0
  213. package/dist/internal/view/index.d.ts.map +1 -0
  214. package/dist/internal/view/index.js +30 -0
  215. package/dist/internal/view/index.js.map +1 -0
  216. package/dist/internal/view/main.d.ts +11 -0
  217. package/dist/internal/view/main.d.ts.map +1 -0
  218. package/dist/internal/view/main.js +98 -0
  219. package/dist/internal/view/main.js.map +1 -0
  220. package/dist/internal/view/page.d.ts +14 -0
  221. package/dist/internal/view/page.d.ts.map +1 -0
  222. package/dist/internal/view/page.js +370 -0
  223. package/dist/internal/view/page.js.map +1 -0
  224. package/dist/internal/view/report.d.ts +52 -0
  225. package/dist/internal/view/report.d.ts.map +1 -0
  226. package/dist/internal/view/report.js +367 -0
  227. package/dist/internal/view/report.js.map +1 -0
  228. package/dist/internal/view/scope.d.ts +11 -0
  229. package/dist/internal/view/scope.d.ts.map +1 -0
  230. package/dist/internal/view/scope.js +41 -0
  231. package/dist/internal/view/scope.js.map +1 -0
  232. package/dist/internal/view/server.d.ts +35 -0
  233. package/dist/internal/view/server.d.ts.map +1 -0
  234. package/dist/internal/view/server.js +141 -0
  235. package/dist/internal/view/server.js.map +1 -0
  236. package/dist/src/act.d.ts +3 -0
  237. package/dist/src/act.d.ts.map +1 -0
  238. package/dist/src/act.js +3 -0
  239. package/dist/src/act.js.map +1 -0
  240. package/dist/src/automate.d.ts +3 -0
  241. package/dist/src/automate.d.ts.map +1 -0
  242. package/dist/src/automate.js +3 -0
  243. package/dist/src/automate.js.map +1 -0
  244. package/dist/src/cli.d.ts +24 -17
  245. package/dist/src/cli.d.ts.map +1 -1
  246. package/dist/src/cli.js +408 -107
  247. package/dist/src/cli.js.map +1 -1
  248. package/dist/src/commands.d.ts +104 -0
  249. package/dist/src/commands.d.ts.map +1 -0
  250. package/dist/src/commands.js +33 -0
  251. package/dist/src/commands.js.map +1 -0
  252. package/dist/src/connect.d.ts +3 -0
  253. package/dist/src/connect.d.ts.map +1 -0
  254. package/dist/src/connect.js +3 -0
  255. package/dist/src/connect.js.map +1 -0
  256. package/dist/src/dispatch.d.ts +14 -0
  257. package/dist/src/dispatch.d.ts.map +1 -0
  258. package/dist/src/dispatch.js +116 -0
  259. package/dist/src/dispatch.js.map +1 -0
  260. package/dist/src/doctor.d.ts +45 -0
  261. package/dist/src/doctor.d.ts.map +1 -0
  262. package/dist/src/doctor.js +284 -0
  263. package/dist/src/doctor.js.map +1 -0
  264. package/dist/src/eval.d.ts +3 -0
  265. package/dist/src/eval.d.ts.map +1 -0
  266. package/dist/src/eval.js +3 -0
  267. package/dist/src/eval.js.map +1 -0
  268. package/dist/src/index.d.ts +9 -2
  269. package/dist/src/index.d.ts.map +1 -1
  270. package/dist/src/index.js +6 -2
  271. package/dist/src/index.js.map +1 -1
  272. package/dist/src/ingest.d.ts +3 -0
  273. package/dist/src/ingest.d.ts.map +1 -0
  274. package/dist/src/ingest.js +3 -0
  275. package/dist/src/ingest.js.map +1 -0
  276. package/dist/src/loop.d.ts +3 -0
  277. package/dist/src/loop.d.ts.map +1 -0
  278. package/dist/src/loop.js +3 -0
  279. package/dist/src/loop.js.map +1 -0
  280. package/dist/src/main.d.ts +1 -1
  281. package/dist/src/main.d.ts.map +1 -1
  282. package/dist/src/main.js +3 -75
  283. package/dist/src/main.js.map +1 -1
  284. package/dist/src/mcp.d.ts +3 -0
  285. package/dist/src/mcp.d.ts.map +1 -0
  286. package/dist/src/mcp.js +3 -0
  287. package/dist/src/mcp.js.map +1 -0
  288. package/dist/src/rules.d.ts +3 -0
  289. package/dist/src/rules.d.ts.map +1 -0
  290. package/dist/src/rules.js +3 -0
  291. package/dist/src/rules.js.map +1 -0
  292. package/dist/src/shape.d.ts +3 -0
  293. package/dist/src/shape.d.ts.map +1 -0
  294. package/dist/src/shape.js +3 -0
  295. package/dist/src/shape.js.map +1 -0
  296. package/dist/src/sync.d.ts +3 -0
  297. package/dist/src/sync.d.ts.map +1 -0
  298. package/dist/src/sync.js +3 -0
  299. package/dist/src/sync.js.map +1 -0
  300. package/dist/src/view.d.ts +3 -0
  301. package/dist/src/view.d.ts.map +1 -0
  302. package/dist/src/view.js +3 -0
  303. package/dist/src/view.js.map +1 -0
  304. package/package.json +81 -21
  305. package/src/act.ts +2 -0
  306. package/src/automate.ts +2 -0
  307. package/src/cli.ts +416 -102
  308. package/src/commands.ts +48 -0
  309. package/src/connect.ts +2 -0
  310. package/src/dispatch.ts +141 -0
  311. package/src/doctor.ts +370 -0
  312. package/src/eval.ts +2 -0
  313. package/src/index.ts +9 -2
  314. package/src/ingest.ts +2 -0
  315. package/src/loop.ts +2 -0
  316. package/src/main.ts +3 -66
  317. package/src/mcp.ts +2 -0
  318. package/src/rules.ts +2 -0
  319. package/src/shape.ts +2 -0
  320. package/src/sync.ts +2 -0
  321. package/src/view.ts +2 -0
@@ -0,0 +1,350 @@
1
+ /**
2
+ * The ingestion orchestrator.
3
+ *
4
+ * `cave ingest` walks a source list (file globs and http(s) URLs — see
5
+ * `web.ts`), skips sources whose content is already ingested (digest
6
+ * provenance claims), batches the rest, composes one prompt per batch,
7
+ * and drives an *agent* over it:
8
+ *
9
+ * - a shell command template (`--agent 'claude -p --mcp-config {mcp-config} …'`)
10
+ * for headless Claude Code / Copilot CLI runs — the prompt is piped to
11
+ * stdin and written to `{prompt-file}`;
12
+ * - a JavaScript function (`agent: async (prompt, files) => text`) for
13
+ * Claude/Copilot SDK scripts using the library API;
14
+ * - or no agent at all — `--plan` emits the batches as NDJSON for a
15
+ * fully external driver.
16
+ *
17
+ * API access for the agent is the MCP server (`{mcp-config}` points at a
18
+ * generated client configuration for `cave mcp --db …`); `--stdout` mode
19
+ * instead treats the agent's stdout as CAVE text and stores it here.
20
+ * Prompts are built lazily per batch, so the injected knowledge context
21
+ * reflects what earlier batches recorded.
22
+ */
23
+ import { spawn } from 'node:child_process';
24
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
25
+ import { tmpdir } from 'node:os';
26
+ import { dirname, join, resolve } from 'node:path';
27
+ import { fileURLToPath } from 'node:url';
28
+ import * as Canonical from '@cavelang/canonical';
29
+ import { Registry } from '@cavelang/canonical';
30
+ import { open } from '@cavelang/store';
31
+ import { syncDb, syncText } from '@cavelang/cli/sync';
32
+ import * as Files from "./files.js";
33
+ import * as Web from "./web.js";
34
+ import * as Context from "./context.js";
35
+ import * as Prompt from "./prompt.js";
36
+ /** Writes an MCP client configuration pointing at `cave mcp --db <db>`. */
37
+ export const writeMcpConfig = (db, options = {}) => {
38
+ const dir = options.dir ?? mkdtempSync(join(tmpdir(), 'cave-ingest-'));
39
+ const server = fileURLToPath(import.meta.resolve('@cavelang/cli/mcp/bin'));
40
+ const path = join(dir, 'cave-mcp.json');
41
+ writeFileSync(path, `${JSON.stringify({
42
+ mcpServers: {
43
+ cave: {
44
+ command: process.execPath,
45
+ args: [server, '--db', resolve(db), ...options.noPrelude === true ? ['--no-prelude'] : []]
46
+ }
47
+ }
48
+ }, undefined, 2)}\n`);
49
+ return path;
50
+ };
51
+ const promptFiles = (files, embed, cwd) => files.map(file => ({
52
+ path: file.path,
53
+ // URL sources carry their extracted text and are always embedded —
54
+ // the agent has no other way to read them readability-cleaned.
55
+ ...file.content !== undefined ? { content: file.content } :
56
+ embed ? { content: readFileSync(resolve(cwd, file.path), 'utf8') } : {}
57
+ }));
58
+ /** Builds the prompt for one batch against the store's *current* state. */
59
+ export const promptFor = (store, files, options) => {
60
+ const cwd = options.cwd ?? process.cwd();
61
+ const context = Context.contextFor(store, files.map(file => file.path));
62
+ return Prompt.buildPrompt({
63
+ files: promptFiles(files, options.embed === true, cwd),
64
+ ...options.instructions === undefined ? {} : { instructions: Prompt.readInstructions(options.instructions) },
65
+ ...context === undefined ? {} : { context },
66
+ mode: options.mode ?? 'mcp'
67
+ });
68
+ };
69
+ /** Selects and batches the sources to process — file globs, literal paths and URLs. */
70
+ export const selectBatches = async (store, options) => {
71
+ const urls = options.patterns.filter(Web.isUrl);
72
+ const expanded = Files.expand(options.patterns.filter(pattern => !Web.isUrl(pattern)), options.cwd);
73
+ const paths = [...new Set([...expanded, ...options.files ?? []])].sort();
74
+ const local = Files.select(store, paths, {
75
+ force: options.force === true,
76
+ ...options.cwd === undefined ? {} : { cwd: options.cwd }
77
+ });
78
+ const remote = await Web.select(store, urls, {
79
+ force: options.force === true,
80
+ ...options.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }
81
+ });
82
+ const selection = {
83
+ files: [...local.files, ...remote.files],
84
+ skipped: [...local.skipped, ...remote.skipped],
85
+ failures: remote.failures
86
+ };
87
+ return { selection, batches: Files.batch(selection.files, options.batchSize ?? 8) };
88
+ };
89
+ const claimCount = (store) => store.db.prepare('SELECT COUNT(*) AS n FROM cave_claim').get().n;
90
+ /**
91
+ * POSIX single-quoting for substituted template values — the act/automate
92
+ * hook convention (spec §25.4): a value always lands as one argument and
93
+ * is never shell-evaluated, so placeholders are written bare.
94
+ */
95
+ const shellQuote = (value) => `'${value.replaceAll("'", `'\\''`)}'`;
96
+ /**
97
+ * Runs one shell agent invocation: `{name}` placeholders substituted into
98
+ * the template — each value shell-quoted, so paths with spaces or shell
99
+ * metacharacters stay single arguments — the prompt piped to stdin,
100
+ * stdout captured. Shared with `@cavelang/cli/eval`, whose agents and judges
101
+ * follow the same contract.
102
+ */
103
+ export const runShellAgent = (template, prompt, substitutions, timeoutSeconds, cwd) => {
104
+ const command = Object.entries(substitutions)
105
+ .reduce((acc, [name, value]) => acc.replaceAll(`{${name}}`, shellQuote(value)), template);
106
+ return new Promise(resolvePromise => {
107
+ let settled = false;
108
+ const settle = (result) => {
109
+ if (!settled) {
110
+ settled = true;
111
+ resolvePromise(result);
112
+ }
113
+ };
114
+ const child = spawn(command, {
115
+ shell: true,
116
+ cwd,
117
+ timeout: timeoutSeconds * 1000,
118
+ stdio: ['pipe', 'pipe', 'inherit']
119
+ });
120
+ let stdout = '';
121
+ child.stdout.on('data', chunk => {
122
+ stdout += String(chunk);
123
+ });
124
+ child.on('error', error => settle({ code: null, stdout, error: error.message }));
125
+ child.on('close', code => settle({ code, stdout }));
126
+ child.stdin.on('error', () => { });
127
+ child.stdin.write(prompt);
128
+ child.stdin.end();
129
+ });
130
+ };
131
+ /** Extracts CAVE text from stdout-mode agent output (```cave fences win). */
132
+ export const caveTextOf = (output) => {
133
+ const fences = [...output.matchAll(/```(?:cave)?\n([\s\S]*?)```/g)].map(match => match[1]);
134
+ return fences.length > 0 ? fences.join('\n') : output;
135
+ };
136
+ /** Runs batches against one mutable store. Strict callers provide a stage. */
137
+ const runMutable = async (options) => {
138
+ const store = options.store;
139
+ const cwd = options.cwd ?? process.cwd();
140
+ const mode = options.mode ?? 'mcp';
141
+ const policy = options.policy;
142
+ const timeoutSeconds = options.timeoutSeconds ?? 600;
143
+ const { selection, batches } = await selectBatches(store, options);
144
+ const reports = [];
145
+ const mcpConfig = typeof options.agent === 'string' && options.agent.includes('{mcp-config}') ?
146
+ writeMcpConfig(options.db, { noPrelude: options.noPrelude === true }) :
147
+ undefined;
148
+ const promptDir = mkdtempSync(join(tmpdir(), 'cave-prompt-'));
149
+ try {
150
+ // Strict input validation is fail-fast before the first paid call. The
151
+ // complete source manifest below still marks healthy selected inputs as
152
+ // not-run and each failed URL as rejected.
153
+ if (policy === 'strict' && selection.failures.length > 0) {
154
+ return {
155
+ policy,
156
+ applied: false,
157
+ matched: selection.files.length + selection.skipped.length + selection.failures.length,
158
+ skipped: selection.skipped,
159
+ batches: [],
160
+ sources: [
161
+ ...selection.skipped.map(path => ({ path, status: 'skipped', problems: [] })),
162
+ ...selection.files.map(file => ({ path: file.path, status: 'not-run', problems: [] })),
163
+ ...selection.failures.map(failure => ({
164
+ path: failure.path,
165
+ status: 'rejected',
166
+ problems: [failure.message],
167
+ failure: failure.kind,
168
+ retryable: failure.retryable,
169
+ ...failure.status === undefined ? {} : { httpStatus: failure.status }
170
+ }))
171
+ ],
172
+ added: 0,
173
+ failed: selection.failures.length
174
+ };
175
+ }
176
+ for (const [index, files] of batches.entries()) {
177
+ const prompt = promptFor(store, files, { ...options, mode });
178
+ const paths = files.map(file => file.path);
179
+ if (options.agent === undefined) {
180
+ reports.push({ files: paths, ok: false, added: 0, problems: [], note: 'no agent configured' });
181
+ if (policy === 'strict')
182
+ break;
183
+ continue;
184
+ }
185
+ const before = claimCount(store);
186
+ let ok;
187
+ let output;
188
+ if (typeof options.agent === 'function') {
189
+ try {
190
+ output = await options.agent(prompt, paths, {
191
+ db: options.db,
192
+ ...mcpConfig === undefined ? {} : { mcpConfig }
193
+ });
194
+ ok = true;
195
+ }
196
+ catch (error) {
197
+ output = '';
198
+ ok = false;
199
+ reports.push({
200
+ files: paths, ok, added: claimCount(store) - before, problems: [],
201
+ note: error instanceof Error ? error.message : String(error)
202
+ });
203
+ if (policy === 'strict')
204
+ break;
205
+ continue;
206
+ }
207
+ }
208
+ else {
209
+ const promptFile = join(promptDir, `batch-${index + 1}.md`);
210
+ writeFileSync(promptFile, prompt);
211
+ const result = await runShellAgent(options.agent, prompt, {
212
+ 'prompt-file': promptFile,
213
+ ...mcpConfig === undefined ? {} : { 'mcp-config': mcpConfig },
214
+ db: resolve(options.db)
215
+ }, timeoutSeconds, cwd);
216
+ ok = result.code === 0;
217
+ output = result.stdout;
218
+ if (!ok) {
219
+ reports.push({
220
+ files: paths, ok, added: claimCount(store) - before, problems: [],
221
+ note: result.error ?? `agent exited with ${result.code}`
222
+ });
223
+ if (policy === 'strict')
224
+ break;
225
+ continue;
226
+ }
227
+ }
228
+ if (mode === 'stdout') {
229
+ // Actor provenance (spec §9.5): mcp-mode appends are stamped by the
230
+ // MCP server; here the orchestrator appends, so it stamps — with the
231
+ // stable ingestion-surface identity, like `src:cli` and
232
+ // `src:agent/<client>`. A content- or batch-derived identity would
233
+ // fork the claim key (§9.2) on every source revision, leaving the
234
+ // old and the re-extracted belief both current.
235
+ const canonical = Canonical.canonicalizeText(caveTextOf(output), store.registry());
236
+ const problems = canonical.problems.map(problem => `line ${problem.line}: ${problem.message}`);
237
+ if (policy === 'strict' && problems.length > 0) {
238
+ reports.push({ files: paths, ok: false, added: 0, problems });
239
+ break;
240
+ }
241
+ const ingested = store.insertResult(canonical, { source: 'ingest' });
242
+ reports.push({
243
+ files: paths,
244
+ ok: problems.length === 0,
245
+ added: ingested.ids.length,
246
+ problems
247
+ });
248
+ if (problems.length > 0) {
249
+ // A partially invalid extraction may be incomplete — withhold the
250
+ // digests so these sources stay eligible for the next run.
251
+ continue;
252
+ }
253
+ }
254
+ else {
255
+ const note = output.trim().split('\n').at(-1) ?? '';
256
+ reports.push({
257
+ files: paths,
258
+ ok: true,
259
+ added: claimCount(store) - before,
260
+ problems: [],
261
+ ...note === '' ? {} : { note }
262
+ });
263
+ }
264
+ Files.recordDigests(store, files);
265
+ }
266
+ }
267
+ finally {
268
+ rmSync(promptDir, { recursive: true, force: true });
269
+ if (mcpConfig !== undefined) {
270
+ rmSync(dirname(mcpConfig), { recursive: true, force: true });
271
+ }
272
+ }
273
+ const sources = [
274
+ ...selection.skipped.map(path => ({ path, status: 'skipped', problems: [] })),
275
+ ...selection.files.map(file => {
276
+ const batch = reports.findIndex(report => report.files.includes(file.path));
277
+ if (batch < 0)
278
+ return { path: file.path, status: 'not-run', problems: [] };
279
+ const report = reports[batch];
280
+ return {
281
+ path: file.path,
282
+ status: report.ok ? 'accepted' : 'rejected',
283
+ batch: batch + 1,
284
+ problems: report.problems,
285
+ ...report.note === undefined ? {} : { note: report.note }
286
+ };
287
+ }),
288
+ ...selection.failures.map(failure => ({
289
+ path: failure.path,
290
+ status: 'rejected',
291
+ problems: [failure.message],
292
+ failure: failure.kind,
293
+ retryable: failure.retryable,
294
+ ...failure.status === undefined ? {} : { httpStatus: failure.status }
295
+ }))
296
+ ];
297
+ return {
298
+ policy,
299
+ applied: true,
300
+ matched: selection.files.length + selection.skipped.length + selection.failures.length,
301
+ skipped: selection.skipped,
302
+ batches: reports,
303
+ sources,
304
+ added: reports.reduce((sum, report) => sum + report.added, 0),
305
+ failed: reports.filter(report => !report.ok).length + selection.failures.length
306
+ };
307
+ };
308
+ /**
309
+ * Runs the full ingestion. Strict is the default: the target is copied into
310
+ * an isolated staging store, every generated MCP configuration and `{db}`
311
+ * substitution points there, and one identity-preserving merge applies the
312
+ * complete run only after every batch succeeds. A fatal batch stops further
313
+ * agent calls and discards all staged claims and digests.
314
+ *
315
+ * Lenient mode writes accepted work batch by batch, continues after failures,
316
+ * and withholds digests for rejected sources so the next invocation retries
317
+ * them. The returned source manifest accounts for every matched input.
318
+ */
319
+ export const run = async (options) => {
320
+ const policy = options.policy ?? 'strict';
321
+ if (policy === 'lenient')
322
+ return runMutable({ ...options, policy });
323
+ const stageDir = mkdtempSync(join(tmpdir(), 'cave-ingest-stage-'));
324
+ const stageDb = join(stageDir, 'stage.db');
325
+ let staged;
326
+ try {
327
+ const stage = open(stageDb, options.noPrelude === true ? { registry: Registry.empty } : {});
328
+ try {
329
+ const seeded = syncText(stage, options.store.exportText({ tx: true, maxSensitivity: 'restricted' }), {
330
+ record: false
331
+ });
332
+ if (seeded.problems.length > 0) {
333
+ throw new Error(`could not stage the current store: ${seeded.problems.map(problem => `line ${problem.line}: ${problem.message}`).join('; ')}`);
334
+ }
335
+ staged = await runMutable({ ...options, db: stageDb, store: stage, policy });
336
+ }
337
+ finally {
338
+ stage.close();
339
+ }
340
+ if (staged.failed > 0 || staged.sources.some(source => source.status === 'not-run')) {
341
+ return { ...staged, applied: false, added: 0 };
342
+ }
343
+ syncDb(options.store, stageDb, { record: false });
344
+ return staged;
345
+ }
346
+ finally {
347
+ rmSync(stageDir, { recursive: true, force: true });
348
+ }
349
+ };
350
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * URL sources for ingestion — `cave ingest https://…` fetches the page
3
+ * with the built-in fetch and reduces HTML to its readable article text
4
+ * (Readability over linkedom), so the agent sees prose instead of markup.
5
+ * Non-HTML responses (markdown, plain text, JSON) pass through verbatim.
6
+ *
7
+ * Provenance mirrors files: the URL is the claim subject and the digest
8
+ * is taken over the *extracted* text, so a page is re-ingested only when
9
+ * its readable content changes — not on every markup or chrome tweak.
10
+ */
11
+ import type { Store } from '@cavelang/store';
12
+ import type { Selected, Selection } from './files.ts';
13
+ /** @returns whether an ingest pattern is a fetchable URL. */
14
+ export declare const isUrl: (pattern: string) => boolean;
15
+ /**
16
+ * @returns the readable text of an HTML page — Readability's article when
17
+ * it finds one, otherwise the whole body with scripts/styles dropped —
18
+ * prefixed with the page title as a heading.
19
+ */
20
+ export declare const readableTextOf: (html: string) => string;
21
+ /** Injection point for tests; the built-in fetch otherwise. */
22
+ export type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
23
+ export type FailureKind = 'network' | 'http';
24
+ export type Failure = {
25
+ readonly path: string;
26
+ readonly kind: FailureKind;
27
+ readonly retryable: boolean;
28
+ readonly message: string;
29
+ readonly status?: number;
30
+ };
31
+ /**
32
+ * Fetches one URL and returns it as a selectable source — readable text
33
+ * for HTML responses, the verbatim body for anything else.
34
+ */
35
+ export declare const fetchDocument: (url: string, fetchImpl?: FetchLike, timeoutSeconds?: number) => Promise<Selected>;
36
+ /**
37
+ * Fetches and digests the given URLs, skipping the ones whose current
38
+ * `ingest-digest` belief already matches (pass `force` to re-ingest all).
39
+ * The fetch always happens — the digest is over the extracted content —
40
+ * but unchanged pages cost no agent run.
41
+ */
42
+ export declare const select: (store: Store, urls: readonly string[], options?: {
43
+ force?: boolean;
44
+ fetchImpl?: FetchLike;
45
+ }) => Promise<Selection & {
46
+ failures: readonly Failure[];
47
+ }>;
48
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAErD,6DAA6D;AAC7D,eAAO,MAAM,KAAK,GAAI,SAAS,MAAM,KAAG,OACT,CAAA;AA0C/B;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,MAe7C,CAAA;AAED,+DAA+D;AAC/D,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE7E,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,CAAA;AAE5C,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAoBD;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,KAAK,MAAM,EACX,YAAW,SAAiB,EAC5B,uBAAmB,KAClB,OAAO,CAAC,QAAQ,CA4BlB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,MAAM,SAAS,MAAM,EAAE,EACvB,UAAS;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,KACvD,OAAO,CAAC,SAAS,GAAG;IAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,CAwBtD,CAAA"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * URL sources for ingestion — `cave ingest https://…` fetches the page
3
+ * with the built-in fetch and reduces HTML to its readable article text
4
+ * (Readability over linkedom), so the agent sees prose instead of markup.
5
+ * Non-HTML responses (markdown, plain text, JSON) pass through verbatim.
6
+ *
7
+ * Provenance mirrors files: the URL is the claim subject and the digest
8
+ * is taken over the *extracted* text, so a page is re-ingested only when
9
+ * its readable content changes — not on every markup or chrome tweak.
10
+ */
11
+ import { Readability } from '@mozilla/readability';
12
+ import { parseHTML } from 'linkedom';
13
+ import { digestOf, isIngested } from "./files.js";
14
+ /** @returns whether an ingest pattern is a fetchable URL. */
15
+ export const isUrl = (pattern) => /^https?:\/\//i.test(pattern);
16
+ /** Block-level elements worth a line of their own in the extracted text. */
17
+ const blockSelector = 'p, h1, h2, h3, h4, h5, h6, li, pre, blockquote, td, figcaption';
18
+ const headingPrefix = {
19
+ H1: '# ', H2: '## ', H3: '### ', H4: '#### ', H5: '##### ', H6: '###### ', LI: '- '
20
+ };
21
+ /** Readability's types are written against the browser DOM lib, which a
22
+ * node-only tsconfig does not load — retype the constructor structurally. */
23
+ const Parser = Readability;
24
+ /** Flattens a DOM subtree into markdown-ish text, one block per line. */
25
+ const textOf = (root) => {
26
+ const blocks = [...root.querySelectorAll(blockSelector)]
27
+ // Keep outermost blocks only — a <p> inside a kept <li> is its text.
28
+ .filter(element => element.parentElement === null || element.parentElement.closest(blockSelector) === null)
29
+ .map(element => {
30
+ const text = element.textContent ?? '';
31
+ return element.tagName === 'PRE' ?
32
+ text.trim() :
33
+ `${headingPrefix[element.tagName] ?? ''}${text.replace(/\s+/g, ' ').trim()}`;
34
+ })
35
+ .filter(line => line !== '');
36
+ return blocks.length > 0 ? blocks.join('\n\n') : (root.textContent ?? '').trim();
37
+ };
38
+ /**
39
+ * @returns the readable text of an HTML page — Readability's article when
40
+ * it finds one, otherwise the whole body with scripts/styles dropped —
41
+ * prefixed with the page title as a heading.
42
+ */
43
+ export const readableTextOf = (html) => {
44
+ const parse = () => parseHTML(html).document;
45
+ const article = new Parser(parse()).parse();
46
+ const body = () => {
47
+ const document = parse();
48
+ for (const element of document.querySelectorAll('script, style, noscript, template')) {
49
+ element.remove();
50
+ }
51
+ return textOf((document.body ?? document));
52
+ };
53
+ const text = article === null || article.content === null || article.content === undefined ?
54
+ body() :
55
+ textOf(parseHTML(`<html><body>${article.content}</body></html>`).document);
56
+ const title = (article?.title ?? parse().title ?? '').trim();
57
+ return title === '' || text.startsWith(`# ${title}`) ? text : `# ${title}\n\n${text}`;
58
+ };
59
+ class FetchFailure extends Error {
60
+ failure;
61
+ constructor(failure) {
62
+ super(failure.message);
63
+ this.failure = failure;
64
+ }
65
+ }
66
+ const retryableStatus = (status) => status === 408 || status === 425 || status === 429 || status >= 500;
67
+ const failureOf = (url, error) => {
68
+ if (error instanceof FetchFailure)
69
+ return error.failure;
70
+ const detail = error instanceof Error ? error.message : String(error);
71
+ return { path: url, kind: 'network', retryable: true, message: `fetch ${url} failed: ${detail}` };
72
+ };
73
+ /**
74
+ * Fetches one URL and returns it as a selectable source — readable text
75
+ * for HTML responses, the verbatim body for anything else.
76
+ */
77
+ export const fetchDocument = async (url, fetchImpl = fetch, timeoutSeconds = 60) => {
78
+ let response;
79
+ try {
80
+ response = await fetchImpl(url, {
81
+ headers: {
82
+ 'user-agent': 'cave-ingest',
83
+ accept: 'text/html, text/markdown, text/plain, application/json;q=0.9, */*;q=0.8'
84
+ },
85
+ redirect: 'follow',
86
+ signal: AbortSignal.timeout(timeoutSeconds * 1000)
87
+ });
88
+ }
89
+ catch (error) {
90
+ throw new FetchFailure(failureOf(url, error));
91
+ }
92
+ if (!response.ok) {
93
+ throw new FetchFailure({
94
+ path: url,
95
+ kind: 'http',
96
+ retryable: retryableStatus(response.status),
97
+ status: response.status,
98
+ message: `fetch ${url} failed: ${response.status} ${response.statusText}`
99
+ });
100
+ }
101
+ const type = response.headers.get('content-type') ?? '';
102
+ const body = await response.text();
103
+ const html = /html|xhtml/i.test(type) || (type === '' && /^\s*</.test(body));
104
+ const content = html ? readableTextOf(body) : body;
105
+ return { path: url, digest: digestOf(content), content };
106
+ };
107
+ /**
108
+ * Fetches and digests the given URLs, skipping the ones whose current
109
+ * `ingest-digest` belief already matches (pass `force` to re-ingest all).
110
+ * The fetch always happens — the digest is over the extracted content —
111
+ * but unchanged pages cost no agent run.
112
+ */
113
+ export const select = async (store, urls, options = {}) => {
114
+ const files = [];
115
+ const skipped = [];
116
+ const failures = [];
117
+ const outcomes = await Promise.all([...new Set(urls)].map(async (url) => {
118
+ try {
119
+ return { document: await fetchDocument(url, options.fetchImpl) };
120
+ }
121
+ catch (error) {
122
+ return { failure: failureOf(url, error) };
123
+ }
124
+ }));
125
+ for (const outcome of outcomes) {
126
+ if ('failure' in outcome) {
127
+ failures.push(outcome.failure);
128
+ continue;
129
+ }
130
+ const document = outcome.document;
131
+ if (options.force !== true && isIngested(store, document.path, document.digest)) {
132
+ skipped.push(document.path);
133
+ }
134
+ else {
135
+ files.push(document);
136
+ }
137
+ }
138
+ return { files, skipped, failures };
139
+ };
140
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Runnable demo (spec §18): the multi-hop recovery pattern central to the
3
+ * active-reconstruction thesis (spec §11.3).
4
+ *
5
+ * Starting from the single cue `reject-valid-tokens` — the *symptom* — the
6
+ * loop must travel edges that only exist as inverse reads:
7
+ *
8
+ * 1. `reject-valid-tokens` ← CAUSED-BY — `token-expiry` (inverse CAUSE)
9
+ * 2. `token-expiry` ← PART-OF — `topic/auth-hardening` (inverse CONTAINS)
10
+ * 3. topic expansion → `auth/middleware`, and with it the bug, the broken
11
+ * check and the fix.
12
+ *
13
+ * ```
14
+ * pnpm --filter @cavelang/cli/loop demo
15
+ * ```
16
+ */
17
+ export declare const knowledge = "\nauth/middleware HAS bug: token-expiry #security #topic:auth-hardening\ntoken-expiry CAUSE reject-valid-tokens\nexpiry-check USES `<`\nexpiry-check NEEDS `<=`\n`<=` FIX token-expiry @auth.ts:42\nauth/middleware NEEDS test: boundary-cases @ 70%\ntopic/auth-hardening CONTAINS token-expiry\ntopic/auth-hardening CONTAINS auth/middleware\ntopic/auth-hardening CONTAINS expiry-check\ndeploy VIA github-actions\nunrelated/service USES postgres\n";
18
+ export declare const run: () => {
19
+ lines: string[];
20
+ };
21
+ export declare const isDirectInvocation: (moduleUrl: string, entryPath: string | undefined, platform?: NodeJS.Platform) => boolean;
22
+ //# sourceMappingURL=demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/demo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAQH,eAAO,MAAM,SAAS,8bAYrB,CAAA;AAED,eAAO,MAAM,GAAG,QAAO;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAoBvC,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,EACjB,WAAW,MAAM,GAAG,SAAS,EAC7B,WAAU,MAAM,CAAC,QAA2B,KAC3C,OAKF,CAAA"}