@geminixiang/mikan 1.0.0-beta.2 → 1.0.0-beta.20

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 (412) hide show
  1. package/CHANGELOG.md +354 -0
  2. package/README.md +42 -16
  3. package/dist/adapter.d.ts +1 -1
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js.map +1 -1
  6. package/dist/adapters/discord/bot.d.ts +1 -0
  7. package/dist/adapters/discord/bot.d.ts.map +1 -1
  8. package/dist/adapters/discord/bot.js +36 -67
  9. package/dist/adapters/discord/bot.js.map +1 -1
  10. package/dist/adapters/discord/context.d.ts.map +1 -1
  11. package/dist/adapters/discord/context.js +17 -42
  12. package/dist/adapters/discord/context.js.map +1 -1
  13. package/dist/adapters/github/bot.d.ts +148 -0
  14. package/dist/adapters/github/bot.d.ts.map +1 -0
  15. package/dist/adapters/github/bot.js +1031 -0
  16. package/dist/adapters/github/bot.js.map +1 -0
  17. package/dist/adapters/github/client.d.ts +118 -0
  18. package/dist/adapters/github/client.d.ts.map +1 -0
  19. package/dist/adapters/github/client.js +309 -0
  20. package/dist/adapters/github/client.js.map +1 -0
  21. package/dist/adapters/github/cloudbuild.d.ts +24 -0
  22. package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
  23. package/dist/adapters/github/cloudbuild.js +71 -0
  24. package/dist/adapters/github/cloudbuild.js.map +1 -0
  25. package/dist/adapters/github/context.d.ts +9 -0
  26. package/dist/adapters/github/context.d.ts.map +1 -0
  27. package/dist/adapters/github/context.js +175 -0
  28. package/dist/adapters/github/context.js.map +1 -0
  29. package/dist/adapters/github/gcp-auth.d.ts +31 -0
  30. package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
  31. package/dist/adapters/github/gcp-auth.js +196 -0
  32. package/dist/adapters/github/gcp-auth.js.map +1 -0
  33. package/dist/adapters/github/ids.d.ts +34 -0
  34. package/dist/adapters/github/ids.d.ts.map +1 -0
  35. package/dist/adapters/github/ids.js +53 -0
  36. package/dist/adapters/github/ids.js.map +1 -0
  37. package/dist/adapters/github/repo.d.ts +30 -0
  38. package/dist/adapters/github/repo.d.ts.map +1 -0
  39. package/dist/adapters/github/repo.js +136 -0
  40. package/dist/adapters/github/repo.js.map +1 -0
  41. package/dist/adapters/github/tool-pack.d.ts +14 -0
  42. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  43. package/dist/adapters/github/tool-pack.js +56 -0
  44. package/dist/adapters/github/tool-pack.js.map +1 -0
  45. package/dist/adapters/github/tools/checks.d.ts +24 -0
  46. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  47. package/dist/adapters/github/tools/checks.js +116 -0
  48. package/dist/adapters/github/tools/checks.js.map +1 -0
  49. package/dist/adapters/github/tools/issue.d.ts +22 -0
  50. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  51. package/dist/adapters/github/tools/issue.js +59 -0
  52. package/dist/adapters/github/tools/issue.js.map +1 -0
  53. package/dist/adapters/github/tools/pr.d.ts +22 -0
  54. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  55. package/dist/adapters/github/tools/pr.js +59 -0
  56. package/dist/adapters/github/tools/pr.js.map +1 -0
  57. package/dist/adapters/github/tools/read.d.ts +22 -0
  58. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  59. package/dist/adapters/github/tools/read.js +152 -0
  60. package/dist/adapters/github/tools/read.js.map +1 -0
  61. package/dist/adapters/github/tools/review-reply.d.ts +19 -0
  62. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  63. package/dist/adapters/github/tools/review-reply.js +49 -0
  64. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  65. package/dist/adapters/github/tools/sync.d.ts +17 -0
  66. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  67. package/dist/adapters/github/tools/sync.js +45 -0
  68. package/dist/adapters/github/tools/sync.js.map +1 -0
  69. package/dist/adapters/github/types.d.ts +350 -0
  70. package/dist/adapters/github/types.d.ts.map +1 -0
  71. package/dist/adapters/github/types.js +2 -0
  72. package/dist/adapters/github/types.js.map +1 -0
  73. package/dist/adapters/intake.d.ts +16 -5
  74. package/dist/adapters/intake.d.ts.map +1 -1
  75. package/dist/adapters/intake.js +79 -22
  76. package/dist/adapters/intake.js.map +1 -1
  77. package/dist/adapters/slack/bot.d.ts +8 -6
  78. package/dist/adapters/slack/bot.d.ts.map +1 -1
  79. package/dist/adapters/slack/bot.js +81 -133
  80. package/dist/adapters/slack/bot.js.map +1 -1
  81. package/dist/adapters/slack/context.d.ts.map +1 -1
  82. package/dist/adapters/slack/context.js +3 -14
  83. package/dist/adapters/slack/context.js.map +1 -1
  84. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  85. package/dist/adapters/slack/response-lifecycle.js +14 -17
  86. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  87. package/dist/adapters/slack/session.d.ts.map +1 -1
  88. package/dist/adapters/slack/session.js +5 -8
  89. package/dist/adapters/slack/session.js.map +1 -1
  90. package/dist/adapters/streaming.d.ts +4 -0
  91. package/dist/adapters/streaming.d.ts.map +1 -1
  92. package/dist/adapters/streaming.js +11 -0
  93. package/dist/adapters/streaming.js.map +1 -1
  94. package/dist/adapters/telegram/bot.d.ts +1 -2
  95. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  96. package/dist/adapters/telegram/bot.js +27 -62
  97. package/dist/adapters/telegram/bot.js.map +1 -1
  98. package/dist/adapters/telegram/context.d.ts.map +1 -1
  99. package/dist/adapters/telegram/context.js +8 -27
  100. package/dist/adapters/telegram/context.js.map +1 -1
  101. package/dist/adapters/types.d.ts +28 -2
  102. package/dist/adapters/types.d.ts.map +1 -1
  103. package/dist/adapters/types.js.map +1 -1
  104. package/dist/agent.d.ts +38 -14
  105. package/dist/agent.d.ts.map +1 -1
  106. package/dist/agent.js +358 -224
  107. package/dist/agent.js.map +1 -1
  108. package/dist/cli/download.d.ts.map +1 -0
  109. package/dist/cli/download.js.map +1 -0
  110. package/dist/cli/ext-git.d.ts +22 -0
  111. package/dist/cli/ext-git.d.ts.map +1 -0
  112. package/dist/cli/ext-git.js +76 -0
  113. package/dist/cli/ext-git.js.map +1 -0
  114. package/dist/cli/ext.d.ts +2 -0
  115. package/dist/cli/ext.d.ts.map +1 -0
  116. package/dist/cli/ext.js +217 -0
  117. package/dist/cli/ext.js.map +1 -0
  118. package/dist/commands/admin.d.ts.map +1 -1
  119. package/dist/commands/admin.js +2 -1
  120. package/dist/commands/admin.js.map +1 -1
  121. package/dist/commands/auto-reply.d.ts.map +1 -1
  122. package/dist/commands/auto-reply.js +2 -6
  123. package/dist/commands/auto-reply.js.map +1 -1
  124. package/dist/commands/extensions.d.ts.map +1 -1
  125. package/dist/commands/extensions.js +16 -6
  126. package/dist/commands/extensions.js.map +1 -1
  127. package/dist/commands/login.d.ts +2 -1
  128. package/dist/commands/login.d.ts.map +1 -1
  129. package/dist/commands/login.js +30 -1
  130. package/dist/commands/login.js.map +1 -1
  131. package/dist/commands/manifest.d.ts +72 -0
  132. package/dist/commands/manifest.d.ts.map +1 -0
  133. package/dist/commands/manifest.js +121 -0
  134. package/dist/commands/manifest.js.map +1 -0
  135. package/dist/commands/model.d.ts.map +1 -1
  136. package/dist/commands/model.js +3 -1
  137. package/dist/commands/model.js.map +1 -1
  138. package/dist/commands/new.d.ts.map +1 -1
  139. package/dist/commands/new.js +2 -1
  140. package/dist/commands/new.js.map +1 -1
  141. package/dist/commands/sandbox.d.ts.map +1 -1
  142. package/dist/commands/sandbox.js +16 -12
  143. package/dist/commands/sandbox.js.map +1 -1
  144. package/dist/commands/text.d.ts +2 -0
  145. package/dist/commands/text.d.ts.map +1 -0
  146. package/dist/commands/text.js +16 -0
  147. package/dist/commands/text.js.map +1 -0
  148. package/dist/commands/types.d.ts +14 -1
  149. package/dist/commands/types.d.ts.map +1 -1
  150. package/dist/commands/types.js.map +1 -1
  151. package/dist/config.d.ts +1 -1
  152. package/dist/config.d.ts.map +1 -1
  153. package/dist/config.js +90 -54
  154. package/dist/config.js.map +1 -1
  155. package/dist/events.d.ts +10 -0
  156. package/dist/events.d.ts.map +1 -1
  157. package/dist/events.js +14 -5
  158. package/dist/events.js.map +1 -1
  159. package/dist/execution-resolver.d.ts +3 -2
  160. package/dist/execution-resolver.d.ts.map +1 -1
  161. package/dist/execution-resolver.js +28 -12
  162. package/dist/execution-resolver.js.map +1 -1
  163. package/dist/harness/extensions/loader.d.ts +39 -9
  164. package/dist/harness/extensions/loader.d.ts.map +1 -1
  165. package/dist/harness/extensions/loader.js +258 -54
  166. package/dist/harness/extensions/loader.js.map +1 -1
  167. package/dist/harness/extensions/registry.d.ts +48 -1
  168. package/dist/harness/extensions/registry.d.ts.map +1 -1
  169. package/dist/harness/extensions/registry.js +146 -0
  170. package/dist/harness/extensions/registry.js.map +1 -1
  171. package/dist/harness/extensions/types.d.ts +161 -14
  172. package/dist/harness/extensions/types.d.ts.map +1 -1
  173. package/dist/harness/extensions/types.js.map +1 -1
  174. package/dist/harness/index.d.ts +5 -5
  175. package/dist/harness/index.d.ts.map +1 -1
  176. package/dist/harness/index.js +2 -2
  177. package/dist/harness/index.js.map +1 -1
  178. package/dist/harness/models.d.ts +5 -0
  179. package/dist/harness/models.d.ts.map +1 -1
  180. package/dist/harness/models.js +10 -0
  181. package/dist/harness/models.js.map +1 -1
  182. package/dist/harness/runner.d.ts +21 -2
  183. package/dist/harness/runner.d.ts.map +1 -1
  184. package/dist/harness/runner.js +80 -22
  185. package/dist/harness/runner.js.map +1 -1
  186. package/dist/harness/session-store.d.ts +4 -1
  187. package/dist/harness/session-store.d.ts.map +1 -1
  188. package/dist/harness/session-store.js +11 -2
  189. package/dist/harness/session-store.js.map +1 -1
  190. package/dist/harness/subagent-runner.d.ts +17 -0
  191. package/dist/harness/subagent-runner.d.ts.map +1 -0
  192. package/dist/harness/subagent-runner.js +307 -0
  193. package/dist/harness/subagent-runner.js.map +1 -0
  194. package/dist/harness/types.d.ts +53 -0
  195. package/dist/harness/types.d.ts.map +1 -1
  196. package/dist/harness/types.js.map +1 -1
  197. package/dist/index.d.ts +1 -1
  198. package/dist/index.d.ts.map +1 -1
  199. package/dist/index.js.map +1 -1
  200. package/dist/main.js +232 -29
  201. package/dist/main.js.map +1 -1
  202. package/dist/provisioner.d.ts.map +1 -1
  203. package/dist/provisioner.js +2 -5
  204. package/dist/provisioner.js.map +1 -1
  205. package/dist/runtime/conversation-runtime.d.ts +1 -1
  206. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  207. package/dist/runtime/conversation-runtime.js +264 -41
  208. package/dist/runtime/conversation-runtime.js.map +1 -1
  209. package/dist/runtime/types.d.ts +32 -5
  210. package/dist/runtime/types.d.ts.map +1 -1
  211. package/dist/runtime/types.js.map +1 -1
  212. package/dist/sandbox/cloudflare.d.ts +2 -0
  213. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  214. package/dist/sandbox/cloudflare.js +7 -0
  215. package/dist/sandbox/cloudflare.js.map +1 -1
  216. package/dist/sandbox/container.d.ts +3 -0
  217. package/dist/sandbox/container.d.ts.map +1 -1
  218. package/dist/sandbox/container.js +8 -2
  219. package/dist/sandbox/container.js.map +1 -1
  220. package/dist/sandbox/firecracker.d.ts +2 -0
  221. package/dist/sandbox/firecracker.d.ts.map +1 -1
  222. package/dist/sandbox/firecracker.js +7 -1
  223. package/dist/sandbox/firecracker.js.map +1 -1
  224. package/dist/sandbox/gondolin-fleet.d.ts +104 -0
  225. package/dist/sandbox/gondolin-fleet.d.ts.map +1 -0
  226. package/dist/sandbox/gondolin-fleet.js +330 -0
  227. package/dist/sandbox/gondolin-fleet.js.map +1 -0
  228. package/dist/sandbox/gondolin-gateway.d.ts +85 -0
  229. package/dist/sandbox/gondolin-gateway.d.ts.map +1 -0
  230. package/dist/sandbox/gondolin-gateway.js +400 -0
  231. package/dist/sandbox/gondolin-gateway.js.map +1 -0
  232. package/dist/sandbox/gondolin-inventory.d.ts +89 -0
  233. package/dist/sandbox/gondolin-inventory.d.ts.map +1 -0
  234. package/dist/sandbox/gondolin-inventory.js +267 -0
  235. package/dist/sandbox/gondolin-inventory.js.map +1 -0
  236. package/dist/sandbox/gondolin-join.d.ts +62 -0
  237. package/dist/sandbox/gondolin-join.d.ts.map +1 -0
  238. package/dist/sandbox/gondolin-join.js +261 -0
  239. package/dist/sandbox/gondolin-join.js.map +1 -0
  240. package/dist/sandbox/gondolin-nfs-advisory.d.ts +15 -0
  241. package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +1 -0
  242. package/dist/sandbox/gondolin-nfs-advisory.js +60 -0
  243. package/dist/sandbox/gondolin-nfs-advisory.js.map +1 -0
  244. package/dist/sandbox/gondolin-placement.d.ts +32 -0
  245. package/dist/sandbox/gondolin-placement.d.ts.map +1 -0
  246. package/dist/sandbox/gondolin-placement.js +83 -0
  247. package/dist/sandbox/gondolin-placement.js.map +1 -0
  248. package/dist/sandbox/gondolin-remote.d.ts +73 -0
  249. package/dist/sandbox/gondolin-remote.d.ts.map +1 -0
  250. package/dist/sandbox/gondolin-remote.js +352 -0
  251. package/dist/sandbox/gondolin-remote.js.map +1 -0
  252. package/dist/sandbox/gondolin-worker-client.d.ts +139 -0
  253. package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -0
  254. package/dist/sandbox/gondolin-worker-client.js +325 -0
  255. package/dist/sandbox/gondolin-worker-client.js.map +1 -0
  256. package/dist/sandbox/gondolin-worker-main.d.ts +2 -0
  257. package/dist/sandbox/gondolin-worker-main.d.ts.map +1 -0
  258. package/dist/sandbox/gondolin-worker-main.js +22 -0
  259. package/dist/sandbox/gondolin-worker-main.js.map +1 -0
  260. package/dist/sandbox/gondolin-worker.d.ts +55 -0
  261. package/dist/sandbox/gondolin-worker.d.ts.map +1 -0
  262. package/dist/sandbox/gondolin-worker.js +201 -0
  263. package/dist/sandbox/gondolin-worker.js.map +1 -0
  264. package/dist/sandbox/gondolin.d.ts +52 -0
  265. package/dist/sandbox/gondolin.d.ts.map +1 -0
  266. package/dist/sandbox/gondolin.js +425 -0
  267. package/dist/sandbox/gondolin.js.map +1 -0
  268. package/dist/sandbox/host.d.ts +2 -0
  269. package/dist/sandbox/host.d.ts.map +1 -1
  270. package/dist/sandbox/host.js +11 -0
  271. package/dist/sandbox/host.js.map +1 -1
  272. package/dist/sandbox/identity.d.ts +21 -0
  273. package/dist/sandbox/identity.d.ts.map +1 -0
  274. package/dist/sandbox/identity.js +36 -0
  275. package/dist/sandbox/identity.js.map +1 -0
  276. package/dist/sandbox/index.d.ts +4 -3
  277. package/dist/sandbox/index.d.ts.map +1 -1
  278. package/dist/sandbox/index.js +5 -3
  279. package/dist/sandbox/index.js.map +1 -1
  280. package/dist/sandbox/types.d.ts +26 -1
  281. package/dist/sandbox/types.d.ts.map +1 -1
  282. package/dist/sandbox/types.js.map +1 -1
  283. package/dist/sandbox/utils.d.ts +11 -0
  284. package/dist/sandbox/utils.d.ts.map +1 -1
  285. package/dist/sandbox/utils.js +35 -0
  286. package/dist/sandbox/utils.js.map +1 -1
  287. package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
  288. package/dist/sessions/agent-memory-file-manager.js +16 -30
  289. package/dist/sessions/agent-memory-file-manager.js.map +1 -1
  290. package/dist/sessions/history-line.d.ts +20 -0
  291. package/dist/sessions/history-line.d.ts.map +1 -0
  292. package/dist/sessions/history-line.js +24 -0
  293. package/dist/sessions/history-line.js.map +1 -0
  294. package/dist/sessions/policy.d.ts.map +1 -1
  295. package/dist/sessions/policy.js +5 -3
  296. package/dist/sessions/policy.js.map +1 -1
  297. package/dist/sessions/session-key.d.ts +31 -0
  298. package/dist/sessions/session-key.d.ts.map +1 -0
  299. package/dist/sessions/session-key.js +44 -0
  300. package/dist/sessions/session-key.js.map +1 -0
  301. package/dist/sessions/store.d.ts.map +1 -1
  302. package/dist/sessions/store.js +2 -2
  303. package/dist/sessions/store.js.map +1 -1
  304. package/dist/tools/bash.d.ts +3 -1
  305. package/dist/tools/bash.d.ts.map +1 -1
  306. package/dist/tools/bash.js +24 -17
  307. package/dist/tools/bash.js.map +1 -1
  308. package/dist/tools/edit.d.ts.map +1 -1
  309. package/dist/tools/edit.js +9 -12
  310. package/dist/tools/edit.js.map +1 -1
  311. package/dist/tools/event.d.ts +1 -1
  312. package/dist/tools/event.d.ts.map +1 -1
  313. package/dist/tools/event.js +33 -4
  314. package/dist/tools/event.js.map +1 -1
  315. package/dist/tools/generate-image.d.ts +17 -0
  316. package/dist/tools/generate-image.d.ts.map +1 -0
  317. package/dist/tools/generate-image.js +63 -0
  318. package/dist/tools/generate-image.js.map +1 -0
  319. package/dist/tools/index.d.ts +16 -2
  320. package/dist/tools/index.d.ts.map +1 -1
  321. package/dist/tools/index.js +27 -3
  322. package/dist/tools/index.js.map +1 -1
  323. package/dist/tools/react.d.ts +15 -0
  324. package/dist/tools/react.d.ts.map +1 -0
  325. package/dist/tools/react.js +40 -0
  326. package/dist/tools/react.js.map +1 -0
  327. package/dist/tools/sandbox.d.ts +2 -2
  328. package/dist/tools/sandbox.d.ts.map +1 -1
  329. package/dist/tools/sandbox.js +8 -7
  330. package/dist/tools/sandbox.js.map +1 -1
  331. package/dist/tools/subagent.d.ts +69 -0
  332. package/dist/tools/subagent.d.ts.map +1 -0
  333. package/dist/tools/subagent.js +286 -0
  334. package/dist/tools/subagent.js.map +1 -0
  335. package/dist/tools/types.d.ts +34 -1
  336. package/dist/tools/types.d.ts.map +1 -1
  337. package/dist/tools/types.js.map +1 -1
  338. package/dist/tools/write.d.ts.map +1 -1
  339. package/dist/tools/write.js +1 -8
  340. package/dist/tools/write.js.map +1 -1
  341. package/dist/trigger.d.ts.map +1 -1
  342. package/dist/trigger.js +1 -2
  343. package/dist/trigger.js.map +1 -1
  344. package/dist/types.d.ts +139 -7
  345. package/dist/types.d.ts.map +1 -1
  346. package/dist/types.js.map +1 -1
  347. package/dist/vault/disabled.d.ts +9 -0
  348. package/dist/vault/disabled.d.ts.map +1 -0
  349. package/dist/vault/disabled.js +23 -0
  350. package/dist/vault/disabled.js.map +1 -0
  351. package/dist/vault/index.d.ts.map +1 -1
  352. package/dist/vault/index.js +3 -24
  353. package/dist/vault/index.js.map +1 -1
  354. package/dist/vault/policy.d.ts +20 -0
  355. package/dist/vault/policy.d.ts.map +1 -0
  356. package/dist/vault/policy.js +20 -0
  357. package/dist/vault/policy.js.map +1 -0
  358. package/dist/vault/routing.d.ts +1 -0
  359. package/dist/vault/routing.d.ts.map +1 -1
  360. package/dist/vault/routing.js +3 -10
  361. package/dist/vault/routing.js.map +1 -1
  362. package/dist/web/admin/portal.d.ts +27 -0
  363. package/dist/web/admin/portal.d.ts.map +1 -1
  364. package/dist/web/admin/portal.js +91 -130
  365. package/dist/web/admin/portal.js.map +1 -1
  366. package/dist/web/admin/types.d.ts +3 -0
  367. package/dist/web/admin/types.d.ts.map +1 -1
  368. package/dist/web/admin/types.js.map +1 -1
  369. package/dist/web/login/oauth.d.ts +2 -3
  370. package/dist/web/login/oauth.d.ts.map +1 -1
  371. package/dist/web/login/oauth.js +0 -31
  372. package/dist/web/login/oauth.js.map +1 -1
  373. package/dist/web/login/portal.js +1 -1
  374. package/dist/web/login/portal.js.map +1 -1
  375. package/dist/web/login/types.d.ts +0 -11
  376. package/dist/web/login/types.d.ts.map +1 -1
  377. package/dist/web/login/types.js.map +1 -1
  378. package/dist/web/portal-shell.d.ts +4 -0
  379. package/dist/web/portal-shell.d.ts.map +1 -0
  380. package/dist/{portal-shell.js → web/portal-shell.js} +2 -2
  381. package/dist/web/portal-shell.js.map +1 -0
  382. package/dist/web/server.d.ts.map +1 -1
  383. package/dist/web/server.js +7 -0
  384. package/dist/web/server.js.map +1 -1
  385. package/dist/web/session-view/command.d.ts.map +1 -1
  386. package/dist/web/session-view/command.js +4 -1
  387. package/dist/web/session-view/command.js.map +1 -1
  388. package/dist/web/session-view/portal.d.ts.map +1 -1
  389. package/dist/web/session-view/portal.js +4 -3
  390. package/dist/web/session-view/portal.js.map +1 -1
  391. package/dist/web/session-view/service.d.ts.map +1 -1
  392. package/dist/web/session-view/service.js +2 -1
  393. package/dist/web/session-view/service.js.map +1 -1
  394. package/dist/web/session-view/types.d.ts +2 -1
  395. package/dist/web/session-view/types.d.ts.map +1 -1
  396. package/dist/web/session-view/types.js.map +1 -1
  397. package/package.json +7 -4
  398. package/dist/download.d.ts.map +0 -1
  399. package/dist/download.js.map +0 -1
  400. package/dist/model-registry.d.ts +0 -4
  401. package/dist/model-registry.d.ts.map +0 -1
  402. package/dist/model-registry.js +0 -7
  403. package/dist/model-registry.js.map +0 -1
  404. package/dist/portal-shell.d.ts +0 -4
  405. package/dist/portal-shell.d.ts.map +0 -1
  406. package/dist/portal-shell.js.map +0 -1
  407. package/dist/runtime/agent-run-controller.d.ts +0 -31
  408. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  409. package/dist/runtime/agent-run-controller.js +0 -195
  410. package/dist/runtime/agent-run-controller.js.map +0 -1
  411. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
  412. /package/dist/{download.js → cli/download.js} +0 -0
