@made-by-moonlight/athene-core 0.9.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 (285) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +241 -0
  3. package/dist/activity-events.d.ts +42 -0
  4. package/dist/activity-events.d.ts.map +1 -0
  5. package/dist/activity-events.js +192 -0
  6. package/dist/activity-events.js.map +1 -0
  7. package/dist/activity-log.d.ts +71 -0
  8. package/dist/activity-log.d.ts.map +1 -0
  9. package/dist/activity-log.js +203 -0
  10. package/dist/activity-log.js.map +1 -0
  11. package/dist/activity-signal.d.ts +20 -0
  12. package/dist/activity-signal.d.ts.map +1 -0
  13. package/dist/activity-signal.js +91 -0
  14. package/dist/activity-signal.js.map +1 -0
  15. package/dist/agent-report.d.ts +148 -0
  16. package/dist/agent-report.d.ts.map +1 -0
  17. package/dist/agent-report.js +516 -0
  18. package/dist/agent-report.js.map +1 -0
  19. package/dist/agent-selection.d.ts +31 -0
  20. package/dist/agent-selection.d.ts.map +1 -0
  21. package/dist/agent-selection.js +69 -0
  22. package/dist/agent-selection.js.map +1 -0
  23. package/dist/agent-workspace-hooks.d.ts +74 -0
  24. package/dist/agent-workspace-hooks.d.ts.map +1 -0
  25. package/dist/agent-workspace-hooks.js +988 -0
  26. package/dist/agent-workspace-hooks.js.map +1 -0
  27. package/dist/atomic-write.d.ts +6 -0
  28. package/dist/atomic-write.d.ts.map +1 -0
  29. package/dist/atomic-write.js +49 -0
  30. package/dist/atomic-write.js.map +1 -0
  31. package/dist/cleanup-stack.d.ts +37 -0
  32. package/dist/cleanup-stack.d.ts.map +1 -0
  33. package/dist/cleanup-stack.js +45 -0
  34. package/dist/cleanup-stack.js.map +1 -0
  35. package/dist/code-review-manager.d.ts +118 -0
  36. package/dist/code-review-manager.d.ts.map +1 -0
  37. package/dist/code-review-manager.js +719 -0
  38. package/dist/code-review-manager.js.map +1 -0
  39. package/dist/code-review-store.d.ts +114 -0
  40. package/dist/code-review-store.d.ts.map +1 -0
  41. package/dist/code-review-store.js +346 -0
  42. package/dist/code-review-store.js.map +1 -0
  43. package/dist/config-generator.d.ts +84 -0
  44. package/dist/config-generator.d.ts.map +1 -0
  45. package/dist/config-generator.js +295 -0
  46. package/dist/config-generator.js.map +1 -0
  47. package/dist/config.d.ts +55 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +852 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/daemon-children.d.ts +55 -0
  52. package/dist/daemon-children.d.ts.map +1 -0
  53. package/dist/daemon-children.js +435 -0
  54. package/dist/daemon-children.js.map +1 -0
  55. package/dist/dashboard-notifications.d.ts +42 -0
  56. package/dist/dashboard-notifications.d.ts.map +1 -0
  57. package/dist/dashboard-notifications.js +123 -0
  58. package/dist/dashboard-notifications.js.map +1 -0
  59. package/dist/events-db.d.ts +39 -0
  60. package/dist/events-db.d.ts.map +1 -0
  61. package/dist/events-db.js +185 -0
  62. package/dist/events-db.js.map +1 -0
  63. package/dist/feature-flags.d.ts +2 -0
  64. package/dist/feature-flags.d.ts.map +1 -0
  65. package/dist/feature-flags.js +9 -0
  66. package/dist/feature-flags.js.map +1 -0
  67. package/dist/feedback-tools.d.ts +97 -0
  68. package/dist/feedback-tools.d.ts.map +1 -0
  69. package/dist/feedback-tools.js +161 -0
  70. package/dist/feedback-tools.js.map +1 -0
  71. package/dist/file-lock.d.ts +5 -0
  72. package/dist/file-lock.d.ts.map +1 -0
  73. package/dist/file-lock.js +59 -0
  74. package/dist/file-lock.js.map +1 -0
  75. package/dist/format-automated-comments.d.ts +18 -0
  76. package/dist/format-automated-comments.d.ts.map +1 -0
  77. package/dist/gh-trace.d.ts +57 -0
  78. package/dist/gh-trace.d.ts.map +1 -0
  79. package/dist/gh-trace.js +320 -0
  80. package/dist/gh-trace.js.map +1 -0
  81. package/dist/git-activity.d.ts +10 -0
  82. package/dist/git-activity.d.ts.map +1 -0
  83. package/dist/git-activity.js +30 -0
  84. package/dist/git-activity.js.map +1 -0
  85. package/dist/global-config.d.ts +1085 -0
  86. package/dist/global-config.d.ts.map +1 -0
  87. package/dist/global-config.js +1067 -0
  88. package/dist/global-config.js.map +1 -0
  89. package/dist/index.d.ts +91 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +59 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/key-value.d.ts +7 -0
  94. package/dist/key-value.d.ts.map +1 -0
  95. package/dist/key-value.js +24 -0
  96. package/dist/key-value.js.map +1 -0
  97. package/dist/lifecycle-manager.d.ts +22 -0
  98. package/dist/lifecycle-manager.d.ts.map +1 -0
  99. package/dist/lifecycle-manager.js +2813 -0
  100. package/dist/lifecycle-manager.js.map +1 -0
  101. package/dist/lifecycle-state.d.ts +28 -0
  102. package/dist/lifecycle-state.d.ts.map +1 -0
  103. package/dist/lifecycle-state.js +446 -0
  104. package/dist/lifecycle-state.js.map +1 -0
  105. package/dist/lifecycle-status-decisions.d.ts +85 -0
  106. package/dist/lifecycle-status-decisions.d.ts.map +1 -0
  107. package/dist/lifecycle-status-decisions.js +262 -0
  108. package/dist/lifecycle-status-decisions.js.map +1 -0
  109. package/dist/lifecycle-transition.d.ts +81 -0
  110. package/dist/lifecycle-transition.d.ts.map +1 -0
  111. package/dist/lifecycle-transition.js +207 -0
  112. package/dist/lifecycle-transition.js.map +1 -0
  113. package/dist/metadata.d.ts +54 -0
  114. package/dist/metadata.d.ts.map +1 -0
  115. package/dist/metadata.js +484 -0
  116. package/dist/metadata.js.map +1 -0
  117. package/dist/migration/storage-v2.d.ts +76 -0
  118. package/dist/migration/storage-v2.d.ts.map +1 -0
  119. package/dist/migration/storage-v2.js +1614 -0
  120. package/dist/migration/storage-v2.js.map +1 -0
  121. package/dist/notification-data.d.ts +135 -0
  122. package/dist/notification-data.d.ts.map +1 -0
  123. package/dist/notification-data.js +204 -0
  124. package/dist/notification-data.js.map +1 -0
  125. package/dist/notification-observability.d.ts +21 -0
  126. package/dist/notification-observability.d.ts.map +1 -0
  127. package/dist/notification-observability.js +154 -0
  128. package/dist/notification-observability.js.map +1 -0
  129. package/dist/notifier-resolution.d.ts +14 -0
  130. package/dist/notifier-resolution.d.ts.map +1 -0
  131. package/dist/notifier-resolution.js +23 -0
  132. package/dist/notifier-resolution.js.map +1 -0
  133. package/dist/observability.d.ts +100 -0
  134. package/dist/observability.d.ts.map +1 -0
  135. package/dist/observability.js +535 -0
  136. package/dist/observability.js.map +1 -0
  137. package/dist/opencode-agents-md.d.ts +3 -0
  138. package/dist/opencode-agents-md.d.ts.map +1 -0
  139. package/dist/opencode-agents-md.js +40 -0
  140. package/dist/opencode-agents-md.js.map +1 -0
  141. package/dist/opencode-config.d.ts +2 -0
  142. package/dist/opencode-config.d.ts.map +1 -0
  143. package/dist/opencode-config.js +17 -0
  144. package/dist/opencode-config.js.map +1 -0
  145. package/dist/opencode-session-id.d.ts +2 -0
  146. package/dist/opencode-session-id.d.ts.map +1 -0
  147. package/dist/opencode-session-id.js +12 -0
  148. package/dist/opencode-session-id.js.map +1 -0
  149. package/dist/opencode-shared.d.ts +80 -0
  150. package/dist/opencode-shared.d.ts.map +1 -0
  151. package/dist/opencode-shared.js +202 -0
  152. package/dist/opencode-shared.js.map +1 -0
  153. package/dist/orchestrator-prompt.d.ts +19 -0
  154. package/dist/orchestrator-prompt.d.ts.map +1 -0
  155. package/dist/orchestrator-prompt.js +130 -0
  156. package/dist/orchestrator-prompt.js.map +1 -0
  157. package/dist/orchestrator-session-strategy.d.ts +5 -0
  158. package/dist/orchestrator-session-strategy.d.ts.map +1 -0
  159. package/dist/orchestrator-session-strategy.js +13 -0
  160. package/dist/orchestrator-session-strategy.js.map +1 -0
  161. package/dist/paths.d.ts +145 -0
  162. package/dist/paths.d.ts.map +1 -0
  163. package/dist/paths.js +288 -0
  164. package/dist/paths.js.map +1 -0
  165. package/dist/platform.d.ts +32 -0
  166. package/dist/platform.d.ts.map +1 -0
  167. package/dist/platform.js +211 -0
  168. package/dist/platform.js.map +1 -0
  169. package/dist/plugin-registry.d.ts +15 -0
  170. package/dist/plugin-registry.d.ts.map +1 -0
  171. package/dist/plugin-registry.js +499 -0
  172. package/dist/plugin-registry.js.map +1 -0
  173. package/dist/portfolio-projects.d.ts +7 -0
  174. package/dist/portfolio-projects.d.ts.map +1 -0
  175. package/dist/portfolio-projects.js +65 -0
  176. package/dist/portfolio-projects.js.map +1 -0
  177. package/dist/portfolio-registry.d.ts +42 -0
  178. package/dist/portfolio-registry.d.ts.map +1 -0
  179. package/dist/portfolio-registry.js +311 -0
  180. package/dist/portfolio-registry.js.map +1 -0
  181. package/dist/portfolio-routing.d.ts +5 -0
  182. package/dist/portfolio-routing.d.ts.map +1 -0
  183. package/dist/portfolio-routing.js +24 -0
  184. package/dist/portfolio-routing.js.map +1 -0
  185. package/dist/portfolio-session-service.d.ts +15 -0
  186. package/dist/portfolio-session-service.d.ts.map +1 -0
  187. package/dist/portfolio-session-service.js +206 -0
  188. package/dist/portfolio-session-service.js.map +1 -0
  189. package/dist/process-cache.d.ts +32 -0
  190. package/dist/process-cache.d.ts.map +1 -0
  191. package/dist/process-cache.js +44 -0
  192. package/dist/process-cache.js.map +1 -0
  193. package/dist/project-resolver.d.ts +5 -0
  194. package/dist/project-resolver.d.ts.map +1 -0
  195. package/dist/project-resolver.js +20 -0
  196. package/dist/project-resolver.js.map +1 -0
  197. package/dist/prompt-builder.d.ts +42 -0
  198. package/dist/prompt-builder.d.ts.map +1 -0
  199. package/dist/prompt-builder.js +182 -0
  200. package/dist/prompt-builder.js.map +1 -0
  201. package/dist/prompts/orchestrator.md.js +4 -0
  202. package/dist/prompts/orchestrator.md.js.map +1 -0
  203. package/dist/query-activity-events.d.ts +42 -0
  204. package/dist/query-activity-events.d.ts.map +1 -0
  205. package/dist/query-activity-events.js +170 -0
  206. package/dist/query-activity-events.js.map +1 -0
  207. package/dist/recovery/actions.d.ts +7 -0
  208. package/dist/recovery/actions.d.ts.map +1 -0
  209. package/dist/recovery/index.d.ts +8 -0
  210. package/dist/recovery/index.d.ts.map +1 -0
  211. package/dist/recovery/logger.d.ts +12 -0
  212. package/dist/recovery/logger.d.ts.map +1 -0
  213. package/dist/recovery/manager.d.ts +24 -0
  214. package/dist/recovery/manager.d.ts.map +1 -0
  215. package/dist/recovery/scanner.d.ts +11 -0
  216. package/dist/recovery/scanner.d.ts.map +1 -0
  217. package/dist/recovery/types.d.ts +170 -0
  218. package/dist/recovery/types.d.ts.map +1 -0
  219. package/dist/recovery/validator.d.ts +8 -0
  220. package/dist/recovery/validator.d.ts.map +1 -0
  221. package/dist/report-watcher.d.ts +93 -0
  222. package/dist/report-watcher.d.ts.map +1 -0
  223. package/dist/report-watcher.js +182 -0
  224. package/dist/report-watcher.js.map +1 -0
  225. package/dist/scm-webhook-utils.d.ts +6 -0
  226. package/dist/scm-webhook-utils.d.ts.map +1 -0
  227. package/dist/scm-webhook-utils.js +36 -0
  228. package/dist/scm-webhook-utils.js.map +1 -0
  229. package/dist/session-manager.d.ts +22 -0
  230. package/dist/session-manager.d.ts.map +1 -0
  231. package/dist/session-manager.js +3077 -0
  232. package/dist/session-manager.js.map +1 -0
  233. package/dist/spawn-target.d.ts +23 -0
  234. package/dist/spawn-target.d.ts.map +1 -0
  235. package/dist/spawn-target.js +39 -0
  236. package/dist/spawn-target.js.map +1 -0
  237. package/dist/storage-key.d.ts +9 -0
  238. package/dist/storage-key.d.ts.map +1 -0
  239. package/dist/storage-key.js +59 -0
  240. package/dist/storage-key.js.map +1 -0
  241. package/dist/tmux.d.ts +39 -0
  242. package/dist/tmux.d.ts.map +1 -0
  243. package/dist/tmux.js +141 -0
  244. package/dist/tmux.js.map +1 -0
  245. package/dist/types.d.ts +1496 -0
  246. package/dist/types.d.ts.map +1 -0
  247. package/dist/types.js +215 -0
  248. package/dist/types.js.map +1 -0
  249. package/dist/update-cache.d.ts +59 -0
  250. package/dist/update-cache.d.ts.map +1 -0
  251. package/dist/update-cache.js +77 -0
  252. package/dist/update-cache.js.map +1 -0
  253. package/dist/utils/metadata-flatten.d.ts +3 -0
  254. package/dist/utils/metadata-flatten.d.ts.map +1 -0
  255. package/dist/utils/metadata-flatten.js +18 -0
  256. package/dist/utils/metadata-flatten.js.map +1 -0
  257. package/dist/utils/pr.d.ts +7 -0
  258. package/dist/utils/pr.d.ts.map +1 -0
  259. package/dist/utils/pr.js +97 -0
  260. package/dist/utils/pr.js.map +1 -0
  261. package/dist/utils/session-from-metadata.d.ts +16 -0
  262. package/dist/utils/session-from-metadata.d.ts.map +1 -0
  263. package/dist/utils/session-from-metadata.js +87 -0
  264. package/dist/utils/session-from-metadata.js.map +1 -0
  265. package/dist/utils/session-id.d.ts +4 -0
  266. package/dist/utils/session-id.d.ts.map +1 -0
  267. package/dist/utils/session-id.js +9 -0
  268. package/dist/utils/session-id.js.map +1 -0
  269. package/dist/utils/validation.d.ts +9 -0
  270. package/dist/utils/validation.d.ts.map +1 -0
  271. package/dist/utils/validation.js +45 -0
  272. package/dist/utils/validation.js.map +1 -0
  273. package/dist/utils.d.ts +65 -0
  274. package/dist/utils.d.ts.map +1 -0
  275. package/dist/utils.js +189 -0
  276. package/dist/utils.js.map +1 -0
  277. package/dist/version-compare.d.ts +27 -0
  278. package/dist/version-compare.d.ts.map +1 -0
  279. package/dist/version-compare.js +121 -0
  280. package/dist/version-compare.js.map +1 -0
  281. package/dist/windows-pty-registry.d.ts +27 -0
  282. package/dist/windows-pty-registry.d.ts.map +1 -0
  283. package/dist/windows-pty-registry.js +109 -0
  284. package/dist/windows-pty-registry.js.map +1 -0
  285. package/package.json +110 -0
