@animus-labs/cortex 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/budget-guard.d.ts +75 -0
  4. package/dist/budget-guard.d.ts.map +1 -0
  5. package/dist/budget-guard.js +142 -0
  6. package/dist/budget-guard.js.map +1 -0
  7. package/dist/compaction/compaction.d.ts +99 -0
  8. package/dist/compaction/compaction.d.ts.map +1 -0
  9. package/dist/compaction/compaction.js +302 -0
  10. package/dist/compaction/compaction.js.map +1 -0
  11. package/dist/compaction/failsafe.d.ts +57 -0
  12. package/dist/compaction/failsafe.d.ts.map +1 -0
  13. package/dist/compaction/failsafe.js +135 -0
  14. package/dist/compaction/failsafe.js.map +1 -0
  15. package/dist/compaction/index.d.ts +381 -0
  16. package/dist/compaction/index.d.ts.map +1 -0
  17. package/dist/compaction/index.js +979 -0
  18. package/dist/compaction/index.js.map +1 -0
  19. package/dist/compaction/microcompaction.d.ts +219 -0
  20. package/dist/compaction/microcompaction.d.ts.map +1 -0
  21. package/dist/compaction/microcompaction.js +536 -0
  22. package/dist/compaction/microcompaction.js.map +1 -0
  23. package/dist/compaction/observational/buffering.d.ts +225 -0
  24. package/dist/compaction/observational/buffering.d.ts.map +1 -0
  25. package/dist/compaction/observational/buffering.js +354 -0
  26. package/dist/compaction/observational/buffering.js.map +1 -0
  27. package/dist/compaction/observational/constants.d.ts +70 -0
  28. package/dist/compaction/observational/constants.d.ts.map +1 -0
  29. package/dist/compaction/observational/constants.js +507 -0
  30. package/dist/compaction/observational/constants.js.map +1 -0
  31. package/dist/compaction/observational/index.d.ts +219 -0
  32. package/dist/compaction/observational/index.d.ts.map +1 -0
  33. package/dist/compaction/observational/index.js +641 -0
  34. package/dist/compaction/observational/index.js.map +1 -0
  35. package/dist/compaction/observational/observer.d.ts +97 -0
  36. package/dist/compaction/observational/observer.d.ts.map +1 -0
  37. package/dist/compaction/observational/observer.js +424 -0
  38. package/dist/compaction/observational/observer.js.map +1 -0
  39. package/dist/compaction/observational/recall-tool.d.ts +27 -0
  40. package/dist/compaction/observational/recall-tool.d.ts.map +1 -0
  41. package/dist/compaction/observational/recall-tool.js +93 -0
  42. package/dist/compaction/observational/recall-tool.js.map +1 -0
  43. package/dist/compaction/observational/reflector.d.ts +94 -0
  44. package/dist/compaction/observational/reflector.d.ts.map +1 -0
  45. package/dist/compaction/observational/reflector.js +167 -0
  46. package/dist/compaction/observational/reflector.js.map +1 -0
  47. package/dist/compaction/observational/types.d.ts +271 -0
  48. package/dist/compaction/observational/types.d.ts.map +1 -0
  49. package/dist/compaction/observational/types.js +15 -0
  50. package/dist/compaction/observational/types.js.map +1 -0
  51. package/dist/context-manager.d.ts +134 -0
  52. package/dist/context-manager.d.ts.map +1 -0
  53. package/dist/context-manager.js +170 -0
  54. package/dist/context-manager.js.map +1 -0
  55. package/dist/cortex-agent.d.ts +1020 -0
  56. package/dist/cortex-agent.d.ts.map +1 -0
  57. package/dist/cortex-agent.js +3589 -0
  58. package/dist/cortex-agent.js.map +1 -0
  59. package/dist/error-classifier.d.ts +48 -0
  60. package/dist/error-classifier.d.ts.map +1 -0
  61. package/dist/error-classifier.js +152 -0
  62. package/dist/error-classifier.js.map +1 -0
  63. package/dist/event-bridge.d.ts +166 -0
  64. package/dist/event-bridge.d.ts.map +1 -0
  65. package/dist/event-bridge.js +381 -0
  66. package/dist/event-bridge.js.map +1 -0
  67. package/dist/index.d.ts +55 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +57 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/mcp-client.d.ts +119 -0
  72. package/dist/mcp-client.d.ts.map +1 -0
  73. package/dist/mcp-client.js +474 -0
  74. package/dist/mcp-client.js.map +1 -0
  75. package/dist/model-wrapper.d.ts +58 -0
  76. package/dist/model-wrapper.d.ts.map +1 -0
  77. package/dist/model-wrapper.js +86 -0
  78. package/dist/model-wrapper.js.map +1 -0
  79. package/dist/noop-logger.d.ts +4 -0
  80. package/dist/noop-logger.d.ts.map +1 -0
  81. package/dist/noop-logger.js +8 -0
  82. package/dist/noop-logger.js.map +1 -0
  83. package/dist/prompt-diagnostics.d.ts +47 -0
  84. package/dist/prompt-diagnostics.d.ts.map +1 -0
  85. package/dist/prompt-diagnostics.js +230 -0
  86. package/dist/prompt-diagnostics.js.map +1 -0
  87. package/dist/provider-manager.d.ts +224 -0
  88. package/dist/provider-manager.d.ts.map +1 -0
  89. package/dist/provider-manager.js +563 -0
  90. package/dist/provider-manager.js.map +1 -0
  91. package/dist/provider-registry.d.ts +115 -0
  92. package/dist/provider-registry.d.ts.map +1 -0
  93. package/dist/provider-registry.js +305 -0
  94. package/dist/provider-registry.js.map +1 -0
  95. package/dist/schema-converter.d.ts +20 -0
  96. package/dist/schema-converter.d.ts.map +1 -0
  97. package/dist/schema-converter.js +48 -0
  98. package/dist/schema-converter.js.map +1 -0
  99. package/dist/skill-preprocessor.d.ts +46 -0
  100. package/dist/skill-preprocessor.d.ts.map +1 -0
  101. package/dist/skill-preprocessor.js +237 -0
  102. package/dist/skill-preprocessor.js.map +1 -0
  103. package/dist/skill-registry.d.ts +107 -0
  104. package/dist/skill-registry.d.ts.map +1 -0
  105. package/dist/skill-registry.js +330 -0
  106. package/dist/skill-registry.js.map +1 -0
  107. package/dist/skill-tool.d.ts +54 -0
  108. package/dist/skill-tool.d.ts.map +1 -0
  109. package/dist/skill-tool.js +88 -0
  110. package/dist/skill-tool.js.map +1 -0
  111. package/dist/sub-agent-manager.d.ts +90 -0
  112. package/dist/sub-agent-manager.d.ts.map +1 -0
  113. package/dist/sub-agent-manager.js +192 -0
  114. package/dist/sub-agent-manager.js.map +1 -0
  115. package/dist/token-estimator.d.ts +23 -0
  116. package/dist/token-estimator.d.ts.map +1 -0
  117. package/dist/token-estimator.js +27 -0
  118. package/dist/token-estimator.js.map +1 -0
  119. package/dist/tool-contract.d.ts +68 -0
  120. package/dist/tool-contract.d.ts.map +1 -0
  121. package/dist/tool-contract.js +35 -0
  122. package/dist/tool-contract.js.map +1 -0
  123. package/dist/tool-result-persistence.d.ts +89 -0
  124. package/dist/tool-result-persistence.d.ts.map +1 -0
  125. package/dist/tool-result-persistence.js +152 -0
  126. package/dist/tool-result-persistence.js.map +1 -0
  127. package/dist/tools/bash/index.d.ts +71 -0
  128. package/dist/tools/bash/index.d.ts.map +1 -0
  129. package/dist/tools/bash/index.js +485 -0
  130. package/dist/tools/bash/index.js.map +1 -0
  131. package/dist/tools/bash/interactive.d.ts +47 -0
  132. package/dist/tools/bash/interactive.d.ts.map +1 -0
  133. package/dist/tools/bash/interactive.js +262 -0
  134. package/dist/tools/bash/interactive.js.map +1 -0
  135. package/dist/tools/bash/safety.d.ts +149 -0
  136. package/dist/tools/bash/safety.d.ts.map +1 -0
  137. package/dist/tools/bash/safety.js +1116 -0
  138. package/dist/tools/bash/safety.js.map +1 -0
  139. package/dist/tools/edit.d.ts +57 -0
  140. package/dist/tools/edit.d.ts.map +1 -0
  141. package/dist/tools/edit.js +310 -0
  142. package/dist/tools/edit.js.map +1 -0
  143. package/dist/tools/glob.d.ts +34 -0
  144. package/dist/tools/glob.d.ts.map +1 -0
  145. package/dist/tools/glob.js +268 -0
  146. package/dist/tools/glob.js.map +1 -0
  147. package/dist/tools/grep.d.ts +53 -0
  148. package/dist/tools/grep.d.ts.map +1 -0
  149. package/dist/tools/grep.js +673 -0
  150. package/dist/tools/grep.js.map +1 -0
  151. package/dist/tools/index.d.ts +62 -0
  152. package/dist/tools/index.d.ts.map +1 -0
  153. package/dist/tools/index.js +52 -0
  154. package/dist/tools/index.js.map +1 -0
  155. package/dist/tools/read.d.ts +43 -0
  156. package/dist/tools/read.d.ts.map +1 -0
  157. package/dist/tools/read.js +459 -0
  158. package/dist/tools/read.js.map +1 -0
  159. package/dist/tools/runtime.d.ts +62 -0
  160. package/dist/tools/runtime.d.ts.map +1 -0
  161. package/dist/tools/runtime.js +116 -0
  162. package/dist/tools/runtime.js.map +1 -0
  163. package/dist/tools/shared/cwd-tracker.d.ts +32 -0
  164. package/dist/tools/shared/cwd-tracker.d.ts.map +1 -0
  165. package/dist/tools/shared/cwd-tracker.js +44 -0
  166. package/dist/tools/shared/cwd-tracker.js.map +1 -0
  167. package/dist/tools/shared/edit-history.d.ts +55 -0
  168. package/dist/tools/shared/edit-history.d.ts.map +1 -0
  169. package/dist/tools/shared/edit-history.js +72 -0
  170. package/dist/tools/shared/edit-history.js.map +1 -0
  171. package/dist/tools/shared/edit-matcher.d.ts +83 -0
  172. package/dist/tools/shared/edit-matcher.d.ts.map +1 -0
  173. package/dist/tools/shared/edit-matcher.js +359 -0
  174. package/dist/tools/shared/edit-matcher.js.map +1 -0
  175. package/dist/tools/shared/file-mutation-lock.d.ts +22 -0
  176. package/dist/tools/shared/file-mutation-lock.d.ts.map +1 -0
  177. package/dist/tools/shared/file-mutation-lock.js +35 -0
  178. package/dist/tools/shared/file-mutation-lock.js.map +1 -0
  179. package/dist/tools/shared/gitignore.d.ts +17 -0
  180. package/dist/tools/shared/gitignore.d.ts.map +1 -0
  181. package/dist/tools/shared/gitignore.js +59 -0
  182. package/dist/tools/shared/gitignore.js.map +1 -0
  183. package/dist/tools/shared/pdf-extractor.d.ts +96 -0
  184. package/dist/tools/shared/pdf-extractor.d.ts.map +1 -0
  185. package/dist/tools/shared/pdf-extractor.js +196 -0
  186. package/dist/tools/shared/pdf-extractor.js.map +1 -0
  187. package/dist/tools/shared/read-registry.d.ts +66 -0
  188. package/dist/tools/shared/read-registry.d.ts.map +1 -0
  189. package/dist/tools/shared/read-registry.js +65 -0
  190. package/dist/tools/shared/read-registry.js.map +1 -0
  191. package/dist/tools/shared/safe-env.d.ts +18 -0
  192. package/dist/tools/shared/safe-env.d.ts.map +1 -0
  193. package/dist/tools/shared/safe-env.js +70 -0
  194. package/dist/tools/shared/safe-env.js.map +1 -0
  195. package/dist/tools/sub-agent.d.ts +91 -0
  196. package/dist/tools/sub-agent.d.ts.map +1 -0
  197. package/dist/tools/sub-agent.js +89 -0
  198. package/dist/tools/sub-agent.js.map +1 -0
  199. package/dist/tools/task-output.d.ts +38 -0
  200. package/dist/tools/task-output.d.ts.map +1 -0
  201. package/dist/tools/task-output.js +186 -0
  202. package/dist/tools/task-output.js.map +1 -0
  203. package/dist/tools/tool-search/index.d.ts +40 -0
  204. package/dist/tools/tool-search/index.d.ts.map +1 -0
  205. package/dist/tools/tool-search/index.js +110 -0
  206. package/dist/tools/tool-search/index.js.map +1 -0
  207. package/dist/tools/tool-search/registry.d.ts +82 -0
  208. package/dist/tools/tool-search/registry.d.ts.map +1 -0
  209. package/dist/tools/tool-search/registry.js +238 -0
  210. package/dist/tools/tool-search/registry.js.map +1 -0
  211. package/dist/tools/undo-edit.d.ts +51 -0
  212. package/dist/tools/undo-edit.d.ts.map +1 -0
  213. package/dist/tools/undo-edit.js +231 -0
  214. package/dist/tools/undo-edit.js.map +1 -0
  215. package/dist/tools/web-fetch/cache.d.ts +49 -0
  216. package/dist/tools/web-fetch/cache.d.ts.map +1 -0
  217. package/dist/tools/web-fetch/cache.js +89 -0
  218. package/dist/tools/web-fetch/cache.js.map +1 -0
  219. package/dist/tools/web-fetch/index.d.ts +53 -0
  220. package/dist/tools/web-fetch/index.d.ts.map +1 -0
  221. package/dist/tools/web-fetch/index.js +513 -0
  222. package/dist/tools/web-fetch/index.js.map +1 -0
  223. package/dist/tools/write.d.ts +59 -0
  224. package/dist/tools/write.d.ts.map +1 -0
  225. package/dist/tools/write.js +316 -0
  226. package/dist/tools/write.js.map +1 -0
  227. package/dist/types.d.ts +881 -0
  228. package/dist/types.d.ts.map +1 -0
  229. package/dist/types.js +16 -0
  230. package/dist/types.js.map +1 -0
  231. package/dist/working-tags.d.ts +44 -0
  232. package/dist/working-tags.d.ts.map +1 -0
  233. package/dist/working-tags.js +103 -0
  234. package/dist/working-tags.js.map +1 -0
  235. package/package.json +87 -0
  236. package/src/budget-guard.ts +170 -0
  237. package/src/compaction/compaction.ts +386 -0
  238. package/src/compaction/failsafe.ts +185 -0
  239. package/src/compaction/index.ts +1199 -0
  240. package/src/compaction/microcompaction.ts +709 -0
  241. package/src/compaction/observational/buffering.ts +430 -0
  242. package/src/compaction/observational/constants.ts +532 -0
  243. package/src/compaction/observational/index.ts +837 -0
  244. package/src/compaction/observational/observer.ts +510 -0
  245. package/src/compaction/observational/recall-tool.ts +130 -0
  246. package/src/compaction/observational/reflector.ts +221 -0
  247. package/src/compaction/observational/types.ts +343 -0
  248. package/src/context-manager.ts +237 -0
  249. package/src/cortex-agent.ts +4297 -0
  250. package/src/error-classifier.ts +199 -0
  251. package/src/event-bridge.ts +508 -0
  252. package/src/index.ts +292 -0
  253. package/src/mcp-client.ts +582 -0
  254. package/src/model-wrapper.ts +128 -0
  255. package/src/noop-logger.ts +9 -0
  256. package/src/prompt-diagnostics.ts +296 -0
  257. package/src/provider-manager.ts +823 -0
  258. package/src/provider-registry.ts +386 -0
  259. package/src/schema-converter.ts +51 -0
  260. package/src/skill-preprocessor.ts +314 -0
  261. package/src/skill-registry.ts +378 -0
  262. package/src/skill-tool.ts +130 -0
  263. package/src/sub-agent-manager.ts +236 -0
  264. package/src/token-estimator.ts +26 -0
  265. package/src/tool-contract.ts +113 -0
  266. package/src/tool-result-persistence.ts +197 -0
  267. package/src/tools/bash/index.ts +633 -0
  268. package/src/tools/bash/interactive.ts +302 -0
  269. package/src/tools/bash/safety.ts +1297 -0
  270. package/src/tools/edit.ts +422 -0
  271. package/src/tools/glob.ts +330 -0
  272. package/src/tools/grep.ts +819 -0
  273. package/src/tools/index.ts +110 -0
  274. package/src/tools/read.ts +580 -0
  275. package/src/tools/runtime.ts +173 -0
  276. package/src/tools/shared/cwd-tracker.ts +50 -0
  277. package/src/tools/shared/edit-history.ts +96 -0
  278. package/src/tools/shared/edit-matcher.ts +457 -0
  279. package/src/tools/shared/file-mutation-lock.ts +40 -0
  280. package/src/tools/shared/gitignore.ts +61 -0
  281. package/src/tools/shared/pdf-extractor.ts +290 -0
  282. package/src/tools/shared/read-registry.ts +93 -0
  283. package/src/tools/shared/safe-env.ts +82 -0
  284. package/src/tools/sub-agent.ts +171 -0
  285. package/src/tools/task-output.ts +236 -0
  286. package/src/tools/tool-search/index.ts +167 -0
  287. package/src/tools/tool-search/registry.ts +278 -0
  288. package/src/tools/undo-edit.ts +314 -0
  289. package/src/tools/web-fetch/cache.ts +112 -0
  290. package/src/tools/web-fetch/index.ts +604 -0
  291. package/src/tools/write.ts +385 -0
  292. package/src/types.ts +1057 -0
  293. package/src/working-tags.ts +118 -0