@@ -0,0 +1,136 @@
1
+ import { execFile } from "child_process";
2
+ import { promisify } from "util";
3
+ const execFileAsync = promisify(execFile);
4
+ const GIT_TIMEOUT_MS = 120_000;
5
+ /**
6
+ * Branches the bot may push: `pi/<name>`. Everything else — including the
7
+ * repo's default branch by construction — is refused, so a driven agent can
8
+ * only ever produce reviewable branches, never touch mainline directly.
9
+ */
10
+ export const GITHUB_PUSH_BRANCH_PATTERN = /^pi\/[A-Za-z0-9._][A-Za-z0-9._/-]*$/;
11
+ /**
12
+ * Pass the ephemeral token as a per-invocation header, never in the remote
13
+ * URL: nothing credential-shaped may end up in `.git/config`, which lives in
14
+ * the conversation dir and is bind-mounted into the sandbox.
15
+ */
16
+ function gitAuthArgs(token) {
17
+ const basic = Buffer.from(`x-access-token:${token}`).toString("base64");
18
+ return ["-c", `http.extraheader=Authorization: basic ${basic}`];
19
+ }
20
+ async function git(args, token) {
21
+ const { stdout } = await execFileAsync("git", [...(token ? gitAuthArgs(token) : []), ...args], {
22
+ timeout: GIT_TIMEOUT_MS,
23
+ env: { ...process.env, GIT_TERMINAL_PROMPT: "0" },
24
+ });
25
+ return stdout;
26
+ }
27
+ /**
28
+ * Git itself rejects these ref shapes; the check just keeps an API-supplied
29
+ * branch name that would parse as a git option (leading dash) or an invalid
30
+ * ref out of argv entirely instead of surfacing as a git error mid-clone.
31
+ */
32
+ function isSafeBranchName(name) {
33
+ return (name.length > 0 && !name.startsWith("-") && !name.includes("..") && !/[\s~^:?*[\\]/.test(name));
34
+ }
35
+ /**
36
+ * Local checkout name for a PR conversation: the PR's real head branch when
37
+ * known (same-repo heads only — the caller resolves that), falling back to
38
+ * the synthetic `pr-<n>` for fork PRs, unresolvable heads, and unsafe names.
39
+ * Using the real name is what lets the agent update the PR in place: commit
40
+ * on a `pi/*` head and `github_pr` pushes back to the same branch.
41
+ */
42
+ function prCheckoutName(prNumber, prHeadBranch) {
43
+ return prHeadBranch && isSafeBranchName(prHeadBranch) ? prHeadBranch : `pr-${prNumber}`;
44
+ }
45
+ /**
46
+ * Shallow-clone a repo into a conversation dir and preconfigure the bot's
47
+ * commit identity. For PR conversations, additionally fetch the PR head and
48
+ * check it out so the agent starts on the code under review — under its real
49
+ * branch name when the caller resolved one, which is what lets the agent push
50
+ * fixes back to the PR itself.
51
+ */
52
+ export async function cloneRepo(options) {
53
+ await git(["clone", "--depth", "50", options.url, options.dir], options.token);
54
+ await git(["-C", options.dir, "config", "user.name", options.botLogin]);
55
+ await git(["-C", options.dir, "config", "user.email", options.botEmail]);
56
+ if (options.prNumber !== undefined) {
57
+ await git(["-C", options.dir, "fetch", "--depth", "50", "origin", `pull/${options.prNumber}/head`], options.token);
58
+ await git([
59
+ "-C",
60
+ options.dir,
61
+ "checkout",
62
+ "-B",
63
+ prCheckoutName(options.prNumber, options.prHeadBranch),
64
+ "FETCH_HEAD",
65
+ ]);
66
+ }
67
+ }
68
+ /**
69
+ * Refresh a conversation clone from origin. Always fetches; only moves the
70
+ * checkout when that provably cannot lose agent work: the target branch is
71
+ * the one checked out, the tree is clean, and it has no commits of its own
72
+ * (`checkout -B` then handles fast-forward and force-pushed heads alike).
73
+ * Anything else stays fetch-only — FETCH_HEAD is left for the agent, which
74
+ * has full credential-less git inside the sandbox, to merge or rebase itself.
75
+ */
76
+ export async function syncRepo(options) {
77
+ const { dir, token } = options;
78
+ let refspec;
79
+ let target;
80
+ if (options.branch) {
81
+ refspec = options.branch;
82
+ target = options.branch;
83
+ }
84
+ else if (options.prNumber !== undefined) {
85
+ refspec = `pull/${options.prNumber}/head`;
86
+ target = prCheckoutName(options.prNumber, options.prHeadBranch);
87
+ }
88
+ else if (options.defaultBranch) {
89
+ refspec = options.defaultBranch;
90
+ target = options.defaultBranch;
91
+ }
92
+ else {
93
+ throw new Error("syncRepo needs a branch, a PR number, or the default branch");
94
+ }
95
+ await git(["-C", dir, "fetch", "--depth", "50", "origin", refspec], token);
96
+ const fetchedSha = (await git(["-C", dir, "rev-parse", "FETCH_HEAD"])).trim();
97
+ const dirty = (await git(["-C", dir, "status", "--porcelain"])).trim().length > 0;
98
+ const currentBranch = (await git(["-C", dir, "rev-parse", "--abbrev-ref", "HEAD"])).trim();
99
+ // Clones made before the head branch name was resolvable sit on the
100
+ // synthetic pr-<n>; treat that as the same checkout so a clean sync
101
+ // migrates them to the real name instead of going fetch-only forever.
102
+ const legacyPrBranch = options.prNumber !== undefined ? `pr-${options.prNumber}` : undefined;
103
+ const onTarget = currentBranch === target || (legacyPrBranch !== undefined && currentBranch === legacyPrBranch);
104
+ let localCommits = 0;
105
+ if (onTarget) {
106
+ // Commits unique to HEAD split two ways: ones the agent committed here
107
+ // (the clone's preconfigured bot identity) are its work and must survive;
108
+ // ones committed by others were force-pushed away upstream and are safe
109
+ // to drop. Filter by the bot committer so a rebased PR head still syncs.
110
+ const botEmail = (await git(["-C", dir, "config", "user.email"])).trim();
111
+ localCommits = Number((await git(["-C", dir, "rev-list", "--count", `--committer=${botEmail}`, "FETCH_HEAD..HEAD"])).trim());
112
+ }
113
+ const updatedCheckout = onTarget && !dirty && localCommits === 0;
114
+ if (updatedCheckout) {
115
+ await git(["-C", dir, "checkout", "-B", target, "FETCH_HEAD"]);
116
+ }
117
+ return { target, fetchedSha, updatedCheckout, dirty, currentBranch, localCommits };
118
+ }
119
+ /**
120
+ * Push one local branch to origin. Non-force by construction (plain refspec),
121
+ * and only `pi/*` branches are accepted.
122
+ */
123
+ export async function pushBranch(options) {
124
+ const { dir, branch, token } = options;
125
+ if (!GITHUB_PUSH_BRANCH_PATTERN.test(branch)) {
126
+ throw new Error(`Refusing to push branch '${branch}': only branches matching pi/<name> may be pushed.`);
127
+ }
128
+ try {
129
+ await git(["-C", dir, "rev-parse", "--verify", "--quiet", `refs/heads/${branch}`]);
130
+ }
131
+ catch {
132
+ throw new Error(`Branch '${branch}' does not exist in the conversation's ./repo clone.`);
133
+ }
134
+ await git(["-C", dir, "push", "origin", `refs/heads/${branch}:refs/heads/${branch}`], token);
135
+ }
136
+ //# sourceMappingURL=repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.js","sourceRoot":"","sources":["../../../src/adapters/github/repo.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport type {\n CloneRepoOptions,\n PushBranchOptions,\n SyncRepoOptions,\n SyncRepoResult,\n} from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst GIT_TIMEOUT_MS = 120_000;\n\n/**\n * Branches the bot may push: `pi/<name>`. Everything else — including the\n * repo's default branch by construction — is refused, so a driven agent can\n * only ever produce reviewable branches, never touch mainline directly.\n */\nexport const GITHUB_PUSH_BRANCH_PATTERN = /^pi\\/[A-Za-z0-9._][A-Za-z0-9._/-]*$/;\n\n/**\n * Pass the ephemeral token as a per-invocation header, never in the remote\n * URL: nothing credential-shaped may end up in `.git/config`, which lives in\n * the conversation dir and is bind-mounted into the sandbox.\n */\nfunction gitAuthArgs(token: string): string[] {\n const basic = Buffer.from(`x-access-token:${token}`).toString(\"base64\");\n return [\"-c\", `http.extraheader=Authorization: basic ${basic}`];\n}\n\nasync function git(args: string[], token?: string): Promise<string> {\n const { stdout } = await execFileAsync(\"git\", [...(token ? gitAuthArgs(token) : []), ...args], {\n timeout: GIT_TIMEOUT_MS,\n env: { ...process.env, GIT_TERMINAL_PROMPT: \"0\" },\n });\n return stdout;\n}\n\n/**\n * Git itself rejects these ref shapes; the check just keeps an API-supplied\n * branch name that would parse as a git option (leading dash) or an invalid\n * ref out of argv entirely instead of surfacing as a git error mid-clone.\n */\nfunction isSafeBranchName(name: string): boolean {\n return (\n name.length > 0 && !name.startsWith(\"-\") && !name.includes(\"..\") && !/[\\s~^:?*[\\\\]/.test(name)\n );\n}\n\n/**\n * Local checkout name for a PR conversation: the PR's real head branch when\n * known (same-repo heads only — the caller resolves that), falling back to\n * the synthetic `pr-<n>` for fork PRs, unresolvable heads, and unsafe names.\n * Using the real name is what lets the agent update the PR in place: commit\n * on a `pi/*` head and `github_pr` pushes back to the same branch.\n */\nfunction prCheckoutName(prNumber: number, prHeadBranch?: string): string {\n return prHeadBranch && isSafeBranchName(prHeadBranch) ? prHeadBranch : `pr-${prNumber}`;\n}\n\n/**\n * Shallow-clone a repo into a conversation dir and preconfigure the bot's\n * commit identity. For PR conversations, additionally fetch the PR head and\n * check it out so the agent starts on the code under review — under its real\n * branch name when the caller resolved one, which is what lets the agent push\n * fixes back to the PR itself.\n */\nexport async function cloneRepo(options: CloneRepoOptions): Promise<void> {\n await git([\"clone\", \"--depth\", \"50\", options.url, options.dir], options.token);\n await git([\"-C\", options.dir, \"config\", \"user.name\", options.botLogin]);\n await git([\"-C\", options.dir, \"config\", \"user.email\", options.botEmail]);\n if (options.prNumber !== undefined) {\n await git(\n [\"-C\", options.dir, \"fetch\", \"--depth\", \"50\", \"origin\", `pull/${options.prNumber}/head`],\n options.token,\n );\n await git([\n \"-C\",\n options.dir,\n \"checkout\",\n \"-B\",\n prCheckoutName(options.prNumber, options.prHeadBranch),\n \"FETCH_HEAD\",\n ]);\n }\n}\n\n/**\n * Refresh a conversation clone from origin. Always fetches; only moves the\n * checkout when that provably cannot lose agent work: the target branch is\n * the one checked out, the tree is clean, and it has no commits of its own\n * (`checkout -B` then handles fast-forward and force-pushed heads alike).\n * Anything else stays fetch-only — FETCH_HEAD is left for the agent, which\n * has full credential-less git inside the sandbox, to merge or rebase itself.\n */\nexport async function syncRepo(options: SyncRepoOptions): Promise<SyncRepoResult> {\n const { dir, token } = options;\n let refspec: string;\n let target: string;\n if (options.branch) {\n refspec = options.branch;\n target = options.branch;\n } else if (options.prNumber !== undefined) {\n refspec = `pull/${options.prNumber}/head`;\n target = prCheckoutName(options.prNumber, options.prHeadBranch);\n } else if (options.defaultBranch) {\n refspec = options.defaultBranch;\n target = options.defaultBranch;\n } else {\n throw new Error(\"syncRepo needs a branch, a PR number, or the default branch\");\n }\n\n await git([\"-C\", dir, \"fetch\", \"--depth\", \"50\", \"origin\", refspec], token);\n const fetchedSha = (await git([\"-C\", dir, \"rev-parse\", \"FETCH_HEAD\"])).trim();\n const dirty = (await git([\"-C\", dir, \"status\", \"--porcelain\"])).trim().length > 0;\n const currentBranch = (await git([\"-C\", dir, \"rev-parse\", \"--abbrev-ref\", \"HEAD\"])).trim();\n // Clones made before the head branch name was resolvable sit on the\n // synthetic pr-<n>; treat that as the same checkout so a clean sync\n // migrates them to the real name instead of going fetch-only forever.\n const legacyPrBranch = options.prNumber !== undefined ? `pr-${options.prNumber}` : undefined;\n const onTarget =\n currentBranch === target || (legacyPrBranch !== undefined && currentBranch === legacyPrBranch);\n let localCommits = 0;\n if (onTarget) {\n // Commits unique to HEAD split two ways: ones the agent committed here\n // (the clone's preconfigured bot identity) are its work and must survive;\n // ones committed by others were force-pushed away upstream and are safe\n // to drop. Filter by the bot committer so a rebased PR head still syncs.\n const botEmail = (await git([\"-C\", dir, \"config\", \"user.email\"])).trim();\n localCommits = Number(\n (\n await git([\"-C\", dir, \"rev-list\", \"--count\", `--committer=${botEmail}`, \"FETCH_HEAD..HEAD\"])\n ).trim(),\n );\n }\n\n const updatedCheckout = onTarget && !dirty && localCommits === 0;\n if (updatedCheckout) {\n await git([\"-C\", dir, \"checkout\", \"-B\", target, \"FETCH_HEAD\"]);\n }\n return { target, fetchedSha, updatedCheckout, dirty, currentBranch, localCommits };\n}\n\n/**\n * Push one local branch to origin. Non-force by construction (plain refspec),\n * and only `pi/*` branches are accepted.\n */\nexport async function pushBranch(options: PushBranchOptions): Promise<void> {\n const { dir, branch, token } = options;\n if (!GITHUB_PUSH_BRANCH_PATTERN.test(branch)) {\n throw new Error(\n `Refusing to push branch '${branch}': only branches matching pi/<name> may be pushed.`,\n );\n }\n try {\n await git([\"-C\", dir, \"rev-parse\", \"--verify\", \"--quiet\", `refs/heads/${branch}`]);\n } catch {\n throw new Error(`Branch '${branch}' does not exist in the conversation's ./repo clone.`);\n }\n await git([\"-C\", dir, \"push\", \"origin\", `refs/heads/${branch}:refs/heads/${branch}`], token);\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import type { PlatformToolPack } from "../../tools/types.js";
2
+ import type { PlatformGithubOps } from "./types.js";
3
+ /**
4
+ * GitHub host-side capability pack — one tool per module under `tools/`:
5
+ * github_pr, github_checks, github_review_reply, github_sync, github_read,
6
+ * github_issue.
7
+ *
8
+ * These tools never run in the sandbox; they call PlatformGithubOps which
9
+ * mints short-lived installation tokens on the host. The pack is only
10
+ * constructed when the GitHub bot is configured; bindRun enables the tools
11
+ * only for github-named conversations so multi-platform processes stay safe.
12
+ */
13
+ export declare function createGithubToolPack(ops: PlatformGithubOps): PlatformToolPack;
14
+ //# sourceMappingURL=tool-pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-pack.d.ts","sourceRoot":"","sources":["../../../src/adapters/github/tool-pack.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,gBAAgB,CA0C7E"}
@@ -0,0 +1,56 @@
1
+ import { createGithubChecksTool } from "./tools/checks.js";
2
+ import { createGithubPrTool } from "./tools/pr.js";
3
+ import { createGithubIssueTool } from "./tools/issue.js";
4
+ import { createGithubReadTool } from "./tools/read.js";
5
+ import { createGithubReviewReplyTool } from "./tools/review-reply.js";
6
+ import { createGithubSyncTool } from "./tools/sync.js";
7
+ /**
8
+ * GitHub host-side capability pack — one tool per module under `tools/`:
9
+ * github_pr, github_checks, github_review_reply, github_sync, github_read,
10
+ * github_issue.
11
+ *
12
+ * These tools never run in the sandbox; they call PlatformGithubOps which
13
+ * mints short-lived installation tokens on the host. The pack is only
14
+ * constructed when the GitHub bot is configured; bindRun enables the tools
15
+ * only for github-named conversations so multi-platform processes stay safe.
16
+ */
17
+ export function createGithubToolPack(ops) {
18
+ const { tool: githubPrTool, setGithubPrFunction } = createGithubPrTool();
19
+ const { tool: githubChecksTool, setGithubChecksFunction } = createGithubChecksTool();
20
+ const { tool: githubReviewReplyTool, setGithubReviewReplyFunction } = createGithubReviewReplyTool();
21
+ const { tool: githubSyncTool, setGithubSyncFunction } = createGithubSyncTool();
22
+ const { tool: githubReadTool, setGithubReadFunction } = createGithubReadTool();
23
+ const { tool: githubIssueTool, setGithubIssueFunction } = createGithubIssueTool();
24
+ return {
25
+ tools: [
26
+ githubPrTool,
27
+ githubChecksTool,
28
+ githubReviewReplyTool,
29
+ githubSyncTool,
30
+ githubReadTool,
31
+ githubIssueTool,
32
+ ],
33
+ bindRun({ conversationId, platformName }) {
34
+ if (platformName !== "github") {
35
+ setGithubPrFunction(null);
36
+ setGithubChecksFunction(null);
37
+ setGithubReviewReplyFunction(null);
38
+ setGithubSyncFunction(null);
39
+ setGithubReadFunction(null);
40
+ setGithubIssueFunction(null);
41
+ return;
42
+ }
43
+ setGithubPrFunction((request) => ops.pushAndCreatePr(conversationId, request));
44
+ setGithubChecksFunction({
45
+ getChecks: (branch) => ops.getChecks(conversationId, branch),
46
+ getJobLog: (jobId) => ops.getJobLog(conversationId, jobId),
47
+ getBuildLog: (buildId) => ops.getBuildLog(conversationId, buildId),
48
+ });
49
+ setGithubReviewReplyFunction((commentId, body) => ops.replyToReviewThread(conversationId, commentId, body));
50
+ setGithubSyncFunction((branch) => ops.syncRepo(conversationId, branch));
51
+ setGithubReadFunction((request) => ops.readGithub(conversationId, request));
52
+ setGithubIssueFunction((request) => ops.manageIssue(conversationId, request));
53
+ },
54
+ };
55
+ }
56
+ //# sourceMappingURL=tool-pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-pack.js","sourceRoot":"","sources":["../../../src/adapters/github/tool-pack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAsB;IACzD,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,mBAAmB,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACzE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACrF,MAAM,EAAE,IAAI,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,GACjE,2BAA2B,EAAE,CAAC;IAChC,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,qBAAqB,EAAE,GAAG,oBAAoB,EAAE,CAAC;IAC/E,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,qBAAqB,EAAE,GAAG,oBAAoB,EAAE,CAAC;IAC/E,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,sBAAsB,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAElF,OAAO;QACL,KAAK,EAAE;YACL,YAAY;YACZ,gBAAgB;YAChB,qBAAqB;YACrB,cAAc;YACd,cAAc;YACd,eAAe;SAChB;QACD,OAAO,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE;YACtC,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC9B,mBAAmB,CAAC,IAAI,CAAC,CAAC;gBAC1B,uBAAuB,CAAC,IAAI,CAAC,CAAC;gBAC9B,4BAA4B,CAAC,IAAI,CAAC,CAAC;gBACnC,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBAC5B,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBAC5B,sBAAsB,CAAC,IAAI,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,mBAAmB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/E,uBAAuB,CAAC;gBACtB,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;gBAC5D,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC;gBAC1D,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,OAAO,CAAC;aACnE,CAAC,CAAC;YACH,4BAA4B,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAC/C,GAAG,CAAC,mBAAmB,CAAC,cAAc,EAAE,SAAS,EAAE,IAAI,CAAC,CACzD,CAAC;YACF,qBAAqB,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;YACxE,qBAAqB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;YAC5E,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;QAChF,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { createGithubChecksTool } from \"./tools/checks.js\";\nimport { createGithubPrTool } from \"./tools/pr.js\";\nimport { createGithubIssueTool } from \"./tools/issue.js\";\nimport { createGithubReadTool } from \"./tools/read.js\";\nimport { createGithubReviewReplyTool } from \"./tools/review-reply.js\";\nimport { createGithubSyncTool } from \"./tools/sync.js\";\nimport type { PlatformToolPack } from \"../../tools/types.js\";\nimport type { PlatformGithubOps } from \"./types.js\";\n\n/**\n * GitHub host-side capability pack — one tool per module under `tools/`:\n * github_pr, github_checks, github_review_reply, github_sync, github_read,\n * github_issue.\n *\n * These tools never run in the sandbox; they call PlatformGithubOps which\n * mints short-lived installation tokens on the host. The pack is only\n * constructed when the GitHub bot is configured; bindRun enables the tools\n * only for github-named conversations so multi-platform processes stay safe.\n */\nexport function createGithubToolPack(ops: PlatformGithubOps): PlatformToolPack {\n const { tool: githubPrTool, setGithubPrFunction } = createGithubPrTool();\n const { tool: githubChecksTool, setGithubChecksFunction } = createGithubChecksTool();\n const { tool: githubReviewReplyTool, setGithubReviewReplyFunction } =\n createGithubReviewReplyTool();\n const { tool: githubSyncTool, setGithubSyncFunction } = createGithubSyncTool();\n const { tool: githubReadTool, setGithubReadFunction } = createGithubReadTool();\n const { tool: githubIssueTool, setGithubIssueFunction } = createGithubIssueTool();\n\n return {\n tools: [\n githubPrTool,\n githubChecksTool,\n githubReviewReplyTool,\n githubSyncTool,\n githubReadTool,\n githubIssueTool,\n ],\n bindRun({ conversationId, platformName }) {\n if (platformName !== \"github\") {\n setGithubPrFunction(null);\n setGithubChecksFunction(null);\n setGithubReviewReplyFunction(null);\n setGithubSyncFunction(null);\n setGithubReadFunction(null);\n setGithubIssueFunction(null);\n return;\n }\n setGithubPrFunction((request) => ops.pushAndCreatePr(conversationId, request));\n setGithubChecksFunction({\n getChecks: (branch) => ops.getChecks(conversationId, branch),\n getJobLog: (jobId) => ops.getJobLog(conversationId, jobId),\n getBuildLog: (buildId) => ops.getBuildLog(conversationId, buildId),\n });\n setGithubReviewReplyFunction((commentId, body) =>\n ops.replyToReviewThread(conversationId, commentId, body),\n );\n setGithubSyncFunction((branch) => ops.syncRepo(conversationId, branch));\n setGithubReadFunction((request) => ops.readGithub(conversationId, request));\n setGithubIssueFunction((request) => ops.manageIssue(conversationId, request));\n },\n };\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import type { AgentTool } from "@earendil-works/pi-agent-core";
2
+ import type { GithubCheckSummary } from "../types.js";
3
+ declare const githubChecksSchema: import("@sinclair/typebox").TObject<{
4
+ branch: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
5
+ job_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
6
+ build_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
7
+ }>;
8
+ export interface GithubChecksFns {
9
+ getChecks: (branch?: string) => Promise<GithubCheckSummary[]>;
10
+ getJobLog: (jobId: number) => Promise<string>;
11
+ getBuildLog: (buildId: string) => Promise<string>;
12
+ }
13
+ /**
14
+ * The `github_checks` tool reads CI check runs (GitHub Actions and other
15
+ * check-reporting apps) for a branch or the conversation's PR head, and can
16
+ * fetch one job's log tail so the agent can diagnose failures and iterate.
17
+ * Read-only, host-side; wired per run and only for GitHub conversations.
18
+ */
19
+ export declare function createGithubChecksTool(): {
20
+ tool: AgentTool<typeof githubChecksSchema>;
21
+ setGithubChecksFunction: (fns: GithubChecksFns | null) => void;
22
+ };
23
+ export {};
24
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../../src/adapters/github/tools/checks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,QAAA,MAAM,kBAAkB;;;;EAsBtB,CAAC;AA+BH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC9D,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,IAAI,EAAE,SAAS,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAC3C,uBAAuB,EAAE,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;CAChE,CAgFA"}
@@ -0,0 +1,116 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ const githubChecksSchema = Type.Object({
3
+ branch: Type.Optional(Type.String({
4
+ description: "Branch whose CI checks to read (e.g. a pi/<name> branch you pushed). " +
5
+ "Omit in a pull-request conversation to read the PR head's checks.",
6
+ })),
7
+ job_id: Type.Optional(Type.Number({
8
+ description: "A [job …] id from the summary output (GitHub Actions checks) — returns that " +
9
+ "CI job's log (tail) instead of the summary, for diagnosing a failing check.",
10
+ })),
11
+ build_id: Type.Optional(Type.String({
12
+ description: "A [build …] uuid from the summary output (Cloud Build checks) — returns that " +
13
+ "build's log (tail) instead of the summary. Mutually exclusive with job_id.",
14
+ })),
15
+ });
16
+ /** Conclusions that mean "this check did not pass and needs attention". */
17
+ const FAILING_CONCLUSIONS = new Set(["failure", "timed_out", "action_required", "cancelled"]);
18
+ function formatCheckLine(run) {
19
+ const state = run.status === "completed" ? (run.conclusion ?? "unknown") : run.status;
20
+ const marker = run.conclusion === null
21
+ ? "…"
22
+ : FAILING_CONCLUSIONS.has(run.conclusion)
23
+ ? "✗"
24
+ : run.conclusion === "success"
25
+ ? "✓"
26
+ : "−";
27
+ // GitHub Actions logs fetch via job_id; Cloud Build logs via build_id when
28
+ // the host has GCP credentials. Other external CI keeps logs on its own
29
+ // service, so advertising an id there would only invite doomed fetches.
30
+ const handle = run.appSlug === "github-actions"
31
+ ? `[job ${run.id}]`
32
+ : run.buildLogAvailable && run.externalId
33
+ ? `[build ${run.externalId}]`
34
+ : `[external CI: ${run.appSlug ?? "unknown"} — logs not on GitHub]`;
35
+ const line = `${marker} ${run.name}: ${state} ${handle}${run.url ? ` (${run.url})` : ""}`;
36
+ const failed = run.conclusion !== null && FAILING_CONCLUSIONS.has(run.conclusion);
37
+ return failed && run.outputSummary
38
+ ? `${line}\n ↳ ${run.outputSummary.replace(/\s*\n\s*/g, " ")}`
39
+ : line;
40
+ }
41
+ /**
42
+ * The `github_checks` tool reads CI check runs (GitHub Actions and other
43
+ * check-reporting apps) for a branch or the conversation's PR head, and can
44
+ * fetch one job's log tail so the agent can diagnose failures and iterate.
45
+ * Read-only, host-side; wired per run and only for GitHub conversations.
46
+ */
47
+ export function createGithubChecksTool() {
48
+ let checksFns = null;
49
+ const tool = {
50
+ name: "github_checks",
51
+ label: "github_checks",
52
+ description: "Read CI status (check runs) for a branch you pushed with github_pr, or for this " +
53
+ "conversation's pull request when branch is omitted. Pass job_id (a [job …] id, " +
54
+ "GitHub Actions) or build_id (a [build …] uuid, Cloud Build) from the summary to " +
55
+ "fetch that run's log. Other external CI checks keep logs on their own service: use " +
56
+ "their summary/url, or reproduce the failure locally in ./repo. Only available in " +
57
+ "GitHub conversations.",
58
+ parameters: githubChecksSchema,
59
+ execute: async (_toolCallId, args, signal) => {
60
+ if (!checksFns) {
61
+ throw new Error("github_checks is only available in GitHub conversations.");
62
+ }
63
+ if (signal?.aborted) {
64
+ throw new Error("Operation aborted");
65
+ }
66
+ if (args.job_id !== undefined && args.build_id !== undefined) {
67
+ throw new Error("Pass either job_id or build_id, not both.");
68
+ }
69
+ if (args.job_id !== undefined) {
70
+ const logText = await checksFns.getJobLog(args.job_id);
71
+ return {
72
+ content: [{ type: "text", text: logText || "(empty log)" }],
73
+ details: undefined,
74
+ };
75
+ }
76
+ if (args.build_id !== undefined) {
77
+ const logText = await checksFns.getBuildLog(args.build_id);
78
+ return {
79
+ content: [{ type: "text", text: logText || "(empty log)" }],
80
+ details: undefined,
81
+ };
82
+ }
83
+ const runs = await checksFns.getChecks(args.branch);
84
+ if (runs.length === 0) {
85
+ return {
86
+ content: [
87
+ {
88
+ type: "text",
89
+ text: "No check runs found — CI may not have started yet; try again shortly.",
90
+ },
91
+ ],
92
+ details: undefined,
93
+ };
94
+ }
95
+ const completed = runs.filter((run) => run.status === "completed");
96
+ const failing = completed.filter((run) => run.conclusion !== null && FAILING_CONCLUSIONS.has(run.conclusion));
97
+ const summary = `${runs.length} check(s): ${completed.length} completed, ${runs.length - completed.length} running, ${failing.length} failing`;
98
+ return {
99
+ content: [
100
+ {
101
+ type: "text",
102
+ text: [summary, ...runs.map(formatCheckLine)].join("\n"),
103
+ },
104
+ ],
105
+ details: undefined,
106
+ };
107
+ },
108
+ };
109
+ return {
110
+ tool,
111
+ setGithubChecksFunction: (fns) => {
112
+ checksFns = fns;
113
+ },
114
+ };
115
+ }
116
+ //# sourceMappingURL=checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../../../../src/adapters/github/tools/checks.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Type } from \"@sinclair/typebox\";\nimport type { GithubCheckSummary } from \"../types.js\";\n\nconst githubChecksSchema = Type.Object({\n branch: Type.Optional(\n Type.String({\n description:\n \"Branch whose CI checks to read (e.g. a pi/<name> branch you pushed). \" +\n \"Omit in a pull-request conversation to read the PR head's checks.\",\n }),\n ),\n job_id: Type.Optional(\n Type.Number({\n description:\n \"A [job …] id from the summary output (GitHub Actions checks) — returns that \" +\n \"CI job's log (tail) instead of the summary, for diagnosing a failing check.\",\n }),\n ),\n build_id: Type.Optional(\n Type.String({\n description:\n \"A [build …] uuid from the summary output (Cloud Build checks) — returns that \" +\n \"build's log (tail) instead of the summary. Mutually exclusive with job_id.\",\n }),\n ),\n});\n\n/** Conclusions that mean \"this check did not pass and needs attention\". */\nconst FAILING_CONCLUSIONS = new Set([\"failure\", \"timed_out\", \"action_required\", \"cancelled\"]);\n\nfunction formatCheckLine(run: GithubCheckSummary): string {\n const state = run.status === \"completed\" ? (run.conclusion ?? \"unknown\") : run.status;\n const marker =\n run.conclusion === null\n ? \"…\"\n : FAILING_CONCLUSIONS.has(run.conclusion)\n ? \"✗\"\n : run.conclusion === \"success\"\n ? \"✓\"\n : \"−\";\n // GitHub Actions logs fetch via job_id; Cloud Build logs via build_id when\n // the host has GCP credentials. Other external CI keeps logs on its own\n // service, so advertising an id there would only invite doomed fetches.\n const handle =\n run.appSlug === \"github-actions\"\n ? `[job ${run.id}]`\n : run.buildLogAvailable && run.externalId\n ? `[build ${run.externalId}]`\n : `[external CI: ${run.appSlug ?? \"unknown\"} — logs not on GitHub]`;\n const line = `${marker} ${run.name}: ${state} ${handle}${run.url ? ` (${run.url})` : \"\"}`;\n const failed = run.conclusion !== null && FAILING_CONCLUSIONS.has(run.conclusion);\n return failed && run.outputSummary\n ? `${line}\\n ↳ ${run.outputSummary.replace(/\\s*\\n\\s*/g, \" \")}`\n : line;\n}\n\nexport interface GithubChecksFns {\n getChecks: (branch?: string) => Promise<GithubCheckSummary[]>;\n getJobLog: (jobId: number) => Promise<string>;\n getBuildLog: (buildId: string) => Promise<string>;\n}\n\n/**\n * The `github_checks` tool reads CI check runs (GitHub Actions and other\n * check-reporting apps) for a branch or the conversation's PR head, and can\n * fetch one job's log tail so the agent can diagnose failures and iterate.\n * Read-only, host-side; wired per run and only for GitHub conversations.\n */\nexport function createGithubChecksTool(): {\n tool: AgentTool<typeof githubChecksSchema>;\n setGithubChecksFunction: (fns: GithubChecksFns | null) => void;\n} {\n let checksFns: GithubChecksFns | null = null;\n\n const tool: AgentTool<typeof githubChecksSchema> = {\n name: \"github_checks\",\n label: \"github_checks\",\n description:\n \"Read CI status (check runs) for a branch you pushed with github_pr, or for this \" +\n \"conversation's pull request when branch is omitted. Pass job_id (a [job …] id, \" +\n \"GitHub Actions) or build_id (a [build …] uuid, Cloud Build) from the summary to \" +\n \"fetch that run's log. Other external CI checks keep logs on their own service: use \" +\n \"their summary/url, or reproduce the failure locally in ./repo. Only available in \" +\n \"GitHub conversations.\",\n parameters: githubChecksSchema,\n execute: async (\n _toolCallId: string,\n args: { branch?: string; job_id?: number; build_id?: string },\n signal?: AbortSignal,\n ) => {\n if (!checksFns) {\n throw new Error(\"github_checks is only available in GitHub conversations.\");\n }\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n if (args.job_id !== undefined && args.build_id !== undefined) {\n throw new Error(\"Pass either job_id or build_id, not both.\");\n }\n\n if (args.job_id !== undefined) {\n const logText = await checksFns.getJobLog(args.job_id);\n return {\n content: [{ type: \"text\" as const, text: logText || \"(empty log)\" }],\n details: undefined,\n };\n }\n\n if (args.build_id !== undefined) {\n const logText = await checksFns.getBuildLog(args.build_id);\n return {\n content: [{ type: \"text\" as const, text: logText || \"(empty log)\" }],\n details: undefined,\n };\n }\n\n const runs = await checksFns.getChecks(args.branch);\n if (runs.length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"No check runs found — CI may not have started yet; try again shortly.\",\n },\n ],\n details: undefined,\n };\n }\n const completed = runs.filter((run) => run.status === \"completed\");\n const failing = completed.filter(\n (run) => run.conclusion !== null && FAILING_CONCLUSIONS.has(run.conclusion),\n );\n const summary = `${runs.length} check(s): ${completed.length} completed, ${runs.length - completed.length} running, ${failing.length} failing`;\n return {\n content: [\n {\n type: \"text\" as const,\n text: [summary, ...runs.map(formatCheckLine)].join(\"\\n\"),\n },\n ],\n details: undefined,\n };\n },\n };\n\n return {\n tool,\n setGithubChecksFunction: (fns) => {\n checksFns = fns;\n },\n };\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import type { AgentTool } from "@earendil-works/pi-agent-core";
2
+ import type { GithubIssueRequest } from "../types.js";
3
+ declare const githubIssueSchema: import("@sinclair/typebox").TObject<{
4
+ action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"add_labels">, import("@sinclair/typebox").TLiteral<"remove_label">, import("@sinclair/typebox").TLiteral<"add_assignees">, import("@sinclair/typebox").TLiteral<"remove_assignees">, import("@sinclair/typebox").TLiteral<"close">, import("@sinclair/typebox").TLiteral<"reopen">]>;
5
+ number: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
6
+ labels: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
7
+ label: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
8
+ assignees: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
9
+ state_reason: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"completed">, import("@sinclair/typebox").TLiteral<"not_planned">]>>;
10
+ }>;
11
+ export type GithubIssueFn = (request: GithubIssueRequest) => Promise<string>;
12
+ /**
13
+ * The `github_issue` tool manages labels, assignees, and open/closed state of
14
+ * issues in the conversation's repo (any issue number — triage). Host-side as
15
+ * the App; wired per run and only for GitHub conversations.
16
+ */
17
+ export declare function createGithubIssueTool(): {
18
+ tool: AgentTool<typeof githubIssueSchema>;
19
+ setGithubIssueFunction: (fn: GithubIssueFn | null) => void;
20
+ };
21
+ export {};
22
+ //# sourceMappingURL=issue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../../../src/adapters/github/tools/issue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,QAAA,MAAM,iBAAiB;;;;;;;EA+BrB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI;IACvC,IAAI,EAAE,SAAS,CAAC,OAAO,iBAAiB,CAAC,CAAC;IAC1C,sBAAsB,EAAE,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;CAC5D,CAiCA"}
@@ -0,0 +1,59 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ const githubIssueSchema = Type.Object({
3
+ action: Type.Union([
4
+ Type.Literal("add_labels"),
5
+ Type.Literal("remove_label"),
6
+ Type.Literal("add_assignees"),
7
+ Type.Literal("remove_assignees"),
8
+ Type.Literal("close"),
9
+ Type.Literal("reopen"),
10
+ ], { description: "Issue management action." }),
11
+ number: Type.Optional(Type.Number({
12
+ description: "Issue/PR number in this repo; omit for this conversation's own.",
13
+ })),
14
+ labels: Type.Optional(Type.Array(Type.String(), { description: "add_labels: label names to add." })),
15
+ label: Type.Optional(Type.String({ description: "remove_label: the label name to remove." })),
16
+ assignees: Type.Optional(Type.Array(Type.String(), {
17
+ description: "add_assignees / remove_assignees: GitHub logins.",
18
+ })),
19
+ state_reason: Type.Optional(Type.Union([Type.Literal("completed"), Type.Literal("not_planned")], {
20
+ description: "close: why the issue is being closed.",
21
+ })),
22
+ });
23
+ /**
24
+ * The `github_issue` tool manages labels, assignees, and open/closed state of
25
+ * issues in the conversation's repo (any issue number — triage). Host-side as
26
+ * the App; wired per run and only for GitHub conversations.
27
+ */
28
+ export function createGithubIssueTool() {
29
+ let issueFn = null;
30
+ const tool = {
31
+ name: "github_issue",
32
+ label: "github_issue",
33
+ description: "Manage issues in this repo: add/remove labels, add/remove assignees, close " +
34
+ "(optionally with state_reason) or reopen. number defaults to this conversation's " +
35
+ "issue; any issue number in this repo works for triage. Only available in GitHub " +
36
+ "conversations.",
37
+ parameters: githubIssueSchema,
38
+ execute: async (_toolCallId, args, signal) => {
39
+ if (!issueFn) {
40
+ throw new Error("github_issue is only available in GitHub conversations.");
41
+ }
42
+ if (signal?.aborted) {
43
+ throw new Error("Operation aborted");
44
+ }
45
+ const report = await issueFn(args);
46
+ return {
47
+ content: [{ type: "text", text: report }],
48
+ details: undefined,
49
+ };
50
+ },
51
+ };
52
+ return {
53
+ tool,
54
+ setGithubIssueFunction: (fn) => {
55
+ issueFn = fn;
56
+ },
57
+ };
58
+ }
59
+ //# sourceMappingURL=issue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.js","sourceRoot":"","sources":["../../../../src/adapters/github/tools/issue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC;IACpC,MAAM,EAAE,IAAI,CAAC,KAAK,CAChB;QACE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;KACvB,EACD,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAC5C;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,MAAM,CAAC;QACV,WAAW,EAAE,iEAAiE;KAC/E,CAAC,CACH;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC,CAC9E;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yCAAyC,EAAE,CAAC,CAAC;IAC7F,SAAS,EAAE,IAAI,CAAC,QAAQ,CACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE;QACxB,WAAW,EAAE,kDAAkD;KAChE,CAAC,CACH;IACD,YAAY,EAAE,IAAI,CAAC,QAAQ,CACzB,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE;QACnE,WAAW,EAAE,uCAAuC;KACrD,CAAC,CACH;CACF,CAAC,CAAC;AAIH;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IAInC,IAAI,OAAO,GAAyB,IAAI,CAAC;IAEzC,MAAM,IAAI,GAAwC;QAChD,IAAI,EAAE,cAAc;QACpB,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,6EAA6E;YAC7E,mFAAmF;YACnF,kFAAkF;YAClF,gBAAgB;QAClB,UAAU,EAAE,iBAAiB;QAC7B,OAAO,EAAE,KAAK,EAAE,WAAmB,EAAE,IAAwB,EAAE,MAAoB,EAAE,EAAE;YACrF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;YAC7E,CAAC;YACD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;YACnC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBAClD,OAAO,EAAE,SAAS;aACnB,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE;YAC7B,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Type } from \"@sinclair/typebox\";\nimport type { GithubIssueRequest } from \"../types.js\";\n\nconst githubIssueSchema = Type.Object({\n action: Type.Union(\n [\n Type.Literal(\"add_labels\"),\n Type.Literal(\"remove_label\"),\n Type.Literal(\"add_assignees\"),\n Type.Literal(\"remove_assignees\"),\n Type.Literal(\"close\"),\n Type.Literal(\"reopen\"),\n ],\n { description: \"Issue management action.\" },\n ),\n number: Type.Optional(\n Type.Number({\n description: \"Issue/PR number in this repo; omit for this conversation's own.\",\n }),\n ),\n labels: Type.Optional(\n Type.Array(Type.String(), { description: \"add_labels: label names to add.\" }),\n ),\n label: Type.Optional(Type.String({ description: \"remove_label: the label name to remove.\" })),\n assignees: Type.Optional(\n Type.Array(Type.String(), {\n description: \"add_assignees / remove_assignees: GitHub logins.\",\n }),\n ),\n state_reason: Type.Optional(\n Type.Union([Type.Literal(\"completed\"), Type.Literal(\"not_planned\")], {\n description: \"close: why the issue is being closed.\",\n }),\n ),\n});\n\nexport type GithubIssueFn = (request: GithubIssueRequest) => Promise<string>;\n\n/**\n * The `github_issue` tool manages labels, assignees, and open/closed state of\n * issues in the conversation's repo (any issue number — triage). Host-side as\n * the App; wired per run and only for GitHub conversations.\n */\nexport function createGithubIssueTool(): {\n tool: AgentTool<typeof githubIssueSchema>;\n setGithubIssueFunction: (fn: GithubIssueFn | null) => void;\n} {\n let issueFn: GithubIssueFn | null = null;\n\n const tool: AgentTool<typeof githubIssueSchema> = {\n name: \"github_issue\",\n label: \"github_issue\",\n description:\n \"Manage issues in this repo: add/remove labels, add/remove assignees, close \" +\n \"(optionally with state_reason) or reopen. number defaults to this conversation's \" +\n \"issue; any issue number in this repo works for triage. Only available in GitHub \" +\n \"conversations.\",\n parameters: githubIssueSchema,\n execute: async (_toolCallId: string, args: GithubIssueRequest, signal?: AbortSignal) => {\n if (!issueFn) {\n throw new Error(\"github_issue is only available in GitHub conversations.\");\n }\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n const report = await issueFn(args);\n return {\n content: [{ type: \"text\" as const, text: report }],\n details: undefined,\n };\n },\n };\n\n return {\n tool,\n setGithubIssueFunction: (fn) => {\n issueFn = fn;\n },\n };\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import type { AgentTool } from "@earendil-works/pi-agent-core";
2
+ import type { GithubPrRequest, GithubPrResult } from "../types.js";
3
+ declare const githubPrSchema: import("@sinclair/typebox").TObject<{
4
+ branch: import("@sinclair/typebox").TString;
5
+ title: import("@sinclair/typebox").TString;
6
+ body: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
7
+ base: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
8
+ draft: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
9
+ }>;
10
+ /**
11
+ * The `github_pr` tool pushes a branch the agent prepared in the
12
+ * conversation's ./repo clone and opens a pull request as the GitHub App.
13
+ * The push and API calls run host-side with an ephemeral repo-scoped token;
14
+ * the sandbox never holds credentials. Wired per run via the setter, and only
15
+ * for GitHub conversations.
16
+ */
17
+ export declare function createGithubPrTool(): {
18
+ tool: AgentTool<typeof githubPrSchema>;
19
+ setGithubPrFunction: (fn: ((request: GithubPrRequest) => Promise<GithubPrResult>) | null) => void;
20
+ };
21
+ export {};
22
+ //# sourceMappingURL=pr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../../../src/adapters/github/tools/pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE,QAAA,MAAM,cAAc;;;;;;EAalB,CAAC;AAIH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,IAAI,EAAE,SAAS,CAAC,OAAO,cAAc,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;CACnG,CAyCA"}
@@ -0,0 +1,59 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ const githubPrSchema = Type.Object({
3
+ branch: Type.String({
4
+ description: 'Local branch inside ./repo to push. Must be named pi/<something> (e.g. "pi/fix-42"); ' +
5
+ "the default branch is never pushable. To update this conversation's own PR, pass its " +
6
+ "checked-out pi/* head branch.",
7
+ }),
8
+ title: Type.String({ description: "Pull request title." }),
9
+ body: Type.Optional(Type.String({ description: "Pull request description (Markdown)." })),
10
+ base: Type.Optional(Type.String({ description: "Target branch; defaults to the repository's default branch." })),
11
+ draft: Type.Optional(Type.Boolean({ description: "Open as a draft pull request." })),
12
+ });
13
+ /**
14
+ * The `github_pr` tool pushes a branch the agent prepared in the
15
+ * conversation's ./repo clone and opens a pull request as the GitHub App.
16
+ * The push and API calls run host-side with an ephemeral repo-scoped token;
17
+ * the sandbox never holds credentials. Wired per run via the setter, and only
18
+ * for GitHub conversations.
19
+ */
20
+ export function createGithubPrTool() {
21
+ let prFn = null;
22
+ const tool = {
23
+ name: "github_pr",
24
+ label: "github_pr",
25
+ description: "Push a pi/<name> branch you committed inside ./repo and open a GitHub pull request " +
26
+ "(or draft) for it. Pushing a branch that already has an open PR — including this " +
27
+ "conversation's own PR head — updates that PR instead of opening a new one. Only " +
28
+ "available in GitHub issue/PR conversations. You cannot push to the default branch " +
29
+ "and you cannot merge — humans review and merge the PR.",
30
+ parameters: githubPrSchema,
31
+ execute: async (_toolCallId, args, signal) => {
32
+ if (!prFn) {
33
+ throw new Error("github_pr is only available in GitHub conversations.");
34
+ }
35
+ if (signal?.aborted) {
36
+ throw new Error("Operation aborted");
37
+ }
38
+ const result = await prFn(args);
39
+ return {
40
+ content: [
41
+ {
42
+ type: "text",
43
+ text: result.updatedExisting
44
+ ? `Pushed to existing PR #${result.number}: ${result.url}`
45
+ : `Opened ${args.draft ? "draft " : ""}PR #${result.number}: ${result.url}`,
46
+ },
47
+ ],
48
+ details: undefined,
49
+ };
50
+ },
51
+ };
52
+ return {
53
+ tool,
54
+ setGithubPrFunction: (fn) => {
55
+ prFn = fn;
56
+ },
57
+ };
58
+ }
59
+ //# sourceMappingURL=pr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.js","sourceRoot":"","sources":["../../../../src/adapters/github/tools/pr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QAClB,WAAW,EACT,uFAAuF;YACvF,uFAAuF;YACvF,+BAA+B;KAClC,CAAC;IACF,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;IAC1D,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC,CAAC;IACzF,IAAI,EAAE,IAAI,CAAC,QAAQ,CACjB,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,6DAA6D,EAAE,CAAC,CAC5F;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC,CAAC;CACrF,CAAC,CAAC;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB;IAIhC,IAAI,IAAI,GAAmE,IAAI,CAAC;IAEhF,MAAM,IAAI,GAAqC;QAC7C,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,WAAW;QAClB,WAAW,EACT,qFAAqF;YACrF,mFAAmF;YACnF,kFAAkF;YAClF,oFAAoF;YACpF,wDAAwD;QAC1D,UAAU,EAAE,cAAc;QAC1B,OAAO,EAAE,KAAK,EAAE,WAAmB,EAAE,IAAkB,EAAE,MAAoB,EAAE,EAAE;YAC/E,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,CAAC;YACD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,MAAM,CAAC,eAAe;4BAC1B,CAAC,CAAC,0BAA0B,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,EAAE;4BAC1D,CAAC,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,EAAE;qBAC9E;iBACF;gBACD,OAAO,EAAE,SAAS;aACnB,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,mBAAmB,EAAE,CAAC,EAAE,EAAE,EAAE;YAC1B,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { Type } from \"@sinclair/typebox\";\nimport type { GithubPrRequest, GithubPrResult } from \"../types.js\";\n\nconst githubPrSchema = Type.Object({\n branch: Type.String({\n description:\n 'Local branch inside ./repo to push. Must be named pi/<something> (e.g. \"pi/fix-42\"); ' +\n \"the default branch is never pushable. To update this conversation's own PR, pass its \" +\n \"checked-out pi/* head branch.\",\n }),\n title: Type.String({ description: \"Pull request title.\" }),\n body: Type.Optional(Type.String({ description: \"Pull request description (Markdown).\" })),\n base: Type.Optional(\n Type.String({ description: \"Target branch; defaults to the repository's default branch.\" }),\n ),\n draft: Type.Optional(Type.Boolean({ description: \"Open as a draft pull request.\" })),\n});\n\ntype GithubPrArgs = GithubPrRequest;\n\n/**\n * The `github_pr` tool pushes a branch the agent prepared in the\n * conversation's ./repo clone and opens a pull request as the GitHub App.\n * The push and API calls run host-side with an ephemeral repo-scoped token;\n * the sandbox never holds credentials. Wired per run via the setter, and only\n * for GitHub conversations.\n */\nexport function createGithubPrTool(): {\n tool: AgentTool<typeof githubPrSchema>;\n setGithubPrFunction: (fn: ((request: GithubPrRequest) => Promise<GithubPrResult>) | null) => void;\n} {\n let prFn: ((request: GithubPrRequest) => Promise<GithubPrResult>) | null = null;\n\n const tool: AgentTool<typeof githubPrSchema> = {\n name: \"github_pr\",\n label: \"github_pr\",\n description:\n \"Push a pi/<name> branch you committed inside ./repo and open a GitHub pull request \" +\n \"(or draft) for it. Pushing a branch that already has an open PR — including this \" +\n \"conversation's own PR head — updates that PR instead of opening a new one. Only \" +\n \"available in GitHub issue/PR conversations. You cannot push to the default branch \" +\n \"and you cannot merge — humans review and merge the PR.\",\n parameters: githubPrSchema,\n execute: async (_toolCallId: string, args: GithubPrArgs, signal?: AbortSignal) => {\n if (!prFn) {\n throw new Error(\"github_pr is only available in GitHub conversations.\");\n }\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n const result = await prFn(args);\n return {\n content: [\n {\n type: \"text\" as const,\n text: result.updatedExisting\n ? `Pushed to existing PR #${result.number}: ${result.url}`\n : `Opened ${args.draft ? \"draft \" : \"\"}PR #${result.number}: ${result.url}`,\n },\n ],\n details: undefined,\n };\n },\n };\n\n return {\n tool,\n setGithubPrFunction: (fn) => {\n prFn = fn;\n },\n };\n}\n"]}