@@ -0,0 +1,5 @@
1
+ export declare function withFileLockSync<T>(lockPath: string, fn: () => T, options?: {
2
+ timeoutMs?: number;
3
+ staleMs?: number;
4
+ }): T;
5
+ //# sourceMappingURL=file-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../src/file-lock.ts"],"names":[],"mappings":"AAOA,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,CAAC,EACX,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACrD,CAAC,CAkDH"}
@@ -0,0 +1,59 @@
1
+ import { mkdirSync, openSync, statSync, rmSync, closeSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+
4
+ function sleepSync(ms) {
5
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
6
+ }
7
+ function withFileLockSync(lockPath, fn, options = {}) {
8
+ const timeoutMs = options.timeoutMs ?? 10_000;
9
+ const staleMs = options.staleMs ?? 60_000;
10
+ mkdirSync(dirname(lockPath), { recursive: true });
11
+ const deadline = Date.now() + timeoutMs;
12
+ let fd = null;
13
+ let waitMs = 10;
14
+ while (fd === null) {
15
+ try {
16
+ fd = openSync(lockPath, "wx");
17
+ }
18
+ catch (err) {
19
+ if (err.code !== "EEXIST") {
20
+ throw new Error(`Failed to acquire file lock: ${lockPath}`, { cause: err });
21
+ }
22
+ try {
23
+ const info = statSync(lockPath);
24
+ if (Date.now() - info.mtimeMs > staleMs) {
25
+ rmSync(lockPath, { force: true });
26
+ continue;
27
+ }
28
+ }
29
+ catch {
30
+ continue;
31
+ }
32
+ if (Date.now() > deadline) {
33
+ throw new Error(`Timed out waiting for file lock: ${lockPath}`, { cause: err });
34
+ }
35
+ sleepSync(waitMs);
36
+ waitMs = Math.min(waitMs * 2, 250);
37
+ }
38
+ }
39
+ try {
40
+ return fn();
41
+ }
42
+ finally {
43
+ try {
44
+ closeSync(fd);
45
+ }
46
+ catch {
47
+ // Ignore cleanup races.
48
+ }
49
+ try {
50
+ rmSync(lockPath, { force: true });
51
+ }
52
+ catch {
53
+ // Best-effort cleanup.
54
+ }
55
+ }
56
+ }
57
+
58
+ export { withFileLockSync };
59
+ //# sourceMappingURL=file-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-lock.js","sources":["../src/file-lock.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGA,SAAS,SAAS,CAAC,EAAU,EAAA;AAC3B,IAAA,OAAO,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;AAClE;AAEM,SAAU,gBAAgB,CAC9B,QAAgB,EAChB,EAAW,EACX,UAAoD,EAAE,EAAA;AAEtD,IAAA,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM;AAC7C,IAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM;AACzC,IAAA,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAEjD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;IACvC,IAAI,EAAE,GAAkB,IAAI;IAC5B,IAAI,MAAM,GAAG,EAAE;AAEf,IAAA,OAAO,EAAE,KAAK,IAAI,EAAE;AAClB,QAAA,IAAI;AACF,YAAA,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;QAC/B;QAAE,OAAO,GAAG,EAAE;AACZ,YAAA,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE;AACpD,gBAAA,MAAM,IAAI,KAAK,CAAC,CAAA,6BAAA,EAAgC,QAAQ,CAAA,CAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;YAC7E;AAEA,YAAA,IAAI;AACF,gBAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC;gBAC/B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE;oBACvC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;oBACjC;gBACF;YACF;AAAE,YAAA,MAAM;gBACN;YACF;AAEA,YAAA,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE;AACzB,gBAAA,MAAM,IAAI,KAAK,CAAC,CAAA,iCAAA,EAAoC,QAAQ,CAAA,CAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;YACjF;YAEA,SAAS,CAAC,MAAM,CAAC;YACjB,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC;QACpC;IACF;AAEA,IAAA,IAAI;QACF,OAAO,EAAE,EAAE;IACb;YAAU;AACR,QAAA,IAAI;YACF,SAAS,CAAC,EAAE,CAAC;QACf;AAAE,QAAA,MAAM;;QAER;AACA,QAAA,IAAI;YACF,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACnC;AAAE,QAAA,MAAM;;QAER;IACF;AACF;;;;"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Format automated (bot) review comments into a detailed message for the agent.
3
+ *
4
+ * Design context (#895): the previous generic "fix the bot's issues" message
5
+ * forced the agent to rediscover comments via `gh api .../pulls/PR/comments`
6
+ * (first page only), which silently drops newly-posted comments that land on
7
+ * later pages. This formatter lists every already-fetched comment and embeds
8
+ * explicit correct-API guidance so the agent never has to guess.
9
+ *
10
+ * Security: bot comment bodies are treated as untrusted third-party data.
11
+ * Each excerpt is stripped of backtick fences and wrapped inline in a code span
12
+ * so crafted content cannot break out into agent-directed instructions (#1334
13
+ * review). The preamble tells the agent explicitly to treat the content as
14
+ * data, not instructions.
15
+ */
16
+ import type { AutomatedComment, PRInfo } from "./types.js";
17
+ export declare function formatAutomatedCommentsMessage(comments: AutomatedComment[], pr?: Pick<PRInfo, "owner" | "repo" | "number">): string;
18
+ //# sourceMappingURL=format-automated-comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-automated-comments.d.ts","sourceRoot":"","sources":["../src/format-automated-comments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA6B3D,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,GAC7C,MAAM,CAmCR"}
@@ -0,0 +1,57 @@
1
+ import type { SessionId } from "./types.js";
2
+ export interface GhTraceContext {
3
+ component: string;
4
+ operation?: string;
5
+ projectId?: string;
6
+ sessionId?: SessionId;
7
+ cwd?: string;
8
+ }
9
+ export interface GhTraceEntry {
10
+ timestamp: string;
11
+ component: string;
12
+ operation: string;
13
+ projectId?: string;
14
+ sessionId?: SessionId;
15
+ cwd?: string;
16
+ args: string[];
17
+ endpoint?: string;
18
+ method?: string;
19
+ ok: boolean;
20
+ exitCode?: number;
21
+ signal?: string;
22
+ durationMs: number;
23
+ stdoutBytes: number;
24
+ stderrBytes: number;
25
+ statusLine?: string;
26
+ httpStatus?: number;
27
+ etag?: string;
28
+ rateLimitLimit?: number;
29
+ rateLimitRemaining?: number;
30
+ rateLimitReset?: number;
31
+ rateLimitResource?: string;
32
+ /** Exact GraphQL cost from response body `rateLimit { cost }` (only for GraphQL calls). */
33
+ graphqlCost?: number;
34
+ /** GraphQL remaining from response body (more accurate than header). */
35
+ graphqlRemaining?: number;
36
+ /** GraphQL reset time from response body. */
37
+ graphqlResetAt?: string;
38
+ }
39
+ interface HeaderMap {
40
+ [key: string]: string | undefined;
41
+ }
42
+ declare function extractOperation(args: string[]): string;
43
+ declare function parseIncludedHttpResponse(stdout: string): {
44
+ statusLine?: string;
45
+ headers: HeaderMap;
46
+ };
47
+ /** Redact sensitive values from gh CLI args before persisting to trace JSONL. */
48
+ declare function redactArgs(args: string[]): string[];
49
+ export declare function execGhObserved(args: string[], ctx: GhTraceContext, timeout?: number): Promise<string>;
50
+ export declare function getGhTraceFilePath(): string | undefined;
51
+ export declare const _testUtils: {
52
+ extractOperation: typeof extractOperation;
53
+ redactArgs: typeof redactArgs;
54
+ parseIncludedHttpResponse: typeof parseIncludedHttpResponse;
55
+ };
56
+ export {};
57
+ //# sourceMappingURL=gh-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gh-trace.d.ts","sourceRoot":"","sources":["../src/gh-trace.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA2D5C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAUD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,SAAS;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAcD,iBAAS,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAwBhD;AAmCD,iBAAS,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC;CACpB,CA4BA;AAyCD,iFAAiF;AACjF,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA6B5C;AAkED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,cAAc,EACnB,OAAO,GAAE,MAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAEvD;AAID,eAAO,MAAM,UAAU;;;;CAItB,CAAC"}
@@ -0,0 +1,320 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { mkdir, appendFile, access } from 'node:fs/promises';
3
+ import { constants } from 'node:fs';
4
+ import { dirname, join, delimiter } from 'node:path';
5
+ import { homedir } from 'node:os';
6
+ import { promisify } from 'node:util';
7
+
8
+ const execFileAsync = promisify(execFile);
9
+ /**
10
+ * Resolve the real gh binary path, bypassing ~/.ao/bin wrapper.
11
+ * AO-owned calls must NOT go through the wrapper (which is for agent sessions).
12
+ *
13
+ * Strips ~/.ao/bin from PATH and resolves gh from the clean PATH.
14
+ * Cached after first resolution.
15
+ */
16
+ let resolvedGhPath = null;
17
+ async function getGhBinaryPath() {
18
+ if (resolvedGhPath)
19
+ return resolvedGhPath;
20
+ const resolved = await resolveGhBinary();
21
+ // Cache only successful resolutions (non-wrapper paths).
22
+ // If resolution fails, retry on next call so transient PATH
23
+ // issues don't permanently route through the wrapper.
24
+ resolvedGhPath = resolved;
25
+ return resolved;
26
+ }
27
+ async function resolveGhBinary() {
28
+ // Build a clean PATH without ~/.ao/bin and walk each directory looking
29
+ // for an executable `gh`. Uses fs.access instead of spawning a shell —
30
+ // avoids blocking the event loop and shell injection concerns.
31
+ const aoBinDir = join(homedir(), ".ao", "bin");
32
+ const dirs = (process.env["PATH"] ?? "")
33
+ .split(delimiter)
34
+ .filter((entry) => entry && entry !== aoBinDir);
35
+ // On Windows the binary is `gh.exe` (or `gh.cmd` for npm shims). Honor
36
+ // PATHEXT so we match whatever the user actually installed.
37
+ const exts = process.platform === "win32"
38
+ ? (process.env["PATHEXT"]?.split(";").filter(Boolean) ?? [".EXE", ".CMD", ".BAT"]).map((e) => e.toLowerCase())
39
+ : [""];
40
+ for (const dir of dirs) {
41
+ for (const ext of exts) {
42
+ const candidate = join(dir, `gh${ext}`);
43
+ try {
44
+ await access(candidate, constants.X_OK);
45
+ return candidate;
46
+ }
47
+ catch {
48
+ // Not found or not executable — try next
49
+ }
50
+ }
51
+ }
52
+ throw new Error("gh CLI not found outside ~/.ao/bin. Install gh or set GH_PATH to the real binary.");
53
+ }
54
+ const GH_TRACE_FILE_ENV = "AO_GH_TRACE_FILE";
55
+ function nowIso() {
56
+ return new Date().toISOString();
57
+ }
58
+ function parseIntHeader(value) {
59
+ if (!value)
60
+ return undefined;
61
+ const trimmed = value.trim();
62
+ if (!trimmed)
63
+ return undefined;
64
+ const parsed = Number.parseInt(trimmed, 10);
65
+ return Number.isFinite(parsed) ? parsed : undefined;
66
+ }
67
+ function extractOperation(args) {
68
+ if (args.length === 0)
69
+ return "gh";
70
+ if (args.length === 1)
71
+ return `gh.${args[0]}`;
72
+ // Walk past leading flags (e.g. --method, -X, -H) to find the first
73
+ // positional arg after args[0]. Without this, "api --method GET ..."
74
+ // gets bucketed as "gh.api.--method" instead of "gh.api.graphql" etc.
75
+ for (let i = 1; i < args.length; i++) {
76
+ const arg = args[i];
77
+ if (!arg || arg.startsWith("-")) {
78
+ // Skip flags and their values (--method GET, -X POST, -H "...", etc.)
79
+ if (arg === "--method" || arg === "-X" || arg === "-H" || arg === "--header" ||
80
+ arg === "-f" || arg === "--raw-field" || arg === "-F" || arg === "--field" ||
81
+ arg === "--input" || arg === "-t" || arg === "--template") {
82
+ i++; // skip the flag's value too
83
+ }
84
+ continue;
85
+ }
86
+ // For REST URL paths like "repos/acme/repo/pulls/123/comments?...",
87
+ // extract only the first path segment to keep cardinality bounded.
88
+ // "graphql" stays as-is; "repos/..." becomes "repos"; "user" stays "user".
89
+ const firstSegment = arg.split("/")[0].split("?")[0];
90
+ return `gh.${args[0]}.${firstSegment}`;
91
+ }
92
+ return `gh.${args[0]}`;
93
+ }
94
+ function extractMethod(args) {
95
+ for (let i = 0; i < args.length; i++) {
96
+ if (args[i] === "--method" || args[i] === "-X") {
97
+ return args[i + 1];
98
+ }
99
+ }
100
+ return args[0] === "api" ? "GET" : undefined;
101
+ }
102
+ function extractEndpoint(args) {
103
+ if (args[0] !== "api")
104
+ return undefined;
105
+ for (let i = 1; i < args.length; i++) {
106
+ const arg = args[i];
107
+ if (!arg)
108
+ continue;
109
+ if (arg === "--method" || arg === "-X" || arg === "-H" || arg === "--header") {
110
+ i++;
111
+ continue;
112
+ }
113
+ if (arg === "-f" || arg === "--raw-field" || arg === "-F" || arg === "--field") {
114
+ i++;
115
+ continue;
116
+ }
117
+ if (arg === "--input") {
118
+ i++;
119
+ continue;
120
+ }
121
+ if (!arg.startsWith("-")) {
122
+ return arg;
123
+ }
124
+ }
125
+ return undefined;
126
+ }
127
+ function parseIncludedHttpResponse(stdout) {
128
+ const headers = {};
129
+ const normalized = stdout.replace(/\r/g, "");
130
+ const lines = normalized.split("\n");
131
+ // Take the LAST HTTP/ status line — on redirects (3xx → 200), the final
132
+ // status line corresponds to the actual resource, not the redirect.
133
+ let startIndex = -1;
134
+ for (let i = lines.length - 1; i >= 0; i--) {
135
+ if (lines[i]?.startsWith("HTTP/")) {
136
+ startIndex = i;
137
+ break;
138
+ }
139
+ }
140
+ if (startIndex === -1) {
141
+ return { headers };
142
+ }
143
+ const statusLine = lines[startIndex];
144
+ for (let i = startIndex + 1; i < lines.length; i++) {
145
+ const line = lines[i];
146
+ if (!line)
147
+ break;
148
+ const colonIndex = line.indexOf(":");
149
+ if (colonIndex === -1)
150
+ continue;
151
+ const key = line.slice(0, colonIndex).trim().toLowerCase();
152
+ const value = line.slice(colonIndex + 1).trim();
153
+ headers[key] = value;
154
+ }
155
+ return { statusLine, headers };
156
+ }
157
+ function extractExitCode(err) {
158
+ const candidate = err;
159
+ if (typeof candidate.exitCode === "number")
160
+ return candidate.exitCode;
161
+ if (typeof candidate.code === "number")
162
+ return candidate.code;
163
+ return undefined;
164
+ }
165
+ function extractSignal(err) {
166
+ const candidate = err;
167
+ return typeof candidate.signal === "string" ? candidate.signal : undefined;
168
+ }
169
+ const ensuredDirs = new Set();
170
+ const warnedTargets = new Set();
171
+ async function writeTrace(entry) {
172
+ const target = process.env[GH_TRACE_FILE_ENV];
173
+ if (!target)
174
+ return;
175
+ const dir = dirname(target);
176
+ const line = `${JSON.stringify(entry)}\n`;
177
+ try {
178
+ if (!ensuredDirs.has(dir)) {
179
+ await mkdir(dir, { recursive: true });
180
+ ensuredDirs.add(dir);
181
+ }
182
+ await appendFile(target, line, "utf-8");
183
+ }
184
+ catch (err) {
185
+ // Warn once per target to surface disk-full / permission errors
186
+ if (!warnedTargets.has(target)) {
187
+ warnedTargets.add(target);
188
+ const msg = err instanceof Error ? err.message : String(err);
189
+ // eslint-disable-next-line no-console -- surface trace write failures once
190
+ console.warn(`[gh-trace] Failed to write trace to ${target}: ${msg}`);
191
+ }
192
+ }
193
+ }
194
+ /** Redact sensitive values from gh CLI args before persisting to trace JSONL. */
195
+ function redactArgs(args) {
196
+ const sensitiveFlags = new Set(["-H", "--header"]);
197
+ const sensitiveFieldPrefixes = ["token=", "password=", "secret=", "authorization="];
198
+ return args.map((arg, i) => {
199
+ // Redact the value after -H / --header if it contains Authorization
200
+ const prev = i > 0 ? args[i - 1] : undefined;
201
+ if (prev && sensitiveFlags.has(prev) && /^authorization:/i.test(arg)) {
202
+ return "Authorization: [REDACTED]";
203
+ }
204
+ // Redact inline -H"Authorization: ..." style
205
+ if (/^-H/i.test(arg) && /authorization:/i.test(arg)) {
206
+ return "-HAuthorization: [REDACTED]";
207
+ }
208
+ // Redact -f/-F field values like token=..., password=...
209
+ for (const prefix of sensitiveFieldPrefixes) {
210
+ if (arg.toLowerCase().startsWith(prefix)) {
211
+ return `${arg.slice(0, prefix.length)}[REDACTED]`;
212
+ }
213
+ }
214
+ // Redact the value following -f/-F if the next positional matches
215
+ if (prev && (prev === "-f" || prev === "--raw-field" || prev === "-F" || prev === "--field")) {
216
+ for (const prefix of sensitiveFieldPrefixes) {
217
+ if (arg.toLowerCase().startsWith(prefix)) {
218
+ return `${arg.slice(0, prefix.length)}[REDACTED]`;
219
+ }
220
+ }
221
+ }
222
+ return arg;
223
+ });
224
+ }
225
+ function buildTraceEntry(args, ctx, result, durationMs) {
226
+ const { statusLine, headers } = parseIncludedHttpResponse(result.stdout ?? "");
227
+ const httpStatus = statusLine
228
+ ? Number.parseInt(statusLine.replace(/^HTTP\/[0-9.]+\s+/, "").split(" ")[0] ?? "", 10)
229
+ : undefined;
230
+ return {
231
+ timestamp: nowIso(),
232
+ component: ctx.component,
233
+ operation: ctx.operation ?? extractOperation(args),
234
+ projectId: ctx.projectId,
235
+ sessionId: ctx.sessionId,
236
+ cwd: ctx.cwd,
237
+ args: redactArgs(args),
238
+ endpoint: extractEndpoint(args),
239
+ method: extractMethod(args),
240
+ ok: result.ok,
241
+ exitCode: result.exitCode,
242
+ signal: result.signal,
243
+ durationMs,
244
+ stdoutBytes: Buffer.byteLength(result.stdout ?? "", "utf-8"),
245
+ stderrBytes: Buffer.byteLength(result.stderr ?? "", "utf-8"),
246
+ statusLine,
247
+ httpStatus: Number.isFinite(httpStatus) ? httpStatus : undefined,
248
+ etag: headers["etag"],
249
+ rateLimitLimit: parseIntHeader(headers["x-ratelimit-limit"]),
250
+ rateLimitRemaining: parseIntHeader(headers["x-ratelimit-remaining"]),
251
+ rateLimitReset: parseIntHeader(headers["x-ratelimit-reset"]),
252
+ rateLimitResource: headers["x-ratelimit-resource"],
253
+ ...parseGraphQLRateLimit(result.stdout ?? "", args),
254
+ };
255
+ }
256
+ /** Extract rateLimit { cost, remaining, resetAt } from GraphQL response body. */
257
+ function parseGraphQLRateLimit(stdout, args) {
258
+ // Only attempt for GraphQL calls
259
+ if (!args.includes("graphql"))
260
+ return {};
261
+ // Quick check — avoid parsing multi-MB response bodies when rateLimit isn't present
262
+ if (!stdout.includes('"rateLimit"'))
263
+ return {};
264
+ // Strip HTTP headers if present (-i flag)
265
+ const bodyMatch = stdout.match(/\r?\n\r?\n([\s\S]*)$/);
266
+ const body = bodyMatch ? bodyMatch[1] : stdout;
267
+ try {
268
+ const parsed = JSON.parse(body.trim());
269
+ const rl = parsed?.data?.rateLimit;
270
+ if (!rl)
271
+ return {};
272
+ return {
273
+ graphqlCost: typeof rl.cost === "number" ? rl.cost : undefined,
274
+ graphqlRemaining: typeof rl.remaining === "number" ? rl.remaining : undefined,
275
+ graphqlResetAt: typeof rl.resetAt === "string" ? rl.resetAt : undefined,
276
+ };
277
+ }
278
+ catch {
279
+ return {};
280
+ }
281
+ }
282
+ async function execGhObserved(args, ctx, timeout = 30_000) {
283
+ const startedAt = Date.now();
284
+ try {
285
+ const ghPath = await getGhBinaryPath();
286
+ const { stdout, stderr } = await execFileAsync(ghPath, args, {
287
+ ...(ctx.cwd ? { cwd: ctx.cwd } : {}),
288
+ // 10 MB — matches the previous per-caller maxBuffer in scm-github.
289
+ // GraphQL batch queries for 25 PRs can produce multi-MB responses.
290
+ maxBuffer: 10 * 1024 * 1024,
291
+ timeout,
292
+ });
293
+ const entry = buildTraceEntry(args, ctx, { ok: true, stdout, stderr }, Date.now() - startedAt);
294
+ await writeTrace(entry);
295
+ return stdout.trim();
296
+ }
297
+ catch (err) {
298
+ const stdout = typeof err.stdout === "string"
299
+ ? err.stdout
300
+ : "";
301
+ const stderr = typeof err.stderr === "string"
302
+ ? err.stderr
303
+ : "";
304
+ const entry = buildTraceEntry(args, ctx, {
305
+ ok: false,
306
+ stdout,
307
+ stderr,
308
+ exitCode: extractExitCode(err),
309
+ signal: extractSignal(err),
310
+ }, Date.now() - startedAt);
311
+ await writeTrace(entry);
312
+ throw err;
313
+ }
314
+ }
315
+ function getGhTraceFilePath() {
316
+ return process.env[GH_TRACE_FILE_ENV];
317
+ }
318
+
319
+ export { execGhObserved, getGhTraceFilePath };
320
+ //# sourceMappingURL=gh-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gh-trace.js","sources":["../src/gh-trace.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Check whether the given workspace has any git commits within the last
3
+ * `windowSeconds` seconds. Swallows errors (e.g. not a git repo, git missing)
4
+ * and returns `false` so callers can use this as a best-effort liveness signal.
5
+ *
6
+ * @param workspacePath Absolute path to the workspace (must be a git repo).
7
+ * @param windowSeconds How far back to look for commits. Defaults to 60s.
8
+ */
9
+ export declare function hasRecentCommits(workspacePath: string, windowSeconds?: number): Promise<boolean>;
10
+ //# sourceMappingURL=git-activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-activity.d.ts","sourceRoot":"","sources":["../src/git-activity.ts"],"names":[],"mappings":"AAWA;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,aAAa,SAAK,GACjB,OAAO,CAAC,OAAO,CAAC,CAWlB"}
@@ -0,0 +1,30 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+
4
+ /**
5
+ * Git-commit-based activity detection helpers for agent plugins.
6
+ *
7
+ * Agents without native JSONL introspection (Aider, Cursor, etc.) can use
8
+ * recent git commits as a signal that the agent has been actively working.
9
+ */
10
+ const execFileAsync = promisify(execFile);
11
+ /**
12
+ * Check whether the given workspace has any git commits within the last
13
+ * `windowSeconds` seconds. Swallows errors (e.g. not a git repo, git missing)
14
+ * and returns `false` so callers can use this as a best-effort liveness signal.
15
+ *
16
+ * @param workspacePath Absolute path to the workspace (must be a git repo).
17
+ * @param windowSeconds How far back to look for commits. Defaults to 60s.
18
+ */
19
+ async function hasRecentCommits(workspacePath, windowSeconds = 60) {
20
+ try {
21
+ const { stdout } = await execFileAsync("git", ["log", `--since=${windowSeconds} seconds ago`, "--format=%H"], { cwd: workspacePath, timeout: 5_000 });
22
+ return stdout.trim().length > 0;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ export { hasRecentCommits };
30
+ //# sourceMappingURL=git-activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-activity.js","sources":["../src/git-activity.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAAA;;;;;AAKG;AAIH,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC;AAEzC;;;;;;;AAOG;AACI,eAAe,gBAAgB,CACpC,aAAqB,EACrB,aAAa,GAAG,EAAE,EAAA;AAElB,IAAA,IAAI;AACF,QAAA,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,KAAK,EACL,CAAC,KAAK,EAAE,CAAA,QAAA,EAAW,aAAa,CAAA,YAAA,CAAc,EAAE,aAAa,CAAC,EAC9D,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,CACvC;QACD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;IACjC;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACF;;;;"}