@@ -0,0 +1,330 @@
1
+ /**
2
+ * SkillRegistry: manages all known skills for the Cortex agent.
3
+ *
4
+ * Config-driven: the consumer provides paths to SKILL.md files from any
5
+ * source (plugins, user directories, built-ins). The registry does not
6
+ * scan directories.
7
+ *
8
+ * Skills are parsed at registration time (frontmatter extracted, body
9
+ * deferred to load time). The registry produces a compact summary for
10
+ * the load_skill tool description.
11
+ *
12
+ * References:
13
+ * - docs/cortex/skill-system.md
14
+ * - docs/cortex/plans/phase-4-sub-agents-and-skills.md
15
+ */
16
+ import * as fs from 'node:fs';
17
+ import * as path from 'node:path';
18
+ import { preprocessSkillBody } from './skill-preprocessor.js';
19
+ // ---------------------------------------------------------------------------
20
+ // Frontmatter parsing
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Parse YAML frontmatter from a SKILL.md file.
24
+ * Expects --- delimited frontmatter at the start of the file.
25
+ *
26
+ * This is a lightweight parser that handles the common SKILL.md patterns
27
+ * without requiring a full YAML library. It handles:
28
+ * - Simple key: value pairs
29
+ * - Multi-line strings (using > or |)
30
+ * - Nested metadata maps
31
+ * - Space-delimited lists (for allowed-tools)
32
+ */
33
+ function parseFrontmatter(content) {
34
+ const trimmed = content.trimStart();
35
+ if (!trimmed.startsWith('---')) {
36
+ return { frontmatter: {}, body: content };
37
+ }
38
+ const endIdx = trimmed.indexOf('\n---', 3);
39
+ if (endIdx < 0) {
40
+ return { frontmatter: {}, body: content };
41
+ }
42
+ const yamlBlock = trimmed.substring(3, endIdx).trim();
43
+ const body = trimmed.substring(endIdx + 4).trimStart();
44
+ const frontmatter = {};
45
+ const lines = yamlBlock.split('\n');
46
+ let currentKey = '';
47
+ let multilineValue = '';
48
+ let inMultiline = false;
49
+ let multilineType = '';
50
+ let inMetadata = false;
51
+ const metadataMap = {};
52
+ for (let i = 0; i < lines.length; i++) {
53
+ const line = lines[i];
54
+ // Handle metadata block (indented key-value pairs)
55
+ if (inMetadata) {
56
+ const metaMatch = line.match(/^ {2}(\w[\w-]*)\s*:\s*(.*)$/);
57
+ if (metaMatch) {
58
+ metadataMap[metaMatch[1]] = metaMatch[2].trim();
59
+ continue;
60
+ }
61
+ // End of metadata block
62
+ frontmatter['metadata'] = { ...metadataMap };
63
+ inMetadata = false;
64
+ }
65
+ // Handle multi-line folded/literal values
66
+ if (inMultiline) {
67
+ if (line.startsWith(' ') || line.trim() === '') {
68
+ if (multilineType === '>') {
69
+ multilineValue += (multilineValue ? ' ' : '') + line.trim();
70
+ }
71
+ else {
72
+ multilineValue += (multilineValue ? '\n' : '') + line.trimStart();
73
+ }
74
+ continue;
75
+ }
76
+ // End of multi-line
77
+ frontmatter[currentKey] = multilineValue.trim();
78
+ inMultiline = false;
79
+ multilineValue = '';
80
+ }
81
+ // Parse key: value
82
+ const kvMatch = line.match(/^(\w[\w-]*)\s*:\s*(.*)$/);
83
+ if (kvMatch) {
84
+ const key = kvMatch[1];
85
+ const rawValue = kvMatch[2].trim();
86
+ if (rawValue === '>' || rawValue === '|') {
87
+ currentKey = key;
88
+ multilineType = rawValue;
89
+ multilineValue = '';
90
+ inMultiline = true;
91
+ continue;
92
+ }
93
+ if (key === 'metadata' && rawValue === '') {
94
+ inMetadata = true;
95
+ continue;
96
+ }
97
+ // Parse boolean values
98
+ if (rawValue === 'true') {
99
+ frontmatter[key] = true;
100
+ }
101
+ else if (rawValue === 'false') {
102
+ frontmatter[key] = false;
103
+ }
104
+ else {
105
+ frontmatter[key] = rawValue;
106
+ }
107
+ }
108
+ }
109
+ // Flush any remaining multi-line or metadata
110
+ if (inMultiline && currentKey) {
111
+ frontmatter[currentKey] = multilineValue.trim();
112
+ }
113
+ if (inMetadata && Object.keys(metadataMap).length > 0) {
114
+ frontmatter['metadata'] = { ...metadataMap };
115
+ }
116
+ return { frontmatter, body };
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // SkillRegistry
120
+ // ---------------------------------------------------------------------------
121
+ export class SkillRegistry {
122
+ entries = new Map();
123
+ /** Consumer-provided variables for ${VAR} substitution. */
124
+ preprocessorVariables = {};
125
+ /** Consumer-provided context for !{script:} executions. */
126
+ scriptContext = {};
127
+ /**
128
+ * Callback fired when skills are added or removed.
129
+ * CortexAgent sets this to rebuild the load_skill tool description.
130
+ */
131
+ onChange = null;
132
+ constructor(configs) {
133
+ if (configs) {
134
+ for (const config of configs) {
135
+ this.addSkill(config);
136
+ }
137
+ }
138
+ }
139
+ /**
140
+ * Add a skill from a SKILL.md file path.
141
+ * Reads and parses the frontmatter synchronously at registration time.
142
+ *
143
+ * If a skill with the same name already exists, the new one replaces it
144
+ * (last-registered wins).
145
+ */
146
+ addSkill(config) {
147
+ let content;
148
+ try {
149
+ content = fs.readFileSync(config.path, 'utf8');
150
+ }
151
+ catch (err) {
152
+ // Skill file not readable; skip silently
153
+ return;
154
+ }
155
+ const { frontmatter } = parseFrontmatter(content);
156
+ const name = typeof frontmatter['name'] === 'string'
157
+ ? frontmatter['name']
158
+ : path.basename(path.dirname(config.path));
159
+ const description = typeof frontmatter['description'] === 'string'
160
+ ? frontmatter['description']
161
+ : '';
162
+ const disableModelInvocation = frontmatter['disable-model-invocation'] === true;
163
+ const entry = {
164
+ name,
165
+ description,
166
+ path: config.path,
167
+ dir: path.dirname(config.path),
168
+ source: config.source,
169
+ frontmatter,
170
+ modelInvocable: !disableModelInvocation,
171
+ };
172
+ if (config.variables) {
173
+ entry.variables = config.variables;
174
+ }
175
+ this.entries.set(name, entry);
176
+ this.onChange?.();
177
+ }
178
+ /**
179
+ * Remove a skill by name.
180
+ */
181
+ removeSkill(name) {
182
+ const existed = this.entries.delete(name);
183
+ if (existed) {
184
+ this.onChange?.();
185
+ }
186
+ }
187
+ /**
188
+ * Get a skill entry by name.
189
+ */
190
+ getEntry(name) {
191
+ return this.entries.get(name) ?? null;
192
+ }
193
+ /**
194
+ * Get all registered skill entries.
195
+ */
196
+ getAll() {
197
+ return [...this.entries.values()];
198
+ }
199
+ /**
200
+ * Get the number of registered skills.
201
+ */
202
+ get size() {
203
+ return this.entries.size;
204
+ }
205
+ /**
206
+ * Generate the available skills summary for the load_skill tool description.
207
+ *
208
+ * Skills with disable-model-invocation: true (modelInvocable: false) are
209
+ * excluded from the summary. The agent cannot see or auto-load them.
210
+ *
211
+ * Format: XML listing with name, source, and description per skill.
212
+ * Each skill consumes approximately 100 tokens.
213
+ */
214
+ getAvailableSkillsSummary(maxTokens = Number.POSITIVE_INFINITY) {
215
+ const invocableSkills = [...this.entries.values()]
216
+ .filter(e => e.modelInvocable)
217
+ .sort((a, b) => {
218
+ // Priority: builtin > user > plugin
219
+ const priority = (s) => {
220
+ if (s === 'builtin')
221
+ return 0;
222
+ if (s === 'user')
223
+ return 1;
224
+ return 2; // plugin:*
225
+ };
226
+ const pa = priority(a.source);
227
+ const pb = priority(b.source);
228
+ if (pa !== pb)
229
+ return pa - pb;
230
+ return a.name.localeCompare(b.name);
231
+ });
232
+ if (invocableSkills.length === 0) {
233
+ return '<available-skills>\n(No skills available)\n</available-skills>';
234
+ }
235
+ let usedTokens = 0;
236
+ const visibleSkills = [];
237
+ for (const entry of invocableSkills) {
238
+ const approxTokens = Math.max(32, Math.ceil((entry.name.length + entry.description.trim().length) / 4));
239
+ if (visibleSkills.length > 0 && usedTokens + approxTokens > maxTokens) {
240
+ continue;
241
+ }
242
+ visibleSkills.push(entry);
243
+ usedTokens += approxTokens;
244
+ }
245
+ const skillXml = visibleSkills.map(e => {
246
+ const desc = e.description.trim();
247
+ return `<skill name="${e.name}" source="${e.source}">\n${desc}\n</skill>`;
248
+ }).join('\n');
249
+ return `<available-skills>\n${skillXml}\n</available-skills>`;
250
+ }
251
+ /**
252
+ * Read and preprocess a skill's full body content.
253
+ * Runs variable substitution, shell commands, and scripts.
254
+ *
255
+ * @param name - The skill name
256
+ * @param callArgs - Arguments from the load_skill tool call
257
+ * @returns The preprocessed skill body
258
+ * @throws Error if the skill is not found
259
+ */
260
+ async getSkillBody(name, callArgs) {
261
+ const entry = this.entries.get(name);
262
+ if (!entry) {
263
+ throw new Error(`Skill not found: "${name}"`);
264
+ }
265
+ // Read the file and extract the body (below frontmatter)
266
+ let content;
267
+ try {
268
+ content = fs.readFileSync(entry.path, 'utf8');
269
+ }
270
+ catch (err) {
271
+ throw new Error(`Cannot read skill file: ${entry.path}`);
272
+ }
273
+ const { body } = parseFrontmatter(content);
274
+ // Build merged variables (consumer + built-ins, consumer wins on collision)
275
+ const variables = {
276
+ SKILL_DIR: entry.dir,
277
+ ARGUMENTS: callArgs.rawArgs,
278
+ };
279
+ // Add positional args
280
+ for (let i = 0; i < 9; i++) {
281
+ variables[String(i + 1)] = callArgs.args[i] ?? '';
282
+ }
283
+ // Merge per-skill variables (e.g., PLUGIN_ROOT for plugin skills)
284
+ if (entry.variables) {
285
+ Object.assign(variables, entry.variables);
286
+ }
287
+ // Merge consumer variables (consumer wins on collision)
288
+ Object.assign(variables, this.preprocessorVariables);
289
+ // Build merged script context (consumer first, Cortex built-ins last so
290
+ // they cannot be overridden — skillDir, args, rawArgs are Cortex-owned)
291
+ const mergedScriptContext = {
292
+ ...this.scriptContext,
293
+ skillDir: entry.dir,
294
+ args: callArgs.args,
295
+ rawArgs: callArgs.rawArgs,
296
+ scriptArgs: {},
297
+ };
298
+ // Run preprocessor
299
+ return preprocessSkillBody(body, {
300
+ variables,
301
+ scriptContext: mergedScriptContext,
302
+ skillDir: entry.dir,
303
+ });
304
+ }
305
+ /**
306
+ * Set consumer-provided variables for ${VAR} substitution.
307
+ * Called each tick during GATHER to update runtime values.
308
+ */
309
+ setPreprocessorVariables(variables) {
310
+ this.preprocessorVariables = variables;
311
+ }
312
+ /**
313
+ * Set consumer-provided context for !{script:} executions.
314
+ * Called each tick during GATHER to update runtime values.
315
+ */
316
+ setScriptContext(context) {
317
+ this.scriptContext = context;
318
+ }
319
+ /**
320
+ * Clear all entries. Called during destroy.
321
+ */
322
+ clear() {
323
+ this.entries.clear();
324
+ this.preprocessorVariables = {};
325
+ this.scriptContext = {};
326
+ }
327
+ }
328
+ // Export parseFrontmatter for testing
329
+ export { parseFrontmatter };
330
+ //# sourceMappingURL=skill-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-registry.js","sourceRoot":"","sources":["../src/skill-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * load_skill tool: loads a skill's full instructions into the agent's
3
+ * active context.
4
+ *
5
+ * The skill body is read from the SkillRegistry, preprocessed (variable
6
+ * substitution, shell commands, scripts), and pushed to the skill buffer.
7
+ * The skill buffer is injected into ephemeral context via transformContext
8
+ * on every subsequent LLM call within the current agentic loop.
9
+ *
10
+ * References:
11
+ * - docs/cortex/skill-system.md
12
+ * - docs/cortex/plans/phase-4-sub-agents-and-skills.md
13
+ */
14
+ import { Type, type Static } from 'typebox';
15
+ import type { SkillRegistry } from './skill-registry.js';
16
+ import type { LoadedSkill } from './types.js';
17
+ export declare const LoadSkillParams: Type.TObject<{
18
+ name: Type.TString;
19
+ arguments: Type.TOptional<Type.TString>;
20
+ }>;
21
+ export type LoadSkillParamsType = Static<typeof LoadSkillParams>;
22
+ export declare const LOAD_SKILL_TOOL_NAME = "load_skill";
23
+ export interface LoadSkillToolConfig {
24
+ /** The skill registry to load skills from. */
25
+ registry: SkillRegistry;
26
+ /** Build the visible skills summary for the tool description. */
27
+ getAvailableSkillsSummary?: () => string;
28
+ /** The skill buffer to push loaded skills into. */
29
+ getSkillBuffer: () => LoadedSkill[];
30
+ /** Push a loaded skill to the buffer (handles deduplication). */
31
+ pushToSkillBuffer: (skill: LoadedSkill) => void;
32
+ }
33
+ /**
34
+ * Create the load_skill tool.
35
+ *
36
+ * Returns a Cortex-native tool. CortexAgent adapts it to pi-agent-core's
37
+ * execute signature when synchronizing the tool inventory.
38
+ * The tool description includes the available skills summary, which
39
+ * updates when skills are added or removed from the registry.
40
+ */
41
+ export declare function createLoadSkillTool(config: LoadSkillToolConfig): {
42
+ name: string;
43
+ description: string;
44
+ parameters: typeof LoadSkillParams;
45
+ execute: (args: unknown) => Promise<unknown>;
46
+ };
47
+ /**
48
+ * Rebuild the load_skill tool's description with the current available
49
+ * skills summary. Called when skills are added or removed.
50
+ *
51
+ * Returns a function that produces the updated description string.
52
+ */
53
+ export declare function buildLoadSkillDescription(registry: SkillRegistry, availableSkillsSummary?: string): string;
54
+ //# sourceMappingURL=skill-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-tool.d.ts","sourceRoot":"","sources":["../src/skill-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,eAAO,MAAM,eAAe;;;EAO1B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAMjE,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAMjD,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,QAAQ,EAAE,aAAa,CAAC;IACxB,iEAAiE;IACjE,yBAAyB,CAAC,EAAE,MAAM,MAAM,CAAC;IACzC,mDAAmD;IACnD,cAAc,EAAE,MAAM,WAAW,EAAE,CAAC;IACpC,iEAAiE;IACjE,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACjD;AAMD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,eAAe,CAAC;IACnC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9C,CA2CA;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,aAAa,EACvB,sBAAsB,CAAC,EAAE,MAAM,GAC9B,MAAM,CAIR"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * load_skill tool: loads a skill's full instructions into the agent's
3
+ * active context.
4
+ *
5
+ * The skill body is read from the SkillRegistry, preprocessed (variable
6
+ * substitution, shell commands, scripts), and pushed to the skill buffer.
7
+ * The skill buffer is injected into ephemeral context via transformContext
8
+ * on every subsequent LLM call within the current agentic loop.
9
+ *
10
+ * References:
11
+ * - docs/cortex/skill-system.md
12
+ * - docs/cortex/plans/phase-4-sub-agents-and-skills.md
13
+ */
14
+ import { Type } from 'typebox';
15
+ // ---------------------------------------------------------------------------
16
+ // Schema
17
+ // ---------------------------------------------------------------------------
18
+ export const LoadSkillParams = Type.Object({
19
+ name: Type.String({
20
+ description: 'The skill name to load.',
21
+ }),
22
+ arguments: Type.Optional(Type.String({
23
+ description: 'Optional arguments to pass to the skill.',
24
+ })),
25
+ });
26
+ // ---------------------------------------------------------------------------
27
+ // Tool name constant
28
+ // ---------------------------------------------------------------------------
29
+ export const LOAD_SKILL_TOOL_NAME = 'load_skill';
30
+ // ---------------------------------------------------------------------------
31
+ // Factory
32
+ // ---------------------------------------------------------------------------
33
+ /**
34
+ * Create the load_skill tool.
35
+ *
36
+ * Returns a Cortex-native tool. CortexAgent adapts it to pi-agent-core's
37
+ * execute signature when synchronizing the tool inventory.
38
+ * The tool description includes the available skills summary, which
39
+ * updates when skills are added or removed from the registry.
40
+ */
41
+ export function createLoadSkillTool(config) {
42
+ return {
43
+ name: LOAD_SKILL_TOOL_NAME,
44
+ description: `Load a skill's full instructions into your active context. Call this tool when you need detailed guidance for a specific task. The skill's instructions will be available in your context for the remainder of this loop.
45
+
46
+ ${config.getAvailableSkillsSummary ? config.getAvailableSkillsSummary() : config.registry.getAvailableSkillsSummary()}`,
47
+ parameters: LoadSkillParams,
48
+ execute: async (args) => {
49
+ const params = args;
50
+ // Check if skill exists
51
+ const entry = config.registry.getEntry(params.name);
52
+ if (!entry) {
53
+ return `Unknown skill: "${params.name}". Check available skills in the tool description.`;
54
+ }
55
+ // Check if the skill is model-invocable
56
+ if (!entry.modelInvocable) {
57
+ return `Skill "${params.name}" is not available for direct loading.`;
58
+ }
59
+ // Load and preprocess the skill body
60
+ try {
61
+ const callArgs = {
62
+ args: params.arguments ? params.arguments.split(/\s+/) : [],
63
+ rawArgs: params.arguments ?? '',
64
+ };
65
+ const body = await config.registry.getSkillBody(params.name, callArgs);
66
+ // Push to skill buffer (deduplication handled by pushToSkillBuffer)
67
+ config.pushToSkillBuffer({ name: params.name, content: body });
68
+ return `Skill "${params.name}" loaded. Full instructions are now active in your context (see the skill instructions section below the conversation history). Review them before proceeding.`;
69
+ }
70
+ catch (err) {
71
+ const message = err instanceof Error ? err.message : String(err);
72
+ return `Failed to load skill "${params.name}": ${message}`;
73
+ }
74
+ },
75
+ };
76
+ }
77
+ /**
78
+ * Rebuild the load_skill tool's description with the current available
79
+ * skills summary. Called when skills are added or removed.
80
+ *
81
+ * Returns a function that produces the updated description string.
82
+ */
83
+ export function buildLoadSkillDescription(registry, availableSkillsSummary) {
84
+ return `Load a skill's full instructions into your active context. Call this tool when you need detailed guidance for a specific task. The skill's instructions will be available in your context for the remainder of this loop.
85
+
86
+ ${availableSkillsSummary ?? registry.getAvailableSkillsSummary()}`;
87
+ }
88
+ //# sourceMappingURL=skill-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-tool.js","sourceRoot":"","sources":["../src/skill-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,IAAI,EAAe,MAAM,SAAS,CAAC;AAI5C,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;QAChB,WAAW,EAAE,yBAAyB;KACvC,CAAC;IACF,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QACnC,WAAW,EAAE,0CAA0C;KACxD,CAAC,CAAC;CACJ,CAAC,CAAC;AAIH,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAiBjD,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA2B;IAM7D,OAAO;QACL,IAAI,EAAE,oBAAoB;QAE1B,WAAW,EAAE;;EAEf,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,EAAE,EAAE;QAEnH,UAAU,EAAE,eAAe;QAE3B,OAAO,EAAE,KAAK,EAAE,IAAa,EAAoB,EAAE;YACjD,MAAM,MAAM,GAAG,IAA2B,CAAC;YAE3C,wBAAwB;YACxB,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,mBAAmB,MAAM,CAAC,IAAI,oDAAoD,CAAC;YAC5F,CAAC;YAED,wCAAwC;YACxC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;gBAC1B,OAAO,UAAU,MAAM,CAAC,IAAI,wCAAwC,CAAC;YACvE,CAAC;YAED,qCAAqC;YACrC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG;oBACf,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;oBAC3D,OAAO,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;iBAChC,CAAC;gBAEF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAEvE,oEAAoE;gBACpE,MAAM,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE/D,OAAO,UAAU,MAAM,CAAC,IAAI,gKAAgK,CAAC;YAC/L,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,OAAO,yBAAyB,MAAM,CAAC,IAAI,MAAM,OAAO,EAAE,CAAC;YAC7D,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAuB,EACvB,sBAA+B;IAE/B,OAAO;;EAEP,sBAAsB,IAAI,QAAQ,CAAC,yBAAyB,EAAE,EAAE,CAAC;AACnE,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * SubAgentManager: tracks active sub-agents, enforces concurrency limits,
3
+ * manages lifecycle, and delivers background completion notifications.
4
+ *
5
+ * Each sub-agent is an independent CortexAgent instance tracked by task ID.
6
+ * The manager does not own the CortexAgent; it tracks references and
7
+ * coordinates lifecycle events for the consumer.
8
+ *
9
+ * References:
10
+ * - docs/cortex/tools/sub-agent.md
11
+ * - docs/cortex/plans/phase-4-sub-agents-and-skills.md
12
+ */
13
+ import type { SubAgentResult, TrackedSubAgent } from './types.js';
14
+ export interface SubAgentManagerConfig {
15
+ /** Maximum concurrent sub-agents. Default: 4. */
16
+ maxConcurrent: number;
17
+ }
18
+ export interface SubAgentLifecycleHooks {
19
+ onSpawned?: (taskId: string, instructions: string, background: boolean) => void;
20
+ onCompleted?: (taskId: string, result: string, status: string, usage: unknown) => void;
21
+ onFailed?: (taskId: string, error: string) => void;
22
+ }
23
+ export declare class SubAgentManager {
24
+ private readonly agents;
25
+ private readonly maxConcurrent;
26
+ private hooks;
27
+ constructor(config?: Partial<SubAgentManagerConfig>);
28
+ /**
29
+ * Set lifecycle hooks. Called by CortexAgent to wire consumer event handlers.
30
+ */
31
+ setHooks(hooks: SubAgentLifecycleHooks): void;
32
+ /**
33
+ * Check if another sub-agent can be spawned within the concurrency limit.
34
+ */
35
+ canSpawn(): boolean;
36
+ /**
37
+ * Get the number of currently active sub-agents.
38
+ */
39
+ get activeCount(): number;
40
+ /**
41
+ * Get the concurrency limit.
42
+ */
43
+ get limit(): number;
44
+ /**
45
+ * Register a newly spawned sub-agent.
46
+ * Returns false if the concurrency limit would be exceeded.
47
+ */
48
+ track(entry: TrackedSubAgent): boolean;
49
+ /**
50
+ * Mark a sub-agent as completed and remove it from tracking.
51
+ */
52
+ complete(taskId: string, result: SubAgentResult): void;
53
+ /**
54
+ * Mark a sub-agent as failed and remove it from tracking.
55
+ */
56
+ fail(taskId: string, error: string): void;
57
+ /**
58
+ * Get a tracked sub-agent by task ID.
59
+ */
60
+ get(taskId: string): TrackedSubAgent | undefined;
61
+ /**
62
+ * Update tool activity for a running sub-agent.
63
+ * Called when child tool_call_start events are forwarded via EventBridge.
64
+ */
65
+ updateToolActivity(taskId: string, toolName: string, summary: string): void;
66
+ /**
67
+ * Get all active sub-agent task IDs.
68
+ */
69
+ getActiveTaskIds(): string[];
70
+ /**
71
+ * Get completion promises for all background sub-agents.
72
+ * Used to build follow-up messages when background agents complete.
73
+ */
74
+ getBackgroundCompletions(): Array<{
75
+ taskId: string;
76
+ completion: Promise<SubAgentResult>;
77
+ }>;
78
+ /**
79
+ * Cancel all active sub-agents. Called during parent destroy().
80
+ * Aborts each sub-agent and removes it from tracking.
81
+ *
82
+ * @param abortFn - Function to abort a CortexAgent (passed to avoid circular dep)
83
+ */
84
+ cancelAll(abortFn: (agent: unknown) => Promise<void>): Promise<void>;
85
+ /**
86
+ * Clean up all state. Called during parent destroy().
87
+ */
88
+ destroy(): void;
89
+ }
90
+ //# sourceMappingURL=sub-agent-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-agent-manager.d.ts","sourceRoot":"","sources":["../src/sub-agent-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMlE,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAChF,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvF,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAMD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAC7D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,KAAK,CAA8B;gBAE/B,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC;IAInD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI;IAI7C;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAiBtC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI;IA0BtD;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAqBzC;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIhD;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAS3E;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;;OAGG;IACH,wBAAwB,IAAI,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;KAAE,CAAC;IAU1F;;;;;OAKG;IACG,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC1E;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB"}