@waratahlabs/canopy 0.5.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 (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +323 -0
  3. package/SKILL.md +97 -0
  4. package/demo/data/openclaw-demo.tc.json +397 -0
  5. package/demo/data/openclaw-nemoclaw-demo.tc.json +475 -0
  6. package/demo/index.html +556 -0
  7. package/dist/adapters/a2a.d.ts +82 -0
  8. package/dist/adapters/a2a.d.ts.map +1 -0
  9. package/dist/adapters/a2a.js +215 -0
  10. package/dist/adapters/a2a.js.map +1 -0
  11. package/dist/adapters/a2a.test.d.ts +2 -0
  12. package/dist/adapters/a2a.test.d.ts.map +1 -0
  13. package/dist/adapters/a2a.test.js +196 -0
  14. package/dist/adapters/a2a.test.js.map +1 -0
  15. package/dist/adapters/langfuse.d.ts +28 -0
  16. package/dist/adapters/langfuse.d.ts.map +1 -0
  17. package/dist/adapters/langfuse.js +192 -0
  18. package/dist/adapters/langfuse.js.map +1 -0
  19. package/dist/adapters/n8n.d.ts +4 -0
  20. package/dist/adapters/n8n.d.ts.map +1 -0
  21. package/dist/adapters/n8n.js +89 -0
  22. package/dist/adapters/n8n.js.map +1 -0
  23. package/dist/adapters/openclaw.d.ts +58 -0
  24. package/dist/adapters/openclaw.d.ts.map +1 -0
  25. package/dist/adapters/openclaw.js +275 -0
  26. package/dist/adapters/openclaw.js.map +1 -0
  27. package/dist/adapters/types.d.ts +33 -0
  28. package/dist/adapters/types.d.ts.map +1 -0
  29. package/dist/adapters/types.js +2 -0
  30. package/dist/adapters/types.js.map +1 -0
  31. package/dist/aivss/atlas/coverage-matrix.d.ts +12 -0
  32. package/dist/aivss/atlas/coverage-matrix.d.ts.map +1 -0
  33. package/dist/aivss/atlas/coverage-matrix.js +272 -0
  34. package/dist/aivss/atlas/coverage-matrix.js.map +1 -0
  35. package/dist/aivss/atlas/loader.d.ts +28 -0
  36. package/dist/aivss/atlas/loader.d.ts.map +1 -0
  37. package/dist/aivss/atlas/loader.js +126 -0
  38. package/dist/aivss/atlas/loader.js.map +1 -0
  39. package/dist/aivss/atlas/loader.test.d.ts +11 -0
  40. package/dist/aivss/atlas/loader.test.d.ts.map +1 -0
  41. package/dist/aivss/atlas/loader.test.js +111 -0
  42. package/dist/aivss/atlas/loader.test.js.map +1 -0
  43. package/dist/aivss/atlas/resolve-path.d.ts +34 -0
  44. package/dist/aivss/atlas/resolve-path.d.ts.map +1 -0
  45. package/dist/aivss/atlas/resolve-path.js +58 -0
  46. package/dist/aivss/atlas/resolve-path.js.map +1 -0
  47. package/dist/aivss/batch/batch-builder.d.ts +11 -0
  48. package/dist/aivss/batch/batch-builder.d.ts.map +1 -0
  49. package/dist/aivss/batch/batch-builder.js +75 -0
  50. package/dist/aivss/batch/batch-builder.js.map +1 -0
  51. package/dist/aivss/index.d.ts +21 -0
  52. package/dist/aivss/index.d.ts.map +1 -0
  53. package/dist/aivss/index.js +19 -0
  54. package/dist/aivss/index.js.map +1 -0
  55. package/dist/aivss/knowledge-base/kb-client.d.ts +9 -0
  56. package/dist/aivss/knowledge-base/kb-client.d.ts.map +1 -0
  57. package/dist/aivss/knowledge-base/kb-client.js +139 -0
  58. package/dist/aivss/knowledge-base/kb-client.js.map +1 -0
  59. package/dist/aivss/knowledge-base/kb-types.d.ts +21 -0
  60. package/dist/aivss/knowledge-base/kb-types.d.ts.map +1 -0
  61. package/dist/aivss/knowledge-base/kb-types.js +2 -0
  62. package/dist/aivss/knowledge-base/kb-types.js.map +1 -0
  63. package/dist/aivss/knowledge-base/search-builder.d.ts +7 -0
  64. package/dist/aivss/knowledge-base/search-builder.d.ts.map +1 -0
  65. package/dist/aivss/knowledge-base/search-builder.js +119 -0
  66. package/dist/aivss/knowledge-base/search-builder.js.map +1 -0
  67. package/dist/aivss/metrics/aa.d.ts +3 -0
  68. package/dist/aivss/metrics/aa.d.ts.map +1 -0
  69. package/dist/aivss/metrics/aa.js +26 -0
  70. package/dist/aivss/metrics/aa.js.map +1 -0
  71. package/dist/aivss/metrics/ad.d.ts +3 -0
  72. package/dist/aivss/metrics/ad.d.ts.map +1 -0
  73. package/dist/aivss/metrics/ad.js +30 -0
  74. package/dist/aivss/metrics/ad.js.map +1 -0
  75. package/dist/aivss/metrics/cs.d.ts +3 -0
  76. package/dist/aivss/metrics/cs.d.ts.map +1 -0
  77. package/dist/aivss/metrics/cs.js +50 -0
  78. package/dist/aivss/metrics/cs.js.map +1 -0
  79. package/dist/aivss/metrics/dc.d.ts +3 -0
  80. package/dist/aivss/metrics/dc.d.ts.map +1 -0
  81. package/dist/aivss/metrics/dc.js +30 -0
  82. package/dist/aivss/metrics/dc.js.map +1 -0
  83. package/dist/aivss/metrics/ds.d.ts +3 -0
  84. package/dist/aivss/metrics/ds.d.ts.map +1 -0
  85. package/dist/aivss/metrics/ds.js +26 -0
  86. package/dist/aivss/metrics/ds.js.map +1 -0
  87. package/dist/aivss/metrics/ei.d.ts +3 -0
  88. package/dist/aivss/metrics/ei.d.ts.map +1 -0
  89. package/dist/aivss/metrics/ei.js +30 -0
  90. package/dist/aivss/metrics/ei.js.map +1 -0
  91. package/dist/aivss/metrics/gv.d.ts +3 -0
  92. package/dist/aivss/metrics/gv.d.ts.map +1 -0
  93. package/dist/aivss/metrics/gv.js +34 -0
  94. package/dist/aivss/metrics/gv.js.map +1 -0
  95. package/dist/aivss/metrics/ll.d.ts +3 -0
  96. package/dist/aivss/metrics/ll.d.ts.map +1 -0
  97. package/dist/aivss/metrics/ll.js +30 -0
  98. package/dist/aivss/metrics/ll.js.map +1 -0
  99. package/dist/aivss/metrics/mr.d.ts +3 -0
  100. package/dist/aivss/metrics/mr.d.ts.map +1 -0
  101. package/dist/aivss/metrics/mr.js +26 -0
  102. package/dist/aivss/metrics/mr.js.map +1 -0
  103. package/dist/aivss/metrics/shared.d.ts +22 -0
  104. package/dist/aivss/metrics/shared.d.ts.map +1 -0
  105. package/dist/aivss/metrics/shared.js +70 -0
  106. package/dist/aivss/metrics/shared.js.map +1 -0
  107. package/dist/aivss/prompts/base-system-prompt.d.ts +2 -0
  108. package/dist/aivss/prompts/base-system-prompt.d.ts.map +1 -0
  109. package/dist/aivss/prompts/base-system-prompt.js +31 -0
  110. package/dist/aivss/prompts/base-system-prompt.js.map +1 -0
  111. package/dist/aivss/prompts/prompt-composer.d.ts +13 -0
  112. package/dist/aivss/prompts/prompt-composer.d.ts.map +1 -0
  113. package/dist/aivss/prompts/prompt-composer.js +21 -0
  114. package/dist/aivss/prompts/prompt-composer.js.map +1 -0
  115. package/dist/aivss/scoring/a2a-corpus.test.d.ts +28 -0
  116. package/dist/aivss/scoring/a2a-corpus.test.d.ts.map +1 -0
  117. package/dist/aivss/scoring/a2a-corpus.test.js +109 -0
  118. package/dist/aivss/scoring/a2a-corpus.test.js.map +1 -0
  119. package/dist/aivss/scoring/determinism.test.d.ts +16 -0
  120. package/dist/aivss/scoring/determinism.test.d.ts.map +1 -0
  121. package/dist/aivss/scoring/determinism.test.js +169 -0
  122. package/dist/aivss/scoring/determinism.test.js.map +1 -0
  123. package/dist/aivss/scoring/heuristic-scorer.d.ts +21 -0
  124. package/dist/aivss/scoring/heuristic-scorer.d.ts.map +1 -0
  125. package/dist/aivss/scoring/heuristic-scorer.js +299 -0
  126. package/dist/aivss/scoring/heuristic-scorer.js.map +1 -0
  127. package/dist/aivss/scoring/heuristic-scorer.test.d.ts +8 -0
  128. package/dist/aivss/scoring/heuristic-scorer.test.d.ts.map +1 -0
  129. package/dist/aivss/scoring/heuristic-scorer.test.js +150 -0
  130. package/dist/aivss/scoring/heuristic-scorer.test.js.map +1 -0
  131. package/dist/aivss/scoring/scoring-mode.d.ts +48 -0
  132. package/dist/aivss/scoring/scoring-mode.d.ts.map +1 -0
  133. package/dist/aivss/scoring/scoring-mode.js +64 -0
  134. package/dist/aivss/scoring/scoring-mode.js.map +1 -0
  135. package/dist/aivss/scoring/v4-engine.d.ts +15 -0
  136. package/dist/aivss/scoring/v4-engine.d.ts.map +1 -0
  137. package/dist/aivss/scoring/v4-engine.js +84 -0
  138. package/dist/aivss/scoring/v4-engine.js.map +1 -0
  139. package/dist/aivss/scoring/v4-engine.test.d.ts +16 -0
  140. package/dist/aivss/scoring/v4-engine.test.d.ts.map +1 -0
  141. package/dist/aivss/scoring/v4-engine.test.js +156 -0
  142. package/dist/aivss/scoring/v4-engine.test.js.map +1 -0
  143. package/dist/aivss/types.d.ts +92 -0
  144. package/dist/aivss/types.d.ts.map +1 -0
  145. package/dist/aivss/types.js +25 -0
  146. package/dist/aivss/types.js.map +1 -0
  147. package/dist/baseline/baseline.test.d.ts +2 -0
  148. package/dist/baseline/baseline.test.d.ts.map +1 -0
  149. package/dist/baseline/baseline.test.js +219 -0
  150. package/dist/baseline/baseline.test.js.map +1 -0
  151. package/dist/baseline/diff.d.ts +42 -0
  152. package/dist/baseline/diff.d.ts.map +1 -0
  153. package/dist/baseline/diff.js +124 -0
  154. package/dist/baseline/diff.js.map +1 -0
  155. package/dist/baseline/store.d.ts +51 -0
  156. package/dist/baseline/store.d.ts.map +1 -0
  157. package/dist/baseline/store.js +92 -0
  158. package/dist/baseline/store.js.map +1 -0
  159. package/dist/batch/anthropic-batch-runner.d.ts +50 -0
  160. package/dist/batch/anthropic-batch-runner.d.ts.map +1 -0
  161. package/dist/batch/anthropic-batch-runner.js +91 -0
  162. package/dist/batch/anthropic-batch-runner.js.map +1 -0
  163. package/dist/batch/bedrock-batch-runner.d.ts +90 -0
  164. package/dist/batch/bedrock-batch-runner.d.ts.map +1 -0
  165. package/dist/batch/bedrock-batch-runner.js +199 -0
  166. package/dist/batch/bedrock-batch-runner.js.map +1 -0
  167. package/dist/batch/providers/anthropic.d.ts +55 -0
  168. package/dist/batch/providers/anthropic.d.ts.map +1 -0
  169. package/dist/batch/providers/anthropic.js +103 -0
  170. package/dist/batch/providers/anthropic.js.map +1 -0
  171. package/dist/batch/providers/bedrock.d.ts +31 -0
  172. package/dist/batch/providers/bedrock.d.ts.map +1 -0
  173. package/dist/batch/providers/bedrock.js +42 -0
  174. package/dist/batch/providers/bedrock.js.map +1 -0
  175. package/dist/batch/providers/harness.d.ts +36 -0
  176. package/dist/batch/providers/harness.d.ts.map +1 -0
  177. package/dist/batch/providers/harness.js +65 -0
  178. package/dist/batch/providers/harness.js.map +1 -0
  179. package/dist/batch/providers/harness.test.d.ts +7 -0
  180. package/dist/batch/providers/harness.test.d.ts.map +1 -0
  181. package/dist/batch/providers/harness.test.js +84 -0
  182. package/dist/batch/providers/harness.test.js.map +1 -0
  183. package/dist/batch/providers/index.d.ts +82 -0
  184. package/dist/batch/providers/index.d.ts.map +1 -0
  185. package/dist/batch/providers/index.js +82 -0
  186. package/dist/batch/providers/index.js.map +1 -0
  187. package/dist/batch/providers/ollama.d.ts +68 -0
  188. package/dist/batch/providers/ollama.d.ts.map +1 -0
  189. package/dist/batch/providers/ollama.js +108 -0
  190. package/dist/batch/providers/ollama.js.map +1 -0
  191. package/dist/batch/response-parser.d.ts +45 -0
  192. package/dist/batch/response-parser.d.ts.map +1 -0
  193. package/dist/batch/response-parser.js +161 -0
  194. package/dist/batch/response-parser.js.map +1 -0
  195. package/dist/batch/types.d.ts +87 -0
  196. package/dist/batch/types.d.ts.map +1 -0
  197. package/dist/batch/types.js +8 -0
  198. package/dist/batch/types.js.map +1 -0
  199. package/dist/cli.d.ts +15 -0
  200. package/dist/cli.d.ts.map +1 -0
  201. package/dist/cli.js +1037 -0
  202. package/dist/cli.js.map +1 -0
  203. package/dist/examples/a2a-assessment.d.ts +20 -0
  204. package/dist/examples/a2a-assessment.d.ts.map +1 -0
  205. package/dist/examples/a2a-assessment.js +115 -0
  206. package/dist/examples/a2a-assessment.js.map +1 -0
  207. package/dist/examples/batch-assessment.d.ts +18 -0
  208. package/dist/examples/batch-assessment.d.ts.map +1 -0
  209. package/dist/examples/batch-assessment.js +112 -0
  210. package/dist/examples/batch-assessment.js.map +1 -0
  211. package/dist/examples/batch-submission-flow.d.ts +2 -0
  212. package/dist/examples/batch-submission-flow.d.ts.map +1 -0
  213. package/dist/examples/batch-submission-flow.js +279 -0
  214. package/dist/examples/batch-submission-flow.js.map +1 -0
  215. package/dist/examples/demo-agent-definition.json +58 -0
  216. package/dist/examples/langfuse-assessment.d.ts +2 -0
  217. package/dist/examples/langfuse-assessment.d.ts.map +1 -0
  218. package/dist/examples/langfuse-assessment.js +46 -0
  219. package/dist/examples/langfuse-assessment.js.map +1 -0
  220. package/dist/examples/model-eval.d.ts +25 -0
  221. package/dist/examples/model-eval.d.ts.map +1 -0
  222. package/dist/examples/model-eval.js +94 -0
  223. package/dist/examples/model-eval.js.map +1 -0
  224. package/dist/examples/openclaw-assessment.d.ts +17 -0
  225. package/dist/examples/openclaw-assessment.d.ts.map +1 -0
  226. package/dist/examples/openclaw-assessment.js +79 -0
  227. package/dist/examples/openclaw-assessment.js.map +1 -0
  228. package/dist/examples/simple-assessment.d.ts +2 -0
  229. package/dist/examples/simple-assessment.d.ts.map +1 -0
  230. package/dist/examples/simple-assessment.js +146 -0
  231. package/dist/examples/simple-assessment.js.map +1 -0
  232. package/dist/examples/threat-model-demo.d.ts +2 -0
  233. package/dist/examples/threat-model-demo.d.ts.map +1 -0
  234. package/dist/examples/threat-model-demo.js +103 -0
  235. package/dist/examples/threat-model-demo.js.map +1 -0
  236. package/dist/index.d.ts +60 -0
  237. package/dist/index.d.ts.map +1 -0
  238. package/dist/index.js +155 -0
  239. package/dist/index.js.map +1 -0
  240. package/dist/output/likec4-generator.d.ts +43 -0
  241. package/dist/output/likec4-generator.d.ts.map +1 -0
  242. package/dist/output/likec4-generator.js +287 -0
  243. package/dist/output/likec4-generator.js.map +1 -0
  244. package/dist/output/slot-filler.d.ts +6 -0
  245. package/dist/output/slot-filler.d.ts.map +1 -0
  246. package/dist/output/slot-filler.js +71 -0
  247. package/dist/output/slot-filler.js.map +1 -0
  248. package/dist/output/tc-assembler.d.ts +30 -0
  249. package/dist/output/tc-assembler.d.ts.map +1 -0
  250. package/dist/output/tc-assembler.js +227 -0
  251. package/dist/output/tc-assembler.js.map +1 -0
  252. package/dist/output/tc-types.d.ts +41 -0
  253. package/dist/output/tc-types.d.ts.map +1 -0
  254. package/dist/output/tc-types.js +5 -0
  255. package/dist/output/tc-types.js.map +1 -0
  256. package/dist/output/tc-validator.test.d.ts +9 -0
  257. package/dist/output/tc-validator.test.d.ts.map +1 -0
  258. package/dist/output/tc-validator.test.js +194 -0
  259. package/dist/output/tc-validator.test.js.map +1 -0
  260. package/dist/providers/anthropic.d.ts +9 -0
  261. package/dist/providers/anthropic.d.ts.map +1 -0
  262. package/dist/providers/anthropic.js +30 -0
  263. package/dist/providers/anthropic.js.map +1 -0
  264. package/dist/providers/bedrock.d.ts +9 -0
  265. package/dist/providers/bedrock.d.ts.map +1 -0
  266. package/dist/providers/bedrock.js +38 -0
  267. package/dist/providers/bedrock.js.map +1 -0
  268. package/dist/providers/index.d.ts +6 -0
  269. package/dist/providers/index.d.ts.map +1 -0
  270. package/dist/providers/index.js +14 -0
  271. package/dist/providers/index.js.map +1 -0
  272. package/dist/providers/types.d.ts +12 -0
  273. package/dist/providers/types.d.ts.map +1 -0
  274. package/dist/providers/types.js +5 -0
  275. package/dist/providers/types.js.map +1 -0
  276. package/dist/references/acsc-risks.d.ts +18 -0
  277. package/dist/references/acsc-risks.d.ts.map +1 -0
  278. package/dist/references/acsc-risks.js +232 -0
  279. package/dist/references/acsc-risks.js.map +1 -0
  280. package/dist/references/aicm.d.ts +41 -0
  281. package/dist/references/aicm.d.ts.map +1 -0
  282. package/dist/references/aicm.js +447 -0
  283. package/dist/references/aicm.js.map +1 -0
  284. package/dist/references/dstg-meaid.d.ts +59 -0
  285. package/dist/references/dstg-meaid.d.ts.map +1 -0
  286. package/dist/references/dstg-meaid.js +352 -0
  287. package/dist/references/dstg-meaid.js.map +1 -0
  288. package/dist/references/index.d.ts +20 -0
  289. package/dist/references/index.d.ts.map +1 -0
  290. package/dist/references/index.js +31 -0
  291. package/dist/references/index.js.map +1 -0
  292. package/dist/references/nemoclaw.d.ts +48 -0
  293. package/dist/references/nemoclaw.d.ts.map +1 -0
  294. package/dist/references/nemoclaw.js +140 -0
  295. package/dist/references/nemoclaw.js.map +1 -0
  296. package/dist/references/nist-ai-rmf.d.ts +31 -0
  297. package/dist/references/nist-ai-rmf.d.ts.map +1 -0
  298. package/dist/references/nist-ai-rmf.js +627 -0
  299. package/dist/references/nist-ai-rmf.js.map +1 -0
  300. package/dist/references/owasp-agentic-top10.d.ts +50 -0
  301. package/dist/references/owasp-agentic-top10.d.ts.map +1 -0
  302. package/dist/references/owasp-agentic-top10.js +202 -0
  303. package/dist/references/owasp-agentic-top10.js.map +1 -0
  304. package/dist/references/registry-parity.test.d.ts +17 -0
  305. package/dist/references/registry-parity.test.d.ts.map +1 -0
  306. package/dist/references/registry-parity.test.js +87 -0
  307. package/dist/references/registry-parity.test.js.map +1 -0
  308. package/dist/references/registry.d.ts +90 -0
  309. package/dist/references/registry.d.ts.map +1 -0
  310. package/dist/references/registry.js +29 -0
  311. package/dist/references/registry.js.map +1 -0
  312. package/dist/tools/model-eval.d.ts +97 -0
  313. package/dist/tools/model-eval.d.ts.map +1 -0
  314. package/dist/tools/model-eval.js +307 -0
  315. package/dist/tools/model-eval.js.map +1 -0
  316. package/package.json +105 -0
  317. package/schemas/threat-composer-v1.schema.json +966 -0
  318. package/vendor/atlas-release/ATLAS-2026.07.yaml +17877 -0
  319. package/vendor/atlas-release/README.md +41 -0
@@ -0,0 +1,192 @@
1
+ import * as fs from "node:fs";
2
+ import yaml from "js-yaml";
3
+ function normalizeLimit(limit) {
4
+ if (!limit || limit < 1)
5
+ return 50;
6
+ return Math.floor(limit);
7
+ }
8
+ function parseRegexPattern(pattern) {
9
+ const match = /^\/(.+)\/([a-z]*)$/.exec(pattern);
10
+ if (!match)
11
+ return pattern;
12
+ return new RegExp(match[1], match[2]);
13
+ }
14
+ function matchOverlay(traceName, overlays) {
15
+ return overlays.find(({ agentNamePattern }) => {
16
+ if (typeof agentNamePattern === "string") {
17
+ return traceName === agentNamePattern || traceName.includes(agentNamePattern);
18
+ }
19
+ return agentNamePattern.test(traceName);
20
+ });
21
+ }
22
+ function responseSnippet(body) {
23
+ return body.replace(/\s+/g, " ").trim().slice(0, 300);
24
+ }
25
+ async function fetchTracePage(config, page, limit) {
26
+ const url = new URL("/api/public/traces", config.host.endsWith("/") ? config.host : `${config.host}/`);
27
+ url.searchParams.set("limit", String(limit));
28
+ url.searchParams.set("page", String(page));
29
+ if (config.fromDate) {
30
+ url.searchParams.set("fromTimestamp", config.fromDate);
31
+ }
32
+ const credentials = Buffer.from(`${config.publicKey}:${config.secretKey}`).toString("base64");
33
+ const res = await fetch(url, {
34
+ headers: {
35
+ Authorization: `Basic ${credentials}`,
36
+ },
37
+ });
38
+ if (!res.ok) {
39
+ const body = await res.text();
40
+ throw new Error(`Langfuse traces request failed with ${res.status} ${res.statusText}: ${responseSnippet(body)}`);
41
+ }
42
+ const payload = (await res.json());
43
+ if (!payload ||
44
+ typeof payload !== "object" ||
45
+ !Array.isArray(payload.data)) {
46
+ throw new Error(`Langfuse traces response missing data array: ${responseSnippet(JSON.stringify(payload))}`);
47
+ }
48
+ return payload;
49
+ }
50
+ function findFirstModel(traces) {
51
+ for (const trace of traces) {
52
+ for (const observation of trace.observations ?? []) {
53
+ if (observation.type === "GENERATION" && observation.model) {
54
+ return observation.model;
55
+ }
56
+ }
57
+ }
58
+ return "unknown";
59
+ }
60
+ function buildAgentDefinition(group) {
61
+ const { id, name, overlay, traces, } = group;
62
+ const agent = {
63
+ id,
64
+ name,
65
+ model: findFirstModel(traces),
66
+ systemPrompt: overlay.systemPrompt,
67
+ tools: overlay.tools,
68
+ permissions: overlay.permissions,
69
+ deploymentContext: overlay.deploymentContext,
70
+ modelComplexity: overlay.modelComplexity,
71
+ mitigationMultiplier: overlay.mitigationMultiplier,
72
+ finetuned: overlay.finetuned,
73
+ dependencies: overlay.dependencies,
74
+ secretManagement: overlay.secretManagement,
75
+ deployment: overlay.deployment,
76
+ };
77
+ if (overlay.dataSources) {
78
+ agent.dataSources = overlay.dataSources;
79
+ }
80
+ if (overlay.autonomyLevel) {
81
+ agent.autonomyLevel = overlay.autonomyLevel;
82
+ }
83
+ return agent;
84
+ }
85
+ function traceMetadataValue(metadata, key) {
86
+ const value = metadata?.[key];
87
+ return typeof value === "string" && value.length > 0 ? value : undefined;
88
+ }
89
+ function resolveHandoff(fromName, toName, agentsByName) {
90
+ const fromAgent = agentsByName.get(fromName);
91
+ const toAgent = agentsByName.get(toName);
92
+ if (!fromAgent || !toAgent) {
93
+ console.warn(`Skipping handoff ${fromName} -> ${toName}: agent name not found in grouped overlays`);
94
+ return undefined;
95
+ }
96
+ return {
97
+ fromAgentId: fromAgent.id,
98
+ toAgentId: toAgent.id,
99
+ fromAgentName: fromAgent.name,
100
+ toAgentName: toAgent.name,
101
+ };
102
+ }
103
+ function buildHandoffs(groups, agents) {
104
+ const agentsByName = new Map(agents.map((agent) => [agent.name, agent]));
105
+ const handoffs = [];
106
+ const seen = new Set();
107
+ for (const group of groups) {
108
+ for (const trace of group.traces) {
109
+ const handoffTo = traceMetadataValue(trace.metadata, "handoff_to");
110
+ const calledBy = traceMetadataValue(trace.metadata, "calledBy");
111
+ const candidates = [
112
+ handoffTo ? resolveHandoff(group.name, handoffTo, agentsByName) : undefined,
113
+ calledBy ? resolveHandoff(calledBy, group.name, agentsByName) : undefined,
114
+ ];
115
+ for (const candidate of candidates) {
116
+ if (!candidate)
117
+ continue;
118
+ const key = `${candidate.fromAgentId}->${candidate.toAgentId}`;
119
+ if (seen.has(key))
120
+ continue;
121
+ seen.add(key);
122
+ handoffs.push(candidate);
123
+ }
124
+ }
125
+ }
126
+ return handoffs;
127
+ }
128
+ export async function parseLangfuseTraces(config, overlays) {
129
+ const limit = normalizeLimit(config.limit);
130
+ const maxPages = Math.max(1, limit);
131
+ const traces = [];
132
+ for (let page = 1; page <= maxPages && traces.length < limit; page += 1) {
133
+ const response = await fetchTracePage(config, page, limit);
134
+ if (response.data.length === 0)
135
+ break;
136
+ traces.push(...response.data);
137
+ }
138
+ const groupsByName = new Map();
139
+ const warnedUnmatchedNames = new Set();
140
+ for (const trace of traces.slice(0, limit)) {
141
+ const overlay = matchOverlay(trace.name, overlays);
142
+ if (!overlay) {
143
+ if (!warnedUnmatchedNames.has(trace.name)) {
144
+ warnedUnmatchedNames.add(trace.name);
145
+ console.warn(`Skipping Langfuse trace "${trace.name}": no matching overlay`);
146
+ }
147
+ continue;
148
+ }
149
+ const existing = groupsByName.get(trace.name);
150
+ if (existing) {
151
+ existing.traces.push(trace);
152
+ continue;
153
+ }
154
+ groupsByName.set(trace.name, {
155
+ id: trace.id,
156
+ name: trace.name,
157
+ overlay,
158
+ traces: [trace],
159
+ });
160
+ }
161
+ const groups = Array.from(groupsByName.values());
162
+ const agents = groups.map(buildAgentDefinition);
163
+ const handoffs = buildHandoffs(groups, agents);
164
+ return {
165
+ agents,
166
+ handoffs,
167
+ workflowName: config.projectId
168
+ ? `Langfuse Assessment - ${config.projectId}`
169
+ : "Langfuse Assessment",
170
+ };
171
+ }
172
+ export function loadOverlaysFromYaml(filePath) {
173
+ const text = fs.readFileSync(filePath, "utf8");
174
+ const parsed = yaml.load(text);
175
+ if (!Array.isArray(parsed)) {
176
+ throw new Error(`Overlay YAML at ${filePath} must contain an array`);
177
+ }
178
+ return parsed.map((entry, index) => {
179
+ if (!entry || typeof entry !== "object") {
180
+ throw new Error(`Overlay at index ${index} in ${filePath} must be an object`);
181
+ }
182
+ const overlay = entry;
183
+ if (typeof overlay.agentNamePattern !== "string") {
184
+ throw new Error(`Overlay at index ${index} in ${filePath} must define agentNamePattern`);
185
+ }
186
+ return {
187
+ ...overlay,
188
+ agentNamePattern: parseRegexPattern(overlay.agentNamePattern),
189
+ };
190
+ });
191
+ }
192
+ //# sourceMappingURL=langfuse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langfuse.js","sourceRoot":"","sources":["../../src/adapters/langfuse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { AgentDefinition } from "../aivss/types";
2
+ import type { AdapterResult, N8NWorkflow } from "./types";
3
+ export declare function parseN8NWorkflow(workflow: N8NWorkflow, defaults?: Partial<AgentDefinition>): AdapterResult;
4
+ //# sourceMappingURL=n8n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"n8n.d.ts","sourceRoot":"","sources":["../../src/adapters/n8n.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EACV,aAAa,EAGb,WAAW,EACZ,MAAM,SAAS,CAAC;AA6CjB,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,WAAW,EACrB,QAAQ,GAAE,OAAO,CAAC,eAAe,CAAM,GACtC,aAAa,CAkDf"}
@@ -0,0 +1,89 @@
1
+ // Recognised AI Agent node type substrings (case-insensitive).
2
+ // Anything matching these is treated as an agent surface for assessment.
3
+ const AGENT_TYPE_HINTS = [
4
+ "agent",
5
+ "llm",
6
+ "lmchat",
7
+ "openaiassistant",
8
+ ".lm",
9
+ ];
10
+ function isAgentNode(node) {
11
+ const t = node.type.toLowerCase();
12
+ return AGENT_TYPE_HINTS.some((hint) => t.includes(hint));
13
+ }
14
+ function readString(obj, key) {
15
+ const v = obj[key];
16
+ return typeof v === "string" && v.length > 0 ? v : undefined;
17
+ }
18
+ function extractSystemPrompt(params) {
19
+ const options = params["options"] ?? {};
20
+ return (readString(options, "systemMessage") ??
21
+ readString(params, "systemMessage") ??
22
+ readString(params, "prompt") ??
23
+ readString(params, "text") ??
24
+ "");
25
+ }
26
+ function extractModel(params) {
27
+ // N8N stores model in various shapes depending on node version.
28
+ const direct = readString(params, "model");
29
+ if (direct)
30
+ return direct;
31
+ const modelObj = params["model"];
32
+ if (modelObj && typeof modelObj === "object") {
33
+ const value = readString(modelObj, "value");
34
+ if (value)
35
+ return value;
36
+ }
37
+ return "unknown";
38
+ }
39
+ export function parseN8NWorkflow(workflow, defaults = {}) {
40
+ const agentNodes = workflow.nodes.filter(isAgentNode);
41
+ const agentNodeIds = new Set(agentNodes.map((n) => n.id));
42
+ const agentNodeByName = new Map(agentNodes.map((n) => [n.name, n]));
43
+ const agents = agentNodes.map((node) => ({
44
+ id: node.id,
45
+ name: node.name,
46
+ model: extractModel(node.parameters),
47
+ systemPrompt: extractSystemPrompt(node.parameters),
48
+ tools: defaults.tools ?? [],
49
+ permissions: defaults.permissions ?? [],
50
+ deploymentContext: defaults.deploymentContext ?? "General",
51
+ modelComplexity: defaults.modelComplexity ?? "Moderate",
52
+ mitigationMultiplier: defaults.mitigationMultiplier ?? 1.2,
53
+ finetuned: defaults.finetuned ?? false,
54
+ dependencies: defaults.dependencies ?? [],
55
+ secretManagement: defaults.secretManagement ?? "Not specified",
56
+ deployment: defaults.deployment ?? "N8N workflow",
57
+ }));
58
+ // Build handoff edges: connections are keyed by source NODE NAME, and each
59
+ // inner array element references the destination by NAME as well.
60
+ const handoffs = [];
61
+ for (const [fromName, conn] of Object.entries(workflow.connections)) {
62
+ const fromNode = agentNodeByName.get(fromName);
63
+ if (!fromNode)
64
+ continue; // non-agent source — skip
65
+ const mainGroups = conn.main ?? [];
66
+ for (const group of mainGroups) {
67
+ for (const target of group) {
68
+ const toNode = agentNodeByName.get(target.node);
69
+ if (!toNode)
70
+ continue; // target is not an agent — skip
71
+ if (!agentNodeIds.has(fromNode.id) || !agentNodeIds.has(toNode.id)) {
72
+ continue;
73
+ }
74
+ handoffs.push({
75
+ fromAgentId: fromNode.id,
76
+ toAgentId: toNode.id,
77
+ fromAgentName: fromNode.name,
78
+ toAgentName: toNode.name,
79
+ });
80
+ }
81
+ }
82
+ }
83
+ return {
84
+ agents,
85
+ handoffs,
86
+ workflowName: workflow.name ?? "N8N Workflow",
87
+ };
88
+ }
89
+ //# sourceMappingURL=n8n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"n8n.js","sourceRoot":"","sources":["../../src/adapters/n8n.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * OpenClaw Adapter — Tier 3 (Capability Surface)
3
+ *
4
+ * Reads a live OpenClaw installation and produces AgentDefinition[] for
5
+ * Canopy threat assessment. No instrumentation or code changes required —
6
+ * the adapter reads `~/.openclaw/openclaw.json` and the skill workspace.
7
+ *
8
+ * Threat surface coverage:
9
+ * - Skills → tools (each SKILL.md = one Tool; skills with apiKey marked dangerous)
10
+ * - Channels → permissions (each enabled channel = read/write permission)
11
+ * - Browser automation → dangerous tool if browser.enabled
12
+ * - Cron → mandatory CRON_AUTONOMOUS_EXECUTION finding on AA metric
13
+ * - MCP servers → supply-chain dependency (CS metric surface)
14
+ * - Multi-agent bindings → HandoffEdge[] (AD metric surface)
15
+ * - Plugins → additional dependencies
16
+ *
17
+ * Mandatory findings (injected as tool descriptions, flagged for assembler):
18
+ * - UNDECLARED_CAPABILITY_RISK: skills without readable SKILL.md
19
+ * - CRON_AUTONOMOUS_EXECUTION: cron.enabled = true
20
+ * - MESSAGING_CHANNEL_ACCESS: one finding per enabled channel
21
+ *
22
+ * Config path resolution order:
23
+ * 1. Explicit `configPath` argument
24
+ * 2. OPENCLAW_CONFIG_PATH env var
25
+ * 3. OPENCLAW_STATE_DIR env var + "/openclaw.json"
26
+ * 4. ~/.openclaw/openclaw.json (default)
27
+ * 5. Legacy: ~/.clawdbot/clawdbot.json
28
+ *
29
+ * Reference: https://github.com/openclaw/openclaw
30
+ */
31
+ import type { AgentDefinition, DeploymentContext } from "../aivss/types.js";
32
+ import type { HandoffEdge } from "./types.js";
33
+ export interface OpenClawAdapterOptions {
34
+ /** Path to openclaw.json. Defaults to ~/.openclaw/openclaw.json. */
35
+ configPath?: string;
36
+ /** Override deployment context. Default: "General". */
37
+ deploymentContext?: DeploymentContext;
38
+ }
39
+ export interface OpenClawAdapterResult {
40
+ agents: AgentDefinition[];
41
+ handoffs: HandoffEdge[];
42
+ /** Skills that had no SKILL.md — UNDECLARED_CAPABILITY_RISK */
43
+ undeclaredSkills: string[];
44
+ /** Resolved config path that was read */
45
+ resolvedConfigPath: string;
46
+ }
47
+ /**
48
+ * Parse a live OpenClaw installation into AgentDefinition[] for Canopy assessment.
49
+ *
50
+ * @example
51
+ * const { agents, handoffs } = await parseOpenClawConfig();
52
+ * const tcFormat = await assessWorkflow({
53
+ * input: { type: "agents", agents, handoffs },
54
+ * applicationName: "My OpenClaw Assistant",
55
+ * });
56
+ */
57
+ export declare function parseOpenClawConfig(options?: OpenClawAdapterOptions): OpenClawAdapterResult;
58
+ //# sourceMappingURL=openclaw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAQ,MAAM,mBAAmB,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA8L9C,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,yCAAyC;IACzC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAsGvB"}
@@ -0,0 +1,275 @@
1
+ /**
2
+ * OpenClaw Adapter — Tier 3 (Capability Surface)
3
+ *
4
+ * Reads a live OpenClaw installation and produces AgentDefinition[] for
5
+ * Canopy threat assessment. No instrumentation or code changes required —
6
+ * the adapter reads `~/.openclaw/openclaw.json` and the skill workspace.
7
+ *
8
+ * Threat surface coverage:
9
+ * - Skills → tools (each SKILL.md = one Tool; skills with apiKey marked dangerous)
10
+ * - Channels → permissions (each enabled channel = read/write permission)
11
+ * - Browser automation → dangerous tool if browser.enabled
12
+ * - Cron → mandatory CRON_AUTONOMOUS_EXECUTION finding on AA metric
13
+ * - MCP servers → supply-chain dependency (CS metric surface)
14
+ * - Multi-agent bindings → HandoffEdge[] (AD metric surface)
15
+ * - Plugins → additional dependencies
16
+ *
17
+ * Mandatory findings (injected as tool descriptions, flagged for assembler):
18
+ * - UNDECLARED_CAPABILITY_RISK: skills without readable SKILL.md
19
+ * - CRON_AUTONOMOUS_EXECUTION: cron.enabled = true
20
+ * - MESSAGING_CHANNEL_ACCESS: one finding per enabled channel
21
+ *
22
+ * Config path resolution order:
23
+ * 1. Explicit `configPath` argument
24
+ * 2. OPENCLAW_CONFIG_PATH env var
25
+ * 3. OPENCLAW_STATE_DIR env var + "/openclaw.json"
26
+ * 4. ~/.openclaw/openclaw.json (default)
27
+ * 5. Legacy: ~/.clawdbot/clawdbot.json
28
+ *
29
+ * Reference: https://github.com/openclaw/openclaw
30
+ */
31
+ import * as fs from "node:fs";
32
+ import * as path from "node:path";
33
+ import * as os from "node:os";
34
+ // ── Path resolution ───────────────────────────────────────────────────────────
35
+ function resolveConfigPath(explicit) {
36
+ if (explicit)
37
+ return explicit;
38
+ if (process.env["OPENCLAW_CONFIG_PATH"])
39
+ return process.env["OPENCLAW_CONFIG_PATH"];
40
+ const stateDir = process.env["OPENCLAW_STATE_DIR"]?.trim();
41
+ if (stateDir)
42
+ return path.join(stateDir, "openclaw.json");
43
+ const home = os.homedir();
44
+ const candidates = [
45
+ path.join(home, ".openclaw", "openclaw.json"),
46
+ path.join(home, ".clawdbot", "clawdbot.json"), // legacy
47
+ ];
48
+ for (const c of candidates) {
49
+ if (fs.existsSync(c))
50
+ return c;
51
+ }
52
+ return candidates[0]; // return default even if missing — caller handles
53
+ }
54
+ function resolveWorkspaceDir(configPath) {
55
+ return path.join(path.dirname(configPath), "workspace");
56
+ }
57
+ // ── Skills → Tools ────────────────────────────────────────────────────────────
58
+ function readSkillMd(skillDir) {
59
+ const p = path.join(skillDir, "SKILL.md");
60
+ try {
61
+ return fs.readFileSync(p, "utf-8");
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ function extractSkillDescription(skillMd) {
68
+ // First non-empty line after the title, or first 200 chars
69
+ const lines = skillMd.split("\n").map((l) => l.trim()).filter(Boolean);
70
+ const descLine = lines.find((l) => !l.startsWith("#"));
71
+ return descLine?.slice(0, 200) ?? skillMd.slice(0, 200);
72
+ }
73
+ function loadSkillTools(workspaceDir, skillEntries, extraDirs) {
74
+ const tools = [];
75
+ const undeclaredSkills = [];
76
+ const skillDirs = [
77
+ path.join(workspaceDir, "skills"),
78
+ ...extraDirs,
79
+ ];
80
+ const seenSkills = new Set();
81
+ for (const skillsRoot of skillDirs) {
82
+ if (!fs.existsSync(skillsRoot))
83
+ continue;
84
+ let entries;
85
+ try {
86
+ entries = fs.readdirSync(skillsRoot);
87
+ }
88
+ catch {
89
+ continue;
90
+ }
91
+ for (const skillName of entries) {
92
+ if (seenSkills.has(skillName))
93
+ continue;
94
+ seenSkills.add(skillName);
95
+ const skillDir = path.join(skillsRoot, skillName);
96
+ const stat = fs.statSync(skillDir, { throwIfNoEntry: false });
97
+ if (!stat?.isDirectory())
98
+ continue;
99
+ const config = skillEntries[skillName] ?? {};
100
+ if (config.enabled === false)
101
+ continue;
102
+ const skillMd = readSkillMd(skillDir);
103
+ if (!skillMd) {
104
+ undeclaredSkills.push(skillName);
105
+ tools.push({
106
+ name: skillName,
107
+ description: `[UNDECLARED_CAPABILITY_RISK] Skill "${skillName}" has no SKILL.md — capabilities unknown. Canopy cannot assess what this skill does or what external services it accesses.`,
108
+ dangerous: true,
109
+ });
110
+ continue;
111
+ }
112
+ const hasCreds = config.apiKey !== undefined && config.apiKey !== null;
113
+ tools.push({
114
+ name: skillName,
115
+ description: extractSkillDescription(skillMd),
116
+ dangerous: hasCreds, // skills with credentials have external service access
117
+ });
118
+ }
119
+ }
120
+ return { tools, undeclaredSkills };
121
+ }
122
+ // ── Channels → permissions ────────────────────────────────────────────────────
123
+ // Channels with elevated risk — they reach into personal/corporate messaging
124
+ const HIGH_RISK_CHANNELS = new Set([
125
+ "imessage",
126
+ "telegram",
127
+ "signal",
128
+ "whatsapp",
129
+ "slack",
130
+ "msteams",
131
+ "discord",
132
+ ]);
133
+ function channelsToPermissions(channels) {
134
+ const perms = [];
135
+ for (const [channelId, config] of Object.entries(channels)) {
136
+ if (!config || typeof config !== "object")
137
+ continue;
138
+ const cfg = config;
139
+ // Skip clearly disabled channels
140
+ if (cfg["enabled"] === false)
141
+ continue;
142
+ const risk = HIGH_RISK_CHANNELS.has(channelId) ? "high-risk:" : "";
143
+ perms.push(`${risk}read:${channelId}`, `${risk}write:${channelId}`);
144
+ }
145
+ return perms;
146
+ }
147
+ // ── Model extraction ──────────────────────────────────────────────────────────
148
+ function extractModel(models) {
149
+ if (!models)
150
+ return "unknown";
151
+ const d = models.default;
152
+ if (typeof d === "string")
153
+ return d;
154
+ if (typeof d === "object" && d !== null) {
155
+ const provider = d.provider ?? "unknown";
156
+ const model = d.model ?? "unknown";
157
+ return `${provider}/${model}`;
158
+ }
159
+ return "unknown";
160
+ }
161
+ // ── System prompt synthesis ───────────────────────────────────────────────────
162
+ function buildSystemPromptSummary(config, channels, skillCount) {
163
+ const name = config.ui?.assistant?.name ?? "OpenClaw Assistant";
164
+ const channelList = channels.slice(0, 5).join(", ") + (channels.length > 5 ? " and more" : "");
165
+ const hasCron = config.cron?.enabled === true;
166
+ const hasBrowser = config.browser?.enabled === true;
167
+ const mcpCount = Object.keys(config.mcp?.servers ?? {}).length;
168
+ return [
169
+ `You are ${name}, a personal AI assistant running on the user's device.`,
170
+ `You respond to messages across ${channels.length} channels: ${channelList}.`,
171
+ `You have access to ${skillCount} installed skills that extend your capabilities.`,
172
+ hasCron ? "You run scheduled (cron) jobs autonomously without user confirmation." : "",
173
+ hasBrowser ? "You have browser automation capabilities." : "",
174
+ mcpCount > 0 ? `You are connected to ${mcpCount} MCP server(s) for extended tool access.` : "",
175
+ ].filter(Boolean).join(" ");
176
+ }
177
+ /**
178
+ * Parse a live OpenClaw installation into AgentDefinition[] for Canopy assessment.
179
+ *
180
+ * @example
181
+ * const { agents, handoffs } = await parseOpenClawConfig();
182
+ * const tcFormat = await assessWorkflow({
183
+ * input: { type: "agents", agents, handoffs },
184
+ * applicationName: "My OpenClaw Assistant",
185
+ * });
186
+ */
187
+ export function parseOpenClawConfig(options = {}) {
188
+ const configPath = resolveConfigPath(options.configPath);
189
+ if (!fs.existsSync(configPath)) {
190
+ throw new Error(`OpenClaw config not found at ${configPath}. ` +
191
+ "Install OpenClaw first: https://docs.openclaw.ai/start/getting-started");
192
+ }
193
+ let config;
194
+ try {
195
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
196
+ }
197
+ catch (err) {
198
+ throw new Error(`Failed to parse OpenClaw config at ${configPath}: ${String(err)}`);
199
+ }
200
+ const workspaceDir = resolveWorkspaceDir(configPath);
201
+ const skillEntries = config.skills?.entries ?? {};
202
+ const extraDirs = config.skills?.load?.extraDirs ?? [];
203
+ // Skills → tools
204
+ const { tools, undeclaredSkills } = loadSkillTools(workspaceDir, skillEntries, extraDirs);
205
+ // Built-in dangerous tools
206
+ if (config.browser?.enabled) {
207
+ tools.push({
208
+ name: "browser",
209
+ description: "Browser automation — navigate pages, fill forms, extract content, execute JS in an active browser session.",
210
+ dangerous: true,
211
+ });
212
+ }
213
+ // MCP servers → tools (each MCP server = a tool surface)
214
+ for (const [serverName] of Object.entries(config.mcp?.servers ?? {})) {
215
+ tools.push({
216
+ name: `mcp:${serverName}`,
217
+ description: `MCP server "${serverName}" — provides additional tools via the Model Context Protocol. Capabilities depend on server implementation.`,
218
+ dangerous: true,
219
+ });
220
+ }
221
+ // Channels → permissions
222
+ const channels = config.channels ?? {};
223
+ const activeChannels = Object.keys(channels).filter((id) => {
224
+ const ch = channels[id];
225
+ return ch && typeof ch === "object" && ch["enabled"] !== false;
226
+ });
227
+ const permissions = channelsToPermissions(channels);
228
+ // Cron → adds CRON_AUTONOMOUS_EXECUTION tool finding
229
+ if (config.cron?.enabled) {
230
+ tools.push({
231
+ name: "cron-scheduler",
232
+ description: "[CRON_AUTONOMOUS_EXECUTION] OpenClaw runs scheduled jobs autonomously (cron.enabled=true). " +
233
+ "The assistant can execute arbitrary tool chains on a schedule without per-execution user confirmation. " +
234
+ "This represents an autonomous execution surface that increases AA (Agentic Autonomy) risk.",
235
+ dangerous: true,
236
+ });
237
+ }
238
+ // Dependencies
239
+ const dependencies = [
240
+ ...activeChannels.map((c) => `channel:${c}`),
241
+ ...Object.keys(config.mcp?.servers ?? {}).map((s) => `mcp:${s}`),
242
+ ...Object.keys(config.plugins ?? {}).map((p) => `plugin:${p}`),
243
+ ];
244
+ const model = extractModel(config.models);
245
+ const systemPrompt = buildSystemPromptSummary(config, activeChannels, tools.length);
246
+ const agent = {
247
+ id: "openclaw-gateway",
248
+ name: config.ui?.assistant?.name ?? "OpenClaw Gateway",
249
+ model,
250
+ systemPrompt,
251
+ tools,
252
+ permissions,
253
+ deploymentContext: options.deploymentContext ?? "General",
254
+ modelComplexity: tools.length > 10 ? "Complex" : tools.length > 4 ? "Moderate" : "Simple",
255
+ mitigationMultiplier: undeclaredSkills.length > 0 ? 1.3 : 1.0,
256
+ finetuned: false,
257
+ dependencies,
258
+ secretManagement: "OpenClaw Secrets Manager",
259
+ deployment: "Local (macOS/Linux personal device)",
260
+ };
261
+ // Multi-agent bindings → HandoffEdge[]
262
+ const handoffs = (config.agents?.bindings ?? []).map((binding) => ({
263
+ fromAgentId: binding.from ?? "openclaw-gateway",
264
+ toAgentId: binding.to ?? "unknown-agent",
265
+ fromAgentName: binding.from ?? "OpenClaw Gateway",
266
+ toAgentName: binding.name ?? binding.to ?? "Sub-agent",
267
+ }));
268
+ return {
269
+ agents: [agent],
270
+ handoffs,
271
+ undeclaredSkills,
272
+ resolvedConfigPath: configPath,
273
+ };
274
+ }
275
+ //# sourceMappingURL=openclaw.js.map